X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fstored%2Fdircmd.c;h=4f4a2d72f92967f6c3b04b52749ea28b9584191f;hb=6bca97aa2a205e95c82ac1900a59f50344658200;hp=9901774a71c28fd0aaaad07ac22b3cdb898b0ccc;hpb=50214f14890aeacf111813aa2749005efdb1ff9a;p=bacula%2Fbacula diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index 9901774a71..4f4a2d72f9 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -20,7 +20,7 @@ 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. @@ -54,8 +54,6 @@ /* 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; @@ -63,6 +61,8 @@ 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(); @@ -97,7 +97,7 @@ static void send_dir_busy_message(BSOCK *dir, DEVICE *dev); 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 */ }; /* @@ -149,6 +149,7 @@ void *handle_connection_request(void *arg) 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")); @@ -174,7 +175,9 @@ void *handle_connection_request(void *arg) Dmsg1(000, "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; } @@ -182,7 +185,8 @@ void *handle_connection_request(void *arg) /* * 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); @@ -385,7 +389,7 @@ static bool do_label(JCR *jcr, int relabel) 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(); @@ -515,6 +519,7 @@ bail_out: if (!dev->is_open()) { dev->clear_volhdr(); } + volume_unused(dcr); /* no longer using volume */ give_back_device_lock(dev, &hold); return; } @@ -548,6 +553,7 @@ static bool read_label(DCR *dcr) ok = false; break; } + volume_unused(dcr); give_back_device_lock(dev, &hold); return ok; } @@ -647,14 +653,16 @@ static bool mount_cmd(JCR *jcr) 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); @@ -668,8 +676,8 @@ static bool mount_cmd(JCR *jcr) } /* 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"); @@ -725,8 +733,8 @@ static bool mount_cmd(JCR *jcr) } } 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); @@ -806,6 +814,7 @@ static bool unmount_cmd(JCR *jcr) if (!unload_autochanger(dcr, -1)) { /* ***FIXME**** what is this ???? */ dev->close(); + free_volume(dev); } if (dev->is_unmountable() && !dev->unmount(0)) { dir->fsend(_("3907 %s"), dev->bstrerror()); @@ -834,9 +843,10 @@ static bool unmount_cmd(JCR *jcr) */ /* 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(); + free_volume(dev); } if (dev->is_unmountable() && !dev->unmount(0)) { dir->fsend(_("3907 %s"), dev->bstrerror()); @@ -911,9 +921,8 @@ static bool release_cmd(JCR *jcr) } 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()); } @@ -931,6 +940,62 @@ static bool release_cmd(JCR *jcr) 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) {