-/*
- * 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
- Copyright (C) 2001-2006 Free Software Foundation Europe e.V.
+ Copyright (C) 2001-2007 Free Software Foundation Europe e.V.
The main author of Bacula is Kern Sibbald, with contributions from
many others, a complete list can be found in the file AUTHORS.
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
*/
+/*
+ * 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 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!!!!
+ *
+ * File daemon commands are handled in fdcmd.c
+ *
+ * Kern Sibbald, May MMI
+ *
+ * Version $Id$
+ *
+ */
#include "bacula.h"
#include "stored.h"
/* 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);
{"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},
int bnet_stat = 0;
char name[MAX_NAME_LENGTH];
- if (bnet_recv(bs) <= 0) {
+ if (bs->recv() <= 0) {
Emsg0(M_ERROR, 0, _("Connection request failed.\n"));
bnet_close(bs);
return NULL;
*/
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);
for (quit=false; !quit;) {
/* Read command */
- if ((bnet_stat = bnet_recv(bs)) <= 0) {
+ if ((bnet_stat = bs->recv()) <= 0) {
break; /* connection terminated */
}
Dmsg1(199, "<dird: %s\n", bs->msg);
if ((!cmds[i].monitoraccess) && (jcr->director->monitor)) {
Dmsg1(100, "Command \"%s\" is invalid.\n", cmds[i].cmd);
bnet_fsend(bs, invalid_cmd);
- bnet_sig(bs, BNET_EOD);
+ bs->signal(BNET_EOD);
break;
}
Dmsg1(200, "Do command: %s\n", cmds[i].cmd);
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
*
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"));
+ Jmsg(jcr, M_INFO, 0, _("Job %s marked to be canceled.\n"), jcr->Job);
bnet_fsend(dir, _("3000 Job %s marked to be canceled.\n"), jcr->Job);
free_jcr(jcr);
}
dcr = find_device(jcr, dev_name, drive);
if (dcr) {
dev = dcr->dev;
- P(dev->mutex); /* 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);
}
- V(dev->mutex);
+ dev->dunlock();
free_dcr(dcr);
jcr->dcr = NULL;
} else {
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;
dcr = find_device(jcr, devname, drive);
if (dcr) {
dev = dcr->dev;
- P(dev->mutex); /* Use P to avoid indefinite block */
- Dmsg1(100, "mount cmd blocked=%d\n", dev->dev_blocked);
- switch (dev->dev_blocked) { /* device blocked? */
+ 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:
/* Someone is waiting, wake him */
Dmsg0(100, "Waiting for mount. Attempting to wake thread\n");
- dev->dev_blocked = BST_MOUNT;
+ dev->set_blocked(BST_MOUNT);
bnet_fsend(dir, "3001 OK mount. Device=%s\n",
dev->print_name());
pthread_cond_broadcast(&dev->wait_next_vol);
if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
dev->bstrerror());
- if (dev->dev_blocked == BST_UNMOUNTED) {
+ if (dev->blocked() == BST_UNMOUNTED) {
/* We blocked the device, so unblock it */
Dmsg0(100, "Unmounted. Unblocking device\n");
unblock_device(dev);
break;
}
read_dev_volume_label(dcr);
- if (dev->dev_blocked == BST_UNMOUNTED) {
+ if (dev->blocked() == BST_UNMOUNTED) {
/* We blocked the device, so unblock it */
Dmsg0(100, "Unmounted. Unblocking device\n");
read_label(dcr); /* this should not be necessary */
unblock_device(dev);
} else {
Dmsg0(100, "Unmounted waiting for mount. Attempting to wake thread\n");
- dev->dev_blocked = BST_MOUNT;
+ dev->set_blocked(BST_MOUNT);
}
if (dev->is_labeled()) {
bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
break;
default:
- bnet_fsend(dir, _("3905 Bizarre wait state %d\n"), dev->dev_blocked);
+ bnet_fsend(dir, _("3905 Bizarre wait state %d\n"), dev->blocked());
break;
}
- V(dev->mutex);
+ dev->dunlock();
free_dcr(dcr);
jcr->dcr = NULL;
} else {
dcr = find_device(jcr, devname, drive);
if (dcr) {
dev = dcr->dev;
- P(dev->mutex); /* 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, _("3901 Device %s is already unmounted.\n"),
dev->print_name());
}
- } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP) {
+ } else if (dev->blocked() == BST_WAITING_FOR_SYSOP) {
Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
- dev->dev_blocked);
+ dev->blocked());
if (!unload_autochanger(dcr, -1)) {
/* ***FIXME**** what is this ???? */
dev->close();
if (dev->is_dvd() && !dev->unmount(0)) {
bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
} else {
- dev->dev_blocked = BST_UNMOUNTED_WAITING_FOR_SYSOP;
+ dev->set_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) {
+ } else if (dev->blocked() == BST_DOING_ACQUIRE) {
bnet_fsend(dir, _("3902 Device %s is busy in acquire.\n"),
dev->print_name());
- } else if (dev->dev_blocked == BST_WRITING_LABEL) {
+ } else if (dev->blocked() == BST_WRITING_LABEL) {
bnet_fsend(dir, _("3903 Device %s is being labeled.\n"),
dev->print_name());
* we simply do it by hand. Gross, but a solution.
*/
/* block_device(dev, BST_UNMOUNTED); replace with 2 lines below */
- dev->dev_blocked = BST_UNMOUNTED;
+ dev->set_blocked(BST_UNMOUNTED);
dev->no_wait_id = 0;
if (!unload_autochanger(dcr, -1)) {
dev->close();
dev->print_name());
}
}
- V(dev->mutex);
+ dev->dunlock();
free_dcr(dcr);
jcr->dcr = NULL;
} else {
dcr = find_device(jcr, devname, drive);
if (dcr) {
dev = dcr->dev;
- P(dev->mutex); /* 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, _("3921 Device %s already released.\n"),
dev->print_name());
- } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP) {
+ } else if (dev->blocked() == BST_WAITING_FOR_SYSOP) {
Dmsg2(90, "%d waiter dev_block=%d.\n", dev->num_waiting,
- dev->dev_blocked);
+ dev->blocked());
unload_autochanger(dcr, -1);
bnet_fsend(dir, _("3922 Device %s waiting for sysop.\n"),
dev->print_name());
- } else if (dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP) {
+ } else if (dev->blocked() == BST_UNMOUNTED_WAITING_FOR_SYSOP) {
Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
- dev->dev_blocked);
+ dev->blocked());
bnet_fsend(dir, _("3922 Device %s waiting for mount.\n"),
dev->print_name());
- } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
+ } else if (dev->blocked() == BST_DOING_ACQUIRE) {
bnet_fsend(dir, _("3923 Device %s is busy in acquire.\n"),
dev->print_name());
- } else if (dev->dev_blocked == BST_WRITING_LABEL) {
+ } else if (dev->blocked() == BST_WRITING_LABEL) {
bnet_fsend(dir, _("3914 Device %s is being labeled.\n"),
dev->print_name());
bnet_fsend(dir, _("3022 Device %s released.\n"),
dev->print_name());
}
- V(dev->mutex);
+ dev->dunlock();
free_dcr(dcr);
jcr->dcr = NULL;
} else {
dcr = find_device(jcr, devname, -1);
if (dcr) {
dev = dcr->dev;
- P(dev->mutex); /* 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);
}
- V(dev->mutex);
+ dev->dunlock();
free_dcr(dcr);
jcr->dcr = NULL;
} else {
bnet_fsend(dir, _("3908 Error scanning autocharger drives/list/slots command: %s\n"),
jcr->errmsg);
}
- bnet_sig(dir, BNET_EOD);
+ dir->signal(BNET_EOD);
return true;
}
dcr = find_device(jcr, devname, drive);
if (dcr) {
dev = dcr->dev;
- P(dev->mutex); /* Use P to avoid indefinite block */
+ dev->dlock(); /* Use P to avoid indefinite block */
if (!dev->is_open()) {
read_volume_label(jcr, dev, Slot);
dev->close();
} else { /* device not being used */
read_volume_label(jcr, dev, Slot);
}
- V(dev->mutex);
+ dev->dunlock();
free_dcr(dcr);
jcr->dcr = NULL;
} else {
pm_strcpy(jcr->errmsg, dir->msg);
bnet_fsend(dir, _("3909 Error scanning readlabel command: %s\n"), jcr->errmsg);
}
- bnet_sig(dir, BNET_EOD);
+ dir->signal(BNET_EOD);
return true;
}
static void send_dir_busy_message(BSOCK *dir, DEVICE *dev)
{
if (dev->is_blocked()) {
- switch (dev->dev_blocked) {
+ switch (dev->blocked()) {
case BST_UNMOUNTED:
bnet_fsend(dir, _("3931 Device %s is BLOCKED. user unmounted.\n"),
dev->print_name());