2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2017 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
21 * Routines for handling mounting tapes for reading and for
24 * Kern Sibbald, August MMII
28 #include "bacula.h" /* pull in global headers */
29 #include "stored.h" /* pull in Storage Deamon headers */
31 static pthread_mutex_t mount_mutex = PTHREAD_MUTEX_INITIALIZER;
48 * If release is set, we rewind the current volume,
49 * which we no longer want, and ask the user (console)
50 * to mount the next volume.
52 * Continue trying until we get it, and then ensure
53 * that we can write on it.
55 * This routine returns a 0 only if it is REALLY
56 * impossible to get the requested Volume.
58 * This routine is entered with the device blocked, but not
62 bool DCR::mount_next_write_volume()
65 bool ask = false, recycle, autochanger;
70 Dmsg2(100, "Enter mount_next_volume(release=%d) dev=%s\n", dev->must_unload(),
73 init_device_wait_timers(dcr);
78 * Attempt to mount the next volume. If something non-fatal goes
79 * wrong, we come back here to re-try (new op messages, re-read
83 Dmsg1(100, "mount_next_vol retry=%d\n", retry);
84 /* Ignore retry if this is poll request */
85 if (dev->is_nospace() || retry++ > 4) {
86 /* Last ditch effort before giving up, force operator to respond */
89 if (!dir_ask_sysop_to_mount_volume(dcr, SD_APPEND)) {
90 Jmsg(jcr, M_FATAL, 0, _("Too many errors trying to mount %s device %s.\n"),
91 dev->print_type(), dev->print_name());
92 goto no_lock_bail_out;
95 Dmsg1(90, "Continue after dir_ask_sysop_to_mount. must_load=%d\n", dev->must_load());
97 if (job_canceled(jcr)) {
98 Jmsg(jcr, M_FATAL, 0, _("Job %d canceled.\n"), jcr->JobId);
103 if (dev->must_unload()) {
104 ask = true; /* ask operator to mount tape */
107 do_swapping(SD_APPEND);
110 if (!find_a_volume()) {
114 if (job_canceled(jcr)) {
117 Dmsg3(100, "After find_a_volume. Vol=%s Slot=%d VolType=%d\n",
118 getVolCatName(), VolCatInfo.Slot, VolCatInfo.VolCatType);
120 dev->notify_newvol_in_attached_dcrs(getVolCatName());
123 * Get next volume and ready it for append
124 * This code ensures that the device is ready for
125 * writing. We start from the assumption that there
126 * may not be a tape mounted.
128 * If the device is a file, we create the output
129 * file. If it is a tape, we check the volume name
130 * and move the tape to the end of data.
133 dcr->setVolCatInfo(false); /* out of date when Vols unlocked */
134 if (autoload_device(dcr, SD_APPEND, NULL) > 0) {
140 if (dev->is_autochanger() && !VolCatInfo.InChanger) {
141 ask = true; /* not in changer, do not retry */
146 Dmsg1(100, "autoload_dev returns %d\n", autochanger);
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.
153 if (!dev->must_unload() && dev->is_tape() && dev->has_cap(CAP_AUTOMOUNT)) {
154 Dmsg0(250, "(1)Ask=0\n");
155 ask = false; /* don't ask SYSOP this time */
157 /* Don't ask if not removable */
158 if (!dev->is_removable()) {
159 Dmsg0(250, "(2)Ask=0\n");
162 Dmsg2(100, "Ask=%d autochanger=%d\n", ask, autochanger);
166 dcr->setVolCatInfo(false); /* out of date when Vols unlocked */
167 if (!dir_ask_sysop_to_mount_volume(dcr, SD_APPEND)) {
168 Dmsg0(150, "Error return ask_sysop ...\n");
169 goto no_lock_bail_out;
173 if (job_canceled(jcr)) {
176 Dmsg3(100, "want vol=%s devvol=%s dev=%s\n", VolumeName,
177 dev->VolHdr.VolumeName, dev->print_name());
179 if (dev->poll && dev->has_cap(CAP_CLOSEONPOLL)) {
184 /* Try autolabel if enabled */
185 Dmsg1(100, "Try open Vol=%s\n", getVolCatName());
186 if (!dev->open_device(dcr, OPEN_READ_WRITE)) {
187 Dmsg1(100, "Try autolabel Vol=%s\n", getVolCatName());
189 try_autolabel(false); /* try to create a new volume label */
192 while (!dev->open_device(dcr, OPEN_READ_WRITE)) {
193 Dmsg1(100, "open_device failed: ERR=%s", dev->bstrerror());
194 if (dev->is_file() && dev->is_removable()) {
196 Dmsg0(150, "call scan_dir_for_vol\n");
197 if (ok && dev->scan_dir_for_volume(dcr)) {
198 if (dev->open_device(dcr, OPEN_READ_WRITE)) {
199 break; /* got a valid volume */
203 if (try_autolabel(false) == try_read_vol) {
204 break; /* created a new volume label */
207 /* ***FIXME*** if autochanger, before giving up try unload and load */
209 Jmsg4(jcr, M_WARNING, 0, _("Open of %s device %s Volume \"%s\" failed: ERR=%s\n"),
210 dev->print_type(), dev->print_name(), dcr->VolumeName, dev->bstrerror());
212 /* If not removable, Volume is broken. This is a serious issue here. */
213 if(dev->is_file() && !dev->is_removable()) {
214 Dmsg3(40, "Volume \"%s\" not loaded on %s device %s.\n",
215 dcr->VolumeName, dev->print_type(), dev->print_name());
216 mark_volume_in_error();
219 Dmsg0(100, "set_unload\n");
220 dev->set_unload(); /* force ask sysop */
224 Dmsg0(100, "goto mount_next_vol\n");
229 * Now check the volume label to make sure we have the right tape mounted
232 switch (check_volume_label(ask, autochanger)) {
234 Dmsg0(50, "set_unload\n");
235 dev->set_unload(); /* want a different Volume */
236 Dmsg0(100, "goto mount_next_vol\n");
246 * Check that volcatinfo is good
248 if (!dev->haveVolCatInfo()) {
249 Dmsg0(100, "Do not have volcatinfo\n");
250 if (!find_a_volume()) {
253 dev->set_volcatinfo_from_dcr(this);
257 * See if we have a fresh tape or a tape with data.
259 * Note, if the LabelType is PRE_LABEL, it was labeled
260 * but never written. If so, rewrite the label but set as
261 * VOL_LABEL. We rewind and return the label (reconstructed)
262 * in the block so that in the case of a new tape, data can
263 * be appended just after the block label. If we are writing
264 * a second volume, the calling routine will write the label
265 * before writing the overflow block.
267 * If the tape is marked as Recycle, we rewrite the label.
269 recycle = strcmp(dev->VolCatInfo.VolCatStatus, "Recycle") == 0;
270 if (dev->VolHdr.LabelType == PRE_LABEL || recycle) {
271 dcr->WroteVol = false;
272 if (!dev->rewrite_volume_label(dcr, recycle)) {
273 mark_volume_in_error();
278 * OK, at this point, we have a valid Bacula label, but
279 * we need to position to the end of the volume, since we are
280 * just now putting it into append mode.
282 Dmsg1(100, "Device previously written, moving to end of data. Expect %lld bytes\n",
283 dev->VolCatInfo.VolCatBytes);
284 Jmsg(jcr, M_INFO, 0, _("Volume \"%s\" previously written, moving to end of data.\n"),
287 if (!dev->eod(dcr)) {
288 Dmsg3(050, "Unable to position to end of data on %s device %s: ERR=%s\n",
289 dev->print_type(), dev->print_name(), dev->bstrerror());
290 Jmsg(jcr, M_ERROR, 0, _("Unable to position to end of data on %s device %s: ERR=%s\n"),
291 dev->print_type(), dev->print_name(), dev->bstrerror());
292 mark_volume_in_error();
296 if (!dev->is_eod_valid(dcr)) {
297 Dmsg0(100, "goto mount_next_vol\n");
301 dev->VolCatInfo.VolCatMounts++; /* Update mounts */
302 Dmsg1(150, "update volinfo mounts=%d\n", dev->VolCatInfo.VolCatMounts);
303 if (!dir_update_volume_info(dcr, false, false)) {
307 /* Return an empty block */
308 empty_block(block); /* we used it for reading so set for write */
311 Dmsg1(150, "set APPEND, normal return from mount_next_write_volume. dev=%s\n",
326 * This routine is meant to be called once the first pass
327 * to ensure that we have a candidate volume to mount.
328 * Otherwise, we ask the sysop to created one.
329 * Note, mount_mutex is already locked on entry and thus
330 * must remain locked on exit from this function.
332 bool DCR::find_a_volume()
337 if (!is_suitable_volume_mounted()) {
338 bool have_vol = false;
339 /* Do we have a candidate volume? */
341 bstrncpy(VolumeName, dev->vol->vol_name, sizeof(VolumeName));
342 have_vol = dir_get_volume_info(this, VolumeName, GET_VOL_INFO_FOR_WRITE);
345 * Get Director's idea of what tape we should have mounted.
349 Dmsg0(200, "Before dir_find_next_appendable_volume.\n");
350 while (!dir_find_next_appendable_volume(dcr)) {
351 Dmsg0(200, "not dir_find_next\n");
352 if (job_canceled(jcr)) {
356 * Unlock the mount mutex while waiting or
357 * the Director for a new volume
360 if (dev->must_wait()) {
362 Dmsg0(40, "No appendable volume. Calling wait_for_device\n");
363 wait_for_device(dcr, retries);
366 ok = dir_ask_sysop_to_create_appendable_volume(dcr);
369 if (!ok || job_canceled(jcr)) {
372 Dmsg0(150, "Again dir_find_next_append...\n");
377 if (dcr->haveVolCatInfo()) {
380 return dir_get_volume_info(dcr, VolumeName, GET_VOL_INFO_FOR_WRITE);
383 int DCR::check_volume_label(bool &ask, bool &autochanger)
385 int vol_label_status;
391 * If we are writing to a stream device, ASSUME the volume label
394 if (dev->has_cap(CAP_STREAM)) {
395 vol_label_status = VOL_OK;
396 create_volume_header(dev, VolumeName, "Default", false);
397 dev->VolHdr.LabelType = PRE_LABEL;
399 vol_label_status = dev->read_dev_volume_label(this);
401 if (job_canceled(jcr)) {
405 Dmsg2(150, "Want dirVol=%s dirStat=%s\n", VolumeName,
406 VolCatInfo.VolCatStatus);
409 * At this point, dev->VolCatInfo has what is in the drive, if anything,
410 * and dcr->VolCatInfo has what the Director wants.
412 switch (vol_label_status) {
414 Dmsg1(150, "Vol OK name=%s\n", dev->VolHdr.VolumeName);
415 dev->VolCatInfo = VolCatInfo; /* structure assignment */
416 break; /* got a Volume */
418 VOLUME_CAT_INFO dcrVolCatInfo, devVolCatInfo;
419 char saveVolumeName[MAX_NAME_LENGTH];
421 Dmsg2(40, "Vol NAME Error Have=%s, want=%s\n", dev->VolHdr.VolumeName, VolumeName);
422 if (dev->is_volume_to_unload()) {
424 goto check_next_volume;
428 /* If not removable, Volume is broken */
429 if (!dev->is_removable()) {
430 Jmsg3(jcr, M_WARNING, 0, _("Volume \"%s\" not loaded on %s device %s.\n"),
431 VolumeName, dev->print_type(), dev->print_name());
432 Dmsg3(40, "Volume \"%s\" not loaded on %s device %s.\n",
433 VolumeName, dev->print_type(), dev->print_name());
434 mark_volume_in_error();
435 goto check_next_volume;
440 * OK, we got a different volume mounted. First save the
441 * requested Volume info (dcr) structure, then query if
442 * this volume is really OK. If not, put back the desired
443 * volume name, mark it not in changer and continue.
445 dcrVolCatInfo = VolCatInfo; /* structure assignment */
446 devVolCatInfo = dev->VolCatInfo; /* structure assignment */
447 /* Check if this is a valid Volume in the pool */
448 bstrncpy(saveVolumeName, VolumeName, sizeof(saveVolumeName));
449 bstrncpy(VolumeName, dev->VolHdr.VolumeName, sizeof(VolumeName));
450 if (!dir_get_volume_info(this, VolumeName, GET_VOL_INFO_FOR_WRITE)) {
451 POOL_MEM vol_info_msg;
452 pm_strcpy(vol_info_msg, jcr->dir_bsock->msg); /* save error message */
453 /* Restore desired volume name, note device info out of sync */
454 /* This gets the info regardless of the Pool */
455 bstrncpy(VolumeName, dev->VolHdr.VolumeName, sizeof(VolumeName));
456 if (autochanger && !dir_get_volume_info(this, VolumeName, GET_VOL_INFO_FOR_READ)) {
458 * If we get here, we know we cannot write on the Volume,
459 * and we know that we cannot read it either, so it
460 * is not in the autochanger.
462 mark_volume_not_inchanger();
464 dev->VolCatInfo = devVolCatInfo; /* structure assignment */
465 dev->set_unload(); /* unload this volume */
466 Jmsg(jcr, M_WARNING, 0, _("Director wanted Volume \"%s\".\n"
467 " Current Volume \"%s\" not acceptable because:\n"
469 dcrVolCatInfo.VolCatName, dev->VolHdr.VolumeName,
470 vol_info_msg.c_str());
472 /* Restore saved DCR before continuing */
473 bstrncpy(VolumeName, saveVolumeName, sizeof(VolumeName));
474 VolCatInfo = dcrVolCatInfo; /* structure assignment */
475 goto check_next_volume;
478 * This was not the volume we expected, but it is OK with
479 * the Director, so use it.
481 Dmsg1(150, "Got new Volume name=%s\n", VolumeName);
482 dev->VolCatInfo = VolCatInfo; /* structure assignment */
483 Dmsg1(100, "Call reserve_volume=%s\n", dev->VolHdr.VolumeName);
484 if (reserve_volume(this, dev->VolHdr.VolumeName) == NULL) {
485 if (!jcr->errmsg[0]) {
486 Jmsg3(jcr, M_WARNING, 0, _("Could not reserve volume %s on %s device %s\n"),
487 dev->VolHdr.VolumeName, dev->print_type(), dev->print_name());
489 Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
492 dev->setVolCatInfo(false);
493 setVolCatInfo(false);
494 goto check_next_volume;
496 break; /* got a Volume */
498 * At this point, we assume we have a blank tape mounted.
501 /* Fall through wanted */
503 switch (try_autolabel(true)) {
505 goto check_next_volume;
507 goto check_read_volume;
513 /* NOTE! Fall-through wanted. */
516 Dmsg0(200, "VOL_NO_MEDIA or default.\n");
517 /* Send error message */
520 Dmsg1(200, "Msg suppressed by poll: %s\n", jcr->errmsg);
523 /* Needed, so the medium can be changed */
524 if (dev->requires_mount()) {
528 goto check_next_volume;
534 dev->setVolCatInfo(false);
535 setVolCatInfo(false);
537 return check_next_vol;
545 return check_read_vol;
550 bool DCR::is_suitable_volume_mounted()
554 /* Volume mounted? */
555 if (dev->VolHdr.VolumeName[0] == 0 || dev->swap_dev || dev->must_unload()) {
556 return false; /* no */
558 bstrncpy(VolumeName, dev->VolHdr.VolumeName, sizeof(VolumeName));
559 ok = dir_get_volume_info(this, VolumeName, GET_VOL_INFO_FOR_WRITE);
561 Dmsg1(40, "dir_get_volume_info failed: %s", jcr->errmsg);
567 bool DCR::do_unload()
569 if (dev->must_unload()) {
570 Dmsg1(100, "must_unload release %s\n", dev->print_name());
576 bool DCR::do_load(bool is_writing)
578 if (dev->must_load()) {
579 Dmsg1(100, "Must load dev=%s\n", dev->print_name());
580 if (autoload_device(this, is_writing, NULL) > 0) {
589 void DCR::do_swapping(bool is_writing)
592 * See if we are asked to swap the Volume from another device
593 * if so, unload the other device here, and attach the
594 * volume to our drive.
597 if (dev->swap_dev->must_unload()) {
599 dev->swap_dev->set_slot(dev->vol->get_slot());
601 Dmsg2(100, "Swap unloading slot=%d %s\n", dev->swap_dev->get_slot(),
602 dev->swap_dev->print_name());
603 unload_dev(this, dev->swap_dev);
606 dev->vol->clear_swapping();
607 Dmsg1(100, "=== set in_use vol=%s\n", dev->vol->vol_name);
608 dev->vol->clear_in_use();
609 dev->VolHdr.VolumeName[0] = 0; /* don't yet have right Volume */
611 Dmsg1(100, "No vol on dev=%s\n", dev->print_name());
613 if (dev->swap_dev->vol) {
614 Dmsg2(100, "Vol=%s on dev=%s\n", dev->swap_dev->vol->vol_name,
615 dev->swap_dev->print_name());
617 Dmsg2(100, "Set swap_dev=NULL for dev=%s swap_dev=%s\n",
618 dev->print_name(), dev->swap_dev->print_name());
619 dev->swap_dev = NULL;
622 Dmsg1(100, "No swap_dev set. dev->vol=%p\n", dev->vol);
624 Dmsg1(100, "No swap_dev set. dev->vol=%p\n", dev->vol);
630 * If permitted, we label the device, make sure we can do
631 * it by checking that the VolCatBytes is zero => not labeled,
632 * once the Volume is labeled we don't want to label another
633 * blank tape with the same name. For disk, we go ahead and
634 * label it anyway, because the OS insures that there is only
635 * one Volume with that name.
636 * As noted above, at this point dcr->VolCatInfo has what
637 * the Director wants and dev->VolCatInfo has info on the
638 * previous tape (or nothing).
641 * try_next_vol label failed, look for another volume
642 * try_read_vol labeled volume, now re-read the label
643 * try_error hard error (catalog update)
644 * try_default I couldn't do anything
646 int DCR::try_autolabel(bool opened)
650 if (dev->poll && !dev->is_tape()) {
651 Dmsg0(100, "No autolabel because polling.\n");
652 return try_default; /* if polling, don't try to create new labels */
654 /* For a tape require it to be opened and read before labeling */
655 if (!opened && (dev->is_tape() || dev->is_null())) {
658 if (dev->has_cap(CAP_LABEL) && (VolCatInfo.VolCatBytes == 0 ||
659 (!dev->is_tape() && strcmp(VolCatInfo.VolCatStatus,
661 Dmsg1(40, "Create new volume label vol=%s\n", VolumeName);
662 /* Create a new Volume label and write it to the device */
663 if (!dev->write_volume_label(dcr, VolumeName,
664 pool_name, false, /* no relabel */ false /* defer label */)) {
665 Dmsg2(100, "write_vol_label failed. vol=%s, pool=%s\n",
666 VolumeName, pool_name);
668 mark_volume_in_error();
672 Dmsg0(150, "dir_update_vol_info. Set Append\n");
673 /* Copy Director's info into the device info */
674 dev->VolCatInfo = VolCatInfo; /* structure assignment */
675 if (!dir_update_volume_info(dcr, true, true)) { /* indicate tape labeled */
676 Dmsg3(100, "Update_vol_info failed no autolabel Volume \"%s\" on %s device %s.\n",
677 VolumeName, dev->print_type(), dev->print_name());
680 Jmsg(dcr->jcr, M_INFO, 0, _("Labeled new Volume \"%s\" on %s device %s.\n"),
681 VolumeName, dev->print_type(), dev->print_name());
682 Dmsg3(100, "Labeled new Volume \"%s\" on %s device %s.\n",
683 VolumeName, dev->print_type(), dev->print_name());
684 return try_read_vol; /* read label we just wrote */
686 Dmsg4(40, "=== Cannot autolabel: cap_label=%d VolCatBytes=%lld is_tape=%d VolCatStatus=%s\n",
687 dev->has_cap(CAP_LABEL), VolCatInfo.VolCatBytes, dev->is_tape(),
688 VolCatInfo.VolCatStatus);
690 if (!dev->has_cap(CAP_LABEL) && VolCatInfo.VolCatBytes == 0) {
691 Jmsg(jcr, M_WARNING, 0, _("%s device %s not configured to autolabel Volumes.\n"),
692 dev->print_type(), dev->print_name());
695 /* If not removable, Volume is broken */
696 if (!dev->is_removable()) {
697 Jmsg3(jcr, M_WARNING, 0, _("Volume \"%s\" not loaded on %s device %s.\n"),
698 VolumeName, dev->print_type(), dev->print_name());
699 Dmsg3(40, "Volume \"%s\" not loaded on %s device %s.\n",
700 VolumeName, dev->print_type(), dev->print_name());
702 mark_volume_in_error();
711 * Mark volume in error in catalog
713 void DCR::mark_volume_in_error()
715 Jmsg(jcr, M_INFO, 0, _("Marking Volume \"%s\" in Error in Catalog.\n"),
717 dev->VolCatInfo = VolCatInfo; /* structure assignment */
718 dev->setVolCatStatus("Error");
719 Dmsg0(150, "dir_update_vol_info. Set Error.\n");
720 dir_update_volume_info(this, false, false);
722 Dmsg0(50, "set_unload\n");
723 dev->set_unload(); /* must get a new volume */
727 * The Volume is not in the correct slot, so mark this
728 * Volume as not being in the Changer.
730 void DCR::mark_volume_not_inchanger()
732 Jmsg(jcr, M_ERROR, 0, _("Autochanger Volume \"%s\" not found in slot %d.\n"
733 " Setting InChanger to zero in catalog.\n"),
734 getVolCatName(), VolCatInfo.Slot);
735 dev->VolCatInfo = VolCatInfo; /* structure assignment */
736 VolCatInfo.InChanger = false;
737 dev->VolCatInfo.InChanger = false;
738 Dmsg0(400, "update vol info in mount\n");
739 dir_update_volume_info(this, true, false); /* set new status */
743 * Either because we are going to hang a new volume, or because
744 * of explicit user request, we release the current volume.
746 void DCR::release_volume()
748 unload_autochanger(this, -1);
751 Jmsg0(jcr, M_ERROR, 0, _("Hey!!!!! WroteVol non-zero !!!!!\n"));
752 Pmsg0(190, "Hey!!!!! WroteVol non-zero !!!!!\n");
755 if (dev->is_open() && (!dev->is_tape() || !dev->has_cap(CAP_ALWAYSOPEN))) {
756 generate_plugin_event(jcr, bsdEventDeviceClose, this);
760 /* If we have not closed the device, then at least rewind the tape */
761 if (dev->is_open()) {
762 dev->offline_or_rewind(this);
766 * Erase all memory of the current volume
769 dev->block_num = dev->file = 0;
770 dev->EndBlock = dev->EndFile = 0;
771 memset(&dev->VolCatInfo, 0, sizeof(dev->VolCatInfo));
773 /* Force re-read of label */
774 dev->clear_labeled();
777 dev->label_type = B_BACULA_LABEL;
780 Dmsg0(190, "release_volume\n");
786 * Check to see if the tape position as defined by the OS is
787 * the same as our concept. If it is not,
788 * it means the user has probably manually rewound the tape.
789 * Note, we check only if num_writers == 0, but this code will
790 * also work fine for any number of writers. If num_writers > 0,
791 * we probably should cancel all jobs using this device, or
792 * perhaps even abort the SD, or at a minimum, mark the tape
793 * in error. Another strategy with num_writers == 0, would be
794 * to rewind the tape and do a new eod() request.
796 bool DCR::is_tape_position_ok()
798 if (dev->is_tape() && dev->num_writers == 0) {
799 int32_t file = dev->get_os_tape_file();
800 if (file >= 0 && file != (int32_t)dev->get_file()) {
801 Jmsg(jcr, M_ERROR, 0, _("Invalid tape position on volume \"%s\""
802 " on device %s. Expected %d, got %d\n"),
803 dev->VolHdr.VolumeName, dev->print_name(), dev->get_file(), file);
805 * If the current file is greater than zero, it means we probably
806 * have some bad count of EOF marks, so mark tape in error. Otherwise
807 * the operator might have moved the tape, so we just release it
811 mark_volume_in_error();
822 * If we are reading, we come here at the end of the tape
823 * and see if there are more volumes to be mounted.
825 bool mount_next_read_volume(DCR *dcr)
827 DEVICE *dev = dcr->dev;
829 Dmsg2(90, "NumReadVolumes=%d CurReadVolume=%d\n", jcr->NumReadVolumes, jcr->CurReadVolume);
831 volume_unused(dcr); /* release current volume */
833 * End Of Tape -- mount next Volume (if another specified)
835 if (jcr->NumReadVolumes > 1 && jcr->CurReadVolume < jcr->NumReadVolumes) {
839 dcr->set_reserved_for_read();
841 if (!acquire_device_for_read(dcr)) {
842 Jmsg3(jcr, M_FATAL, 0, _("Cannot open %s Dev=%s, Vol=%s for reading.\n"),
843 dev->print_type(), dev->print_name(), dcr->VolumeName);
844 jcr->setJobStatus(JS_FatalError); /* Jmsg is not working for *SystemJob* */
847 return true; /* next volume mounted */
849 Dmsg0(90, "End of Device reached.\n");