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