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