-/*
- * This file handles accepting Director Commands
- *
- * Most Director commands are handled here, with the
- * exception of the Job command command and subsequent
- * subcommands that are handled
- * in job.c.
- *
- * N.B. in this file, in general we must use P(dev->mutex) rather
- * than lock_device(dev) so that we can examine the blocked
- * state rather than blocking ourselves because a Job
- * thread has the device blocked. In some "safe" cases,
- * we can do things to a blocked device. CAREFUL!!!!
- *
- * File daemon commands are handled in fdcmd.c
- *
- * Kern Sibbald, May MMI
- *
- * Version $Id$
- *
- */
/*
Bacula® - The Network Backup Solution
many others, a complete list can be found in the file AUTHORS.
This program is Free Software; you can redistribute it and/or
modify it under the terms of version two of the GNU General Public
- License as published by the Free Software Foundation plus additions
- that are listed in the file LICENSE.
+ License as published by the Free Software Foundation and included
+ in the file LICENSE.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
* in job.c.
*
* N.B. in this file, in general we must use P(dev->mutex) rather
- * than lock_device(dev) so that we can examine the blocked
+ * than dev->r_lock() so that we can examine the blocked
* state rather than blocking ourselves because a Job
* thread has the device blocked. In some "safe" cases,
* we can do things to a blocked device. CAREFUL!!!!
/* Forward referenced functions */
static bool label_cmd(JCR *jcr);
+static bool die_cmd(JCR *jcr);
static bool relabel_cmd(JCR *jcr);
static bool readlabel_cmd(JCR *jcr);
static bool release_cmd(JCR *jcr);
static bool changer_cmd(JCR *sjcr);
static bool do_label(JCR *jcr, int relabel);
static DCR *find_device(JCR *jcr, POOL_MEM &dev_name, int drive);
-static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot);
+static void read_volume_label(JCR *jcr, DCR *dcr, DEVICE *dev, int Slot);
static void label_volume_if_ok(DCR *dcr, char *oldname,
char *newname, char *poolname,
int Slot, int relabel);
-static bool try_autoload_device(JCR *jcr, int slot, const char *VolName);
+static bool try_autoload_device(JCR *jcr, DCR *dcr, int slot, const char *VolName);
static void send_dir_busy_message(BSOCK *dir, DEVICE *dev);
struct s_cmds {
{"autochanger", changer_cmd, 0},
{"bootstrap", bootstrap_cmd, 0},
{"cancel", cancel_cmd, 0},
+ {".die", die_cmd, 0},
{"label", label_cmd, 0}, /* label a tape */
{"mount", mount_cmd, 0},
{"readlabel", readlabel_cmd, 0},
*/
Dmsg1(110, "Conn: %s", bs->msg);
if (sscanf(bs->msg, "Hello Start Job %127s", name) == 1) {
+ Dmsg0(110, "Got a FD connection\n");
handle_filed_connection(bs, name);
return NULL;
}
/*
* This is a connection from the Director, so setup a JCR
*/
- Dmsg0(110, "Start Dir Job\n");
+ Dmsg0(110, "Got a DIR connection\n");
jcr = new_jcr(sizeof(JCR), stored_free_jcr); /* create Job Control Record */
jcr->dir_bsock = bs; /* save Director bsock */
jcr->dir_bsock->set_jcr(jcr);
return NULL;
}
+
+/*
+ * Force SD to die, and hopefully dump itself. Turned on only
+ * in development version.
+ */
+static bool die_cmd(JCR *jcr)
+{
+#ifdef DEVELOPER
+ JCR *djcr = NULL;
+ int a;
+ Pmsg0(000, "I have been requested to die ...");
+ a = djcr->JobId; /* ref NULL pointer */
+#endif
+ return 0;
+}
+
+
+
/*
* Set debug level as requested by the Director
*
jcr->unlock();
if (jcr->file_bsock) {
bnet_sig(jcr->file_bsock, BNET_TERMINATE);
+ } else {
+ /* Still waiting for FD to connect, release it */
+ pthread_cond_signal(&jcr->job_start_wait); /* wake waiting job */
}
/* If thread waiting on mount, wake him */
if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->waiting_for_mount()) {
pthread_cond_broadcast(&jcr->dcr->dev->wait_next_vol);
+ Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId);
pthread_cond_broadcast(&wait_device_release);
}
if (jcr->read_dcr && jcr->read_dcr->dev && jcr->read_dcr->dev->waiting_for_mount()) {
pthread_cond_broadcast(&jcr->read_dcr->dev->wait_next_vol);
+ Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId);
pthread_cond_broadcast(&wait_device_release);
}
Jmsg(jcr, M_INFO, 0, _("Job %s marked to be canceled.\n"), jcr->Job);
dcr = find_device(jcr, dev_name, drive);
if (dcr) {
dev = dcr->dev;
- dev->lock(); /* Use P to avoid indefinite block */
+ dev->dlock(); /* Use P to avoid indefinite block */
if (!dev->is_open()) {
Dmsg1(400, "Can %slabel. Device is not open\n", relabel?"re":"");
label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
Dmsg0(400, "Can relabel. device not used\n");
label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
}
- dev->unlock();
+ dev->dunlock();
free_dcr(dcr);
- jcr->dcr = NULL;
} else {
bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), dev_name.c_str());
}
Dmsg0(90, "try_autoload_device - looking for volume_info\n");
- if (!try_autoload_device(dcr->jcr, slot, volname)) {
+ if (!try_autoload_device(dcr->jcr, dcr, slot, volname)) {
goto bail_out; /* error */
}
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"), dev->bstrerror());
+ bnet_fsend(dir, _("3914 Failed to label Volume (no media): ERR=%s\n"), dev->bstrerror());
break;
default:
bnet_fsend(dir, _("3913 Cannot label Volume. "
bail_out:
if (!dev->is_open()) {
- free_volume(dev);
+ dev->clear_volhdr();
}
give_back_device_lock(dev, &hold);
return;
if (found) {
Dmsg1(100, "Found device %s\n", device->hdr.name);
- dcr = new_dcr(jcr, device->dev);
+ dcr = new_dcr(jcr, NULL, device->dev);
dcr->device = device;
- jcr->dcr = dcr;
}
return dcr;
}
dcr = find_device(jcr, devname, drive);
if (dcr) {
dev = dcr->dev;
- dev->lock(); /* Use P to avoid indefinite block */
+ dev->dlock(); /* Use P to avoid indefinite block */
Dmsg1(100, "mount cmd blocked=%d\n", dev->blocked());
switch (dev->blocked()) { /* device blocked? */
case BST_WAITING_FOR_SYSOP:
bnet_fsend(dir, "3001 OK mount. Device=%s\n",
dev->print_name());
pthread_cond_broadcast(&dev->wait_next_vol);
+ Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)dcr->jcr->JobId);
pthread_cond_broadcast(&wait_device_release);
break;
case BST_UNMOUNTED_WAITING_FOR_SYSOP:
case BST_UNMOUNTED:
if (dev->is_autochanger() && slot > 0) {
- try_autoload_device(jcr, slot, "");
+ try_autoload_device(jcr, dcr, slot, "");
}
/* We freed the device, so reopen it and wake any waiting threads */
if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
dev->print_name());
}
pthread_cond_broadcast(&dev->wait_next_vol);
+ Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)dcr->jcr->JobId);
pthread_cond_broadcast(&wait_device_release);
break;
case BST_NOT_BLOCKED:
if (dev->is_autochanger() && slot > 0) {
- try_autoload_device(jcr, slot, "");
+ try_autoload_device(jcr, dcr, slot, "");
}
if (dev->is_open()) {
if (dev->is_labeled()) {
bnet_fsend(dir, _("3905 Bizarre wait state %d\n"), dev->blocked());
break;
}
- dev->unlock();
+ dev->dunlock();
free_dcr(dcr);
- jcr->dcr = NULL;
} else {
bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
}
dcr = find_device(jcr, devname, drive);
if (dcr) {
dev = dcr->dev;
- dev->lock(); /* Use P to avoid indefinite block */
+ dev->dlock(); /* Use P to avoid indefinite block */
if (!dev->is_open()) {
if (!dev->is_busy()) {
unload_autochanger(dcr, -1);
dev->print_name());
}
}
- dev->unlock();
+ dev->dunlock();
free_dcr(dcr);
- jcr->dcr = NULL;
} else {
bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
}
dcr = find_device(jcr, devname, drive);
if (dcr) {
dev = dcr->dev;
- dev->lock(); /* Use P to avoid indefinite block */
+ dev->dlock(); /* Use P to avoid indefinite block */
if (!dev->is_open()) {
if (!dev->is_busy()) {
unload_autochanger(dcr, -1);
bnet_fsend(dir, _("3022 Device %s released.\n"),
dev->print_name());
}
- dev->unlock();
+ dev->dunlock();
free_dcr(dcr);
- jcr->dcr = NULL;
} else {
bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
}
dcr = find_device(jcr, devname, -1);
if (dcr) {
dev = dcr->dev;
- dev->lock(); /* Use P to avoid indefinite block */
+ dev->dlock(); /* Use P to avoid indefinite block */
if (!dev->device->changer_res) {
bnet_fsend(dir, _("3995 Device %s is not an autochanger.\n"),
dev->print_name());
} else { /* device not being used */
autochanger_cmd(dcr, dir, cmd);
}
- dev->unlock();
+ dev->dunlock();
free_dcr(dcr);
- jcr->dcr = NULL;
} else {
bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
}
dcr = find_device(jcr, devname, drive);
if (dcr) {
dev = dcr->dev;
- dev->lock(); /* Use P to avoid indefinite block */
+ dev->dlock(); /* Use P to avoid indefinite block */
if (!dev->is_open()) {
- read_volume_label(jcr, dev, Slot);
+ read_volume_label(jcr, dcr, dev, Slot);
dev->close();
/* Under certain "safe" conditions, we can steal the lock */
} else if (dev->can_steal_lock()) {
- read_volume_label(jcr, dev, Slot);
+ read_volume_label(jcr, dcr, dev, Slot);
} else if (dev->is_busy() || dev->is_blocked()) {
send_dir_busy_message(dir, dev);
} else { /* device not being used */
- read_volume_label(jcr, dev, Slot);
+ read_volume_label(jcr, dcr, dev, Slot);
}
- dev->unlock();
+ dev->dunlock();
free_dcr(dcr);
- jcr->dcr = NULL;
} else {
bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
}
*
* Enter with the mutex set
*/
-static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot)
+static void read_volume_label(JCR *jcr, DCR *dcr, DEVICE *dev, int Slot)
{
BSOCK *dir = jcr->dir_bsock;
bsteal_lock_t hold;
- DCR *dcr = jcr->dcr;
dcr->dev = dev;
steal_device_lock(dev, &hold, BST_WRITING_LABEL);
- if (!try_autoload_device(jcr, Slot, "")) {
+ if (!try_autoload_device(jcr, dcr, Slot, "")) {
goto bail_out; /* error */
}
return;
}
-static bool try_autoload_device(JCR *jcr, int slot, const char *VolName)
+static bool try_autoload_device(JCR *jcr, DCR *dcr, int slot, const char *VolName)
{
- DCR *dcr = jcr->dcr;
BSOCK *dir = jcr->dir_bsock;
bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));