]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/dircmd.c
ffba811bf1f8d5bb50641c3caacff0fbc1784610
[bacula/bacula] / bacula / src / stored / dircmd.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2001-2012 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version three of the GNU Affero General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU Affero General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  *  This file handles accepting Director Commands
30  *
31  *    Most Director commands are handled here, with the
32  *    exception of the Job command command and subsequent
33  *    subcommands that are handled
34  *    in job.c.
35  *
36  *    N.B. in this file, in general we must use P(dev->mutex) rather
37  *      than dev->r_lock() so that we can examine the blocked
38  *      state rather than blocking ourselves because a Job
39  *      thread has the device blocked. In some "safe" cases,
40  *      we can do things to a blocked device. CAREFUL!!!!
41  *
42  *    File daemon commands are handled in fdcmd.c
43  *
44  *     Kern Sibbald, May MMI
45  *
46  */
47
48 #include "bacula.h"
49 #include "stored.h"
50
51 /* Exported variables */
52
53 /* Imported variables */
54 extern BSOCK *filed_chan;
55 extern struct s_last_job last_job;
56 extern bool init_done;
57
58 /* Static variables */
59 static char derrmsg[]     = "3900 Invalid command:";
60 static char OKsetdebug[]  = "3000 OK setdebug=%d\n";
61 static char invalid_cmd[] = "3997 Invalid command for a Director with Monitor directive enabled.\n";
62 static char OK_bootstrap[]    = "3000 OK bootstrap\n";
63 static char ERROR_bootstrap[] = "3904 Error bootstrap\n";
64
65 /* Imported functions */
66 extern void terminate_child();
67 extern bool job_cmd(JCR *jcr);
68 extern bool use_cmd(JCR *jcr);
69 extern bool run_cmd(JCR *jcr);
70 extern bool status_cmd(JCR *sjcr);
71 extern bool qstatus_cmd(JCR *jcr);
72 //extern bool query_cmd(JCR *jcr);
73
74 /* Forward referenced functions */
75 static bool label_cmd(JCR *jcr);
76 static bool die_cmd(JCR *jcr);
77 static bool relabel_cmd(JCR *jcr);
78 static bool readlabel_cmd(JCR *jcr);
79 static bool release_cmd(JCR *jcr);
80 static bool setdebug_cmd(JCR *jcr);
81 static bool cancel_cmd(JCR *cjcr);
82 static bool mount_cmd(JCR *jcr);
83 static bool unmount_cmd(JCR *jcr);
84 //static bool action_on_purge_cmd(JCR *jcr);
85 static bool bootstrap_cmd(JCR *jcr);
86 static bool changer_cmd(JCR *sjcr);
87 static bool do_label(JCR *jcr, int relabel);
88 static DCR *find_device(JCR *jcr, POOL_MEM &dev_name, int drive);
89 static void read_volume_label(JCR *jcr, DCR *dcr, DEVICE *dev, int Slot);
90 static void label_volume_if_ok(DCR *dcr, char *oldname,
91                                char *newname, char *poolname,
92                                int Slot, int relabel);
93 static bool try_autoload_device(JCR *jcr, DCR *dcr, int slot, const char *VolName);
94 static void send_dir_busy_message(BSOCK *dir, DEVICE *dev);
95
96 struct s_cmds {
97    const char *cmd;
98    bool (*func)(JCR *jcr);
99    bool monitoraccess;                      /* set if monitors can access this cmd */
100 };
101
102 /*
103  * The following are the recognized commands from the Director.
104  */
105 static struct s_cmds cmds[] = {
106    {"JobId=",      job_cmd,         0},     /* start Job */
107    {"autochanger", changer_cmd,     0},
108    {"bootstrap",   bootstrap_cmd,   0},
109    {"cancel",      cancel_cmd,      0},
110    {".die",        die_cmd,         0},
111    {"label",       label_cmd,       0},     /* label a tape */
112    {"mount",       mount_cmd,       0},
113    {"readlabel",   readlabel_cmd,   0},
114    {"release",     release_cmd,     0},
115    {"relabel",     relabel_cmd,     0},     /* relabel a tape */
116    {"setdebug=",   setdebug_cmd,    0},     /* set debug level */
117    {"status",      status_cmd,      1},
118    {".status",     qstatus_cmd,     1},
119    {"unmount",     unmount_cmd,     0},
120 //   {"action_on_purge",  action_on_purge_cmd,    0},
121    {"use storage=", use_cmd,        0},
122    {"run",         run_cmd,         0},
123 // {"query",       query_cmd,       0},
124    {NULL,        NULL}                      /* list terminator */
125 };
126
127
128 /*
129  * Connection request. We accept connections either from the
130  *  Director or a Client (File daemon).
131  *
132  * Note, we are running as a seperate thread of the Storage daemon.
133  *  and it is because a Director has made a connection with
134  *  us on the "Message" channel.
135  *
136  * Basic tasks done here:
137  *  - Create a JCR record
138  *  - If it was from the FD, call handle_filed_connection()
139  *  - Authenticate the Director
140  *  - We wait for a command
141  *  - We execute the command
142  *  - We continue or exit depending on the return status
143  */
144 void *handle_connection_request(void *arg)
145 {
146    BSOCK *bs = (BSOCK *)arg;
147    JCR *jcr;
148    int i;
149    bool found, quit;
150    int bnet_stat = 0;
151    char name[500];
152    char tbuf[100];
153
154    if (bs->recv() <= 0) {
155       Emsg1(M_ERROR, 0, _("Connection request from %s failed.\n"), bs->who());
156       bmicrosleep(5, 0);   /* make user wait 5 seconds */
157       bs->close();
158       return NULL;
159    }
160
161    /*
162     * Do a sanity check on the message received
163     */
164    if (bs->msglen < 25 || bs->msglen > (int)sizeof(name)) {
165       Dmsg1(000, "<filed: %s", bs->msg);
166       Emsg2(M_ERROR, 0, _("Invalid connection from %s. Len=%d\n"), bs->who(), bs->msglen);
167       bmicrosleep(5, 0);   /* make user wait 5 seconds */
168       bs->close();
169       return NULL;
170    }
171    /*
172     * See if this is a File daemon connection. If so
173     *   call FD handler.
174     */
175    Dmsg1(110, "Conn: %s", bs->msg);
176    if (debug_level == 3) {
177       Dmsg1(000, "<filed: %s", bs->msg);
178    }
179    if (sscanf(bs->msg, "Hello Start Job %127s", name) == 1) {
180       Dmsg1(110, "Got a FD connection at %s\n", bstrftimes(tbuf, sizeof(tbuf), 
181             (utime_t)time(NULL)));
182       Dmsg1(50, "%s", bs->msg);
183       handle_filed_connection(bs, name);
184       return NULL;
185    }
186
187    /* 
188     * This is a connection from the Director, so setup a JCR 
189     */
190    Dmsg1(110, "Got a DIR connection at %s\n", bstrftimes(tbuf, sizeof(tbuf), 
191          (utime_t)time(NULL)));
192    jcr = new_jcr(sizeof(JCR), stored_free_jcr); /* create Job Control Record */
193    jcr->dir_bsock = bs;               /* save Director bsock */
194    jcr->dir_bsock->set_jcr(jcr);
195    jcr->dcrs = New(alist(10, not_owned_by_alist));
196    /* Initialize FD start condition variable */
197    int errstat = pthread_cond_init(&jcr->job_start_wait, NULL);
198    if (errstat != 0) {
199       berrno be;
200       Jmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), be.bstrerror(errstat));
201       goto bail_out;
202    }
203
204    Dmsg0(1000, "stored in start_job\n");
205
206    /*
207     * Authenticate the Director
208     */
209    if (!authenticate_director(jcr)) {
210       Jmsg(jcr, M_FATAL, 0, _("Unable to authenticate Director\n"));
211       goto bail_out;
212    }
213    Dmsg0(90, "Message channel init completed.\n");
214
215    for (quit=false; !quit;) {
216       /* Read command */
217       if ((bnet_stat = bs->recv()) <= 0) {
218          break;               /* connection terminated */
219       }
220       Dmsg1(199, "<dird: %s\n", bs->msg);
221       /* Ensure that device initialization is complete */
222       while (!init_done) {
223          bmicrosleep(1, 0);
224       }
225       found = false;
226       for (i=0; cmds[i].cmd; i++) {
227         if (strncmp(cmds[i].cmd, bs->msg, strlen(cmds[i].cmd)) == 0) {
228            if ((!cmds[i].monitoraccess) && (jcr->director->monitor)) {
229               Dmsg1(100, "Command \"%s\" is invalid.\n", cmds[i].cmd);
230               bs->fsend(invalid_cmd);
231               bs->signal(BNET_EOD);
232               break;
233            }
234            Dmsg1(200, "Do command: %s\n", cmds[i].cmd);
235            if (!cmds[i].func(jcr)) { /* do command */
236               quit = true; /* error, get out */
237               Dmsg1(190, "Command %s requests quit\n", cmds[i].cmd);
238            }
239            found = true;             /* indicate command found */
240            break;
241         }
242       }
243       if (!found) {                   /* command not found */
244         POOL_MEM err_msg;
245         Mmsg(err_msg, "%s %s\n", derrmsg, bs->msg);
246         bs->fsend(err_msg.c_str());
247         break;
248       }
249    }
250 bail_out:
251    generate_daemon_event(jcr, "JobEnd");
252    dequeue_messages(jcr);             /* send any queued messages */
253    bs->signal(BNET_TERMINATE);
254    free_jcr(jcr);
255    return NULL;
256 }
257
258
259 /*
260  * Force SD to die, and hopefully dump itself.  Turned on only
261  *  in development version.
262  */
263 static bool die_cmd(JCR *jcr)
264 {
265 #ifdef DEVELOPER
266    JCR *djcr = NULL;
267    int a, b;
268    BSOCK *dir = jcr->dir_bsock;
269    pthread_mutex_t m=PTHREAD_MUTEX_INITIALIZER;
270
271    if (strstr(dir->msg, "deadlock")) {
272       Pmsg0(000, "I have been requested to deadlock ...\n");
273       P(m);
274       P(m);
275    }
276    
277    Pmsg1(000, "I have been requested to die ... (%s)\n", dir->msg);
278    a = djcr->JobId;   /* ref NULL pointer */
279    b = a;             /* Keep compiler quiet */
280    a = b;
281 #endif
282    return 0;
283 }
284
285      
286
287 /*
288  * Set debug level as requested by the Director
289  *
290  */
291 static bool setdebug_cmd(JCR *jcr)
292 {
293    BSOCK *dir = jcr->dir_bsock;
294    int32_t level, trace_flag;
295
296    Dmsg1(10, "setdebug_cmd: %s", dir->msg);
297    if (sscanf(dir->msg, "setdebug=%d trace=%d", &level, &trace_flag) != 2 || level < 0) {
298       dir->fsend(_("3991 Bad setdebug command: %s\n"), dir->msg);
299       return 0;
300    }
301    debug_level = level;
302    set_trace(trace_flag);
303    return dir->fsend(OKsetdebug, level);
304 }
305
306
307 /*
308  * Cancel a Job
309  *   Be careful, we switch to using the job's JCR! So, using
310  *   BSOCKs on that jcr can have two threads in the same code.
311  */
312 static bool cancel_cmd(JCR *cjcr)
313 {
314    BSOCK *dir = cjcr->dir_bsock;
315    int oldStatus;
316    char Job[MAX_NAME_LENGTH];
317    JCR *jcr;
318
319    if (sscanf(dir->msg, "cancel Job=%127s", Job) == 1) {
320       if (!(jcr=get_jcr_by_full_name(Job))) {
321          dir->fsend(_("3904 Job %s not found.\n"), Job);
322       } else {
323          oldStatus = jcr->JobStatus;
324          jcr->setJobStatus(JS_Canceled);
325          Dmsg2(800, "Cancel JobId=%d %p\n", jcr->JobId, jcr);
326          if (!jcr->authenticated && oldStatus == JS_WaitFD) {
327             pthread_cond_signal(&jcr->job_start_wait); /* wake waiting thread */
328          }
329          if (jcr->file_bsock) {
330             jcr->file_bsock->set_terminated();
331             jcr->file_bsock->set_timed_out();
332             Dmsg2(800, "Term bsock jid=%d %p\n", jcr->JobId, jcr);
333          } else {
334             /* Still waiting for FD to connect, release it */
335             pthread_cond_signal(&jcr->job_start_wait); /* wake waiting job */
336             Dmsg2(800, "Signal FD connect jid=%d %p\n", jcr->JobId, jcr);
337          }
338          /* If thread waiting on mount, wake him */
339          if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->waiting_for_mount()) {
340             pthread_cond_broadcast(&jcr->dcr->dev->wait_next_vol);
341             Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId);
342             pthread_cond_broadcast(&wait_device_release);
343          }
344          if (jcr->read_dcr && jcr->read_dcr->dev && jcr->read_dcr->dev->waiting_for_mount()) {
345             pthread_cond_broadcast(&jcr->read_dcr->dev->wait_next_vol);
346             Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId);
347             pthread_cond_broadcast(&wait_device_release);
348          }
349          dir->fsend(_("3000 JobId=%ld Job=\"%s\" marked to be canceled.\n"), jcr->JobId, jcr->Job);
350          free_jcr(jcr);
351       }
352    } else {
353       dir->fsend(_("3903 Error scanning cancel command.\n"));
354    }
355    dir->signal(BNET_EOD);
356    return 1;
357 }
358
359 /*
360  * Label a Volume
361  *
362  */
363 static bool label_cmd(JCR *jcr)
364 {
365    return do_label(jcr, 0);
366 }
367
368 static bool relabel_cmd(JCR *jcr)
369 {
370    return do_label(jcr, 1);
371 }
372
373 static bool do_label(JCR *jcr, int relabel)
374 {
375    POOLMEM *newname, *oldname, *poolname, *mtype;
376    POOL_MEM dev_name;
377    BSOCK *dir = jcr->dir_bsock;
378    DCR *dcr;
379    DEVICE *dev;
380    bool ok = false;
381    int32_t slot, drive;
382
383    newname = get_memory(dir->msglen+1);
384    oldname = get_memory(dir->msglen+1);
385    poolname = get_memory(dir->msglen+1);
386    mtype = get_memory(dir->msglen+1);
387    if (relabel) {
388       if (sscanf(dir->msg, "relabel %127s OldName=%127s NewName=%127s PoolName=%127s "
389                  "MediaType=%127s Slot=%d drive=%d",
390                   dev_name.c_str(), oldname, newname, poolname, mtype, 
391                   &slot, &drive) == 7) {
392          ok = true;
393       }
394    } else {
395       *oldname = 0;
396       if (sscanf(dir->msg, "label %127s VolumeName=%127s PoolName=%127s "
397                  "MediaType=%127s Slot=%d drive=%d", 
398           dev_name.c_str(), newname, poolname, mtype, &slot, &drive) == 6) {
399          ok = true;
400       }
401    }
402    if (ok) {
403       unbash_spaces(newname);
404       unbash_spaces(oldname);
405       unbash_spaces(poolname);
406       unbash_spaces(mtype);
407       dcr = find_device(jcr, dev_name, drive);
408       if (dcr) {
409          dev = dcr->dev;
410          dev->dlock();                 /* Use P to avoid indefinite block */
411          if (!dev->is_open() && !dev->is_busy()) {
412             Dmsg1(400, "Can %slabel. Device is not open\n", relabel?"re":"");
413             label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
414             dev->close();
415          /* Under certain "safe" conditions, we can steal the lock */
416          } else if (dev->can_steal_lock()) {
417             Dmsg0(400, "Can relabel. can_steal_lock\n");
418             label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
419          } else if (dev->is_busy() || dev->is_blocked()) {
420             send_dir_busy_message(dir, dev);
421          } else {                     /* device not being used */
422             Dmsg0(400, "Can relabel. device not used\n");
423             label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
424          }
425          dev->dunlock();
426          free_dcr(dcr);
427       } else {
428          dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), dev_name.c_str());
429       }
430    } else {
431       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
432       pm_strcpy(jcr->errmsg, dir->msg);
433       dir->fsend(_("3903 Error scanning label command: %s\n"), jcr->errmsg);
434    }
435    free_memory(oldname);
436    free_memory(newname);
437    free_memory(poolname);
438    free_memory(mtype);
439    dir->signal(BNET_EOD);
440    return true;
441 }
442
443 /*
444  * Read the tape label and determine if we can safely
445  * label the tape (not a Bacula volume), then label it.
446  *
447  *  Enter with the mutex set
448  */
449 static void label_volume_if_ok(DCR *dcr, char *oldname,
450                                char *newname, char *poolname,
451                                int slot, int relabel)
452 {
453    BSOCK *dir = dcr->jcr->dir_bsock;
454    bsteal_lock_t hold;
455    DEVICE *dev = dcr->dev;
456    int label_status;
457    int mode;
458    const char *volname = (relabel == 1) ? oldname : newname;
459    char ed1[50];
460
461    steal_device_lock(dev, &hold, BST_WRITING_LABEL);
462    Dmsg1(100, "Stole device %s lock, writing label.\n", dev->print_name());
463
464
465    Dmsg0(90, "try_autoload_device - looking for volume_info\n");
466    if (!try_autoload_device(dcr->jcr, dcr, slot, volname)) {
467       goto bail_out;                  /* error */
468    }
469
470    /* Ensure that the device is open -- autoload_device() closes it */
471    if (dev->is_tape()) {
472       mode = OPEN_READ_WRITE;
473    } else {
474       mode = CREATE_READ_WRITE;
475    }
476
477    if (relabel) {
478       dev->truncating = true;         /* let open() know we will truncate it */
479    }
480    /* Set old volume name for open if relabeling */
481    dcr->setVolCatName(volname);
482    if (!dev->open(dcr, mode)) {
483       dir->fsend(_("3910 Unable to open device \"%s\": ERR=%s\n"),
484          dev->print_name(), dev->bstrerror());
485       goto bail_out;      
486    }
487
488    /* See what we have for a Volume */
489    label_status = read_dev_volume_label(dcr);
490    
491    /* Set new volume name */
492    dcr->setVolCatName(newname);
493    switch(label_status) {
494    case VOL_NAME_ERROR:
495    case VOL_VERSION_ERROR:
496    case VOL_LABEL_ERROR:
497    case VOL_OK:
498       if (!relabel) {
499          dir->fsend(_(
500             "3920 Cannot label Volume because it is already labeled: \"%s\"\n"),
501              dev->VolHdr.VolumeName);
502          break;
503       }
504
505       /* Relabel request. If oldname matches, continue */
506       if (strcmp(oldname, dev->VolHdr.VolumeName) != 0) {
507          dir->fsend(_("3921 Wrong volume mounted.\n"));
508          break;
509       }
510       if (dev->label_type != B_BACULA_LABEL) {
511          dir->fsend(_("3922 Cannot relabel an ANSI/IBM labeled Volume.\n"));
512          break;
513       }
514       /* Fall through wanted! */
515    case VOL_IO_ERROR:
516    case VOL_NO_LABEL:
517       if (!write_new_volume_label_to_dev(dcr, newname, poolname, 
518               relabel, true /* write dvd now */)) {
519          dir->fsend(_("3912 Failed to label Volume: ERR=%s\n"), dev->bstrerror());
520          break;
521       }
522       bstrncpy(dcr->VolumeName, newname, sizeof(dcr->VolumeName));
523       /* The following 3000 OK label. string is scanned in ua_label.c */
524       dir->fsend("3000 OK label. VolBytes=%s DVD=%d Volume=\"%s\" Device=%s\n",
525                  edit_uint64(dev->VolCatInfo.VolCatBytes, ed1),
526                  dev->is_dvd()?1:0, newname, dev->print_name());
527       break;
528    case VOL_NO_MEDIA:
529       dir->fsend(_("3914 Failed to label Volume (no media): ERR=%s\n"), dev->bstrerror());
530       break;
531    default:
532       dir->fsend(_("3913 Cannot label Volume. "
533 "Unknown status %d from read_volume_label()\n"), label_status);
534       break;
535    }
536
537 bail_out:
538    if (!dev->is_open()) {
539       dev->clear_volhdr();
540    }
541    volume_unused(dcr);                   /* no longer using volume */
542    give_back_device_lock(dev, &hold);
543    return;
544 }
545
546
547 /*
548  * Read the tape label
549  *
550  *  Enter with the mutex set
551  */
552 static bool read_label(DCR *dcr)
553 {
554    int ok;
555    JCR *jcr = dcr->jcr;
556    BSOCK *dir = jcr->dir_bsock;
557    bsteal_lock_t hold;
558    DEVICE *dev = dcr->dev;
559
560    steal_device_lock(dev, &hold, BST_DOING_ACQUIRE);
561
562    dcr->VolumeName[0] = 0;
563    dev->clear_labeled();              /* force read of label */
564    switch (read_dev_volume_label(dcr)) {
565    case VOL_OK:
566       dir->fsend(_("3001 Mounted Volume: %s\n"), dev->VolHdr.VolumeName);
567       ok = true;
568       break;
569    default:
570       dir->fsend(_("3902 Cannot mount Volume on Storage Device \"%s\" because:\n%s"),
571          dev->print_name(), jcr->errmsg);
572       ok = false;
573       break;
574    }
575    volume_unused(dcr);
576    give_back_device_lock(dev, &hold);
577    return ok;
578 }
579
580 /* 
581  * Searches for device by name, and if found, creates a dcr and
582  *  returns it.
583  */
584 static DCR *find_device(JCR *jcr, POOL_MEM &devname, int drive)
585 {
586    DEVRES *device;
587    AUTOCHANGER *changer;
588    bool found = false;
589    DCR *dcr = NULL;
590
591    unbash_spaces(devname);
592    foreach_res(device, R_DEVICE) {
593       /* Find resource, and make sure we were able to open it */
594       if (strcmp(device->hdr.name, devname.c_str()) == 0) {
595          if (!device->dev) {
596             device->dev = init_dev(jcr, device);
597          }
598          if (!device->dev) {
599             Jmsg(jcr, M_WARNING, 0, _("\n"
600                "     Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
601                  devname.c_str());
602             continue;
603          }
604          Dmsg1(20, "Found device %s\n", device->hdr.name);
605          found = true;
606          break;
607       }
608    }
609    if (!found) {
610       foreach_res(changer, R_AUTOCHANGER) {
611          /* Find resource, and make sure we were able to open it */
612          if (strcmp(devname.c_str(), changer->hdr.name) == 0) {
613             /* Try each device in this AutoChanger */
614             foreach_alist(device, changer->device) {
615                Dmsg1(100, "Try changer device %s\n", device->hdr.name);
616                if (!device->dev) {
617                   device->dev = init_dev(jcr, device);
618                }
619                if (!device->dev) {
620                   Dmsg1(100, "Device %s could not be opened. Skipped\n", devname.c_str());
621                   Jmsg(jcr, M_WARNING, 0, _("\n"
622                      "     Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
623                        device->hdr.name, devname.c_str());
624                   continue;
625                }
626                if (!device->dev->autoselect) {
627                   Dmsg1(100, "Device %s not autoselect skipped.\n", devname.c_str());
628                   continue;              /* device is not available */
629                }
630                if (drive < 0 || drive == (int)device->dev->drive_index) {
631                   Dmsg1(20, "Found changer device %s\n", device->hdr.name);
632                   found = true;
633                   break;
634                }
635                Dmsg3(100, "Device %s drive wrong: want=%d got=%d skipping\n",
636                   devname.c_str(), drive, (int)device->dev->drive_index);
637             }
638             break;                    /* we found it but could not open a device */
639          }
640       }
641    }
642
643    if (found) {
644       Dmsg1(100, "Found device %s\n", device->hdr.name);
645       dcr = new_dcr(jcr, NULL, device->dev);
646       dcr->device = device;
647    }
648    return dcr;
649 }
650
651
652 /*
653  * Mount command from Director
654  */
655 static bool mount_cmd(JCR *jcr)
656 {
657    POOL_MEM devname;
658    BSOCK *dir = jcr->dir_bsock;
659    DEVICE *dev;
660    DCR *dcr;
661    int32_t drive;
662    int32_t slot = 0;
663    bool ok;
664
665    ok = sscanf(dir->msg, "mount %127s drive=%d slot=%d", devname.c_str(), 
666                &drive, &slot) == 3;
667    if (!ok) {
668       ok = sscanf(dir->msg, "mount %127s drive=%d", devname.c_str(), &drive) == 2;
669    }
670    Dmsg3(100, "ok=%d drive=%d slot=%d\n", ok, drive, slot);
671    if (ok) {
672       dcr = find_device(jcr, devname, drive);
673       if (dcr) {
674          dev = dcr->dev;
675          dev->dlock();                 /* Use P to avoid indefinite block */
676          Dmsg2(100, "mount cmd blocked=%d must_unload=%d\n", dev->blocked(), 
677             dev->must_unload());
678          switch (dev->blocked()) {         /* device blocked? */
679          case BST_WAITING_FOR_SYSOP:
680             /* Someone is waiting, wake him */
681             Dmsg0(100, "Waiting for mount. Attempting to wake thread\n");
682             dev->set_blocked(BST_MOUNT);
683             dir->fsend("3001 OK mount requested. %sDevice=%s\n", 
684                        slot>0?_("Specified slot ignored. "):"",
685                        dev->print_name());
686             pthread_cond_broadcast(&dev->wait_next_vol);
687             Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)dcr->jcr->JobId);
688             pthread_cond_broadcast(&wait_device_release);
689             break;
690
691          /* In both of these two cases, we (the user) unmounted the Volume */
692          case BST_UNMOUNTED_WAITING_FOR_SYSOP:
693          case BST_UNMOUNTED:
694             Dmsg2(100, "Unmounted changer=%d slot=%d\n", dev->is_autochanger(), slot);
695             if (dev->is_autochanger() && slot > 0) {
696                try_autoload_device(jcr, dcr, slot, "");
697             }
698             /* We freed the device, so reopen it and wake any waiting threads */
699             if (!dev->open(dcr, OPEN_READ_ONLY)) {
700                dir->fsend(_("3901 Unable to open device \"%s\": ERR=%s\n"),
701                   dev->print_name(), dev->bstrerror());
702                if (dev->blocked() == BST_UNMOUNTED) {
703                   /* We blocked the device, so unblock it */
704                   Dmsg0(100, "Unmounted. Unblocking device\n");
705                   unblock_device(dev);
706                }
707                break;
708             }
709             read_dev_volume_label(dcr);
710             if (dev->blocked() == BST_UNMOUNTED) {
711                /* We blocked the device, so unblock it */
712                Dmsg0(100, "Unmounted. Unblocking device\n");
713                read_label(dcr);       /* this should not be necessary */
714                unblock_device(dev);
715             } else {
716                Dmsg0(100, "Unmounted waiting for mount. Attempting to wake thread\n");
717                dev->set_blocked(BST_MOUNT);
718             }
719             if (dev->is_labeled()) {
720                dir->fsend(_("3001 Device \"%s\" is mounted with Volume \"%s\"\n"),
721                   dev->print_name(), dev->VolHdr.VolumeName);
722             } else {
723                dir->fsend(_("3905 Device \"%s\" open but no Bacula volume is mounted.\n"
724                                  "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
725                           dev->print_name());
726             }
727             pthread_cond_broadcast(&dev->wait_next_vol);
728             Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)dcr->jcr->JobId);
729             pthread_cond_broadcast(&wait_device_release);
730             break;
731
732          case BST_DOING_ACQUIRE:
733             dir->fsend(_("3001 Device \"%s\" is doing acquire.\n"),
734                        dev->print_name());
735             break;
736
737          case BST_WRITING_LABEL:
738             dir->fsend(_("3903 Device \"%s\" is being labeled.\n"), 
739                dev->print_name());
740             break;
741
742          case BST_NOT_BLOCKED:
743             Dmsg2(100, "Not blocked changer=%d slot=%d\n", dev->is_autochanger(), slot);
744             if (dev->is_autochanger() && slot > 0) {
745                try_autoload_device(jcr, dcr, slot, "");
746             }
747             if (dev->is_open()) {
748                if (dev->is_labeled()) {
749                   dir->fsend(_("3001 Device \"%s\" is mounted with Volume \"%s\"\n"),
750                      dev->print_name(), dev->VolHdr.VolumeName);
751                } else {
752                   dir->fsend(_("3905 Device \"%s\" open but no Bacula volume is mounted.\n"
753                                  "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
754                              dev->print_name());
755                }
756             } else if (dev->is_tape()) {
757                if (!dev->open(dcr, OPEN_READ_ONLY)) {
758                   dir->fsend(_("3901 Unable to open device \"%s\": ERR=%s\n"),
759                      dev->print_name(), dev->bstrerror());
760                   break;
761                }
762                read_label(dcr);
763                if (dev->is_labeled()) {
764                   dir->fsend(_("3001 Device \"%s\" is already mounted with Volume \"%s\"\n"),
765                      dev->print_name(), dev->VolHdr.VolumeName);
766                } else {
767                   dir->fsend(_("3905 Device \"%s\" open but no Bacula volume is mounted.\n"
768                                     "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
769                              dev->print_name());
770                }
771             } else if (dev->is_unmountable()) {
772                if (dev->mount(1)) {
773                   dir->fsend(_("3002 Device \"%s\" is mounted.\n"), dev->print_name());
774                } else {
775                   dir->fsend(_("3907 %s"), dev->bstrerror());
776                } 
777             } else { /* must be file */
778                dir->fsend(_("3906 File device \"%s\" is always mounted.\n"),
779                   dev->print_name());
780                pthread_cond_broadcast(&dev->wait_next_vol);
781                Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)dcr->jcr->JobId);
782                pthread_cond_broadcast(&wait_device_release);
783             }
784             break;
785
786          case BST_RELEASING:
787             dir->fsend(_("3930 Device \"%s\" is being released.\n"), dev->print_name());
788             break;
789
790          default:
791             dir->fsend(_("3905 Unknown wait state %d\n"), dev->blocked());
792             break;
793          }
794          dev->dunlock();
795          free_dcr(dcr);
796       } else {
797          dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
798       }
799    } else {
800       pm_strcpy(jcr->errmsg, dir->msg);
801       dir->fsend(_("3909 Error scanning mount command: %s\n"), jcr->errmsg);
802    }
803    dir->signal(BNET_EOD);
804    return true;
805 }
806
807 /*
808  * unmount command from Director
809  */
810 static bool unmount_cmd(JCR *jcr)
811 {
812    POOL_MEM devname;
813    BSOCK *dir = jcr->dir_bsock;
814    DEVICE *dev;
815    DCR *dcr;
816    int32_t drive;
817
818    if (sscanf(dir->msg, "unmount %127s drive=%d", devname.c_str(), &drive) == 2) {
819       dcr = find_device(jcr, devname, drive);
820       if (dcr) {
821          dev = dcr->dev;
822          dev->dlock();                 /* Use P to avoid indefinite block */
823          if (!dev->is_open()) {
824             if (!dev->is_busy()) {
825                unload_autochanger(dcr, -1);          
826             }
827             if (dev->is_unmountable()) {
828                if (dev->unmount(0)) {
829                   dir->fsend(_("3002 Device \"%s\" unmounted.\n"), 
830                      dev->print_name());
831                } else {
832                   dir->fsend(_("3907 %s"), dev->bstrerror());
833                } 
834             } else {
835                Dmsg0(90, "Device already unmounted\n");
836                dir->fsend(_("3901 Device \"%s\" is already unmounted.\n"), 
837                   dev->print_name());
838             }
839          } else if (dev->blocked() == BST_WAITING_FOR_SYSOP) {
840             Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
841                dev->blocked());
842             if (!unload_autochanger(dcr, -1)) {
843                /* ***FIXME**** what is this ????  */
844                dev->close();
845                free_volume(dev);
846             }
847             if (dev->is_unmountable() && !dev->unmount(0)) {
848                dir->fsend(_("3907 %s"), dev->bstrerror());
849             } else {
850                dev->set_blocked(BST_UNMOUNTED_WAITING_FOR_SYSOP);
851                dir->fsend(_("3001 Device \"%s\" unmounted.\n"), 
852                   dev->print_name());
853             }
854
855          } else if (dev->blocked() == BST_DOING_ACQUIRE) {
856             dir->fsend(_("3902 Device \"%s\" is busy in acquire.\n"), 
857                dev->print_name());
858
859          } else if (dev->blocked() == BST_WRITING_LABEL) {
860             dir->fsend(_("3903 Device \"%s\" is being labeled.\n"), 
861                dev->print_name());
862
863          } else if (dev->is_busy()) {
864             send_dir_busy_message(dir, dev);
865          } else {                     /* device not being used */
866             Dmsg0(90, "Device not in use, unmounting\n");
867             /* On FreeBSD, I am having ASSERT() failures in block_device()
868              * and I can only imagine that the thread id that we are
869              * leaving in no_wait_id is being re-used. So here,
870              * we simply do it by hand.  Gross, but a solution.
871              */
872             /*  block_device(dev, BST_UNMOUNTED); replace with 2 lines below */
873             dev->set_blocked(BST_UNMOUNTED);
874             clear_thread_id(dev->no_wait_id);
875             if (!unload_autochanger(dcr, -1)) {
876                dev->close();
877                free_volume(dev);
878             }
879             if (dev->is_unmountable() && !dev->unmount(0)) {
880                dir->fsend(_("3907 %s"), dev->bstrerror());
881             } else {
882                dir->fsend(_("3002 Device \"%s\" unmounted.\n"), 
883                   dev->print_name());
884             }
885          }
886          dev->dunlock();
887          free_dcr(dcr);
888       } else {
889          dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
890       }
891    } else {
892       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
893       pm_strcpy(jcr->errmsg, dir->msg);
894       dir->fsend(_("3907 Error scanning unmount command: %s\n"), jcr->errmsg);
895    }
896    dir->signal(BNET_EOD);
897    return true;
898 }
899
900 #if 0
901 /*
902  * The truncate command will recycle a volume. The director can call this
903  * after purging a volume so that disk space will not be wasted. Only useful
904  * for File Storage, of course.
905  *
906  *
907  * It is currently disabled
908  */
909 static bool action_on_purge_cmd(JCR *jcr)
910 {
911    BSOCK *dir = jcr->dir_bsock;
912
913    char devname[MAX_NAME_LENGTH];
914    char volumename[MAX_NAME_LENGTH];
915    int32_t action;
916
917    /* TODO: Need to find a free device and ask for slot to the director */
918    if (sscanf(dir->msg, 
919               "action_on_purge %127s vol=%127s action=%d",
920               devname, volumename, &action)!= 5) 
921    {
922       dir->fsend(_("3916 Error scanning action_on_purge command\n"));
923       goto done;
924    }
925    unbash_spaces(volumename);
926    unbash_spaces(devname);
927
928    /* Check if action is correct */
929    if (action & AOP_TRUNCTATE) {
930
931    } 
932    /* ... */
933
934 done:
935    dir->signal(BNET_EOD);
936    return true;
937 }
938 #endif
939
940 /*
941  * Release command from Director. This rewinds the device and if
942  *   configured does a offline and ensures that Bacula will
943  *   re-read the label of the tape before continuing. This gives
944  *   the operator the chance to change the tape anytime before the
945  *   next job starts.
946  */
947 static bool release_cmd(JCR *jcr)
948 {
949    POOL_MEM devname;
950    BSOCK *dir = jcr->dir_bsock;
951    DEVICE *dev;
952    DCR *dcr;
953    int32_t drive;
954
955    if (sscanf(dir->msg, "release %127s drive=%d", devname.c_str(), &drive) == 2) {
956       dcr = find_device(jcr, devname, drive);
957       if (dcr) {
958          dev = dcr->dev;
959          dev->dlock();                 /* Use P to avoid indefinite block */
960          if (!dev->is_open()) {
961             if (!dev->is_busy()) {
962                unload_autochanger(dcr, -1);
963             }
964             Dmsg0(90, "Device already released\n");
965             dir->fsend(_("3921 Device \"%s\" already released.\n"), 
966                dev->print_name());
967
968          } else if (dev->blocked() == BST_WAITING_FOR_SYSOP) {
969             Dmsg2(90, "%d waiter dev_block=%d.\n", dev->num_waiting,
970                dev->blocked());
971             unload_autochanger(dcr, -1);
972             dir->fsend(_("3922 Device \"%s\" waiting for sysop.\n"), 
973                dev->print_name());
974
975          } else if (dev->blocked() == BST_UNMOUNTED_WAITING_FOR_SYSOP) {
976             Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
977                dev->blocked());
978             dir->fsend(_("3922 Device \"%s\" waiting for mount.\n"), 
979                dev->print_name());
980
981          } else if (dev->blocked() == BST_DOING_ACQUIRE) {
982             dir->fsend(_("3923 Device \"%s\" is busy in acquire.\n"), 
983                dev->print_name());
984
985          } else if (dev->blocked() == BST_WRITING_LABEL) {
986             dir->fsend(_("3914 Device \"%s\" is being labeled.\n"), 
987                dev->print_name());
988
989          } else if (dev->is_busy()) {
990             send_dir_busy_message(dir, dev);
991          } else {                     /* device not being used */
992             Dmsg0(90, "Device not in use, releasing\n");
993             dcr->release_volume();
994             dir->fsend(_("3022 Device \"%s\" released.\n"), 
995                dev->print_name());
996          }
997          dev->dunlock();
998          free_dcr(dcr);
999       } else {
1000          dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
1001       }
1002    } else {
1003       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
1004       pm_strcpy(jcr->errmsg, dir->msg);
1005       dir->fsend(_("3927 Error scanning release command: %s\n"), jcr->errmsg);
1006    }
1007    dir->signal(BNET_EOD);
1008    return true;
1009 }
1010
1011 static pthread_mutex_t bsr_mutex = PTHREAD_MUTEX_INITIALIZER;
1012 static uint32_t bsr_uniq = 0;
1013
1014 static bool get_bootstrap_file(JCR *jcr, BSOCK *sock)
1015 {
1016    POOLMEM *fname = get_pool_memory(PM_FNAME);
1017    FILE *bs;
1018    bool ok = false;
1019
1020    if (jcr->RestoreBootstrap) {
1021       unlink(jcr->RestoreBootstrap);
1022       free_pool_memory(jcr->RestoreBootstrap);
1023    }
1024    P(bsr_mutex);
1025    bsr_uniq++;
1026    Mmsg(fname, "%s/%s.%s.%d.bootstrap", me->working_directory, me->hdr.name,
1027       jcr->Job, bsr_uniq);
1028    V(bsr_mutex);
1029    Dmsg1(400, "bootstrap=%s\n", fname);
1030    jcr->RestoreBootstrap = fname;
1031    bs = fopen(fname, "a+b");           /* create file */
1032    if (!bs) {
1033       berrno be;
1034       Jmsg(jcr, M_FATAL, 0, _("Could not create bootstrap file %s: ERR=%s\n"),
1035          jcr->RestoreBootstrap, be.bstrerror());
1036       goto bail_out;
1037    }
1038    Dmsg0(10, "=== Bootstrap file ===\n");
1039    while (sock->recv() >= 0) {
1040        Dmsg1(10, "%s", sock->msg);
1041        fputs(sock->msg, bs);
1042    }
1043    fclose(bs);
1044    Dmsg0(10, "=== end bootstrap file ===\n");
1045    jcr->bsr = parse_bsr(jcr, jcr->RestoreBootstrap);
1046    if (!jcr->bsr) {
1047       Jmsg(jcr, M_FATAL, 0, _("Error parsing bootstrap file.\n"));
1048       goto bail_out;
1049    }
1050    if (debug_level >= 10) {
1051       dump_bsr(jcr->bsr, true);
1052    }
1053    /* If we got a bootstrap, we are reading, so create read volume list */
1054    create_restore_volume_list(jcr);
1055    ok = true;
1056
1057 bail_out:
1058    unlink(jcr->RestoreBootstrap);
1059    free_pool_memory(jcr->RestoreBootstrap);
1060    jcr->RestoreBootstrap = NULL;
1061    if (!ok) {
1062       sock->fsend(ERROR_bootstrap);
1063       return false;
1064    }
1065    return sock->fsend(OK_bootstrap);
1066 }
1067
1068 static bool bootstrap_cmd(JCR *jcr)
1069 {
1070    return get_bootstrap_file(jcr, jcr->dir_bsock);
1071 }
1072
1073 /*
1074  * Autochanger command from Director
1075  */
1076 static bool changer_cmd(JCR *jcr)
1077 {
1078    POOL_MEM devname;
1079    BSOCK *dir = jcr->dir_bsock;
1080    DEVICE *dev;
1081    DCR *dcr;
1082    const char *cmd = NULL;
1083    bool ok = false;
1084    /*
1085     * A safe_cmd may call autochanger script but does not load/unload
1086     *    slots so it can be done at the same time that the drive is open.
1087     */
1088    bool safe_cmd = false;
1089
1090    if (sscanf(dir->msg, "autochanger listall %127s", devname.c_str()) == 1) {
1091       cmd = "listall";
1092       safe_cmd = ok = true;
1093    } else if (sscanf(dir->msg, "autochanger list %127s", devname.c_str()) == 1) {
1094       cmd = "list";
1095       safe_cmd = ok = true;
1096    } else if (sscanf(dir->msg, "autochanger slots %127s", devname.c_str()) == 1) {
1097       cmd = "slots";
1098       safe_cmd = ok = true;
1099    } else if (sscanf(dir->msg, "autochanger drives %127s", devname.c_str()) == 1) {
1100       cmd = "drives";
1101       safe_cmd = ok = true;
1102    }
1103    if (ok) {
1104       dcr = find_device(jcr, devname, -1);
1105       if (dcr) {
1106          dev = dcr->dev;
1107          dev->dlock();                 /* Use P to avoid indefinite block */
1108          if (!dev->device->changer_res) {
1109             dir->fsend(_("3998 Device \"%s\" is not an autochanger.\n"), 
1110                dev->print_name());
1111          /* Under certain "safe" conditions, we can steal the lock */
1112          } else if (safe_cmd || !dev->is_open() || dev->can_steal_lock()) {
1113             autochanger_cmd(dcr, dir, cmd);
1114          } else if (dev->is_busy() || dev->is_blocked()) {
1115             send_dir_busy_message(dir, dev);
1116          } else {                     /* device not being used */
1117             autochanger_cmd(dcr, dir, cmd);
1118          }
1119          dev->dunlock();
1120          free_dcr(dcr);
1121       } else {
1122          dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
1123       }
1124    } else {  /* error on scanf */
1125       pm_strcpy(jcr->errmsg, dir->msg);
1126       dir->fsend(_("3908 Error scanning autochanger drives/list/slots command: %s\n"),
1127          jcr->errmsg);
1128    }
1129    dir->signal(BNET_EOD);
1130    return true;
1131 }
1132
1133 /*
1134  * Read and return the Volume label
1135  */
1136 static bool readlabel_cmd(JCR *jcr)
1137 {
1138    POOL_MEM devname;
1139    BSOCK *dir = jcr->dir_bsock;
1140    DEVICE *dev;
1141    DCR *dcr;
1142    int32_t Slot, drive;
1143
1144    if (sscanf(dir->msg, "readlabel %127s Slot=%d drive=%d", devname.c_str(), 
1145        &Slot, &drive) == 3) {
1146       dcr = find_device(jcr, devname, drive);
1147       if (dcr) {
1148          dev = dcr->dev;
1149          dev->dlock();                 /* Use P to avoid indefinite block */
1150          if (!dev->is_open()) {
1151             read_volume_label(jcr, dcr, dev, Slot);
1152             dev->close();
1153          /* Under certain "safe" conditions, we can steal the lock */
1154          } else if (dev->can_steal_lock()) {
1155             read_volume_label(jcr, dcr, dev, Slot);
1156          } else if (dev->is_busy() || dev->is_blocked()) {
1157             send_dir_busy_message(dir, dev);
1158          } else {                     /* device not being used */
1159             read_volume_label(jcr, dcr, dev, Slot);
1160          }
1161          dev->dunlock();
1162          free_dcr(dcr);
1163       } else {
1164          dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
1165       }
1166    } else {
1167       pm_strcpy(jcr->errmsg, dir->msg);
1168       dir->fsend(_("3909 Error scanning readlabel command: %s\n"), jcr->errmsg);
1169    }
1170    dir->signal(BNET_EOD);
1171    return true;
1172 }
1173
1174
1175 /*
1176  * Read the tape label
1177  *
1178  *  Enter with the mutex set
1179  */
1180 static void read_volume_label(JCR *jcr, DCR *dcr, DEVICE *dev, int Slot)
1181 {
1182    BSOCK *dir = jcr->dir_bsock;
1183    bsteal_lock_t hold;
1184
1185    dcr->dev = dev;
1186    steal_device_lock(dev, &hold, BST_WRITING_LABEL);
1187
1188    if (!try_autoload_device(jcr, dcr, Slot, "")) {
1189       goto bail_out;                  /* error */
1190    }
1191
1192    dev->clear_labeled();              /* force read of label */
1193    switch (read_dev_volume_label(dcr)) {
1194    case VOL_OK:
1195       /* DO NOT add quotes around the Volume name. It is scanned in the DIR */
1196       dir->fsend(_("3001 Volume=%s Slot=%d\n"), dev->VolHdr.VolumeName, Slot);
1197       Dmsg1(100, "Volume: %s\n", dev->VolHdr.VolumeName);
1198       break;
1199    default:
1200       dir->fsend(_("3902 Cannot mount Volume on Storage Device \"%s\" because:\n%s"),
1201                  dev->print_name(), jcr->errmsg);
1202       break;
1203    }
1204
1205 bail_out:
1206    give_back_device_lock(dev, &hold);
1207    return;
1208 }
1209
1210 static bool try_autoload_device(JCR *jcr, DCR *dcr, int slot, const char *VolName)
1211 {
1212    BSOCK *dir = jcr->dir_bsock;
1213
1214    bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
1215    dcr->VolCatInfo.Slot = slot;
1216    dcr->VolCatInfo.InChanger = slot > 0;
1217    if (autoload_device(dcr, 0, dir) < 0) {    /* autoload if possible */
1218       return false;
1219    }
1220    return true;
1221 }
1222
1223 static void send_dir_busy_message(BSOCK *dir, DEVICE *dev)
1224 {
1225    if (dev->is_blocked()) {
1226       switch (dev->blocked()) {
1227       case BST_UNMOUNTED:
1228          dir->fsend(_("3931 Device \"%s\" is BLOCKED. user unmounted.\n"),
1229             dev->print_name());
1230          break;
1231       case BST_UNMOUNTED_WAITING_FOR_SYSOP:
1232          dir->fsend(_("3932 Device \"%s\" is BLOCKED. user unmounted during wait for media/mount.\n"),
1233              dev->print_name());
1234          break;
1235       case BST_WAITING_FOR_SYSOP:
1236          dir->fsend(_("3933 Device \"%s\" is BLOCKED waiting for media.\n"),
1237             dev->print_name());
1238          break;
1239       case BST_DOING_ACQUIRE:
1240          dir->fsend(_("3934 Device \"%s\" is being initialized.\n"),
1241             dev->print_name());
1242          break;
1243       case BST_WRITING_LABEL:
1244          dir->fsend(_("3935 Device \"%s\" is blocked labeling a Volume.\n"),
1245             dev->print_name());
1246          break;
1247       default:
1248          dir->fsend(_("3935 Device \"%s\" is blocked for unknown reason.\n"),
1249             dev->print_name());
1250          break;
1251       }
1252    } else if (dev->can_read()) {
1253        dir->fsend(_("3936 Device \"%s\" is busy reading.\n"),
1254                    dev->print_name());;
1255    } else {
1256        dir->fsend(_("3937 Device \"%s\" is busy with writers=%d reserved=%d.\n"),
1257           dev->print_name(), dev->num_writers, dev->num_reserved());
1258    }
1259 }