}
DCR *dcr = (DCR *)malloc(sizeof(DCR));
memset(dcr, 0, sizeof(DCR));
- if (jcr) {
- jcr->dcr = dcr;
- }
dcr->jcr = jcr;
- dcr->dev = dev;
if (dev) {
+ if (jcr) {
+ jcr->dcr = dcr;
+ }
+ dcr->dev = dev;
dcr->device = dev->device;
+ dcr->block = new_block(dev);
+ dcr->rec = new_record();
+ dcr->max_job_spool_size = dev->device->max_job_spool_size;
+ /* Attach this dcr only if dev is initialized */
+ if (dev->fd != 0 && jcr && jcr->JobType != JT_SYSTEM) {
+ dev->attached_dcrs->append(dcr); /* attach dcr to device */
+// jcr->dcrs->append(dcr); /* put dcr in list for Job */
+ }
}
- dcr->block = new_block(dev);
- dcr->rec = new_record();
dcr->spool_fd = -1;
- dcr->max_job_spool_size = dev->device->max_job_spool_size;
- /* Attach this dcr only if dev is initialized */
- if (dev->fd != 0 && jcr && jcr->JobType != JT_SYSTEM) {
- dev->attached_dcrs->append(dcr); /* attach dcr to device */
-// jcr->dcrs->append(dcr); /* put dcr in list for Job */
- }
return dcr;
}
DCR *ldcr;
int num = jcr->dcrs->size();
for (i=0; i < num; i++) {
- ldcr = (DCR *)jcr->dcrs->get(i);
- if (ldcr == dcr) {
- jcr->dcrs->remove(i);
- if (jcr->dcr == dcr) {
- jcr->dcr = NULL;
- }
- }
+ ldcr = (DCR *)jcr->dcrs->get(i);
+ if (ldcr == dcr) {
+ jcr->dcrs->remove(i);
+ if (jcr->dcr == dcr) {
+ jcr->dcr = NULL;
+ }
+ }
}
}
}
dcr->reserved_device = false;
if (dev->num_writers < 0) {
Jmsg1(dcr->jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers);
- dev->num_writers = 0;
+ dev->num_writers = 0;
}
unlock_device(dev);
}
/* Detach this dcr only if the dev is initialized */
if (dev->fd != 0 && jcr && jcr->JobType != JT_SYSTEM) {
- dev->attached_dcrs->remove(dcr); /* detach dcr from device */
+ dev->attached_dcrs->remove(dcr); /* detach dcr from device */
// remove_dcr_from_dcrs(dcr); /* remove dcr from jcr list */
}
if (dcr->block) {
if (dcr->jcr) {
dcr->jcr->dcr = NULL;
}
- free_unused_volume(dcr); /* free unused vols attached to this dcr */
+ free_unused_volume(dcr); /* free unused vols attached to this dcr */
free(dcr);
}
* leave the block pointers just after the label.
*
* Returns: NULL if failed for any reason
- * dcr if successful
+ * dcr if successful
*/
DCR *acquire_device_for_read(DCR *dcr)
{
if (dev->num_writers > 0) {
Jmsg2(jcr, M_FATAL, 0, _("Num_writers=%d not zero. Job %d canceled.\n"),
- dev->num_writers, jcr->JobId);
+ dev->num_writers, jcr->JobId);
goto get_out;
}
vol = vol->next;
}
if (!vol) {
- goto get_out; /* should not happen */
+ goto get_out; /* should not happen */
}
bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
init_device_wait_timers(dcr);
tape_previously_mounted = dev->can_read() || dev->can_append() ||
- dev->is_labeled();
+ dev->is_labeled();
tape_initially_mounted = tape_previously_mounted;
}
for (i=0; i<5; i++) {
- dev->clear_labeled(); /* force reread of label */
+ dev->clear_labeled(); /* force reread of label */
if (job_canceled(jcr)) {
Mmsg1(dev->errmsg, _("Job %d canceled.\n"), jcr->JobId);
- goto get_out; /* error return */
+ goto get_out; /* error return */
}
/*
* This code ensures that the device is ready for
*/
Dmsg1(100, "bstored: open vol=%s\n", dcr->VolumeName);
if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
- if (dev->dev_errno == EIO) { /* no tape loaded */
+ if (dev->dev_errno == EIO) { /* no tape loaded */
Jmsg3(jcr, M_WARNING, 0, _("Open device %s Volume \"%s\" failed (EIO): ERR=%s\n"),
- dev->print_name(), dcr->VolumeName, strerror_dev(dev));
- goto default_path;
- }
-
+ dev->print_name(), dcr->VolumeName, strerror_dev(dev));
+ goto default_path;
+ }
+
#ifdef xxx_needed
- /* If we have a dvd that requires mount,
- * we need to try to open the label, so the info can be reported
- * if a wrong volume has been mounted.
- */
- if (dev->is_dvd() && (dcr->VolCatInfo.VolCatParts > 0)) {
- break;
- }
+ /* If we have a dvd that requires mount,
+ * we need to try to open the label, so the info can be reported
+ * if a wrong volume has been mounted.
+ */
+ if (dev->is_dvd() && (dcr->VolCatInfo.VolCatParts > 0)) {
+ break;
+ }
#endif
-
+
Jmsg3(jcr, M_FATAL, 0, _("Open device %s Volume \"%s\" failed: ERR=%s\n"),
- dev->print_name(), dcr->VolumeName, strerror_dev(dev));
- goto get_out;
+ dev->print_name(), dcr->VolumeName, strerror_dev(dev));
+ goto get_out;
}
Dmsg1(100, "opened dev %s OK\n", dev->print_name());
vol_label_status = read_dev_volume_label(dcr);
switch (vol_label_status) {
case VOL_OK:
- vol_ok = true;
- memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
- break; /* got it */
+ vol_ok = true;
+ memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
+ break; /* got it */
case VOL_IO_ERROR:
- /*
- * Send error message generated by read_dev_volume_label()
- * only we really had a tape mounted. This supresses superfluous
- * error messages when nothing is mounted.
- */
- if (tape_previously_mounted) {
+ /*
+ * Send error message generated by read_dev_volume_label()
+ * only we really had a tape mounted. This supresses superfluous
+ * error messages when nothing is mounted.
+ */
+ if (tape_previously_mounted) {
Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
- }
- goto default_path;
+ }
+ goto default_path;
case VOL_NAME_ERROR:
- if (tape_initially_mounted) {
- tape_initially_mounted = false;
- goto default_path;
- }
- /* Fall through */
+ if (tape_initially_mounted) {
+ tape_initially_mounted = false;
+ goto default_path;
+ }
+ /* Fall through */
default:
Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
default_path:
- tape_previously_mounted = true;
-
- /* If the device requires mount, close it, so the device can be ejected.
- * FIXME: This should perhaps be done for all devices. */
- if (dev->requires_mount()) {
- force_close_device(dev);
- }
-
- /* Call autochanger only once unless ask_sysop called */
- if (try_autochanger) {
- int stat;
+ tape_previously_mounted = true;
+
+ /* If the device requires mount, close it, so the device can be ejected.
+ * FIXME: This should perhaps be done for all devices. */
+ if (dev->requires_mount()) {
+ force_close_device(dev);
+ }
+
+ /* Call autochanger only once unless ask_sysop called */
+ if (try_autochanger) {
+ int stat;
Dmsg2(200, "calling autoload Vol=%s Slot=%d\n",
- dcr->VolumeName, dcr->VolCatInfo.Slot);
- stat = autoload_device(dcr, 0, NULL);
- if (stat > 0) {
- try_autochanger = false;
- continue; /* try reading volume mounted */
- }
- }
-
- /* Mount a specific volume and no other */
+ dcr->VolumeName, dcr->VolCatInfo.Slot);
+ stat = autoload_device(dcr, 0, NULL);
+ if (stat > 0) {
+ try_autochanger = false;
+ continue; /* try reading volume mounted */
+ }
+ }
+
+ /* Mount a specific volume and no other */
Dmsg0(200, "calling dir_ask_sysop\n");
- if (!dir_ask_sysop_to_mount_volume(dcr)) {
- goto get_out; /* error return */
- }
- try_autochanger = true; /* permit using autochanger again */
- continue; /* try reading again */
+ if (!dir_ask_sysop_to_mount_volume(dcr)) {
+ goto get_out; /* error return */
+ }
+ try_autochanger = true; /* permit using autochanger again */
+ continue; /* try reading again */
} /* end switch */
break;
} /* end for loop */
if (!vol_ok) {
Jmsg1(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s.\n"),
- dev->print_name());
+ dev->print_name());
goto get_out;
}
* If this is the first one, we read the label.
*
* Returns: NULL if failed for any reason
- * dcr if successful.
+ * dcr if successful.
* Note, normally reserve_device_for_append() is called
* before this routine.
*/
*/
bstrncpy(dcr->VolumeName, dev->VolHdr.VolumeName, sizeof(dcr->VolumeName));
if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE) &&
- !(dir_find_next_appendable_volume(dcr) &&
- strcmp(dev->VolHdr.VolumeName, dcr->VolumeName) == 0)) { /* wrong tape mounted */
+ !(dir_find_next_appendable_volume(dcr) &&
+ strcmp(dev->VolHdr.VolumeName, dcr->VolumeName) == 0)) { /* wrong tape mounted */
Dmsg2(190, "Wrong tape mounted: %s. wants:%s\n", dev->VolHdr.VolumeName,
- dcr->VolumeName);
- /* Release volume reserved by dir_find_next_appendable_volume() */
- if (dcr->VolumeName[0]) {
- free_unused_volume(dcr);
- }
- if (dev->num_writers != 0 || dev->reserved_device) {
+ dcr->VolumeName);
+ /* Release volume reserved by dir_find_next_appendable_volume() */
+ if (dcr->VolumeName[0]) {
+ free_unused_volume(dcr);
+ }
+ if (dev->num_writers != 0 || dev->reserved_device) {
Jmsg3(jcr, M_FATAL, 0, _("Wanted Volume \"%s\", but device %s is busy writing on \"%s\" .\n"),
- dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName);
+ dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName);
Dmsg3(200, "Wanted Volume \"%s\", but device %s is busy writing on \"%s\" .\n",
- dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName);
- goto get_out;
- }
- /* Wrong tape mounted, release it, then fall through to get correct one */
+ dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName);
+ goto get_out;
+ }
+ /* Wrong tape mounted, release it, then fall through to get correct one */
Dmsg0(190, "Wrong tape mounted, release and try mount.\n");
- release = true;
- do_mount = true;
+ release = true;
+ do_mount = true;
} else {
- /*
- * At this point, the correct tape is already mounted, so
- * we do not need to do mount_next_write_volume(), unless
- * we need to recycle the tape.
- */
+ /*
+ * At this point, the correct tape is already mounted, so
+ * we do not need to do mount_next_write_volume(), unless
+ * we need to recycle the tape.
+ */
recycle = strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0;
Dmsg1(190, "Correct tape mounted. recycle=%d\n", recycle);
- if (recycle && dev->num_writers != 0) {
+ if (recycle && dev->num_writers != 0) {
Jmsg(jcr, M_FATAL, 0, _("Cannot recycle volume \"%s\""
" on device %s because it is in use by another job.\n"),
- dev->VolHdr.VolumeName, dev->print_name());
- goto get_out;
- }
- if (dev->num_writers == 0) {
- memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
- }
+ dev->VolHdr.VolumeName, dev->print_name());
+ goto get_out;
+ }
+ if (dev->num_writers == 0) {
+ memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
+ }
}
} else {
/* Not already in append mode, so mount the device */
Dmsg0(190, "Do mount_next_write_vol\n");
bool mounted = mount_next_write_volume(dcr, release);
if (!mounted) {
- if (!job_canceled(jcr)) {
+ if (!job_canceled(jcr)) {
/* Reduce "noise" -- don't print if job canceled */
Jmsg(jcr, M_FATAL, 0, _("Could not ready device %s for append.\n"),
- dev->print_name());
+ dev->print_name());
Dmsg1(200, "Could not ready device %s for append.\n",
- dev->print_name());
- }
- goto get_out;
+ dev->print_name());
+ }
+ goto get_out;
}
}
- dev->num_writers++; /* we are now a writer */
+ dev->num_writers++; /* we are now a writer */
if (jcr->NumVolumes == 0) {
jcr->NumVolumes = 1;
}
}
if (dev->can_read()) {
- dev->clear_read(); /* clear read bit */
+ dev->clear_read(); /* clear read bit */
/******FIXME**** send read volume usage statistics to director */
Dmsg1(100, "There are %d writers in release_device\n", dev->num_writers);
if (dev->is_labeled()) {
Dmsg0(100, "dir_create_jobmedia_record. Release\n");
- if (!dev->at_weot() && !dir_create_jobmedia_record(dcr)) {
+ if (!dev->at_weot() && !dir_create_jobmedia_record(dcr)) {
Jmsg(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
- dcr->VolCatInfo.VolCatName, jcr->Job);
- }
- /* If no more writers, write an EOF */
- if (!dev->num_writers && dev->can_write()) {
- weof_dev(dev, 1);
- write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName);
- }
- if (!dev->at_weot()) {
- dev->VolCatInfo.VolCatFiles = dev->file; /* set number of files */
- dev->VolCatInfo.VolCatJobs++; /* increment number of jobs */
- /* Note! do volume update before close, which zaps VolCatInfo */
+ dcr->VolCatInfo.VolCatName, jcr->Job);
+ }
+ /* If no more writers, write an EOF */
+ if (!dev->num_writers && dev->can_write()) {
+ weof_dev(dev, 1);
+ write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName);
+ }
+ if (!dev->at_weot()) {
+ dev->VolCatInfo.VolCatFiles = dev->file; /* set number of files */
+ dev->VolCatInfo.VolCatJobs++; /* increment number of jobs */
+ /* Note! do volume update before close, which zaps VolCatInfo */
Dmsg0(100, "dir_update_vol_info. Release0\n");
- dir_update_volume_info(dcr, false); /* send Volume info to Director */
- }
+ dir_update_volume_info(dcr, false); /* send Volume info to Director */
+ }
}
} else {
- /*
+ /*
* If we reach here, it is most likely because the job
* has failed, since the device is not in read mode and
* there are no writers. It was probably reserved.
alert = edit_device_codes(dcr, alert, dcr->device->alert_command, "");
bpipe = open_bpipe(alert, 0, "r");
if (bpipe) {
- while (fgets(line, sizeof(line), bpipe->rfd)) {
+ while (fgets(line, sizeof(line), bpipe->rfd)) {
Jmsg(jcr, M_ALERT, 0, _("Alert: %s"), line);
- }
- status = close_bpipe(bpipe);
+ }
+ status = close_bpipe(bpipe);
} else {
- status = errno;
+ status = errno;
}
if (status != 0) {
- berrno be;
+ berrno be;
Jmsg(jcr, M_ALERT, 0, _("3997 Bad alert command: %s: ERR=%s.\n"),
- alert, be.strerror(status));
+ alert, be.strerror(status));
}
Dmsg1(400, "alert status=%d\n", status);
/*
* Use Device command from Director
* He tells is what Device Name to use, the Media Type,
- * the Pool Name, and the Pool Type.
+ * the Pool Name, and the Pool Type.
*
* Ensure that the device exists and is opened, then store
- * the media and pool info in the JCR. This class is used
- * only temporarily in this file.
+ * the media and pool info in the JCR. This class is used
+ * only temporarily in this file.
*/
class DIRSTORE {
public:
DIRSTORE *store;
DEVRES *device;
bool PreferMountedVols;
+ char VolumeName[MAX_NAME_LENGTH];
};
static dlist *vol_list = NULL;
* not be mounted again.
*
* Return: VOLRES entry on success
- * NULL if the Volume is already in the list
+ * NULL if the Volume is already in the list
*/
VOLRES *new_volume(DCR *dcr, const char *VolumeName)
{
free(vol->vol_name);
free(vol);
if (dcr->dev) {
- nvol->dev = dcr->dev;
+ nvol->dev = dcr->dev;
}
return NULL;
}
* Search for a Volume name in the Volume list.
*
* Returns: VOLRES entry on success
- * NULL if the Volume is not in the list
+ * NULL if the Volume is not in the list
*/
VOLRES *find_volume(const char *VolumeName)
{
* Free a Volume from the Volume list
*
* Returns: true if the Volume found and removed from the list
- * false if the Volume is not in the list
+ * false if the Volume is not in the list
*/
bool free_volume(DEVICE *dev)
{
P(vol_list_lock);
for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
if (vol->dcr == dcr && (vol->dev == NULL ||
- strcmp(vol->vol_name, vol->dev->VolHdr.VolumeName) != 0)) {
- vol_list->remove(vol);
- free(vol->vol_name);
- free(vol);
- break;
+ strcmp(vol->vol_name, vol->dev->VolHdr.VolumeName) != 0)) {
+ vol_list->remove(vol);
+ free(vol->vol_name);
+ free(vol);
+ break;
}
}
V(vol_list_lock);
/*
* List Volumes -- this should be moved to status.c
*/
-void list_volumes(BSOCK *user)
+void list_volumes(BSOCK *user)
{
VOLRES *vol;
for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
}
for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
Dmsg3(000, "Unreleased Volume=%s dcr=0x%x dev=0x%x\n", vol->vol_name,
- vol->dcr, vol->dev);
+ vol->dcr, vol->dev);
}
delete vol_list;
vol_list = NULL;
{
VOLRES *vol = find_volume(dcr->VolumeName);
if (!vol) {
- return false; /* vol not in list */
+ return false; /* vol not in list */
}
- if (!vol->dev) { /* vol not attached to device */
+ if (!vol->dev) { /* vol not attached to device */
return false;
}
- if (dcr->dev == vol->dev) { /* same device OK */
+ if (dcr->dev == vol->dev) { /* same device OK */
return false;
}
if (!vol->dev->is_busy()) {
POOL_MEM store_name, dev_name, media_type, pool_name, pool_type;
BSOCK *dir = jcr->dir_bsock;
int append;
- bool ok;
+ bool ok;
int Copy, Stripe;
DIRSTORE *store;
RCTX rctx;
rctx.jcr = jcr;
/*
* If there are multiple devices, the director sends us
- * use_device for each device that it wants to use.
+ * use_device for each device that it wants to use.
*/
Dmsg1(100, "<dird: %s", dir->msg);
jcr->dirstore = New(alist(10, not_owned_by_alist));
do {
ok = sscanf(dir->msg, use_storage, store_name.c_str(),
- media_type.c_str(), pool_name.c_str(),
- pool_type.c_str(), &append, &Copy, &Stripe) == 7;
+ media_type.c_str(), pool_name.c_str(),
+ pool_type.c_str(), &append, &Copy, &Stripe) == 7;
if (!ok) {
- break;
+ break;
}
unbash_spaces(store_name);
unbash_spaces(media_type);
/* Now get all devices */
while (bnet_recv(dir) >= 0) {
- ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
- if (!ok) {
- break;
- }
- unbash_spaces(dev_name);
- store->device->append(bstrdup(dev_name.c_str()));
+ ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
+ if (!ok) {
+ break;
+ }
+ unbash_spaces(dev_name);
+ store->device->append(bstrdup(dev_name.c_str()));
}
} while (ok && bnet_recv(dir) >= 0);
char *device_name;
foreach_alist(store, jcr->dirstore) {
Dmsg4(100, "Storage=%s media_type=%s pool=%s pool_type=%s\n",
- store->name, store->media_type, store->pool_name,
- store->pool_type);
+ store->name, store->media_type, store->pool_name,
+ store->pool_type);
foreach_alist(device_name, store->device) {
Dmsg1(100, " Device=%s\n", device_name);
}
}
#endif
- /*
+ /*
* At this point, we have a list of all the Director's Storage
* resources indicated for this Job, which include Pool, PoolType,
- * storage name, and Media type.
+ * storage name, and Media type.
* Then for each of the Storage resources, we have a list of
* device names that were given.
*
rctx.PreferMountedVols = jcr->PreferMountedVols;
ok = find_suitable_device_for_job(jcr, rctx);
if (ok) {
- goto done;
+ goto done;
}
if (rctx.PreferMountedVols) {
- rctx.PreferMountedVols = false;
- ok = find_suitable_device_for_job(jcr, rctx);
- if (ok) {
- goto done;
- }
+ rctx.PreferMountedVols = false;
+ ok = find_suitable_device_for_job(jcr, rctx);
+ if (ok) {
+ goto done;
+ }
}
if (verbose) {
- unbash_spaces(dir->msg);
- pm_strcpy(jcr->errmsg, dir->msg);
+ unbash_spaces(dir->msg);
+ pm_strcpy(jcr->errmsg, dir->msg);
Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
}
Jmsg(jcr, M_FATAL, 0, _("\n"
" Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"),
- dev_name.c_str(), media_type.c_str());
+ dev_name.c_str(), media_type.c_str());
bnet_fsend(dir, NO_device, dev_name.c_str());
#ifdef implemented
for (error=(char*)rctx->errors.first(); error;
- error=(char*)rctx->errors.next()) {
+ error=(char*)rctx->errors.next()) {
Jmsg(jcr, M_INFO, 0, "%s", error);
}
#endif
delete jcr->dirstore;
#ifdef implemented
for (error=(char*)rctx->errors.first(); error;
- error=(char*)rctx->errors.next()) {
+ error=(char*)rctx->errors.next()) {
free(error);
}
#endif
init_jcr_device_wait_timers(jcr);
for ( ;; ) {
- int need_wait = false;
+ int can_wait = false;
ok = false;
P(search_lock);
foreach_alist(store, jcr->dirstore) {
- rctx.store = store;
- foreach_alist(device_name, store->device) {
- int stat;
- rctx.device_name = device_name;
- stat = search_res_for_device(rctx);
- if (stat == 1) { /* found available device */
- dcr = jcr->dcr;
- ok = true;
- break;
- } else if (stat == 0) { /* device busy */
- need_wait = true;
- }
- /* otherwise error */
-// rctx->errors.push(bstrdup(jcr->errmsg));
- }
- if (ok) {
- break;
- }
+ rctx.store = store;
+ foreach_alist(device_name, store->device) {
+ int stat;
+ rctx.device_name = device_name;
+ stat = search_res_for_device(rctx);
+ if (stat == 1) { /* found available device */
+ ok = true;
+ break;
+ } else if (stat == 0) { /* device busy */
+ can_wait = true;
+ }
+ /* otherwise error */
+// rctx->errors.push(bstrdup(jcr->errmsg));
+ }
+ if (ok) {
+ break;
+ }
}
V(search_lock);
/*
- * If there is some device for which we can wait, then
+ * We did not find a suitable device, so
+ * if there is some device for which we can wait, then
* wait and try again until the wait time expires
*/
- if (!need_wait || !wait_for_device(jcr, first)) {
- break;
+ if (!can_wait || !wait_for_device(jcr, first)) {
+ break;
}
- first = false;
+ first = false; /* first wait complete */
+
#ifdef implemented
for (error=(char*)rctx->errors.first(); error;
- error=(char*)rctx->errors.next()) {
- free(error);
+ error=(char*)rctx->errors.next()) {
+ free(error);
}
#endif
}
- if (!ok && dcr) {
+ if (dcr) {
free_dcr(dcr);
}
Dmsg1(100, "Try res=%s\n", rctx.device->hdr.name);
/* Find resource, and make sure we were able to open it */
if (fnmatch(rctx.device_name, rctx.device->hdr.name, 0) == 0) {
- stat = reserve_device(rctx);
- if (stat != 1) {
- return stat;
- }
+ stat = reserve_device(rctx);
+ if (stat != 1) {
+ return stat;
+ }
Dmsg1(220, "Got: %s", dir->msg);
- bash_spaces(rctx.device_name);
- ok = bnet_fsend(dir, OK_device, rctx.device_name);
+ bash_spaces(rctx.device_name);
+ ok = bnet_fsend(dir, OK_device, rctx.device_name);
Dmsg1(100, ">dird dev: %s", dir->msg);
- return ok ? 1 : -1;
+ return ok ? 1 : -1;
}
}
foreach_res(changer, R_AUTOCHANGER) {
Dmsg1(100, "Try changer res=%s\n", changer->hdr.name);
/* Find resource, and make sure we were able to open it */
if (fnmatch(rctx.device_name, changer->hdr.name, 0) == 0) {
- /* Try each device in this AutoChanger */
- foreach_alist(rctx.device, changer->device) {
+ /* Try each device in this AutoChanger */
+ foreach_alist(rctx.device, changer->device) {
Dmsg1(100, "Try changer device %s\n", rctx.device->hdr.name);
- stat = reserve_device(rctx);
- if (stat == -1) { /* hard error */
- return -1;
- }
- if (stat == 0) { /* must wait, try next one */
- continue;
- }
- POOL_MEM dev_name;
+ stat = reserve_device(rctx);
+ if (stat == -1) { /* hard error */
+ return -1;
+ }
+ if (stat == 0) { /* must wait, try next one */
+ continue;
+ }
+ POOL_MEM dev_name;
Dmsg1(100, "Device %s opened.\n", rctx.device_name);
- pm_strcpy(dev_name, rctx.device->hdr.name);
- bash_spaces(dev_name);
- ok = bnet_fsend(dir, OK_device, dev_name.c_str()); /* Return real device name */
+ pm_strcpy(dev_name, rctx.device->hdr.name);
+ bash_spaces(dev_name);
+ ok = bnet_fsend(dir, OK_device, dev_name.c_str()); /* Return real device name */
Dmsg1(100, ">dird changer: %s", dir->msg);
- return ok ? 1 : -1;
- }
+ return ok ? 1 : -1;
+ }
}
}
- return 0; /* nothing found */
+ return 0; /* nothing found */
}
/*
* Try to reserve a specific device.
*
* Returns: 1 -- OK, have DCR
- * 0 -- must wait
- * -1 -- fatal error
+ * 0 -- must wait
+ * -1 -- fatal error
*/
static int reserve_device(RCTX &rctx)
{
if (rctx.device->changer_res) {
Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
" Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
- rctx.device->hdr.name, rctx.device_name);
+ rctx.device->hdr.name, rctx.device_name);
} else {
Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
" Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
- rctx.device_name);
+ rctx.device_name);
}
return -1; /* no use waiting */
}
bstrncpy(dcr->media_type, rctx.store->media_type, name_len);
bstrncpy(dcr->dev_name, rctx.device_name, name_len);
if (rctx.store->append == SD_APPEND) {
+#ifdef implemented
+ if (dir_find_next_appendable_volume(dcr)) {
+ Dmsg1(000, "Looking for Volume=%s\n", dcr->VolumeName);
+ } else {
+ Dmsg0(000, "No next volume found\n");
+ dcr->VolumeName[0] = 0;
+ }
+#endif
ok = reserve_device_for_append(dcr, rctx.PreferMountedVols);
Dmsg3(200, "dev_name=%s mediatype=%s ok=%d\n", dcr->dev_name, dcr->media_type, ok);
} else {
dev->block(BST_DOING_ACQUIRE);
- if (is_device_unmounted(dev)) {
+ if (is_device_unmounted(dev)) {
Dmsg1(200, "Device %s is BLOCKED due to user unmount.\n", dev->print_name());
Mmsg(jcr->errmsg, _("Device %s is BLOCKED due to user unmount.\n"),
- dev->print_name());
+ dev->print_name());
goto bail_out;
}
if (dev->is_busy()) {
Dmsg4(200, "Device %s is busy ST_READ=%d num_writers=%d reserved=%d.\n", dev->print_name(),
- dev->state & ST_READ?1:0, dev->num_writers, dev->reserved_device);
+ dev->state & ST_READ?1:0, dev->num_writers, dev->reserved_device);
Mmsg1(jcr->errmsg, _("Device %s is busy.\n"),
- dev->print_name());
+ dev->print_name());
goto bail_out;
}
/*
* Returns: 1 if drive can be reserved
- * 0 if we should wait
- * -1 on error
+ * 0 if we should wait
+ * -1 on error
*/
static int can_reserve_drive(DCR *dcr, bool PreferMountedVols)
{
JCR *jcr = dcr->jcr;
if (PreferMountedVols && !dev->VolHdr.VolumeName[0] && dev->is_tape()) {
- return 0; /* No volume mounted */
+ return 0; /* No volume mounted */
}
/*
*/
if (dev->num_writers == 0) {
/* Now check if there are any reservations on the drive */
- if (dev->reserved_device) {
- /* Yes, now check if we want the same Pool and pool type */
- if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
- strcmp(dev->pool_type, dcr->pool_type) == 0) {
- /* OK, compatible device */
- } else {
- /* Drive not suitable for us */
- return 0; /* wait */
- }
+ if (dev->reserved_device) {
+ /* Yes, now check if we want the same Pool and pool type */
+ if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
+ strcmp(dev->pool_type, dcr->pool_type) == 0) {
+ /* OK, compatible device */
+ } else {
+ /* Drive not suitable for us */
+ return 0; /* wait */
+ }
} else if (dev->can_append()) {
- /* Device in append mode, check if changing pool */
- if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
- strcmp(dev->pool_type, dcr->pool_type) == 0) {
- /* OK, compatible device */
- } else {
- /* Changing pool, unload old tape if any in drive */
- unload_autochanger(dcr, 0);
- }
+ /* Device in append mode, check if changing pool */
+ if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
+ strcmp(dev->pool_type, dcr->pool_type) == 0) {
+ /* OK, compatible device */
+ } else {
+ /* Changing pool, unload old tape if any in drive */
+ unload_autochanger(dcr, 0);
+ }
}
/* Device is available but not yet reserved, reserve it for us */
bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
- return 1; /* reserve drive */
+ return 1; /* reserve drive */
}
/*
Dmsg0(190, "device already in append.\n");
/* Yes, now check if we want the same Pool and pool type */
if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
- strcmp(dev->pool_type, dcr->pool_type) == 0) {
- /* OK, compatible device */
- return 1;
+ strcmp(dev->pool_type, dcr->pool_type) == 0) {
+ /* OK, compatible device */
+ return 1;
} else {
- /* Drive not suitable for us */
+ /* Drive not suitable for us */
Jmsg(jcr, M_WARNING, 0, _("Wanted Pool \"%s\", but device %s is using Pool \"%s\" .\n"),
- dcr->pool_name, dev->print_name(), dev->pool_name);
- return 0; /* wait */
+ dcr->pool_name, dev->print_name(), dev->pool_name);
+ return 0; /* wait */
}
} else {
Pmsg0(000, _("Logic error!!!! Should not get here.\n"));
Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
- return -1; /* error, should not get here */
+ return -1; /* error, should not get here */
}
return 0;