jcr->NumReadVolumes, jcr->CurReadVolume);
goto get_out; /* should not happen */
}
+ /*
+ * Note, if we want to be able to work from a .bsr file only
+ * for disaster recovery, we must "simulate" reading the catalog
+ */
bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
+ bstrncpy(dcr->VolCatInfo.VolCatName, vol->VolumeName, sizeof(dcr->VolCatInfo.VolCatName));
bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type));
dcr->VolCatInfo.Slot = vol->Slot;
+ dcr->VolCatInfo.InChanger = vol->Slot > 0;
+ if (reserve_volume(dcr, dcr->VolumeName) == NULL) {
+ Dmsg2(100, "Could not reserve volume %s on %s\n", dcr->VolumeName,
+ dcr->dev->print_name());
+ Jmsg2(jcr, M_FATAL, 0, _("Could not reserve volume %s on %s\n"), dcr->VolumeName,
+ dcr->dev->print_name());
+ goto get_out;
+ }
+ if (dev->vol && dev->vol->is_swapping()) {
+ dev->vol->set_slot(vol->Slot);
+ Dmsg3(100, "swapping: slot=%d Vol=%s dev=%s\n", dev->vol->get_slot(),
+ dev->vol->vol_name, dev->print_name());
+ }
/*
* If the MediaType requested for this volume is not the
goto get_out; /* error return */
}
- dcr->do_swapping();
-
- autoload_device(dcr, 0, NULL);
+ dcr->do_swapping(false/*is_writing*/);
/*
* This code ensures that the device is ready for
bstrncpy(lastVolume, dcr->VolumeName, sizeof(lastVolume));
if (dcr->can_i_use_volume()) {
Dmsg1(100, "Call reserve_volume. Vol=%s\n", dcr->VolumeName);
- if (reserve_volume(dcr, dcr->VolumeName) == 0) {
+ if (reserve_volume(dcr, dcr->VolumeName) == NULL) {
Dmsg2(100, "Could not reserve volume %s on %s\n", dcr->VolumeName,
dcr->dev->print_name());
continue;
POOLMEM *changer;
if (!dev->is_autochanger()) {
- Dmsg1(200, "Device %s is not an autochanger\n", dev->print_name());
+ Dmsg1(100, "Device %s is not an autochanger\n", dev->print_name());
return 0;
}
/* An empty ChangerCommand => virtual disk autochanger */
if (dcr->device->changer_command && dcr->device->changer_command[0] == 0) {
+ Dmsg0(100, "ChangerCommand=0, virtual disk changer\n");
return 1; /* nothing to load */
}
slot = dcr->VolCatInfo.InChanger ? dcr->VolCatInfo.Slot : 0;
+ Dmsg3(100, "autoload: slot=%d InChgr=%d Vol=%s\n", dcr->VolCatInfo.Slot,
+ dcr->VolCatInfo.InChanger, dcr->VolCatInfo.VolCatName);
/*
* Handle autoloaders here. If we cannot autoload it, we
* will return 0 so that the sysop will be asked to load it.
return -1;
}
if (!dcr->device->changer_command) {
- Jmsg(jcr, M_FATAL, 0, _("3992 Missing Changer command.\n"));
+// Jmsg(jcr, M_FATAL, 0, _("3992 Missing Changer command.\n"));
return -1;
}
if (dev->Slot > 0) {
* the Volume parts multiple times without losing track of what the
* main Volume parameters are.
*/
-void DEVICE::close_part(DCR *dcr)
+void DEVICE::close_part(DCR * /*dcr*/)
{
VOLUME_LABEL saveVolHdr;
VOLUME_CAT_INFO saveVolCatInfo; /* Volume Catalog Information */
close(); /* close current part */
VolHdr = saveVolHdr; /* structure assignment */
VolCatInfo = saveVolCatInfo; /* structure assignment */
- dcr->VolCatInfo = saveVolCatInfo; /* structure assignment */
}
boffset_t DEVICE::lseek(DCR *dcr, boffset_t offset, int whence)
bool is_eod_valid();
int check_volume_label(bool &ask, bool &autochanger);
void release_volume();
- void do_swapping();
+ void do_swapping(bool is_writing);
};
/*
} else if (dev->is_busy()) {
send_dir_busy_message(dir, dev);
} else { /* device not being used */
- Dmsg0(90, "Device not in use, releaseing\n");
+ Dmsg0(90, "Device not in use, releasing\n");
unload_autochanger(dcr, -1);
dcr->release_volume();
dir->fsend(_("3022 Device %s released.\n"),
if (dev->must_unload()) {
ask = true; /* ask operator to mount tape */
}
- do_swapping();
+ do_swapping(true /*writing*/);
if (!is_suitable_volume_mounted()) {
bool have_vol = false;
* 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 {
return dir_get_volume_info(this, GET_VOL_INFO_FOR_WRITE);
}
-void DCR::do_swapping()
+void DCR::do_swapping(bool is_writing)
{
if (dev->must_unload()) {
Dmsg1(100, "swapping: unloading %s\n", dev->print_name());
}
if (dev->must_load()) {
Dmsg1(100, "swapping: must load %s\n", dev->print_name());
- dev->clear_load();
- dev->clear_volhdr(); /* force "load" */
+ if (autoload_device(this, is_writing, NULL) > 0) {
+ dev->clear_load();
+ }
}
}
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();
/* Changing pool, unload old tape if any in drive */
Dmsg0(dbglvl, "OK dev: num_writers=0, not reserved, pool change, unload changer\n");
/* ***FIXME*** use set_unload() */
- unload_autochanger(dcr, 0);
+ unload_autochanger(dcr, -1);
}
}
/* Device is available but not yet reserved, reserve it for us */
General:
03May08
+kes Rework SD acquire for read to handle autochanger Volume
+ swapping.
kes Implement regression that explicitly tests swapping a Volume
from one drive to another.
kes Enhance disk-changer to detect most error conditions.