Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- Bacula® is a registered trademark of John Walker.
+ Bacula® is a registered trademark of Kern Sibbald.
The licensor of Bacula is the Free Software Foundation Europe
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
/* Imported variables */
extern BSOCK *filed_chan;
-extern int r_first, r_last;
-extern struct s_res resources[];
extern struct s_last_job last_job;
extern bool init_done;
static char derrmsg[] = "3900 Invalid command\n";
static char OKsetdebug[] = "3000 OK setdebug=%d\n";
static char invalid_cmd[] = "3997 Invalid command for a Director with Monitor directive enabled.\n";
+static char OK_bootstrap[] = "3000 OK bootstrap\n";
+static char ERROR_bootstrap[] = "3904 Error bootstrap\n";
/* Imported functions */
extern void terminate_child();
struct s_cmds {
const char *cmd;
bool (*func)(JCR *jcr);
- int monitoraccess; /* specify if monitors have access to this function */
+ bool monitoraccess; /* set if monitors can access this cmd */
};
/*
bool found, quit;
int bnet_stat = 0;
char name[500];
+ char tbuf[100];
if (bs->recv() <= 0) {
Emsg0(M_ERROR, 0, _("Connection request failed.\n"));
Dmsg1(000, "<filed: %s", bs->msg);
}
if (sscanf(bs->msg, "Hello Start Job %127s", name) == 1) {
- Dmsg0(110, "Got a FD connection\n");
+ Dmsg1(110, "Got a FD connection at %s\n", bstrftimes(tbuf, sizeof(tbuf),
+ (utime_t)time(NULL)));
+ Dmsg1(50, "%s", bs->msg);
handle_filed_connection(bs, name);
return NULL;
}
/*
* This is a connection from the Director, so setup a JCR
*/
- Dmsg0(110, "Got a DIR connection\n");
+ Dmsg1(110, "Got a DIR connection at %s\n", bstrftimes(tbuf, sizeof(tbuf),
+ (utime_t)time(NULL)));
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);
if (dcr) {
dev = dcr->dev;
dev->dlock(); /* Use P to avoid indefinite block */
- if (!dev->is_open()) {
+ if (!dev->is_open() && !dev->is_busy()) {
Dmsg1(400, "Can %slabel. Device is not open\n", relabel?"re":"");
label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
dev->close();
}
bail_out:
- volume_unused(dcr); /* no longer using */
if (!dev->is_open()) {
dev->clear_volhdr();
}
+ volume_unused(dcr); /* no longer using volume */
give_back_device_lock(dev, &hold);
return;
}
if (dcr) {
dev = dcr->dev;
dev->dlock(); /* Use P to avoid indefinite block */
- Dmsg1(100, "mount cmd blocked=%d\n", dev->blocked());
+ Dmsg2(100, "mount cmd blocked=%d must_unload=%d\n", dev->blocked(),
+ dev->must_unload());
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->set_blocked(BST_MOUNT);
- dir->fsend("3001 OK mount. Device=%s\n",
- dev->print_name());
+ dir->fsend("3001 OK mount requested. %sDevice=%s\n",
+ slot>0?_("Specified slot ignored. "):"",
+ 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);
}
/* We freed the device, so reopen it and wake any waiting threads */
if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
- dir->fsend(_("3901 open device failed: ERR=%s\n"),
- dev->bstrerror());
+ dir->fsend(_("3901 Unable to open device %s: ERR=%s\n"),
+ dev->print_name(), dev->bstrerror());
if (dev->blocked() == BST_UNMOUNTED) {
/* We blocked the device, so unblock it */
Dmsg0(100, "Unmounted. Unblocking device\n");
}
} else if (dev->is_tape()) {
if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
- dir->fsend(_("3901 open device failed: ERR=%s\n"),
- dev->bstrerror());
+ dir->fsend(_("3901 Unable to open device %s: ERR=%s\n"),
+ dev->print_name(), dev->bstrerror());
break;
}
read_label(dcr);
*/
/* block_device(dev, BST_UNMOUNTED); replace with 2 lines below */
dev->set_blocked(BST_UNMOUNTED);
- dev->no_wait_id = 0;
+ clear_thread_id(dev->no_wait_id);
if (!unload_autochanger(dcr, -1)) {
dev->close();
}
} else if (dev->is_busy()) {
send_dir_busy_message(dir, dev);
} else { /* device not being used */
- Dmsg0(90, "Device not in use, releaseing\n");
- unload_autochanger(dcr, -1);
- release_volume(dcr);
+ Dmsg0(90, "Device not in use, releasing\n");
+ dcr->release_volume();
dir->fsend(_("3022 Device %s released.\n"),
dev->print_name());
}
return true;
}
+static pthread_mutex_t bsr_mutex = PTHREAD_MUTEX_INITIALIZER;
+static uint32_t bsr_uniq = 0;
+
+static bool get_bootstrap_file(JCR *jcr, BSOCK *sock)
+{
+ POOLMEM *fname = get_pool_memory(PM_FNAME);
+ FILE *bs;
+ bool ok = false;
+
+ if (jcr->RestoreBootstrap) {
+ unlink(jcr->RestoreBootstrap);
+ free_pool_memory(jcr->RestoreBootstrap);
+ }
+ P(bsr_mutex);
+ bsr_uniq++;
+ Mmsg(fname, "%s/%s.%s.%d.bootstrap", me->working_directory, me->hdr.name,
+ jcr->Job, bsr_uniq);
+ V(bsr_mutex);
+ Dmsg1(400, "bootstrap=%s\n", fname);
+ jcr->RestoreBootstrap = fname;
+ bs = fopen(fname, "a+b"); /* create file */
+ if (!bs) {
+ berrno be;
+ Jmsg(jcr, M_FATAL, 0, _("Could not create bootstrap file %s: ERR=%s\n"),
+ jcr->RestoreBootstrap, be.bstrerror());
+ goto bail_out;
+ }
+ Dmsg0(10, "=== Bootstrap file ===\n");
+ while (sock->recv() >= 0) {
+ Dmsg1(10, "%s", sock->msg);
+ fputs(sock->msg, bs);
+ }
+ fclose(bs);
+ Dmsg0(10, "=== end bootstrap file ===\n");
+ jcr->bsr = parse_bsr(jcr, jcr->RestoreBootstrap);
+ if (!jcr->bsr) {
+ Jmsg(jcr, M_FATAL, 0, _("Error parsing bootstrap file.\n"));
+ goto bail_out;
+ }
+ if (debug_level >= 10) {
+ dump_bsr(jcr->bsr, true);
+ }
+ /* If we got a bootstrap, we are reading, so create read volume list */
+ create_restore_volume_list(jcr);
+ ok = true;
+
+bail_out:
+ unlink(jcr->RestoreBootstrap);
+ free_pool_memory(jcr->RestoreBootstrap);
+ jcr->RestoreBootstrap = NULL;
+ if (!ok) {
+ sock->fsend(ERROR_bootstrap);
+ return false;
+ }
+ return sock->fsend(OK_bootstrap);
+}
static bool bootstrap_cmd(JCR *jcr)
{