X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fstored%2Fdircmd.c;h=a53efa31c3cb443e4e22fdb178df95e1333652a0;hb=34d8c5f57e3487c6394e07595e102d3c35875d14;hp=8987fbfb1d6289520db9f075b9c4f13bfb2082b7;hpb=0a081e9e25b55e1e3b4645d0bed21d6a95be2a61;p=bacula%2Fbacula diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index 8987fbfb1d..a53efa31c3 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -1,35 +1,14 @@ -/* - * 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-2008 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. 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 @@ -41,11 +20,32 @@ 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. */ +/* + * 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" @@ -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; @@ -75,6 +73,7 @@ extern bool qstatus_cmd(JCR *jcr); /* 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); @@ -86,17 +85,17 @@ static bool bootstrap_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 { 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 */ }; /* @@ -107,6 +106,7 @@ static struct s_cmds 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}, @@ -146,20 +146,22 @@ void *handle_connection_request(void *arg) int i; bool found, quit; int bnet_stat = 0; - char name[MAX_NAME_LENGTH]; + char name[500]; + char tbuf[100]; - if (bnet_recv(bs) <= 0) { + if (bs->recv() <= 0) { Emsg0(M_ERROR, 0, _("Connection request failed.\n")); - bnet_close(bs); + bs->close(); return NULL; } /* * Do a sanity check on the message received */ - if (bs->msglen < 25 || bs->msglen > (int)sizeof(name)-25) { + if (bs->msglen < 25 || bs->msglen > (int)sizeof(name)) { + Dmsg1(000, "msg); Emsg1(M_ERROR, 0, _("Invalid connection. Len=%d\n"), bs->msglen); - bnet_close(bs); + bs->close(); return NULL; } /* @@ -167,7 +169,12 @@ void *handle_connection_request(void *arg) * call FD handler. */ Dmsg1(110, "Conn: %s", bs->msg); + if (debug_level == 3) { + Dmsg1(000, "msg); + } if (sscanf(bs->msg, "Hello Start Job %127s", name) == 1) { + Dmsg1(110, "Got a FD connection at %s\n", bstrftimes(tbuf, sizeof(tbuf), + (utime_t)time(NULL))); handle_filed_connection(bs, name); return NULL; } @@ -175,15 +182,17 @@ void *handle_connection_request(void *arg) /* * This is a connection from the Director, so setup a JCR */ - Dmsg0(110, "Start Dir Job\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->jcr = jcr; + jcr->dir_bsock->set_jcr(jcr); jcr->dcrs = New(alist(10, not_owned_by_alist)); /* Initialize FD start condition variable */ int errstat = pthread_cond_init(&jcr->job_start_wait, NULL); if (errstat != 0) { - Jmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), strerror(errstat)); + berrno be; + Jmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), be.bstrerror(errstat)); goto bail_out; } @@ -200,7 +209,7 @@ void *handle_connection_request(void *arg) for (quit=false; !quit;) { /* Read command */ - if ((bnet_stat = bnet_recv(bs)) <= 0) { + if ((bnet_stat = bs->recv()) <= 0) { break; /* connection terminated */ } Dmsg1(199, "msg); @@ -213,8 +222,8 @@ void *handle_connection_request(void *arg) if (strncmp(cmds[i].cmd, bs->msg, strlen(cmds[i].cmd)) == 0) { 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->fsend(invalid_cmd); + bs->signal(BNET_EOD); break; } Dmsg1(200, "Do command: %s\n", cmds[i].cmd); @@ -227,18 +236,36 @@ void *handle_connection_request(void *arg) } } if (!found) { /* command not found */ - bnet_fsend(bs, derrmsg); + bs->fsend(derrmsg); break; } } bail_out: generate_daemon_event(jcr, "JobEnd"); dequeue_messages(jcr); /* send any queued messages */ - bnet_sig(bs, BNET_TERMINATE); + bs->signal(BNET_TERMINATE); free_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 * @@ -250,12 +277,12 @@ static bool setdebug_cmd(JCR *jcr) Dmsg1(10, "setdebug_cmd: %s", dir->msg); if (sscanf(dir->msg, "setdebug=%d trace=%d", &level, &trace_flag) != 2 || level < 0) { - bnet_fsend(dir, _("3991 Bad setdebug command: %s\n"), dir->msg); + dir->fsend(_("3991 Bad setdebug command: %s\n"), dir->msg); return 0; } debug_level = level; set_trace(trace_flag); - return bnet_fsend(dir, OKsetdebug, level); + return dir->fsend(OKsetdebug, level); } @@ -271,35 +298,38 @@ static bool cancel_cmd(JCR *cjcr) if (sscanf(dir->msg, "cancel Job=%127s", Job) == 1) { if (!(jcr=get_jcr_by_full_name(Job))) { - bnet_fsend(dir, _("3904 Job %s not found.\n"), Job); + dir->fsend(_("3904 Job %s not found.\n"), Job); } else { - 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 */ } - 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 marked to be canceled.\n")); - bnet_fsend(dir, _("3000 Job %s marked to be canceled.\n"), jcr->Job); + Jmsg(jcr, M_INFO, 0, _("Job %s marked to be canceled.\n"), jcr->Job); + dir->fsend(_("3000 Job %s marked to be canceled.\n"), jcr->Job); free_jcr(jcr); } } else { - bnet_fsend(dir, _("3903 Error scanning cancel command.\n")); + dir->fsend(_("3903 Error scanning cancel command.\n")); } - bnet_sig(dir, BNET_EOD); + dir->signal(BNET_EOD); return 1; } @@ -355,8 +385,8 @@ static bool do_label(JCR *jcr, int relabel) dcr = find_device(jcr, dev_name, drive); if (dcr) { dev = dcr->dev; - P(dev->mutex); /* Use P to avoid indefinite block */ - if (!dev->is_open()) { + dev->dlock(); /* Use P to avoid indefinite block */ + 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(); @@ -370,22 +400,21 @@ static bool do_label(JCR *jcr, int 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 { - bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), dev_name.c_str()); + dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), dev_name.c_str()); } } else { /* NB dir->msg gets clobbered in bnet_fsend, so save command */ pm_strcpy(jcr->errmsg, dir->msg); - bnet_fsend(dir, _("3903 Error scanning label command: %s\n"), jcr->errmsg); + dir->fsend(_("3903 Error scanning label command: %s\n"), jcr->errmsg); } free_memory(oldname); free_memory(newname); free_memory(poolname); free_memory(mtype); - bnet_sig(dir, BNET_EOD); + dir->signal(BNET_EOD); return true; } @@ -412,7 +441,7 @@ static void label_volume_if_ok(DCR *dcr, char *oldname, 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 */ } @@ -429,8 +458,8 @@ static void label_volume_if_ok(DCR *dcr, char *oldname, /* 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()); + dir->fsend(_("3910 Unable to open device %s: ERR=%s\n"), + dev->print_name(), dev->bstrerror()); goto bail_out; } @@ -445,7 +474,7 @@ static void label_volume_if_ok(DCR *dcr, char *oldname, case VOL_LABEL_ERROR: case VOL_OK: if (!relabel) { - bnet_fsend(dir, _( + dir->fsend(_( "3920 Cannot label Volume because it is already labeled: \"%s\"\n"), dev->VolHdr.VolumeName); break; @@ -453,11 +482,11 @@ static void label_volume_if_ok(DCR *dcr, char *oldname, /* Relabel request. If oldname matches, continue */ if (strcmp(oldname, dev->VolHdr.VolumeName) != 0) { - bnet_fsend(dir, _("3921 Wrong volume mounted.\n")); + dir->fsend(_("3921 Wrong volume mounted.\n")); break; } if (dev->label_type != B_BACULA_LABEL) { - bnet_fsend(dir, _("3922 Cannot relabel an ANSI/IBM labeled Volume.\n")); + dir->fsend(_("3922 Cannot relabel an ANSI/IBM labeled Volume.\n")); break; } /* Fall through wanted! */ @@ -465,28 +494,29 @@ static void label_volume_if_ok(DCR *dcr, char *oldname, case VOL_NO_LABEL: 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()); + dir->fsend(_("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. VolBytes=%s DVD=%d Volume=\"%s\" Device=%s\n", + dir->fsend("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"), dev->bstrerror()); + dir->fsend(_("3914 Failed to label Volume (no media): ERR=%s\n"), dev->bstrerror()); break; default: - bnet_fsend(dir, _("3913 Cannot label Volume. " + dir->fsend(_("3913 Cannot label Volume. " "Unknown status %d from read_volume_label()\n"), label_status); break; } bail_out: if (!dev->is_open()) { - free_volume(dev); + dev->clear_volhdr(); } + volume_unused(dcr); /* no longer using volume */ give_back_device_lock(dev, &hold); return; } @@ -511,15 +541,16 @@ static bool read_label(DCR *dcr) dev->clear_labeled(); /* force read of label */ switch (read_dev_volume_label(dcr)) { case VOL_OK: - bnet_fsend(dir, _("3001 Mounted Volume: %s\n"), dev->VolHdr.VolumeName); + dir->fsend(_("3001 Mounted Volume: %s\n"), dev->VolHdr.VolumeName); ok = true; break; default: - bnet_fsend(dir, _("3902 Cannot mount Volume on Storage Device %s because:\n%s"), + dir->fsend(_("3902 Cannot mount Volume on Storage Device %s because:\n%s"), dev->print_name(), jcr->errmsg); ok = false; break; } + volume_unused(dcr); give_back_device_lock(dev, &hold); return ok; } @@ -538,7 +569,7 @@ static DCR *find_device(JCR *jcr, POOL_MEM &devname, int drive) unbash_spaces(devname); foreach_res(device, R_DEVICE) { /* Find resource, and make sure we were able to open it */ - if (fnmatch(device->hdr.name, devname.c_str(), 0) == 0) { + if (strcmp(device->hdr.name, devname.c_str()) == 0) { if (!device->dev) { device->dev = init_dev(jcr, device); } @@ -556,7 +587,7 @@ static DCR *find_device(JCR *jcr, POOL_MEM &devname, int drive) if (!found) { foreach_res(changer, R_AUTOCHANGER) { /* Find resource, and make sure we were able to open it */ - if (fnmatch(devname.c_str(), changer->hdr.name, 0) == 0) { + if (strcmp(devname.c_str(), changer->hdr.name) == 0) { /* Try each device in this AutoChanger */ foreach_alist(device, changer->device) { Dmsg1(100, "Try changer device %s\n", device->hdr.name); @@ -589,9 +620,8 @@ static DCR *find_device(JCR *jcr, POOL_MEM &devname, int drive) 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; } @@ -619,16 +649,18 @@ static bool mount_cmd(JCR *jcr) 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 */ + 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->dev_blocked = BST_MOUNT; - bnet_fsend(dir, "3001 OK mount. Device=%s\n", + dev->set_blocked(BST_MOUNT); + dir->fsend("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; @@ -636,13 +668,13 @@ static bool mount_cmd(JCR *jcr) 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) { - bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"), - dev->bstrerror()); - if (dev->dev_blocked == BST_UNMOUNTED) { + 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"); unblock_device(dev); @@ -650,93 +682,93 @@ static bool mount_cmd(JCR *jcr) 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"), + dir->fsend(_("3001 Device %s is mounted with Volume \"%s\"\n"), dev->print_name(), dev->VolHdr.VolumeName); } else { - bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n" + dir->fsend(_("3905 Device %s open but no Bacula volume is mounted.\n" "If this is not a blank tape, try unmounting and remounting the Volume.\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_DOING_ACQUIRE: - bnet_fsend(dir, _("3001 Device %s is doing acquire.\n"), + dir->fsend(_("3001 Device %s is doing acquire.\n"), dev->print_name()); break; case BST_WRITING_LABEL: - bnet_fsend(dir, _("3903 Device %s is being labeled.\n"), + dir->fsend(_("3903 Device %s is being labeled.\n"), dev->print_name()); 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, _("3001 Device %s is mounted with Volume \"%s\"\n"), + dir->fsend(_("3001 Device %s is mounted with Volume \"%s\"\n"), dev->print_name(), dev->VolHdr.VolumeName); } else { - bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n" + dir->fsend(_("3905 Device %s open but no Bacula volume is mounted.\n" "If this is not a blank tape, try unmounting and remounting the Volume.\n"), dev->print_name()); } } else if (dev->is_tape()) { if (dev->open(dcr, OPEN_READ_ONLY) < 0) { - bnet_fsend(dir, _("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); if (dev->is_labeled()) { - bnet_fsend(dir, _("3001 Device %s is already mounted with Volume \"%s\"\n"), + dir->fsend(_("3001 Device %s is already mounted with Volume \"%s\"\n"), dev->print_name(), dev->VolHdr.VolumeName); } else { - bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n" + dir->fsend(_("3905 Device %s open but no Bacula volume is mounted.\n" "If this is not a blank tape, try unmounting and remounting the Volume.\n"), dev->print_name()); } - } else if (dev->is_dvd()) { + } else if (dev->is_unmountable()) { if (dev->mount(1)) { - bnet_fsend(dir, _("3002 Device %s is mounted.\n"), + dir->fsend(_("3002 Device %s is mounted.\n"), dev->print_name()); } else { - bnet_fsend(dir, _("3907 %s"), dev->bstrerror()); + dir->fsend(_("3907 %s"), dev->bstrerror()); } } else { /* must be file */ - bnet_fsend(dir, _("3906 File device %s is always mounted.\n"), + dir->fsend(_("3906 File device %s is always mounted.\n"), dev->print_name()); } break; default: - bnet_fsend(dir, _("3905 Bizarre wait state %d\n"), dev->dev_blocked); + dir->fsend(_("3905 Bizarre wait state %d\n"), dev->blocked()); break; } - V(dev->mutex); + 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()); + dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str()); } } else { pm_strcpy(jcr->errmsg, dir->msg); - bnet_fsend(dir, _("3909 Error scanning mount command: %s\n"), jcr->errmsg); + dir->fsend(_("3909 Error scanning mount command: %s\n"), jcr->errmsg); } - bnet_sig(dir, BNET_EOD); + dir->signal(BNET_EOD); return true; } @@ -755,44 +787,44 @@ static bool unmount_cmd(JCR *jcr) 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); } - if (dev->is_dvd()) { + if (dev->is_unmountable()) { if (dev->unmount(0)) { - bnet_fsend(dir, _("3002 Device %s unmounted.\n"), + dir->fsend(_("3002 Device %s unmounted.\n"), dev->print_name()); } else { - bnet_fsend(dir, _("3907 %s"), dev->bstrerror()); + dir->fsend(_("3907 %s"), dev->bstrerror()); } } else { Dmsg0(90, "Device already unmounted\n"); - bnet_fsend(dir, _("3901 Device %s is already unmounted.\n"), + dir->fsend(_("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()); + if (dev->is_unmountable() && !dev->unmount(0)) { + dir->fsend(_("3907 %s"), dev->bstrerror()); } else { - dev->dev_blocked = BST_UNMOUNTED_WAITING_FOR_SYSOP; - bnet_fsend(dir, _("3001 Device %s unmounted.\n"), + dev->set_blocked(BST_UNMOUNTED_WAITING_FOR_SYSOP); + dir->fsend(_("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"), + } else if (dev->blocked() == BST_DOING_ACQUIRE) { + dir->fsend(_("3902 Device %s is busy in acquire.\n"), dev->print_name()); - } else if (dev->dev_blocked == BST_WRITING_LABEL) { - bnet_fsend(dir, _("3903 Device %s is being labeled.\n"), + } else if (dev->blocked() == BST_WRITING_LABEL) { + dir->fsend(_("3903 Device %s is being labeled.\n"), dev->print_name()); } else if (dev->is_busy()) { @@ -805,30 +837,29 @@ static bool unmount_cmd(JCR *jcr) * 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->no_wait_id = 0; + dev->set_blocked(BST_UNMOUNTED); + clear_thread_id(dev->no_wait_id); if (!unload_autochanger(dcr, -1)) { dev->close(); } - if (dev->is_dvd() && !dev->unmount(0)) { - bnet_fsend(dir, _("3907 %s"), dev->bstrerror()); + if (dev->is_unmountable() && !dev->unmount(0)) { + dir->fsend(_("3907 %s"), dev->bstrerror()); } else { - bnet_fsend(dir, _("3002 Device %s unmounted.\n"), + dir->fsend(_("3002 Device %s unmounted.\n"), dev->print_name()); } } - V(dev->mutex); + 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()); + dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str()); } } else { /* NB dir->msg gets clobbered in bnet_fsend, so save command */ pm_strcpy(jcr->errmsg, dir->msg); - bnet_fsend(dir, _("3907 Error scanning unmount command: %s\n"), jcr->errmsg); + dir->fsend(_("3907 Error scanning unmount command: %s\n"), jcr->errmsg); } - bnet_sig(dir, BNET_EOD); + dir->signal(BNET_EOD); return true; } @@ -851,63 +882,65 @@ static bool release_cmd(JCR *jcr) 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); } Dmsg0(90, "Device already released\n"); - bnet_fsend(dir, _("3921 Device %s already released.\n"), + dir->fsend(_("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"), + dir->fsend(_("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); - bnet_fsend(dir, _("3922 Device %s waiting for mount.\n"), + dev->blocked()); + dir->fsend(_("3922 Device %s waiting for mount.\n"), dev->print_name()); - } else if (dev->dev_blocked == BST_DOING_ACQUIRE) { - bnet_fsend(dir, _("3923 Device %s is busy in acquire.\n"), + } else if (dev->blocked() == BST_DOING_ACQUIRE) { + dir->fsend(_("3923 Device %s is busy in acquire.\n"), dev->print_name()); - } else if (dev->dev_blocked == BST_WRITING_LABEL) { - bnet_fsend(dir, _("3914 Device %s is being labeled.\n"), + } else if (dev->blocked() == BST_WRITING_LABEL) { + dir->fsend(_("3914 Device %s is being labeled.\n"), dev->print_name()); } 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); - bnet_fsend(dir, _("3022 Device %s released.\n"), + Dmsg0(90, "Device not in use, releasing\n"); + dcr->release_volume(); + dir->fsend(_("3022 Device %s released.\n"), dev->print_name()); } - V(dev->mutex); + 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()); + dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str()); } } else { /* NB dir->msg gets clobbered in bnet_fsend, so save command */ pm_strcpy(jcr->errmsg, dir->msg); - bnet_fsend(dir, _("3927 Error scanning release command: %s\n"), jcr->errmsg); + dir->fsend(_("3927 Error scanning release command: %s\n"), jcr->errmsg); } - bnet_sig(dir, BNET_EOD); + dir->signal(BNET_EOD); return true; } static bool bootstrap_cmd(JCR *jcr) { + /* If getting the bootstrap file succeeds, we do not need + * the FD because we will be reading. + */ + jcr->need_fd = false; return get_bootstrap_file(jcr, jcr->dir_bsock); } @@ -942,9 +975,9 @@ static bool changer_cmd(JCR *jcr) 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"), + dir->fsend(_("3995 Device %s is not an autochanger.\n"), dev->print_name()); /* Under certain "safe" conditions, we can steal the lock */ } else if (safe_cmd || !dev->is_open() || dev->can_steal_lock()) { @@ -954,18 +987,17 @@ static bool changer_cmd(JCR *jcr) } 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, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str()); + dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str()); } } else { /* error on scanf */ pm_strcpy(jcr->errmsg, dir->msg); - bnet_fsend(dir, _("3908 Error scanning autocharger drives/list/slots command: %s\n"), + dir->fsend(_("3908 Error scanning autocharger drives/list/slots command: %s\n"), jcr->errmsg); } - bnet_sig(dir, BNET_EOD); + dir->signal(BNET_EOD); return true; } @@ -986,29 +1018,28 @@ static bool readlabel_cmd(JCR *jcr) 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); + 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); } - V(dev->mutex); + 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()); + dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str()); } } else { pm_strcpy(jcr->errmsg, dir->msg); - bnet_fsend(dir, _("3909 Error scanning readlabel command: %s\n"), jcr->errmsg); + dir->fsend(_("3909 Error scanning readlabel command: %s\n"), jcr->errmsg); } - bnet_sig(dir, BNET_EOD); + dir->signal(BNET_EOD); return true; } @@ -1018,16 +1049,15 @@ static bool readlabel_cmd(JCR *jcr) * * 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 */ } @@ -1035,11 +1065,11 @@ static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot) switch (read_dev_volume_label(dcr)) { case VOL_OK: /* DO NOT add quotes around the Volume name. It is scanned in the DIR */ - bnet_fsend(dir, _("3001 Volume=%s Slot=%d\n"), dev->VolHdr.VolumeName, Slot); + dir->fsend(_("3001 Volume=%s Slot=%d\n"), dev->VolHdr.VolumeName, Slot); Dmsg1(100, "Volume: %s\n", dev->VolHdr.VolumeName); break; default: - bnet_fsend(dir, _("3902 Cannot mount Volume on Storage Device %s because:\n%s"), + dir->fsend(_("3902 Cannot mount Volume on Storage Device %s because:\n%s"), dev->print_name(), jcr->errmsg); break; } @@ -1049,9 +1079,8 @@ bail_out: 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)); @@ -1066,37 +1095,37 @@ static bool try_autoload_device(JCR *jcr, int slot, const char *VolName) 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"), + dir->fsend(_("3931 Device %s is BLOCKED. user unmounted.\n"), dev->print_name()); break; case BST_UNMOUNTED_WAITING_FOR_SYSOP: - bnet_fsend(dir, _("3932 Device %s is BLOCKED. user unmounted during wait for media/mount.\n"), + dir->fsend(_("3932 Device %s is BLOCKED. user unmounted during wait for media/mount.\n"), dev->print_name()); break; case BST_WAITING_FOR_SYSOP: - bnet_fsend(dir, _("3933 Device %s is BLOCKED waiting for media.\n"), + dir->fsend(_("3933 Device %s is BLOCKED waiting for media.\n"), dev->print_name()); break; case BST_DOING_ACQUIRE: - bnet_fsend(dir, _("3934 Device %s is being initialized.\n"), + dir->fsend(_("3934 Device %s is being initialized.\n"), dev->print_name()); break; case BST_WRITING_LABEL: - bnet_fsend(dir, _("3935 Device %s is blocked labeling a Volume.\n"), + dir->fsend(_("3935 Device %s is blocked labeling a Volume.\n"), dev->print_name()); break; default: - bnet_fsend(dir, _("3935 Device %s is blocked for unknown reason.\n"), + dir->fsend(_("3935 Device %s is blocked for unknown reason.\n"), dev->print_name()); break; } } else if (dev->can_read()) { - bnet_fsend(dir, _("3936 Device %s is busy reading.\n"), + dir->fsend(_("3936 Device %s is busy reading.\n"), dev->print_name());; } else { - bnet_fsend(dir, _("3937 Device %s is busy with %d writer(s).\n"), + dir->fsend(_("3937 Device %s is busy with %d writer(s).\n"), dev->print_name(), dev->num_writers); } }