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