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