]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/mount.c
kes Stop searching for Volumes in SD askdir if DIR returns the
[bacula/bacula] / bacula / src / stored / mount.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2002-2008 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of John Walker.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  *
30  *  Routines for handling mounting tapes for reading and for
31  *    writing.
32  *
33  *   Kern Sibbald, August MMII
34  *
35  *   Version $Id$
36  */
37
38 #include "bacula.h"                   /* pull in global headers */
39 #include "stored.h"                   /* pull in Storage Deamon headers */
40
41
42 enum {
43    try_next_vol = 1,
44    try_read_vol,
45    try_error,
46    try_default
47 };
48
49 enum {
50    check_next_vol = 1,
51    check_ok,
52    check_read_vol,
53    check_error
54 };
55
56 /*
57  * If release is set, we rewind the current volume,
58  * which we no longer want, and ask the user (console)
59  * to mount the next volume.
60  *
61  *  Continue trying until we get it, and then ensure
62  *  that we can write on it.
63  *
64  * This routine returns a 0 only if it is REALLY
65  *  impossible to get the requested Volume.
66  *
67  */
68 bool DCR::mount_next_write_volume()
69 {
70    int retry = 0;
71    bool ask = false, recycle, autochanger;
72    int mode;
73    DCR *dcr = this;
74
75    Dmsg2(150, "Enter mount_next_volume(release=%d) dev=%s\n", dev->must_unload(),
76       dev->print_name());
77
78    init_device_wait_timers(dcr);
79    lock_volumes();
80    
81    /*
82     * Attempt to mount the next volume. If something non-fatal goes
83     *  wrong, we come back here to re-try (new op messages, re-read
84     *  Volume, ...)
85     */
86 mount_next_vol:
87    Dmsg1(150, "mount_next_vol retry=%d\n", retry);
88    /* Ignore retry if this is poll request */
89    if (!dev->poll && retry++ > 4) {
90       /* Last ditch effort before giving up, force operator to respond */
91       VolCatInfo.Slot = 0;
92       unlock_volumes();
93       if (!dir_ask_sysop_to_mount_volume(dcr, ST_APPEND)) {
94          Jmsg(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s.\n"),
95               dev->print_name());
96          goto no_lock_bail_out;
97       }
98       lock_volumes();
99    }
100    if (job_canceled(jcr)) {
101       Jmsg(jcr, M_FATAL, 0, _("Job %d canceled.\n"), jcr->JobId);
102       goto bail_out;
103    }
104    recycle = false;
105    if (dev->must_unload()) {
106       Dmsg0(150, "mount_next_volume release=1\n");
107       unload_autochanger(dcr, -1);
108       release_volume();
109       dev->clear_unload();
110       ask = true;                     /* ask operator to mount tape */
111    }
112    /*
113     * See if we are asked to swap the Volume from another device
114     *  if so, unload the other device here, and attach the
115     *  volume to our drive.
116     */
117    if (dev->swap_dev) {
118       Dmsg1(100, "Swap unloading %s\n", dev->swap_dev->print_name());
119       if (dev->swap_dev->must_unload()) {
120          unload_dev(dcr, dev->swap_dev);
121       }
122       if (dev->vol) {
123          dev->vol->clear_swapping();
124          dev->vol->set_in_use();
125          dev->VolHdr.VolumeName[0] = 0;  /* don't yet have right Volume */
126       }
127       dev->swap_dev = NULL;
128    }
129    if (dev->must_load()) {
130       dev->clear_load();
131       dev->clear_volhdr();               /* force "load" */
132    }
133    if (!is_suitable_volume_mounted()) {
134       bool have_vol = false;
135       /* Do we have a candidate volume? */
136       if (dev->vol) {
137          bstrncpy(VolumeName, dev->vol->vol_name, sizeof(VolumeName));
138          have_vol = dir_get_volume_info(this, GET_VOL_INFO_FOR_WRITE);
139       }
140       /*
141        * Get Director's idea of what tape we should have mounted.
142        *    in dcr->VolCatInfo
143        */
144       if (!have_vol) {
145          Dmsg0(200, "Before dir_find_next_appendable_volume.\n");
146          while (!dir_find_next_appendable_volume(dcr)) {
147             Dmsg0(200, "not dir_find_next\n");
148             if (job_canceled(jcr)) {
149                goto bail_out;
150             }
151             unlock_volumes();
152             if (!dir_ask_sysop_to_create_appendable_volume(dcr)) {
153                goto no_lock_bail_out;
154              }
155              lock_volumes();
156              Dmsg0(200, "Again dir_find_next_append...\n");
157          }
158          goto mount_next_vol;   
159       }
160    }
161    if (job_canceled(jcr)) {
162       goto bail_out;
163    }
164    Dmsg3(150, "After find_next_append. Vol=%s Slot=%d Parts=%d\n",
165          VolCatInfo.VolCatName, VolCatInfo.Slot, VolCatInfo.VolCatParts);
166    
167    /*
168     * Get next volume and ready it for append
169     * This code ensures that the device is ready for
170     * writing. We start from the assumption that there
171     * may not be a tape mounted.
172     *
173     * If the device is a file, we create the output
174     * file. If it is a tape, we check the volume name
175     * and move the tape to the end of data.
176     *
177     */
178    if (autoload_device(dcr, 1, NULL) > 0) {
179       autochanger = true;
180       ask = false;
181    } else {
182       autochanger = false;
183       VolCatInfo.Slot = 0;
184    }
185    Dmsg1(200, "autoload_dev returns %d\n", autochanger);
186    /*
187     * If we autochanged to correct Volume or (we have not just
188     *   released the Volume AND we can automount) we go ahead
189     *   and read the label. If there is no tape in the drive,
190     *   we will fail, recurse and ask the operator the next time.
191     */
192    if (!dev->must_unload() && dev->is_tape() && dev->has_cap(CAP_AUTOMOUNT)) {
193       Dmsg0(150, "(1)Ask=0\n");
194       ask = false;                 /* don't ask SYSOP this time */
195    }
196    /* Don't ask if not removable */
197    if (!dev->is_removable()) {
198       Dmsg0(150, "(2)Ask=0\n");
199       ask = false;
200    }
201    Dmsg2(150, "Ask=%d autochanger=%d\n", ask, autochanger);
202    dev->must_unload();       /* release next time if we "recurse" */
203
204    if (ask && !dir_ask_sysop_to_mount_volume(dcr, ST_APPEND)) {
205       Dmsg0(150, "Error return ask_sysop ...\n");
206       goto bail_out;          /* error return */
207    }
208    if (job_canceled(jcr)) {
209       goto bail_out;
210    }
211    Dmsg3(150, "want vol=%s devvol=%s dev=%s\n", VolumeName, 
212       dev->VolHdr.VolumeName, dev->print_name());
213
214    if (dev->poll && dev->has_cap(CAP_CLOSEONPOLL)) {
215       dev->close();
216    }
217
218    /* Ensure the device is open */
219    if (dev->has_cap(CAP_STREAM)) {
220       mode = OPEN_WRITE_ONLY;
221    } else {
222       mode = OPEN_READ_WRITE;
223    }
224    /* Try autolabel if enabled */
225    if (dev->open(dcr, mode) < 0) {
226       try_autolabel(false);      /* try to create a new volume label */
227    }
228    while (dev->open(dcr, mode) < 0) {
229       Dmsg1(150, "open_device failed: ERR=%s\n", dev->bstrerror());
230       if ((dev->is_file() && dev->is_removable()) || dev->is_dvd()) {
231          bool ok = true;
232          Dmsg0(150, "call scan_dir_for_vol\n");
233          if (dev->is_dvd()) {
234             if (!dev->mount(0)) {
235                ok = false;
236             }
237          }
238          if (ok && dev->scan_dir_for_volume(dcr)) {
239             if (dev->open(dcr, mode) >= 0) {
240                break;                    /* got a valid volume */
241             }
242          }
243          if (ok && dev->is_dvd()) {
244             dev->unmount(0);
245          }
246       }
247       if (try_autolabel(false) == try_read_vol) {
248          break;                       /* created a new volume label */
249       }
250       /* If DVD, ignore the error, very often you cannot open the device
251        * (when there is no DVD, or when the one inserted is a wrong one) */
252       if (dev->poll || dev->is_dvd() || dev->is_removable()) {
253          goto mount_next_vol;
254       } else {
255          Jmsg(jcr, M_ERROR, 0, _("Could not open device %s: ERR=%s\n"),
256             dev->print_name(), dev->print_errmsg());
257          goto bail_out;
258       }
259    }
260
261    /*
262     * Now check the volume label to make sure we have the right tape mounted
263     */
264 read_volume:
265
266    switch (check_volume_label(ask, autochanger)) {
267    case check_next_vol:
268       goto mount_next_vol;
269    case check_read_vol:
270       goto read_volume;
271    case check_error:
272       goto bail_out;
273    case check_ok:
274       break;
275    }
276
277    /*
278     * See if we have a fresh tape or a tape with data.
279     *
280     * Note, if the LabelType is PRE_LABEL, it was labeled
281     *  but never written. If so, rewrite the label but set as
282     *  VOL_LABEL.  We rewind and return the label (reconstructed)
283     *  in the block so that in the case of a new tape, data can
284     *  be appended just after the block label.  If we are writing
285     *  a second volume, the calling routine will write the label
286     *  before writing the overflow block.
287     *
288     *  If the tape is marked as Recycle, we rewrite the label.
289     */
290    recycle = strcmp(dev->VolCatInfo.VolCatStatus, "Recycle") == 0;
291    if (dev->VolHdr.LabelType == PRE_LABEL || recycle) {
292       if (!rewrite_volume_label(dcr, recycle)) {
293          mark_volume_in_error();
294          goto mount_next_vol;
295       }
296    } else {
297       /*
298        * OK, at this point, we have a valid Bacula label, but
299        * we need to position to the end of the volume, since we are
300        * just now putting it into append mode.
301        */
302       Dmsg0(200, "Device previously written, moving to end of data\n");
303       Jmsg(jcr, M_INFO, 0, _("Volume \"%s\" previously written, moving to end of data.\n"),
304          VolumeName);
305
306       if (!dev->eod(dcr)) {
307          Jmsg(jcr, M_ERROR, 0, _("Unable to position to end of data on device %s: ERR=%s\n"),
308             dev->print_name(), dev->bstrerror());
309          mark_volume_in_error();
310          goto mount_next_vol;
311       }
312       if (!is_eod_valid()) {
313          goto mount_next_vol;
314       }
315
316       dev->VolCatInfo.VolCatMounts++;      /* Update mounts */
317       Dmsg1(150, "update volinfo mounts=%d\n", dev->VolCatInfo.VolCatMounts);
318       if (!dir_update_volume_info(dcr, false, false)) {
319          goto bail_out;
320       }
321       
322       /* Return an empty block */
323       empty_block(block);             /* we used it for reading so set for write */
324    }
325    dev->set_append();
326    Dmsg1(150, "set APPEND, normal return from mount_next_write_volume. dev=%s\n",
327       dev->print_name());
328
329    unlock_volumes();
330    return true;
331
332 bail_out:
333    unlock_volumes();
334
335 no_lock_bail_out:
336    return false;
337 }
338
339 int DCR::check_volume_label(bool &ask, bool &autochanger)
340 {
341    int vol_label_status;
342    /*
343     * If we are writing to a stream device, ASSUME the volume label
344     *  is correct.
345     */
346    if (dev->has_cap(CAP_STREAM)) {
347       vol_label_status = VOL_OK;
348       create_volume_label(dev, VolumeName, "Default", false /* not DVD */);
349       dev->VolHdr.LabelType = PRE_LABEL;
350    } else {
351       vol_label_status = read_dev_volume_label(this);
352    }
353    if (job_canceled(jcr)) {
354       goto check_bail_out;
355    }
356
357    Dmsg2(150, "Want dirVol=%s dirStat=%s\n", VolumeName,
358       VolCatInfo.VolCatStatus);
359    /*
360     * At this point, dev->VolCatInfo has what is in the drive, if anything,
361     *          and   dcr->VolCatInfo has what the Director wants.
362     */
363    switch (vol_label_status) {
364    case VOL_OK:
365       Dmsg1(150, "Vol OK name=%s\n", dev->VolHdr.VolumeName);
366       dev->VolCatInfo = VolCatInfo;       /* structure assignment */
367       break;                    /* got a Volume */
368    case VOL_NAME_ERROR:
369       VOLUME_CAT_INFO dcrVolCatInfo, devVolCatInfo;
370       char saveVolumeName[MAX_NAME_LENGTH];
371
372       /* If not removable, Volume is broken */
373       if (!dev->is_removable()) {
374          Jmsg(jcr, M_WARNING, 0, _("Volume \"%s\" not on device %s.\n"),
375             VolumeName, dev->print_name());
376          mark_volume_in_error();
377          goto check_next_volume;
378       }
379
380       Dmsg1(150, "Vol NAME Error Name=%s\n", VolumeName);
381       /* If polling and got a previous bad name, ignore it */
382       if (dev->poll && strcmp(dev->BadVolName, dev->VolHdr.VolumeName) == 0) {
383          ask = true;
384          Dmsg1(200, "Vol Name error supress due to poll. Name=%s\n", VolumeName);
385          goto check_next_volume;
386       }
387       /*
388        * OK, we got a different volume mounted. First save the
389        *  requested Volume info (dcr) structure, then query if
390        *  this volume is really OK. If not, put back the desired
391        *  volume name, mark it not in changer and continue.
392        */
393       dcrVolCatInfo = VolCatInfo;      /* structure assignment */
394       devVolCatInfo = dev->VolCatInfo;      /* structure assignment */
395       /* Check if this is a valid Volume in the pool */
396       bstrncpy(saveVolumeName, VolumeName, sizeof(saveVolumeName));
397       bstrncpy(VolumeName, dev->VolHdr.VolumeName, sizeof(VolumeName));
398       if (!dir_get_volume_info(this, GET_VOL_INFO_FOR_WRITE)) {
399          POOL_MEM vol_info_msg;
400          pm_strcpy(vol_info_msg, jcr->dir_bsock->msg);  /* save error message */
401          /* Restore desired volume name, note device info out of sync */
402          /* This gets the info regardless of the Pool */
403          bstrncpy(VolumeName, dev->VolHdr.VolumeName, sizeof(VolumeName));
404          if (autochanger && !dir_get_volume_info(this, GET_VOL_INFO_FOR_READ)) {
405             /*
406              * If we get here, we know we cannot write on the Volume,
407              *  and we know that we cannot read it either, so it 
408              *  is not in the autochanger.
409              */
410             mark_volume_not_inchanger();
411          }
412          dev->VolCatInfo = devVolCatInfo;    /* structure assignment */
413          bstrncpy(dev->BadVolName, dev->VolHdr.VolumeName, sizeof(dev->BadVolName));
414          Jmsg(jcr, M_WARNING, 0, _("Director wanted Volume \"%s\".\n"
415               "    Current Volume \"%s\" not acceptable because:\n"
416               "    %s"),
417              dcrVolCatInfo.VolCatName, dev->VolHdr.VolumeName,
418              vol_info_msg.c_str());
419          ask = true;
420          /* Restore saved DCR before continuing */
421          bstrncpy(VolumeName, saveVolumeName, sizeof(VolumeName));
422          VolCatInfo = dcrVolCatInfo;  /* structure assignment */
423          goto check_next_volume;
424       }
425       /*
426        * This was not the volume we expected, but it is OK with
427        * the Director, so use it.
428        */
429       Dmsg1(150, "Got new Volume name=%s\n", VolumeName);
430       dev->VolCatInfo = VolCatInfo;   /* structure assignment */
431       break;                /* got a Volume */
432    /*
433     * At this point, we assume we have a blank tape mounted.
434     */
435    case VOL_IO_ERROR:
436       if (dev->is_dvd()) {
437          Jmsg(jcr, M_FATAL, 0, "%s", jcr->errmsg);
438          mark_volume_in_error();
439          goto check_bail_out;       /* we could not write on DVD */
440       }
441       /* Fall through wanted */
442    case VOL_NO_LABEL:
443       switch (try_autolabel(true)) {
444       case try_next_vol:
445          goto check_next_volume;
446       case try_read_vol:
447          goto check_read_volume;
448       case try_error:
449          goto check_bail_out;
450       case try_default:
451          break;
452       }
453
454       /* NOTE! Fall-through wanted. */
455    case VOL_NO_MEDIA:
456    default:
457       Dmsg0(200, "VOL_NO_MEDIA or default.\n");
458       /* Send error message */
459       if (!dev->poll) {
460       } else {
461          Dmsg1(200, "Msg suppressed by poll: %s\n", jcr->errmsg);
462       }
463       ask = true;
464       /* Needed, so the medium can be changed */
465       if (dev->requires_mount()) {
466          dev->close();
467       }
468       goto check_next_volume;
469    }
470    return check_ok;
471
472 check_next_volume:
473    return check_next_vol;
474
475 check_bail_out:
476    return check_error;
477
478 check_read_volume:
479    return check_read_vol;
480
481 }
482
483
484 bool DCR::is_suitable_volume_mounted()
485 {
486
487    /* Volume mounted? */
488    if (dev->VolHdr.VolumeName[0] == 0 || dev->swap_dev || dev->must_unload()) {
489       return false;                      /* no */
490    }
491    bstrncpy(VolumeName, dev->VolHdr.VolumeName, sizeof(VolumeName));
492    return dir_get_volume_info(this, GET_VOL_INFO_FOR_WRITE);
493 }
494
495
496
497 /*
498  * Check if the current position on the volume corresponds to
499  *  what is in the catalog.
500  */
501 bool DCR::is_eod_valid()
502 {
503    if (dev->is_dvd()) {
504       char ed1[50], ed2[50];
505       if (dev->VolCatInfo.VolCatBytes == dev->part_start + dev->part_size) {
506          Jmsg(jcr, M_INFO, 0, _("Ready to append to end of Volume \"%s\""
507               " part=%d size=%s\n"), VolumeName, 
508               dev->part, edit_uint64(dev->VolCatInfo.VolCatBytes,ed1));
509       } else {
510          Jmsg(jcr, M_ERROR, 0, _("Bacula cannot write on DVD Volume \"%s\" because: "
511               "The sizes do not match! Volume=%s Catalog=%s\n"),
512               VolumeName,
513               edit_uint64(dev->part_start + dev->part_size, ed1),
514               edit_uint64(dev->VolCatInfo.VolCatBytes, ed2));
515          mark_volume_in_error();
516          return false;
517       }
518    } else if (dev->is_tape()) {
519       /*
520        * Check if we are positioned on the tape at the same place
521        * that the database says we should be.
522        */
523       if (dev->VolCatInfo.VolCatFiles == dev->get_file()) {
524          Jmsg(jcr, M_INFO, 0, _("Ready to append to end of Volume \"%s\" at file=%d.\n"),
525               VolumeName, dev->get_file());
526       } else {
527          Jmsg(jcr, M_ERROR, 0, _("Bacula cannot write on tape Volume \"%s\" because:\n"
528               "The number of files mismatch! Volume=%u Catalog=%u\n"),
529               VolumeName, dev->get_file(), dev->VolCatInfo.VolCatFiles);
530          mark_volume_in_error();
531          return false;
532       }
533    } else if (dev->is_file()) {
534       char ed1[50], ed2[50];
535       boffset_t pos;
536       pos = dev->lseek(this, (boffset_t)0, SEEK_END);
537       if (dev->VolCatInfo.VolCatBytes == (uint64_t)pos) {
538          Jmsg(jcr, M_INFO, 0, _("Ready to append to end of Volume \"%s\""
539               " size=%s\n"), VolumeName, 
540               edit_uint64(dev->VolCatInfo.VolCatBytes, ed1));
541       } else {
542          Jmsg(jcr, M_ERROR, 0, _("Bacula cannot write on disk Volume \"%s\" because: "
543               "The sizes do not match! Volume=%s Catalog=%s\n"),
544               VolumeName,
545               edit_uint64(pos, ed1),
546               edit_uint64(dev->VolCatInfo.VolCatBytes, ed2));
547          mark_volume_in_error();
548          return false;
549       }
550    }
551    return true;
552 }
553
554
555 /*
556  * If permitted, we label the device, make sure we can do
557  *   it by checking that the VolCatBytes is zero => not labeled,
558  *   once the Volume is labeled we don't want to label another
559  *   blank tape with the same name.  For disk, we go ahead and
560  *   label it anyway, because the OS insures that there is only
561  *   one Volume with that name.
562  * As noted above, at this point dcr->VolCatInfo has what
563  *   the Director wants and dev->VolCatInfo has info on the
564  *   previous tape (or nothing).
565  *
566  * Return codes are:
567  *   try_next_vol        label failed, look for another volume
568  *   try_read_vol        labeled volume, now re-read the label
569  *   try_error           hard error (catalog update)
570  *   try_default         I couldn't do anything
571  */
572 int DCR::try_autolabel(bool opened)
573 {
574    DCR *dcr = this;
575
576    if (dev->poll && !dev->is_tape()) {
577       return try_default;       /* if polling, don't try to create new labels */
578    }
579    /* For a tape require it to be opened and read before labeling */
580    if (!opened && dev->is_tape()) {
581       return try_default;
582    }
583    if (dev->has_cap(CAP_LABEL) && (VolCatInfo.VolCatBytes == 0 ||
584          (!dev->is_tape() && strcmp(VolCatInfo.VolCatStatus,
585                                 "Recycle") == 0))) {
586       Dmsg0(150, "Create volume label\n");
587       /* Create a new Volume label and write it to the device */
588       if (!write_new_volume_label_to_dev(dcr, VolumeName,
589              pool_name, false, /* no relabel */ false /* defer DVD label */)) {
590          Dmsg0(150, "!write_vol_label\n");
591          if (opened) { 
592             mark_volume_in_error();
593          }
594          return try_next_vol;
595       }
596       Dmsg0(150, "dir_update_vol_info. Set Append\n");
597       /* Copy Director's info into the device info */
598       dev->VolCatInfo = VolCatInfo;    /* structure assignment */
599       if (!dir_update_volume_info(dcr, true, true)) {  /* indicate tape labeled */
600          return try_error;
601       }
602       Jmsg(dcr->jcr, M_INFO, 0, _("Labeled new Volume \"%s\" on device %s.\n"),
603          VolumeName, dev->print_name());
604       return try_read_vol;   /* read label we just wrote */
605    }
606    if (!dev->has_cap(CAP_LABEL) && VolCatInfo.VolCatBytes == 0) {
607       Jmsg(jcr, M_WARNING, 0, _("Device %s not configured to autolabel Volumes.\n"), 
608          dev->print_name());
609    }
610    /* If not removable, Volume is broken */
611    if (!dev->is_removable()) {
612       Jmsg(jcr, M_WARNING, 0, _("Volume \"%s\" not on device %s.\n"),
613          VolumeName, dev->print_name());
614       mark_volume_in_error();
615       return try_next_vol;
616    }
617    return try_default;
618 }
619
620
621 /*
622  * Mark volume in error in catalog
623  */
624 void DCR::mark_volume_in_error()
625 {
626    Jmsg(jcr, M_INFO, 0, _("Marking Volume \"%s\" in Error in Catalog.\n"),
627         VolumeName);
628    dev->VolCatInfo = VolCatInfo;     /* structure assignment */
629    bstrncpy(dev->VolCatInfo.VolCatStatus, "Error", sizeof(dev->VolCatInfo.VolCatStatus));
630    Dmsg0(150, "dir_update_vol_info. Set Error.\n");
631    dir_update_volume_info(this, false, false);
632    volume_unused(this);
633 }
634
635 /*
636  * The Volume is not in the correct slot, so mark this
637  *   Volume as not being in the Changer.
638  */
639 void DCR::mark_volume_not_inchanger()
640 {
641    Jmsg(jcr, M_ERROR, 0, _("Autochanger Volume \"%s\" not found in slot %d.\n"
642 "    Setting InChanger to zero in catalog.\n"),
643         VolCatInfo.VolCatName, VolCatInfo.Slot);
644    dev->VolCatInfo = VolCatInfo;    /* structure assignment */
645    VolCatInfo.InChanger = false;
646    dev->VolCatInfo.InChanger = false;
647    Dmsg0(400, "update vol info in mount\n");
648    dir_update_volume_info(this, true, false);  /* set new status */
649 }
650
651 /*
652  * Either because we are going to hang a new volume, or because
653  *  of explicit user request, we release the current volume.
654  */
655 void DCR::release_volume()
656 {
657    if (WroteVol) {
658       Jmsg0(jcr, M_ERROR, 0, _("Hey!!!!! WroteVol non-zero !!!!!\n"));
659       Dmsg0(190, "Hey!!!!! WroteVol non-zero !!!!!\n");
660    }
661    /*
662     * First erase all memory of the current volume
663     */
664    free_volume(dev);
665    dev->block_num = dev->file = 0;
666    dev->EndBlock = dev->EndFile = 0;
667    memset(&dev->VolCatInfo, 0, sizeof(dev->VolCatInfo));
668    memset(&VolCatInfo, 0, sizeof(VolCatInfo));
669    dev->clear_volhdr();
670    /* Force re-read of label */
671    dev->clear_labeled();
672    dev->clear_read();
673    dev->clear_append();
674    dev->label_type = B_BACULA_LABEL;
675    VolumeName[0] = 0;
676
677    if (dev->is_open() && (!dev->is_tape() || !dev->has_cap(CAP_ALWAYSOPEN))) {
678       dev->close();
679    }
680
681    /* If we have not closed the device, then at least rewind the tape */
682    if (dev->is_open()) {
683       dev->offline_or_rewind();
684    }
685    Dmsg0(190, "release_volume\n");
686 }
687
688 /*
689  * If we are reading, we come here at the end of the tape
690  *  and see if there are more volumes to be mounted.
691  */
692 bool mount_next_read_volume(DCR *dcr)
693 {
694    DEVICE *dev = dcr->dev;
695    JCR *jcr = dcr->jcr;
696    Dmsg2(90, "NumReadVolumes=%d CurReadVolume=%d\n", jcr->NumReadVolumes, jcr->CurReadVolume);
697
698    volume_unused(dcr);                /* release current volume */
699    /*
700     * End Of Tape -- mount next Volume (if another specified)
701     */
702    if (jcr->NumReadVolumes > 1 && jcr->CurReadVolume < jcr->NumReadVolumes) {
703       dev->close();
704       if (!acquire_device_for_read(dcr)) {
705          Jmsg2(jcr, M_FATAL, 0, _("Cannot open Dev=%s, Vol=%s\n"), dev->print_name(),
706                dcr->VolumeName);
707          return false;
708       }
709       return true;                    /* next volume mounted */
710    }
711    Dmsg0(90, "End of Device reached.\n");
712    return false;
713 }