* Attempt to "recover" by obtaining a new Volume.
*
* Here are a few things to know:
- * jcr->VolCatInfo contains the info on the "current" tape for this job.
+ * dcr->VolCatInfo contains the info on the "current" tape for this job.
* dev->VolCatInfo contains the info on the tape in the drive.
* The tape in the drive could have changed several times since
* the last time the job used it (jcr->VolCatInfo).
- * jcr->VolumeName is the name of the current/desired tape in the drive.
+ * dcr->VolumeName is the name of the current/desired tape in the drive.
*
* We enter with device locked, and
* exit with device locked.
* Returns: true on success
* false on failure
*/
-bool fixup_device_block_write_error(DCR *dcr, DEV_BLOCK *block)
+bool fixup_device_block_write_error(DCR *dcr)
{
uint32_t stat;
char PrevVolName[MAX_NAME_LENGTH];
DEV_BLOCK *label_blk;
+ DEV_BLOCK *block = dcr->block;
char b1[30], b2[30];
time_t wait_time;
char dt[MAX_TIME_LENGTH];
/* Create a jobmedia record for this job */
if (!dir_create_jobmedia_record(dcr)) {
Jmsg(jcr, M_ERROR, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
- jcr->VolCatInfo.VolCatName, jcr->Job);
+ dcr->VolCatInfo.VolCatName, jcr->Job);
P(dev->mutex);
unblock_device(dev);
return false;
bstrncpy(dev->VolHdr.PrevVolName, PrevVolName, sizeof(dev->VolHdr.PrevVolName));
label_blk = new_block(dev);
+ dcr->block = label_blk;
/* Inform User about end of medium */
Jmsg(jcr, M_INFO, 0, _("End of medium on Volume \"%s\" Bytes=%s Blocks=%s at %s.\n"),
edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2),
bstrftime(dt, sizeof(dt), time(NULL)));
- if (!mount_next_write_volume(dcr, label_blk, 1)) {
+ if (!mount_next_write_volume(dcr, 1)) {
free_block(label_blk);
+ dcr->block = block;
P(dev->mutex);
unblock_device(dev);
return false; /* device locked */
P(dev->mutex); /* lock again */
Jmsg(jcr, M_INFO, 0, _("New volume \"%s\" mounted on device %s at %s.\n"),
- jcr->VolumeName, dev_name(dev), bstrftime(dt, sizeof(dt), time(NULL)));
+ dcr->VolumeName, dev_name(dev), bstrftime(dt, sizeof(dt), time(NULL)));
/*
* If this is a new tape, the label_blk will contain the
* empty label_blk, and nothing will be written.
*/
Dmsg0(190, "write label block to dev\n");
- if (!write_block_to_dev(dcr, label_blk)) {
+ if (!write_block_to_dev(dcr)) {
Pmsg1(0, "write_block_to_device Volume label failed. ERR=%s",
strerror_dev(dev));
free_block(label_blk);
+ dcr->block = block;
unblock_device(dev);
return false; /* device locked */
}
free_block(label_blk);
+ dcr->block = block;
/*
* Walk through all attached jcrs indicating the volume has changed
*/
Dmsg1(100, "Walk attached jcrs. Volume=%s\n", dev->VolCatInfo.VolCatName);
- for (JCR *mjcr=NULL; (mjcr=next_attached_jcr(dev, mjcr)); ) {
+// for (JCR *mjcr=NULL; (mjcr=next_attached_jcr(dev, mjcr)); ) {
+ DCR *mdcr;
+ foreach_dlist(mdcr, dev->attached_dcrs) {
+ JCR *mjcr = mdcr->jcr;
if (mjcr->JobId == 0) {
continue; /* ignore console */
}
- mjcr->dcr->NewVol = true;
+ mdcr->NewVol = true;
if (jcr != mjcr) {
- pm_strcpy(&mjcr->VolumeName, jcr->VolumeName); /* get a copy of the new volume */
- bstrncpy(mjcr->dcr->VolumeName, jcr->VolumeName, sizeof(mjcr->dcr->VolumeName));
+ bstrncpy(mdcr->VolumeName, dcr->VolumeName, sizeof(mdcr->VolumeName));
}
}
/* Write overflow block to device */
Dmsg0(190, "Write overflow block to dev\n");
- if (!write_block_to_dev(dcr, block)) {
+ if (!write_block_to_dev(dcr)) {
Pmsg1(0, "write_block_to_device overflow block failed. ERR=%s",
strerror_dev(dev));
unblock_device(dev);
* that we can get the filename; the device_name for
* a file is the directory only.
*
- * Retuns: 0 on failure
- * 1 on success
+ * Returns: false on failure
+ * true on success
*/
-int first_open_device(DEVICE *dev)
+bool first_open_device(DEVICE *dev)
{
Dmsg0(120, "start open_output_device()\n");
if (!dev) {
- return 0;
+ return false;
}
lock_device(dev);
if (!dev_is_tape(dev)) {
Dmsg0(129, "Device is file, deferring open.\n");
unlock_device(dev);
- return 1;
+ return true;
}
if (!(dev->state & ST_OPENED)) {
if (open_dev(dev, NULL, mode) < 0) {
Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
unlock_device(dev);
- return 0;
+ return false;
}
}
Dmsg1(129, "open_dev %s OK\n", dev_name(dev));
unlock_device(dev);
- return 1;
+ return true;
}
/*
* Make sure device is open, if not do so
*/
-int open_device(JCR *jcr, DEVICE *dev)
+bool open_device(DCR *dcr)
{
+ DEVICE *dev = dcr->dev;
/* Open device */
if (!(dev_state(dev, ST_OPENED))) {
int mode;
} else {
mode = OPEN_READ_WRITE;
}
- if (open_dev(dev, jcr->VolCatInfo.VolCatName, mode) < 0) {
- Jmsg2(jcr, M_FATAL, 0, _("Unable to open device %s. ERR=%s\n"),
- dev_name(dev), strerror_dev(dev));
- return 0;
+ if (open_dev(dev, dcr->VolCatInfo.VolCatName, mode) < 0) {
+ /* If polling, ignore the error */
+ if (!dev->poll) {
+ Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device %s. ERR=%s\n"),
+ dev_name(dev), strerror_dev(dev));
+ }
+ return false;
}
}
- return 1;
+ return true;
}
void dev_lock(DEVICE *dev)
/*
* Check if the device is blocked or not
*/
-int device_is_unmounted(DEVICE *dev)
+bool device_is_unmounted(DEVICE *dev)
{
- int stat;
- P(dev->mutex);
- stat = (dev->dev_blocked == BST_UNMOUNTED) ||
- (dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
- V(dev->mutex);
+ bool stat;
+ int blocked = dev->dev_blocked;
+ stat = (blocked == BST_UNMOUNTED) ||
+ (blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
return stat;
}
+const char *edit_blocked_reason(DEVICE *dev)
+{
+ switch (dev->dev_blocked) {
+ case BST_NOT_BLOCKED:
+ return "not blocked";
+ case BST_UNMOUNTED:
+ return "user unmounted device";
+ case BST_WAITING_FOR_SYSOP:
+ return "waiting for operator action";
+ case BST_DOING_ACQUIRE:
+ return "opening, validating, or positioning tape";
+ case BST_WRITING_LABEL:
+ return "labeling tape";
+ case BST_UNMOUNTED_WAITING_FOR_SYSOP:
+ return "closed by user during mount request";
+ case BST_MOUNT:
+ return "mount request";
+ default:
+ return "unknown blocked code";
+ }
+}
+
void _unlock_device(const char *file, int line, DEVICE *dev)
{
Dmsg2(500, "unlock from %s:%d\n", file, line);