static bool use_storage_cmd(JCR *jcr);
static void queue_reserve_message(JCR *jcr);
static void pop_reserve_messages(JCR *jcr);
+void switch_device(DCR *dcr, DEVICE *dev);
/* Requests from the Director daemon */
static char use_storage[] = "use storage=%127s media_type=%127s "
VOLRES *reserve_volume(DCR *dcr, const char *VolumeName)
{
VOLRES *vol, *nvol;
- DEVICE *dev = dcr->dev;
+ DEVICE * volatile dev = dcr->dev;
ASSERT(dev != NULL);
*/
if (strcmp(vol->vol_name, VolumeName) == 0) {
Dmsg1(dbglvl, "=== OK, vol=%s on device. set not released.\n", VolumeName);
+ vol->released = false; /* retake vol if released previously */
goto get_out; /* Volume already on this device */
} else {
+ /* Don't release a volume if it is in use */
+ if (!vol->released) {
+ Dmsg1(dbglvl, "Cannot free vol=%s. It is not released.\n", vol->vol_name);
+ vol = NULL; /* vol in use */
+ goto get_out;
+ }
Dmsg2(dbglvl, "reserve_vol free vol=%s at %p\n", vol->vol_name, vol->vol_name);
unload_autochanger(dcr, -1); /* unload the volume */
free_volume(dev);
/* Check if we are trying to use the Volume on a different drive */
if (dev != vol->dev) {
/* Caller wants to switch Volume to another device */
+ switch_device(dcr, vol->dev);
+ dev = vol->dev;
+#ifdef xxx
if (!vol->dev->is_busy()) {
/* OK to move it -- I'm not sure this will work */
Dmsg3(dbglvl, "==== Swap vol=%s from dev=%s to %s\n", VolumeName,
dev->vol = vol; /* point dev at vol */
dev->VolHdr.VolumeName[0] = 0;
} else {
- Dmsg3(dbglvl, "Volume busy could not swap vol=%s from dev=%s to %s\n",
+ Dmsg3(dbglvl, "==== Swap not possible Vol busy vol=%s from dev=%s to %s\n",
VolumeName, vol->dev->print_name(), dev->print_name());
vol = NULL; /* device busy */
goto get_out;
}
+#endif
}
}
dev->vol = vol;
dcr->VolCatInfo.Slot = save_dcr.VolCatInfo.Slot;
bstrncpy(dcr->pool_name, save_dcr.pool_name, sizeof(dcr->pool_name));
bstrncpy(dcr->pool_type, save_dcr.pool_type, sizeof(dcr->pool_type));
- bstrncpy(dcr->dev_name, save_dcr.dev_name, sizeof(dcr->dev_name));
+ bstrncpy(dcr->dev_name, dev->dev_name, sizeof(dcr->dev_name));
dev->reserved_device++;
dcr->reserved_device = true;
Jmsg1(dcr->jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers);
dev->num_writers = 0;
}
+ if (dev->reserved_device == 0 && dev->num_writers == 0) {
+ volume_unused(dcr);
+ }
}
-
- volume_unused(dcr);
}
/*
return false;
}
+#ifdef xxx
if (dev->is_busy()) {
Dmsg1(dbglvl, "vol_unused: busy on %s\n", dev->print_name());
debug_list_volumes("dev busy cannot unreserve_volume");
return false;
}
+#endif
#ifdef xxx
if (dev->num_writers > 0 || dev->reserved_device > 0) {
ASSERT(0);
Dmsg3(dbglvl, "=== mark released vol=%s num_writers=%d reserved=%d\n",
dev->vol->vol_name, dev->num_writers, dev->reserved_device);
dev->vol->released = true;
- if (dev->is_tape() || dev->is_autochanger()) {
+ if (dev->is_tape()) { // || dev->is_autochanger()) {
return true;
} else {
/*
dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
Dmsg3(dbglvl, "Vol=%s num_writers=%d, have_vol=%d\n",
rctx.VolumeName, dcr->dev->num_writers, rctx.have_volume);
- if (!rctx.have_volume) {
+ if (rctx.have_volume) {
+ if (reserve_volume(dcr, rctx.VolumeName)) {
+ Dmsg1(dbglvl, "Reserved vol=%s\n", rctx.VolumeName);
+ } else {
+ Dmsg1(dbglvl, "Could not reserve vol=%s\n", rctx.VolumeName);
+ goto bail_out;
+ }
+ } else {
dcr->any_volume = true;
Dmsg0(dbglvl, "no vol, call find_next_appendable_vol.\n");
if (dir_find_next_appendable_volume(dcr)) {
Dmsg1(dbglvl, "looking for Volume=%s\n", rctx.VolumeName);
} else {
Dmsg0(dbglvl, "No next volume found\n");
+ rctx.have_volume = false;
+ rctx.VolumeName[0] = 0;
/*
* If there is at least one volume that is valid and in use,
* but we get here, check if we are running with prefers
if (dcr->volume_in_use && !rctx.PreferMountedVols) {
rctx.PreferMountedVols = true;
if (dcr->VolumeName[0]) {
- volume_unused(dcr);
+ unreserve_device(dcr);
}
goto bail_out;
}
/*
* Note. Under some circumstances, the Director can hand us
- * a Volume name that is no the same as the one on the current
+ * a Volume name that is not the same as the one on the current
* drive, and in that case, the call above to find the next
* volume will fail because in attempting to reserve the Volume
* the code will realize that we already have a tape mounted,
*/
if (dcr->dev->num_writers != 0) {
if (dcr->VolumeName[0]) {
- volume_unused(dcr);
+ unreserve_device(dcr);
}
goto bail_out;
}
- rctx.have_volume = false;
- rctx.VolumeName[0] = 0;
}
}
} else {
bail_out:
rctx.have_volume = false;
rctx.VolumeName[0] = 0;
-// free_dcr(dcr);
Dmsg0(dbglvl, "Not OK.\n");
return 0;
}