extern BSOCK *filed_chan;
extern int r_first, r_last;
extern struct s_res resources[];
-extern char my_name[];
-extern time_t daemon_start_time;
extern struct s_last_job last_job;
extern bool init_done;
if ((bnet_stat = bnet_recv(bs)) <= 0) {
break; /* connection terminated */
}
- Dmsg1(199, "<dird: %s", bs->msg);
+ Dmsg1(199, "<dird: %s\n", bs->msg);
/* Ensure that device initialization is complete */
while (!init_done) {
bmicrosleep(1, 0);
Dmsg1(200, "Do command: %s\n", cmds[i].cmd);
if (!cmds[i].func(jcr)) { /* do command */
quit = true; /* error, get out */
- Dmsg1(190, "Command %s requsts quit\n", cmds[i].cmd);
+ Dmsg1(190, "Command %s reqeusts quit\n", cmds[i].cmd);
}
found = true; /* indicate command found */
break;
if (!(jcr=get_jcr_by_full_name(Job))) {
bnet_fsend(dir, _("3904 Job %s not found.\n"), Job);
} else {
- P(jcr->mutex);
+ jcr->lock();
oldStatus = jcr->JobStatus;
set_jcr_job_status(jcr, JS_Canceled);
if (!jcr->authenticated && oldStatus == JS_WaitFD) {
pthread_cond_signal(&jcr->job_start_wait); /* wake waiting thread */
}
- V(jcr->mutex);
+ jcr->unlock();
if (jcr->file_bsock) {
bnet_sig(jcr->file_bsock, BNET_TERMINATE);
}
pthread_cond_broadcast(&jcr->read_dcr->dev->wait_next_vol);
pthread_cond_broadcast(&wait_device_release);
}
+ Jmsg(jcr, M_INFO, 0, _("Job marked to be canceled.\n"));
bnet_fsend(dir, _("3000 Job %s marked to be canceled.\n"), jcr->Job);
free_jcr(jcr);
}
DEVICE *dev = dcr->dev;
int label_status;
int mode;
+ const char *volname = (relabel == 1) ? oldname : newname;
+ char ed1[50];
steal_device_lock(dev, &hold, BST_WRITING_LABEL);
Dmsg1(100, "Stole device %s lock, writing label.\n", dev->print_name());
- if (!try_autoload_device(dcr->jcr, slot, newname)) {
+
+ Dmsg0(90, "try_autoload_device - looking for volume_info\n");
+ if (!try_autoload_device(dcr->jcr, slot, volname)) {
goto bail_out; /* error */
}
} else {
mode = CREATE_READ_WRITE;
}
+
+ if (relabel) {
+ dev->truncating = true; /* let open() know we will truncate it */
+ }
+ /* Set old volume name for open if relabeling */
+ bstrncpy(dcr->VolCatInfo.VolCatName, volname, sizeof(dcr->VolCatInfo.VolCatName));
if (dev->open(dcr, mode) < 0) {
bnet_fsend(dir, _("3910 Unable to open device %s: ERR=%s\n"),
dev->print_name(), dev->strerror());
- return;
+ goto bail_out;
}
/* See what we have for a Volume */
label_status = read_dev_volume_label(dcr);
+ /* Set new volume name */
+ bstrncpy(dcr->VolCatInfo.VolCatName, newname, sizeof(dcr->VolCatInfo.VolCatName));
switch(label_status) {
case VOL_NAME_ERROR:
case VOL_VERSION_ERROR:
bnet_fsend(dir, _("3922 Cannot relabel an ANSI/IBM labeled Volume.\n"));
break;
}
- free_volume(dev); /* release old volume name */
/* Fall through wanted! */
case VOL_IO_ERROR:
case VOL_NO_LABEL:
- if (!write_new_volume_label_to_dev(dcr, newname, poolname)) {
- bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), strerror_dev(dev));
+ if (!write_new_volume_label_to_dev(dcr, newname, poolname,
+ relabel, true /* write dvd now */)) {
+ bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), dev->bstrerror());
break;
}
bstrncpy(dcr->VolumeName, newname, sizeof(dcr->VolumeName));
/* The following 3000 OK label. string is scanned in ua_label.c */
- bnet_fsend(dir, "3000 OK label. Volume=%s Device=%s\n",
- newname, dev->print_name());
+ bnet_fsend(dir, "3000 OK label. VolBytes=%s DVD=%d Volume=\"%s\" Device=%s\n",
+ edit_uint64(dev->VolCatInfo.VolCatBytes, ed1),
+ dev->is_dvd()?1:0, newname, dev->print_name());
break;
case VOL_NO_MEDIA:
- bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), strerror_dev(dev));
+ bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), dev->bstrerror());
break;
default:
bnet_fsend(dir, _("3913 Cannot label Volume. "
DEVICE *dev;
DCR *dcr;
int drive;
+ int slot = 0;
+ bool ok;
- if (sscanf(dir->msg, "mount %127s drive=%d", devname.c_str(), &drive) == 2) {
+ ok = sscanf(dir->msg, "mount %127s drive=%d slot=%d", devname.c_str(),
+ &drive, &slot) == 3;
+ if (!ok) {
+ ok = sscanf(dir->msg, "mount %127s drive=%d", devname.c_str(), &drive) == 2;
+ }
+ if (ok) {
dcr = find_device(jcr, devname, drive);
if (dcr) {
dev = dcr->dev;
/* In both of these two cases, we (the user) unmounted the Volume */
case BST_UNMOUNTED_WAITING_FOR_SYSOP:
case BST_UNMOUNTED:
+ if (dev->is_autochanger() && slot > 0) {
+ try_autoload_device(jcr, slot, "");
+ }
/* We freed the device, so reopen it and wake any waiting threads */
if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
- strerror_dev(dev));
+ dev->bstrerror());
if (dev->dev_blocked == BST_UNMOUNTED) {
/* We blocked the device, so unblock it */
Dmsg0(100, "Unmounted. Unblocking device\n");
break;
case BST_NOT_BLOCKED:
+ if (dev->is_autochanger() && slot > 0) {
+ try_autoload_device(jcr, slot, "");
+ }
if (dev->is_open()) {
if (dev->is_labeled()) {
bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
} else if (dev->is_tape()) {
if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
- strerror_dev(dev));
+ dev->bstrerror());
break;
}
read_label(dcr);
bnet_fsend(dir, _("3002 Device %s is mounted.\n"),
dev->print_name());
} else {
- bnet_fsend(dir, _("3907 %s"), strerror_dev(dev));
+ bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
}
} else { /* must be file */
bnet_fsend(dir, _("3906 File device %s is always mounted.\n"),
if (!dev->is_busy()) {
unload_autochanger(jcr->dcr, -1);
}
- Dmsg0(90, "Device already unmounted\n");
- bnet_fsend(dir, _("3901 Device %s is already unmounted.\n"),
- dev->print_name());
-
+ if (dev->is_dvd()) {
+ if (unmount_dvd(dev, 0)) {
+ bnet_fsend(dir, _("3002 Device %s unmounted.\n"),
+ dev->print_name());
+ } else {
+ bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
+ }
+ } else {
+ Dmsg0(90, "Device already unmounted\n");
+ bnet_fsend(dir, _("3901 Device %s is already unmounted.\n"),
+ dev->print_name());
+ }
} else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP) {
Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
dev->dev_blocked);
if (!unload_autochanger(jcr->dcr, -1)) {
dev->close();
}
- dev->dev_blocked = BST_UNMOUNTED_WAITING_FOR_SYSOP;
- bnet_fsend(dir, _("3001 Device %s unmounted.\n"),
- dev->print_name());
+ if (dev->is_dvd() && !unmount_dvd(dev, 0)) {
+ bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
+ } else {
+ dev->dev_blocked = BST_UNMOUNTED_WAITING_FOR_SYSOP;
+ bnet_fsend(dir, _("3001 Device %s unmounted.\n"),
+ dev->print_name());
+ }
} else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
bnet_fsend(dir, _("3902 Device %s is busy in acquire.\n"),
if (!unload_autochanger(jcr->dcr, -1)) {
dev->close();
}
- bnet_fsend(dir, _("3002 Device %s unmounted.\n"),
- dev->print_name());
+ if (dev->is_dvd() && !unmount_dvd(dev, 0)) {
+ bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
+ } else {
+ bnet_fsend(dir, _("3002 Device %s unmounted.\n"),
+ dev->print_name());
+ }
}
V(dev->mutex);
free_dcr(dcr);
DCR *dcr;
const char *cmd = NULL;
bool ok = false;
+ /*
+ * A safe_cmd may call autochanger script but does not load/unload
+ * slots so it can be done at the same time that the drive is open.
+ */
+ bool safe_cmd = false;
if (sscanf(dir->msg, "autochanger list %127s", devname.c_str()) == 1) {
cmd = "list";
- ok = true;
+ safe_cmd = ok = true;
} else if (sscanf(dir->msg, "autochanger slots %127s", devname.c_str()) == 1) {
cmd = "slots";
- ok = true;
+ safe_cmd = ok = true;
} else if (sscanf(dir->msg, "autochanger drives %127s", devname.c_str()) == 1) {
cmd = "drives";
- ok = true;
+ safe_cmd = ok = true;
}
if (ok) {
dcr = find_device(jcr, devname, -1);
if (dcr) {
dev = dcr->dev;
P(dev->mutex); /* Use P to avoid indefinite block */
- if (!dev->is_tape()) {
+ if (!dev->device->changer_res) {
bnet_fsend(dir, _("3995 Device %s is not an autochanger.\n"),
dev->print_name());
/* Under certain "safe" conditions, we can steal the lock */
- } else if (!dev->is_open() || dev->can_steal_lock()) {
+ } else if (safe_cmd || !dev->is_open() || dev->can_steal_lock()) {
autochanger_cmd(dcr, dir, cmd);
} else if (dev->is_busy() || dev->is_blocked()) {
send_dir_busy_message(dir, dev);