]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/mount.c
More tweaks to the mount volume routines to get everything
[bacula/bacula] / bacula / src / stored / mount.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2002-2007 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 static void mark_volume_not_inchanger(DCR *dcr);
42 static int try_autolabel(DCR *dcr, bool opened);
43
44 enum {
45    try_next_vol = 1,
46    try_read_vol,
47    try_error,
48    try_default
49 };
50
51 /*
52  * If release is set, we rewind the current volume,
53  * which we no longer want, and ask the user (console)
54  * to mount the next volume.
55  *
56  *  Continue trying until we get it, and then ensure
57  *  that we can write on it.
58  *
59  * This routine returns a 0 only if it is REALLY
60  *  impossible to get the requested Volume.
61  *
62  */
63 bool mount_next_write_volume(DCR *dcr, bool have_vol, bool release)
64 {
65    int retry = 0;
66    bool ask = false, recycle, autochanger;
67    int vol_label_status;
68    DEVICE *dev = dcr->dev;
69    JCR *jcr = dcr->jcr;
70    DEV_BLOCK *block = dcr->block;
71    int mode;
72
73    Dmsg2(150, "Enter mount_next_volume(release=%d) dev=%s\n", release,
74       dev->print_name());
75
76    init_device_wait_timers(dcr);
77
78    /*
79     * Attempt to mount the next volume. If something non-fatal goes
80     *  wrong, we come back here to re-try (new op messages, re-read
81     *  Volume, ...)
82     */
83 mount_next_vol:
84    Dmsg1(150, "mount_next_vol retry=%d\n", retry);
85    /* Ignore retry if this is poll request */
86    if (!dev->poll && retry++ > 4) {
87       /* Last ditch effort before giving up, force operator to respond */
88       dcr->VolCatInfo.Slot = 0;
89       if (!dir_ask_sysop_to_mount_volume(dcr)) {
90          Jmsg(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s.\n"),
91               dev->print_name());
92          return false;
93       }
94    }
95    if (job_canceled(jcr)) {
96       Jmsg(jcr, M_FATAL, 0, _("Job %d canceled.\n"), jcr->JobId);
97       return false;
98    }
99    recycle = false;
100    if (release) {
101       Dmsg0(150, "mount_next_volume release=1\n");
102       release_volume(dcr);
103       ask = true;                     /* ask operator to mount tape */
104    }
105
106    /*
107     * Get Director's idea of what tape we should have mounted.
108     *    in dcr->VolCatInfo
109     */
110    Dmsg0(200, "Before dir_find_next_appendable_volume.\n");
111    if (!have_vol) {
112       while (!dir_find_next_appendable_volume(dcr)) {
113          Dmsg0(200, "not dir_find_next\n");
114          if (!dir_ask_sysop_to_create_appendable_volume(dcr)) {
115             return false;
116           }
117           Dmsg0(200, "Again dir_find_next_append...\n");
118        }
119    } else {
120       have_vol = false;               /* set false for next pass if any */
121    }
122    if (job_canceled(jcr)) {
123       return false;
124    }
125    Dmsg3(150, "After find_next_append. Vol=%s Slot=%d Parts=%d\n",
126          dcr->VolCatInfo.VolCatName, dcr->VolCatInfo.Slot, dcr->VolCatInfo.VolCatParts);
127    
128    /*
129     * Get next volume and ready it for append
130     * This code ensures that the device is ready for
131     * writing. We start from the assumption that there
132     * may not be a tape mounted.
133     *
134     * If the device is a file, we create the output
135     * file. If it is a tape, we check the volume name
136     * and move the tape to the end of data.
137     *
138     */
139    if (autoload_device(dcr, 1, NULL) > 0) {
140       autochanger = true;
141       ask = false;
142    } else {
143       autochanger = false;
144       dcr->VolCatInfo.Slot = 0;
145    }
146    Dmsg1(200, "autoload_dev returns %d\n", autochanger);
147    /*
148     * If we autochanged to correct Volume or (we have not just
149     *   released the Volume AND we can automount) we go ahead
150     *   and read the label. If there is no tape in the drive,
151     *   we will fail, recurse and ask the operator the next time.
152     */
153    if (!release && dev->is_tape() && dev->has_cap(CAP_AUTOMOUNT)) {
154       Dmsg0(150, "(1)Ask=0\n");
155       ask = false;                 /* don't ask SYSOP this time */
156    }
157    /* Don't ask if not removable */
158    if (!dev->is_removable()) {
159       Dmsg0(150, "(2)Ask=0\n");
160       ask = false;
161    }
162    Dmsg2(150, "Ask=%d autochanger=%d\n", ask, autochanger);
163    release = true;                /* release next time if we "recurse" */
164
165    if (ask && !dir_ask_sysop_to_mount_volume(dcr)) {
166       Dmsg0(150, "Error return ask_sysop ...\n");
167       return false;          /* error return */
168    }
169    if (job_canceled(jcr)) {
170       return false;
171    }
172    Dmsg1(150, "want vol=%s\n", dcr->VolumeName);
173
174    if (dev->poll && dev->has_cap(CAP_CLOSEONPOLL)) {
175       dev->close();
176    }
177
178    /* Ensure the device is open */
179    if (dev->has_cap(CAP_STREAM)) {
180       mode = OPEN_WRITE_ONLY;
181    } else {
182       mode = OPEN_READ_WRITE;
183    }
184    /* Try autolabel if enabled */
185    if (dev->open(dcr, mode) < 0) {
186       try_autolabel(dcr, false);      /* try to create a new volume label */
187    }
188    while (dev->open(dcr, mode) < 0) {
189       Dmsg1(150, "open_device failed: ERR=%s\n", dev->bstrerror());
190       if ((dev->is_file() && dev->is_removable()) || dev->is_dvd()) {
191          bool ok = true;
192          Dmsg0(150, "call scan_dir_for_vol\n");
193          if (dev->is_dvd()) {
194             if (!dev->mount(0)) {
195                ok = false;
196             }
197          }
198          if (ok && dev->scan_dir_for_volume(dcr)) {
199             if (dev->open(dcr, mode) >= 0) {
200                break;                    /* got a valid volume */
201             }
202          }
203          if (ok && dev->is_dvd()) {
204             dev->unmount(0);
205          }
206       }
207       if (try_autolabel(dcr, false) == try_read_vol) {
208          break;                       /* created a new volume label */
209       }
210       /* If DVD, ignore the error, very often you cannot open the device
211        * (when there is no DVD, or when the one inserted is a wrong one) */
212       if (dev->poll || dev->is_dvd() || dev->is_removable()) {
213          goto mount_next_vol;
214       } else {
215          Jmsg(jcr, M_ERROR, 0, _("Could not open device %s: ERR=%s\n"),
216             dev->print_name(), dev->print_errmsg());
217          return false;
218       }
219    }
220
221    /*
222     * Now make sure we have the right tape mounted
223     */
224 read_volume:
225    /*
226     * If we are writing to a stream device, ASSUME the volume label
227     *  is correct.
228     */
229    if (dev->has_cap(CAP_STREAM)) {
230       vol_label_status = VOL_OK;
231       create_volume_label(dev, dcr->VolumeName, "Default", false /* not DVD */);
232       dev->VolHdr.LabelType = PRE_LABEL;
233    } else {
234       vol_label_status = read_dev_volume_label(dcr);
235    }
236    if (job_canceled(jcr)) {
237       return false;
238    }
239
240    Dmsg2(150, "Want dirVol=%s dirStat=%s\n", dcr->VolumeName,
241       dcr->VolCatInfo.VolCatStatus);
242    /*
243     * At this point, dev->VolCatInfo has what is in the drive, if anything,
244     *          and   dcr->VolCatInfo has what the Director wants.
245     */
246    switch (vol_label_status) {
247    case VOL_OK:
248       Dmsg1(150, "Vol OK name=%s\n", dcr->VolumeName);
249       dev->VolCatInfo = dcr->VolCatInfo;       /* structure assignment */
250       recycle = strcmp(dev->VolCatInfo.VolCatStatus, "Recycle") == 0;
251       break;                    /* got a Volume */
252    case VOL_NAME_ERROR:
253       VOLUME_CAT_INFO dcrVolCatInfo, devVolCatInfo;
254       char VolumeName[MAX_NAME_LENGTH];
255
256       /* If not removable, Volume is broken */
257       if (!dev->is_removable()) {
258          Jmsg(jcr, M_WARNING, 0, _("Volume \"%s\" not on device %s.\n"),
259             dcr->VolumeName, dev->print_name());
260          mark_volume_in_error(dcr);
261          goto mount_next_vol;
262       }
263
264       Dmsg1(150, "Vol NAME Error Name=%s\n", dcr->VolumeName);
265       /* If polling and got a previous bad name, ignore it */
266       if (dev->poll && strcmp(dev->BadVolName, dev->VolHdr.VolumeName) == 0) {
267          ask = true;
268          Dmsg1(200, "Vol Name error supress due to poll. Name=%s\n", dcr->VolumeName);
269          goto mount_next_vol;
270       }
271       /*
272        * OK, we got a different volume mounted. First save the
273        *  requested Volume info (dcr) structure, then query if
274        *  this volume is really OK. If not, put back the desired
275        *  volume name, mark it not in changer and continue.
276        */
277       dcrVolCatInfo = dcr->VolCatInfo;      /* structure assignment */
278       devVolCatInfo = dev->VolCatInfo;      /* structure assignment */
279       /* Check if this is a valid Volume in the pool */
280       bstrncpy(VolumeName, dcr->VolumeName, sizeof(VolumeName));
281       bstrncpy(dcr->VolumeName, dev->VolHdr.VolumeName, sizeof(dcr->VolumeName));
282       if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE)) {
283          POOL_MEM vol_info_msg;
284          pm_strcpy(vol_info_msg, jcr->dir_bsock->msg);  /* save error message */
285          /* Restore desired volume name, note device info out of sync */
286          /* This gets the info regardless of the Pool */
287          bstrncpy(dcr->VolumeName, dev->VolHdr.VolumeName, sizeof(dcr->VolumeName));
288          if (autochanger && !dir_get_volume_info(dcr, GET_VOL_INFO_FOR_READ)) {
289             /*
290              * If we get here, we know we cannot write on the Volume,
291              *  and we know that we cannot read it either, so it 
292              *  is not in the autochanger.
293              */
294             mark_volume_not_inchanger(dcr);
295          }
296          dev->VolCatInfo = devVolCatInfo;    /* structure assignment */
297          bstrncpy(dev->BadVolName, dev->VolHdr.VolumeName, sizeof(dev->BadVolName));
298          Jmsg(jcr, M_WARNING, 0, _("Director wanted Volume \"%s\".\n"
299               "    Current Volume \"%s\" not acceptable because:\n"
300               "    %s"),
301              dcrVolCatInfo.VolCatName, dev->VolHdr.VolumeName,
302              vol_info_msg.c_str());
303          ask = true;
304          /* Restore saved DCR before continuing */
305          bstrncpy(dcr->VolumeName, VolumeName, sizeof(dcr->VolumeName));
306          dcr->VolCatInfo = dcrVolCatInfo;  /* structure assignment */
307          goto mount_next_vol;
308       }
309       /*
310        * This was not the volume we expected, but it is OK with
311        * the Director, so use it.
312        */
313       Dmsg1(150, "want new name=%s\n", dcr->VolumeName);
314       dev->VolCatInfo = dcr->VolCatInfo;   /* structure assignment */
315       recycle = strcmp(dev->VolCatInfo.VolCatStatus, "Recycle") == 0;
316       break;                /* got a Volume */
317    /*
318     * At this point, we assume we have a blank tape mounted.
319     */
320    case VOL_IO_ERROR:
321       if (dev->is_dvd()) {
322          Jmsg(jcr, M_FATAL, 0, "%s", jcr->errmsg);
323          mark_volume_in_error(dcr);
324          return false;       /* we could not write on DVD */
325       }
326       /* Fall through wanted */
327    case VOL_NO_LABEL:
328       switch (try_autolabel(dcr, true)) {
329       case try_next_vol:
330          goto mount_next_vol;
331       case try_read_vol:
332          goto read_volume;
333       case try_error:
334          return false;
335       case try_default:
336          break;
337       }
338
339       /* NOTE! Fall-through wanted. */
340    case VOL_NO_MEDIA:
341    default:
342       Dmsg0(200, "VOL_NO_MEDIA or default.\n");
343       /* Send error message */
344       if (!dev->poll) {
345       } else {
346          Dmsg1(200, "Msg suppressed by poll: %s\n", jcr->errmsg);
347       }
348       ask = true;
349       /* Needed, so the medium can be changed */
350       if (dev->requires_mount()) {
351          dev->close();
352       }
353       goto mount_next_vol;
354    }
355
356    /*
357     * See if we have a fresh tape or a tape with data.
358     *
359     * Note, if the LabelType is PRE_LABEL, it was labeled
360     *  but never written. If so, rewrite the label but set as
361     *  VOL_LABEL.  We rewind and return the label (reconstructed)
362     *  in the block so that in the case of a new tape, data can
363     *  be appended just after the block label.  If we are writing
364     *  a second volume, the calling routine will write the label
365     *  before writing the overflow block.
366     *
367     *  If the tape is marked as Recycle, we rewrite the label.
368     */
369    if (dev->VolHdr.LabelType == PRE_LABEL || recycle) {
370       if (!rewrite_volume_label(dcr, recycle)) {
371          mark_volume_in_error(dcr);
372          goto mount_next_vol;
373       }
374    } else {
375       /*
376        * OK, at this point, we have a valid Bacula label, but
377        * we need to position to the end of the volume, since we are
378        * just now putting it into append mode.
379        */
380       Dmsg0(200, "Device previously written, moving to end of data\n");
381       Jmsg(jcr, M_INFO, 0, _("Volume \"%s\" previously written, moving to end of data.\n"),
382          dcr->VolumeName);
383       if (!dev->eod(dcr)) {
384          Jmsg(jcr, M_ERROR, 0, _("Unable to position to end of data on device %s: ERR=%s\n"),
385             dev->print_name(), dev->bstrerror());
386          mark_volume_in_error(dcr);
387          goto mount_next_vol;
388       }
389       if (dev->is_dvd()) {
390          char ed1[50], ed2[50];
391          if (dev->VolCatInfo.VolCatBytes == dev->part_start + dev->part_size) {
392             Jmsg(jcr, M_INFO, 0, _("Ready to append to end of Volume \"%s\""
393                  " part=%d size=%s\n"), dcr->VolumeName, 
394                  dev->part, edit_uint64(dev->VolCatInfo.VolCatBytes,ed1));
395          } else {
396             Jmsg(jcr, M_ERROR, 0, _("Bacula cannot write on DVD Volume \"%s\" because: "
397                  "The sizes do not match! Volume=%s Catalog=%s\n"),
398                  dcr->VolumeName,
399                  edit_uint64(dev->part_start + dev->part_size, ed1),
400                  edit_uint64(dev->VolCatInfo.VolCatBytes, ed2));
401             mark_volume_in_error(dcr);
402             goto mount_next_vol;
403          }
404       } else if (dev->is_tape()) {
405          /*
406           * Check if we are positioned on the tape at the same place
407           * that the database says we should be.
408           */
409          if (dev->VolCatInfo.VolCatFiles == dev->get_file()) {
410             Jmsg(jcr, M_INFO, 0, _("Ready to append to end of Volume \"%s\" at file=%d.\n"),
411                  dcr->VolumeName, dev->get_file());
412          } else {
413             Jmsg(jcr, M_ERROR, 0, _("Bacula cannot write on tape Volume \"%s\" because:\n"
414                  "The number of files mismatch! Volume=%u Catalog=%u\n"),
415                  dcr->VolumeName, dev->get_file(), dev->VolCatInfo.VolCatFiles);
416             mark_volume_in_error(dcr);
417             goto mount_next_vol;
418          }
419       } else if (dev->is_file()) {
420          char ed1[50], ed2[50];
421          boffset_t pos;
422          pos = dev->lseek(dcr, (boffset_t)0, SEEK_END);
423          if (dev->VolCatInfo.VolCatBytes == (uint64_t)pos) {
424             Jmsg(jcr, M_INFO, 0, _("Ready to append to end of Volume \"%s\""
425                  " size=%s\n"), dcr->VolumeName, 
426                  edit_uint64(dev->VolCatInfo.VolCatBytes, ed1));
427          } else {
428             Jmsg(jcr, M_ERROR, 0, _("Bacula cannot write on disk Volume \"%s\" because: "
429                  "The sizes do not match! Volume=%s Catalog=%s\n"),
430                  dcr->VolumeName,
431                  edit_uint64(pos, ed1),
432                  edit_uint64(dev->VolCatInfo.VolCatBytes, ed2));
433             mark_volume_in_error(dcr);
434             goto mount_next_vol;
435          }
436       }
437       dev->VolCatInfo.VolCatMounts++;      /* Update mounts */
438       Dmsg1(150, "update volinfo mounts=%d\n", dev->VolCatInfo.VolCatMounts);
439       if (!dir_update_volume_info(dcr, false)) {
440          return false;
441       }
442       
443       /*
444        * DVD : check if the last part was removed or truncated, or if a written
445        * part was overwritten.   
446        * We need to do it after dir_update_volume_info, so we have the EndBlock
447        * info. (nb: I don't understand why VolCatFiles is set (used to check
448        * tape file number), but not EndBlock)
449        * Maybe could it be changed "dev->is_file()" (would remove the fixme above)   
450        *
451        * Disabled: I had problems with this code... 
452        * (maybe is it related to the seek bug ?)   
453        */
454 #ifdef xxx
455       if (dev->is_dvd()) {
456          Dmsg2(150, "DVD/File sanity check addr=%u vs endblock=%u\n", (unsigned int)dev->file_addr, (unsigned int)dev->VolCatInfo.EndBlock);
457          if (dev->file_addr == dev->VolCatInfo.EndBlock+1) {
458             Jmsg(jcr, M_INFO, 0, _("Ready to append to end of Volume \"%s\" at file address=%u.\n"),
459                  dcr->VolumeName, (unsigned int)dev->file_addr);
460          }
461          else {
462             Jmsg(jcr, M_ERROR, 0, _("Bacula cannot write on Volume \"%s\" because:\n"
463                                     "The EOD file address is wrong: Volume file address=%u != Catalog Endblock=%u(+1)\n"
464                                     "Perhaps You removed the DVD last part in spool directory.\n"),
465                  dcr->VolumeName, (unsigned int)dev->file_addr, (unsigned int)dev->VolCatInfo.EndBlock);
466             mark_volume_in_error(dcr);
467             goto mount_next_vol;
468          }
469       }
470 #endif
471       
472       /* Return an empty block */
473       empty_block(block);             /* we used it for reading so set for write */
474    }
475    dev->set_append();
476    Dmsg1(150, "set APPEND, normal return from mount_next_write_volume. dev=%s\n",
477       dev->print_name());
478
479    return true;
480 }
481
482 /*
483  * If permitted, we label the device, make sure we can do
484  *   it by checking that the VolCatBytes is zero => not labeled,
485  *   once the Volume is labeled we don't want to label another
486  *   blank tape with the same name.  For disk, we go ahead and
487  *   label it anyway, because the OS insures that there is only
488  *   one Volume with that name.
489  * As noted above, at this point dcr->VolCatInfo has what
490  *   the Director wants and dev->VolCatInfo has info on the
491  *   previous tape (or nothing).
492  *
493  * Return codes are:
494  *   try_next_vol        label failed, look for another volume
495  *   try_read_vol        labeled volume, now re-read the label
496  *   try_error           hard error (catalog update)
497  *   try_default         I couldn't do anything
498  */
499 static int try_autolabel(DCR *dcr, bool opened)
500 {
501    DEVICE *dev = dcr->dev;
502
503    if (dev->poll && !dev->is_tape()) {
504       return try_default;       /* if polling, don't try to create new labels */
505    }
506    /* For a tape require it to be opened and read before labeling */
507    if (!opened && dev->is_tape()) {
508       return try_default;
509    }
510    if (dev->has_cap(CAP_LABEL) && (dcr->VolCatInfo.VolCatBytes == 0 ||
511          (!dev->is_tape() && strcmp(dcr->VolCatInfo.VolCatStatus,
512                                 "Recycle") == 0))) {
513       Dmsg0(150, "Create volume label\n");
514       /* Create a new Volume label and write it to the device */
515       if (!write_new_volume_label_to_dev(dcr, dcr->VolumeName,
516              dcr->pool_name, false, /* no relabel */ false /* defer DVD label */)) {
517          Dmsg0(150, "!write_vol_label\n");
518          if (opened) { 
519             mark_volume_in_error(dcr);
520          }
521          return try_next_vol;
522       }
523       Dmsg0(150, "dir_update_vol_info. Set Append\n");
524       /* Copy Director's info into the device info */
525       dev->VolCatInfo = dcr->VolCatInfo;    /* structure assignment */
526       if (!dir_update_volume_info(dcr, true)) {  /* indicate tape labeled */
527          return try_error;
528       }
529       Jmsg(dcr->jcr, M_INFO, 0, _("Labeled new Volume \"%s\" on device %s.\n"),
530          dcr->VolumeName, dev->print_name());
531       return try_read_vol;   /* read label we just wrote */
532    }
533    if (!dev->has_cap(CAP_LABEL) && dcr->VolCatInfo.VolCatBytes == 0) {
534       Jmsg(dcr->jcr, M_WARNING, 0, _("Device %s not configured to autolabel Volumes.\n"), 
535          dev->print_name());
536    }
537    /* If not removable, Volume is broken */
538    if (!dev->is_removable()) {
539       Jmsg(dcr->jcr, M_WARNING, 0, _("Volume \"%s\" not on device %s.\n"),
540          dcr->VolumeName, dev->print_name());
541       mark_volume_in_error(dcr);
542       return try_next_vol;
543    }
544    return try_default;
545 }
546
547
548 /*
549  * Mark volume in error in catalog
550  */
551 void mark_volume_in_error(DCR *dcr)
552 {
553    DEVICE *dev = dcr->dev;
554    Jmsg(dcr->jcr, M_INFO, 0, _("Marking Volume \"%s\" in Error in Catalog.\n"),
555         dcr->VolumeName);
556    dev->VolCatInfo = dcr->VolCatInfo;     /* structure assignment */
557    bstrncpy(dev->VolCatInfo.VolCatStatus, "Error", sizeof(dev->VolCatInfo.VolCatStatus));
558    Dmsg0(150, "dir_update_vol_info. Set Error.\n");
559    dir_update_volume_info(dcr, false);
560 }
561
562 /*
563  * The Volume is not in the correct slot, so mark this
564  *   Volume as not being in the Changer.
565  */
566 static void mark_volume_not_inchanger(DCR *dcr)
567 {
568    JCR *jcr = dcr->jcr;
569    DEVICE *dev = dcr->dev;
570    Jmsg(jcr, M_ERROR, 0, _("Autochanger Volume \"%s\" not found in slot %d.\n"
571 "    Setting InChanger to zero in catalog.\n"),
572         dcr->VolCatInfo.VolCatName, dcr->VolCatInfo.Slot);
573    dev->VolCatInfo = dcr->VolCatInfo;    /* structure assignment */
574    dcr->VolCatInfo.InChanger = false;
575    dev->VolCatInfo.InChanger = false;
576    Dmsg0(400, "update vol info in mount\n");
577    dir_update_volume_info(dcr, true);  /* set new status */
578 }
579
580 /*
581  * Either because we are going to hang a new volume, or because
582  *  of explicit user request, we release the current volume.
583  */
584 void release_volume(DCR *dcr)
585 {
586    JCR *jcr = dcr->jcr;
587    DEVICE *dev = dcr->dev;
588    if (dcr->WroteVol) {
589       Jmsg0(jcr, M_ERROR, 0, _("Hey!!!!! WroteVol non-zero !!!!!\n"));
590       Dmsg0(190, "Hey!!!!! WroteVol non-zero !!!!!\n");
591    }
592    /*
593     * First erase all memory of the current volume
594     */
595    free_volume(dev);
596    dev->block_num = dev->file = 0;
597    dev->EndBlock = dev->EndFile = 0;
598    memset(&dev->VolCatInfo, 0, sizeof(dev->VolCatInfo));
599    memset(&dcr->VolCatInfo, 0, sizeof(dcr->VolCatInfo));
600    dev->clear_volhdr();
601    /* Force re-read of label */
602    dev->clear_labeled();
603    dev->clear_read();
604    dev->clear_append();
605    dev->label_type = B_BACULA_LABEL;
606    dcr->VolumeName[0] = 0;
607
608    if (dev->is_open() && (!dev->is_tape() || !dev->has_cap(CAP_ALWAYSOPEN))) {
609       dev->close();
610    }
611
612    /* If we have not closed the device, then at least rewind the tape */
613    if (dev->is_open()) {
614       dev->offline_or_rewind();
615    }
616    Dmsg0(190, "release_volume\n");
617 }
618
619 /*
620  * If we are reading, we come here at the end of the tape
621  *  and see if there are more volumes to be mounted.
622  */
623 bool mount_next_read_volume(DCR *dcr)
624 {
625    DEVICE *dev = dcr->dev;
626    JCR *jcr = dcr->jcr;
627    Dmsg2(90, "NumReadVolumes=%d CurReadVolume=%d\n", jcr->NumReadVolumes, jcr->CurReadVolume);
628    /*
629     * End Of Tape -- mount next Volume (if another specified)
630     */
631    if (jcr->NumReadVolumes > 1 && jcr->CurReadVolume < jcr->NumReadVolumes) {
632       dev->close();
633       if (!acquire_device_for_read(dcr)) {
634          Jmsg2(jcr, M_FATAL, 0, _("Cannot open Dev=%s, Vol=%s\n"), dev->print_name(),
635                dcr->VolumeName);
636          return false;
637       }
638       return true;                    /* next volume mounted */
639    }
640    Dmsg0(90, "End of Device reached.\n");
641    return false;
642 }