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