goto bail_out;
}
recycle = false;
+
if (dev->must_unload()) {
- Dmsg0(150, "mount_next_volume release=1\n");
- unload_autochanger(dcr, -1);
- release_volume();
- dev->clear_unload();
ask = true; /* ask operator to mount tape */
}
- /*
- * See if we are asked to swap the Volume from another device
- * if so, unload the other device here, and attach the
- * volume to our drive.
- */
- if (dev->swap_dev) {
- Dmsg1(100, "Swap unloading %s\n", dev->swap_dev->print_name());
- if (dev->swap_dev->must_unload()) {
- unload_dev(dcr, dev->swap_dev);
- }
- if (dev->vol) {
- dev->vol->clear_swapping();
- dev->vol->set_in_use();
- dev->VolHdr.VolumeName[0] = 0; /* don't yet have right Volume */
- }
- dev->swap_dev = NULL;
- }
- if (dev->must_load()) {
- dev->clear_load();
- dev->clear_volhdr(); /* force "load" */
- }
+ do_swapping(true /*writing*/);
+
if (!is_suitable_volume_mounted()) {
bool have_vol = false;
/* Do we have a candidate volume? */
* and move the tape to the end of data.
*
*/
- if (autoload_device(dcr, 1, NULL) > 0) {
+ if (autoload_device(dcr, true/*writing*/, NULL) > 0) {
autochanger = true;
ask = false;
} else {
autochanger = false;
VolCatInfo.Slot = 0;
}
- Dmsg1(200, "autoload_dev returns %d\n", autochanger);
+ Dmsg1(150, "autoload_dev returns %d\n", autochanger);
/*
* If we autochanged to correct Volume or (we have not just
* released the Volume AND we can automount) we go ahead
}
/* If DVD, ignore the error, very often you cannot open the device
* (when there is no DVD, or when the one inserted is a wrong one) */
- if (dev->poll || dev->is_dvd() || dev->is_removable()) {
+ if (dev->poll || dev->is_dvd()) {
goto mount_next_vol;
} else {
Jmsg(jcr, M_ERROR, 0, _("Could not open device %s: ERR=%s\n"),
return dir_get_volume_info(this, GET_VOL_INFO_FOR_WRITE);
}
+void DCR::do_swapping(bool is_writing)
+{
+ if (dev->must_unload()) {
+ Dmsg1(100, "swapping: unloading %s\n", dev->print_name());
+ release_volume();
+ dev->clear_unload();
+ }
+ /*
+ * See if we are asked to swap the Volume from another device
+ * if so, unload the other device here, and attach the
+ * volume to our drive.
+ */
+ if (dev->swap_dev) {
+ if (dev->swap_dev->must_unload()) {
+ if (dev->vol) {
+ dev->swap_dev->set_slot(dev->vol->get_slot());
+ }
+ Dmsg2(100, "Swap unloading slot=%d %s\n", dev->swap_dev->get_slot(),
+ dev->swap_dev->print_name());
+ unload_dev(this, dev->swap_dev);
+ }
+ if (dev->vol) {
+ dev->vol->clear_swapping();
+ dev->vol->set_in_use();
+ dev->VolHdr.VolumeName[0] = 0; /* don't yet have right Volume */
+ }
+ dev->swap_dev = NULL;
+ }
+ if (dev->must_load()) {
+ Dmsg1(100, "swapping: must load %s\n", dev->print_name());
+ if (autoload_device(this, is_writing, NULL) > 0) {
+ dev->clear_load();
+ }
+ }
+}
/*
{
Jmsg(jcr, M_INFO, 0, _("Marking Volume \"%s\" in Error in Catalog.\n"),
VolumeName);
- dev->VolCatInfo = VolCatInfo; /* structure assignment */
+ dev->VolCatInfo = VolCatInfo; /* structure assignment */
bstrncpy(dev->VolCatInfo.VolCatStatus, "Error", sizeof(dev->VolCatInfo.VolCatStatus));
Dmsg0(150, "dir_update_vol_info. Set Error.\n");
dir_update_volume_info(this, false, false);
volume_unused(this);
+ dev->set_unload(); /* must get a new volume */
}
/*
*/
void DCR::release_volume()
{
+ unload_autochanger(this, -1);
+
if (WroteVol) {
Jmsg0(jcr, M_ERROR, 0, _("Hey!!!!! WroteVol non-zero !!!!!\n"));
Dmsg0(190, "Hey!!!!! WroteVol non-zero !!!!!\n");
dev->block_num = dev->file = 0;
dev->EndBlock = dev->EndFile = 0;
memset(&dev->VolCatInfo, 0, sizeof(dev->VolCatInfo));
- memset(&VolCatInfo, 0, sizeof(VolCatInfo));
+// memset(&VolCatInfo, 0, sizeof(VolCatInfo));
dev->clear_volhdr();
/* Force re-read of label */
dev->clear_labeled();
if (dev->is_open()) {
dev->offline_or_rewind();
}
+ dev->set_unload();
Dmsg0(190, "release_volume\n");
}
+/*
+ * Insanity check
+ *
+ * Check to see if the tape position as defined by the OS is
+ * the same as our concept. If it is not,
+ * it means the user has probably manually rewound the tape.
+ * Note, we check only if num_writers == 0, but this code will
+ * also work fine for any number of writers. If num_writers > 0,
+ * we probably should cancel all jobs using this device, or
+ * perhaps even abort the SD, or at a minimum, mark the tape
+ * in error. Another strategy with num_writers == 0, would be
+ * to rewind the tape and do a new eod() request.
+ */
+bool DCR::is_tape_position_ok()
+{
+ if (dev->is_tape() && dev->num_writers == 0) {
+ int32_t file = dev->get_os_tape_file();
+ if (file >= 0 && file != (int32_t)dev->get_file()) {
+ Jmsg(jcr, M_ERROR, 0, _("Invalid tape position on volume \"%s\""
+ " on device %s. Expected %d, got %d\n"),
+ dev->VolHdr.VolumeName, dev->print_name(), dev->get_file(), file);
+ /*
+ * If the current file is greater than zero, it means we probably
+ * have some bad count of EOF marks, so mark tape in error. Otherwise
+ * the operator might have moved the tape, so we just release it
+ * and try again.
+ */
+ if (file > 0) {
+ mark_volume_in_error();
+ }
+ release_volume();
+ return false;
+ }
+ }
+ return true;
+}
+
+
/*
* If we are reading, we come here at the end of the tape
* and see if there are more volumes to be mounted.