]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/dircmd.c
update version
[bacula/bacula] / bacula / src / stored / dircmd.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2001-2010 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  *  This file handles accepting Director Commands
30  *
31  *    Most Director commands are handled here, with the
32  *    exception of the Job command command and subsequent
33  *    subcommands that are handled
34  *    in job.c.
35  *
36  *    N.B. in this file, in general we must use P(dev->mutex) rather
37  *      than dev->r_lock() so that we can examine the blocked
38  *      state rather than blocking ourselves because a Job
39  *      thread has the device blocked. In some "safe" cases,
40  *      we can do things to a blocked device. CAREFUL!!!!
41  *
42  *    File daemon commands are handled in fdcmd.c
43  *
44  *     Kern Sibbald, May MMI
45  *
46  */
47
48 #include "bacula.h"
49 #include "stored.h"
50
51 /* Exported variables */
52
53 /* Imported variables */
54 extern BSOCK *filed_chan;
55 extern struct s_last_job last_job;
56 extern bool init_done;
57
58 /* Static variables */
59 static char derrmsg[]     = "3900 Invalid command:";
60 static char OKsetdebug[]  = "3000 OK setdebug=%d\n";
61 static char invalid_cmd[] = "3997 Invalid command for a Director with Monitor directive enabled.\n";
62 static char OK_bootstrap[]    = "3000 OK bootstrap\n";
63 static char ERROR_bootstrap[] = "3904 Error bootstrap\n";
64
65 /* Imported functions */
66 extern void terminate_child();
67 extern bool job_cmd(JCR *jcr);
68 extern bool use_cmd(JCR *jcr);
69 extern bool run_cmd(JCR *jcr);
70 extern bool status_cmd(JCR *sjcr);
71 extern bool qstatus_cmd(JCR *jcr);
72 //extern bool query_cmd(JCR *jcr);
73
74 /* Forward referenced functions */
75 static bool label_cmd(JCR *jcr);
76 static bool die_cmd(JCR *jcr);
77 static bool relabel_cmd(JCR *jcr);
78 static bool readlabel_cmd(JCR *jcr);
79 static bool release_cmd(JCR *jcr);
80 static bool setdebug_cmd(JCR *jcr);
81 static bool cancel_cmd(JCR *cjcr);
82 static bool mount_cmd(JCR *jcr);
83 static bool unmount_cmd(JCR *jcr);
84 //static bool action_on_purge_cmd(JCR *jcr);
85 static bool bootstrap_cmd(JCR *jcr);
86 static bool changer_cmd(JCR *sjcr);
87 static bool do_label(JCR *jcr, int relabel);
88 static DCR *find_device(JCR *jcr, POOL_MEM &dev_name, int drive);
89 static void read_volume_label(JCR *jcr, DCR *dcr, DEVICE *dev, int Slot);
90 static void label_volume_if_ok(DCR *dcr, char *oldname,
91                                char *newname, char *poolname,
92                                int Slot, int relabel);
93 static bool try_autoload_device(JCR *jcr, DCR *dcr, int slot, const char *VolName);
94 static void send_dir_busy_message(BSOCK *dir, DEVICE *dev);
95
96 struct s_cmds {
97    const char *cmd;
98    bool (*func)(JCR *jcr);
99    bool monitoraccess;                      /* set if monitors can access this cmd */
100 };
101
102 /*
103  * The following are the recognized commands from the Director.
104  */
105 static struct s_cmds cmds[] = {
106    {"JobId=",      job_cmd,         0},     /* start Job */
107    {"autochanger", changer_cmd,     0},
108    {"bootstrap",   bootstrap_cmd,   0},
109    {"cancel",      cancel_cmd,      0},
110    {".die",        die_cmd,         0},
111    {"label",       label_cmd,       0},     /* label a tape */
112    {"mount",       mount_cmd,       0},
113    {"readlabel",   readlabel_cmd,   0},
114    {"release",     release_cmd,     0},
115    {"relabel",     relabel_cmd,     0},     /* relabel a tape */
116    {"setdebug=",   setdebug_cmd,    0},     /* set debug level */
117    {"status",      status_cmd,      1},
118    {".status",     qstatus_cmd,     1},
119    {"unmount",     unmount_cmd,     0},
120 //   {"action_on_purge",  action_on_purge_cmd,    0},
121    {"use storage=", use_cmd,        0},
122    {"run",         run_cmd,         0},
123 // {"query",       query_cmd,       0},
124    {NULL,        NULL}                      /* list terminator */
125 };
126
127
128 /*
129  * Connection request. We accept connections either from the
130  *  Director or a Client (File daemon).
131  *
132  * Note, we are running as a seperate thread of the Storage daemon.
133  *  and it is because a Director has made a connection with
134  *  us on the "Message" channel.
135  *
136  * Basic tasks done here:
137  *  - Create a JCR record
138  *  - If it was from the FD, call handle_filed_connection()
139  *  - Authenticate the Director
140  *  - We wait for a command
141  *  - We execute the command
142  *  - We continue or exit depending on the return status
143  */
144 void *handle_connection_request(void *arg)
145 {
146    BSOCK *bs = (BSOCK *)arg;
147    JCR *jcr;
148    int i;
149    bool found, quit;
150    int bnet_stat = 0;
151    char name[500];
152    char tbuf[100];
153
154    if (bs->recv() <= 0) {
155       Emsg1(M_ERROR, 0, _("Connection request from %s failed.\n"), bs->who());
156       bs->close();
157       return NULL;
158    }
159
160    /*
161     * Do a sanity check on the message received
162     */
163    if (bs->msglen < 25 || bs->msglen > (int)sizeof(name)) {
164       Dmsg1(000, "<filed: %s", bs->msg);
165       Emsg2(M_ERROR, 0, _("Invalid connection from %s. Len=%d\n"), bs->who(), bs->msglen);
166       bs->close();
167       return NULL;
168    }
169    /*
170     * See if this is a File daemon connection. If so
171     *   call FD handler.
172     */
173    Dmsg1(110, "Conn: %s", bs->msg);
174    if (debug_level == 3) {
175       Dmsg1(000, "<filed: %s", bs->msg);
176    }
177    if (sscanf(bs->msg, "Hello Start Job %127s", name) == 1) {
178       Dmsg1(110, "Got a FD connection at %s\n", bstrftimes(tbuf, sizeof(tbuf), 
179             (utime_t)time(NULL)));
180       Dmsg1(50, "%s", bs->msg);
181       handle_filed_connection(bs, name);
182       return NULL;
183    }
184
185    /* 
186     * This is a connection from the Director, so setup a JCR 
187     */
188    Dmsg1(110, "Got a DIR connection at %s\n", bstrftimes(tbuf, sizeof(tbuf), 
189          (utime_t)time(NULL)));
190    jcr = new_jcr(sizeof(JCR), stored_free_jcr); /* create Job Control Record */
191    jcr->dir_bsock = bs;               /* save Director bsock */
192    jcr->dir_bsock->set_jcr(jcr);
193    jcr->dcrs = New(alist(10, not_owned_by_alist));
194    /* Initialize FD start condition variable */
195    int errstat = pthread_cond_init(&jcr->job_start_wait, NULL);
196    if (errstat != 0) {
197       berrno be;
198       Jmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), be.bstrerror(errstat));
199       goto bail_out;
200    }
201
202    Dmsg0(1000, "stored in start_job\n");
203
204    /*
205     * Authenticate the Director
206     */
207    if (!authenticate_director(jcr)) {
208       Jmsg(jcr, M_FATAL, 0, _("Unable to authenticate Director\n"));
209       goto bail_out;
210    }
211    Dmsg0(90, "Message channel init completed.\n");
212
213    for (quit=false; !quit;) {
214       /* Read command */
215       if ((bnet_stat = bs->recv()) <= 0) {
216          break;               /* connection terminated */
217       }
218       Dmsg1(199, "<dird: %s\n", bs->msg);
219       /* Ensure that device initialization is complete */
220       while (!init_done) {
221          bmicrosleep(1, 0);
222       }
223       found = false;
224       for (i=0; cmds[i].cmd; i++) {
225         if (strncmp(cmds[i].cmd, bs->msg, strlen(cmds[i].cmd)) == 0) {
226            if ((!cmds[i].monitoraccess) && (jcr->director->monitor)) {
227               Dmsg1(100, "Command \"%s\" is invalid.\n", cmds[i].cmd);
228               bs->fsend(invalid_cmd);
229               bs->signal(BNET_EOD);
230               break;
231            }
232            Dmsg1(200, "Do command: %s\n", cmds[i].cmd);
233            if (!cmds[i].func(jcr)) { /* do command */
234               quit = true; /* error, get out */
235               Dmsg1(190, "Command %s requests quit\n", cmds[i].cmd);
236            }
237            found = true;             /* indicate command found */
238            break;
239         }
240       }
241       if (!found) {                   /* command not found */
242         POOL_MEM err_msg;
243         Mmsg(err_msg, "%s %s\n", derrmsg, bs->msg);
244         bs->fsend(err_msg.c_str());
245         break;
246       }
247    }
248 bail_out:
249    generate_daemon_event(jcr, "JobEnd");
250    dequeue_messages(jcr);             /* send any queued messages */
251    bs->signal(BNET_TERMINATE);
252    free_jcr(jcr);
253    return NULL;
254 }
255
256
257 /*
258  * Force SD to die, and hopefully dump itself.  Turned on only
259  *  in development version.
260  */
261 static bool die_cmd(JCR *jcr)
262 {
263 #ifdef DEVELOPER
264    JCR *djcr = NULL;
265    int a;
266    BSOCK *dir = jcr->dir_bsock;
267    pthread_mutex_t m=PTHREAD_MUTEX_INITIALIZER;
268
269    if (strstr(dir->msg, "deadlock")) {
270       Pmsg0(000, "I have been requested to deadlock ...\n");
271       P(m);
272       P(m);
273    }
274    
275    Pmsg1(000, "I have been requested to die ... (%s)\n", dir->msg);
276    a = djcr->JobId;   /* ref NULL pointer */
277 #endif
278    return 0;
279 }
280
281      
282
283 /*
284  * Set debug level as requested by the Director
285  *
286  */
287 static bool setdebug_cmd(JCR *jcr)
288 {
289    BSOCK *dir = jcr->dir_bsock;
290    int level, trace_flag;
291
292    Dmsg1(10, "setdebug_cmd: %s", dir->msg);
293    if (sscanf(dir->msg, "setdebug=%d trace=%d", &level, &trace_flag) != 2 || level < 0) {
294       dir->fsend(_("3991 Bad setdebug command: %s\n"), dir->msg);
295       return 0;
296    }
297    debug_level = level;
298    set_trace(trace_flag);
299    return dir->fsend(OKsetdebug, level);
300 }
301
302
303 /*
304  * Cancel a Job
305  */
306 static bool cancel_cmd(JCR *cjcr)
307 {
308    BSOCK *dir = cjcr->dir_bsock;
309    int oldStatus;
310    char Job[MAX_NAME_LENGTH];
311    JCR *jcr;
312
313    if (sscanf(dir->msg, "cancel Job=%127s", Job) == 1) {
314       if (!(jcr=get_jcr_by_full_name(Job))) {
315          dir->fsend(_("3904 Job %s not found.\n"), Job);
316       } else {
317          oldStatus = jcr->JobStatus;
318          set_jcr_job_status(jcr, JS_Canceled);
319          Dmsg2(800, "Cancel JobId=%d %p\n", jcr->JobId, jcr);
320          if (!jcr->authenticated && oldStatus == JS_WaitFD) {
321             pthread_cond_signal(&jcr->job_start_wait); /* wake waiting thread */
322          }
323          if (jcr->file_bsock) {
324             jcr->file_bsock->signal(BNET_TERMINATE);
325             jcr->file_bsock->set_terminated();
326             Dmsg2(800, "Term bsock jid=%d %p\n", jcr->JobId, jcr);
327          } else {
328             /* Still waiting for FD to connect, release it */
329             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"), 
768                      dev->print_name());
769                } else {
770                   dir->fsend(_("3907 %s"), dev->bstrerror());
771                } 
772             } else { /* must be file */
773                dir->fsend(_("3906 File device %s is always mounted.\n"),
774                   dev->print_name());
775                pthread_cond_broadcast(&dev->wait_next_vol);
776                Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)dcr->jcr->JobId);
777                pthread_cond_broadcast(&wait_device_release);
778             }
779             break;
780
781          default:
782             dir->fsend(_("3905 Bizarre wait state %d\n"), dev->blocked());
783             break;
784          }
785          dev->dunlock();
786          free_dcr(dcr);
787       } else {
788          dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
789       }
790    } else {
791       pm_strcpy(jcr->errmsg, dir->msg);
792       dir->fsend(_("3909 Error scanning mount command: %s\n"), jcr->errmsg);
793    }
794    dir->signal(BNET_EOD);
795    return true;
796 }
797
798 /*
799  * unmount command from Director
800  */
801 static bool unmount_cmd(JCR *jcr)
802 {
803    POOL_MEM devname;
804    BSOCK *dir = jcr->dir_bsock;
805    DEVICE *dev;
806    DCR *dcr;
807    int drive;
808
809    if (sscanf(dir->msg, "unmount %127s drive=%d", devname.c_str(), &drive) == 2) {
810       dcr = find_device(jcr, devname, drive);
811       if (dcr) {
812          dev = dcr->dev;
813          dev->dlock();                 /* Use P to avoid indefinite block */
814          if (!dev->is_open()) {
815             if (!dev->is_busy()) {
816                unload_autochanger(dcr, -1);          
817             }
818             if (dev->is_unmountable()) {
819                if (dev->unmount(0)) {
820                   dir->fsend(_("3002 Device %s unmounted.\n"), 
821                      dev->print_name());
822                } else {
823                   dir->fsend(_("3907 %s"), dev->bstrerror());
824                } 
825             } else {
826                Dmsg0(90, "Device already unmounted\n");
827                dir->fsend(_("3901 Device %s is already unmounted.\n"), 
828                   dev->print_name());
829             }
830          } else if (dev->blocked() == BST_WAITING_FOR_SYSOP) {
831             Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
832                dev->blocked());
833             if (!unload_autochanger(dcr, -1)) {
834                /* ***FIXME**** what is this ????  */
835                dev->close();
836                free_volume(dev);
837             }
838             if (dev->is_unmountable() && !dev->unmount(0)) {
839                dir->fsend(_("3907 %s"), dev->bstrerror());
840             } else {
841                dev->set_blocked(BST_UNMOUNTED_WAITING_FOR_SYSOP);
842                dir->fsend(_("3001 Device %s unmounted.\n"), 
843                   dev->print_name());
844             }
845
846          } else if (dev->blocked() == BST_DOING_ACQUIRE) {
847             dir->fsend(_("3902 Device %s is busy in acquire.\n"), 
848                dev->print_name());
849
850          } else if (dev->blocked() == BST_WRITING_LABEL) {
851             dir->fsend(_("3903 Device %s is being labeled.\n"), 
852                dev->print_name());
853
854          } else if (dev->is_busy()) {
855             send_dir_busy_message(dir, dev);
856          } else {                     /* device not being used */
857             Dmsg0(90, "Device not in use, unmounting\n");
858             /* On FreeBSD, I am having ASSERT() failures in block_device()
859              * and I can only imagine that the thread id that we are
860              * leaving in no_wait_id is being re-used. So here,
861              * we simply do it by hand.  Gross, but a solution.
862              */
863             /*  block_device(dev, BST_UNMOUNTED); replace with 2 lines below */
864             dev->set_blocked(BST_UNMOUNTED);
865             clear_thread_id(dev->no_wait_id);
866             if (!unload_autochanger(dcr, -1)) {
867                dev->close();
868                free_volume(dev);
869             }
870             if (dev->is_unmountable() && !dev->unmount(0)) {
871                dir->fsend(_("3907 %s"), dev->bstrerror());
872             } else {
873                dir->fsend(_("3002 Device %s unmounted.\n"), 
874                   dev->print_name());
875             }
876          }
877          dev->dunlock();
878          free_dcr(dcr);
879       } else {
880          dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
881       }
882    } else {
883       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
884       pm_strcpy(jcr->errmsg, dir->msg);
885       dir->fsend(_("3907 Error scanning unmount command: %s\n"), jcr->errmsg);
886    }
887    dir->signal(BNET_EOD);
888    return true;
889 }
890
891 #if 0
892 /*
893  * The truncate command will recycle a volume. The director can call this
894  * after purging a volume so that disk space will not be wasted. Only useful
895  * for File Storage, of course.
896  *
897  *
898  * It is currently disabled
899  */
900 static bool action_on_purge_cmd(JCR *jcr)
901 {
902    BSOCK *dir = jcr->dir_bsock;
903
904    char devname[MAX_NAME_LENGTH];
905    char volumename[MAX_NAME_LENGTH];
906    int action;
907
908    /* TODO: Need to find a free device and ask for slot to the director */
909    if (sscanf(dir->msg, 
910               "action_on_purge %127s vol=%127s action=%d",
911               devname, volumename, &action)!= 5) 
912    {
913       dir->fsend(_("3916 Error scanning action_on_purge command\n"));
914       goto done;
915    }
916    unbash_spaces(volumename);
917    unbash_spaces(devname);
918
919    /* Check if action is correct */
920    if (action & AOP_TRUNCTATE) {
921
922    } 
923    /* ... */
924
925 done:
926    dir->signal(BNET_EOD);
927    return true;
928 }
929 #endif
930
931 /*
932  * Release command from Director. This rewinds the device and if
933  *   configured does a offline and ensures that Bacula will
934  *   re-read the label of the tape before continuing. This gives
935  *   the operator the chance to change the tape anytime before the
936  *   next job starts.
937  */
938 static bool release_cmd(JCR *jcr)
939 {
940    POOL_MEM devname;
941    BSOCK *dir = jcr->dir_bsock;
942    DEVICE *dev;
943    DCR *dcr;
944    int drive;
945
946    if (sscanf(dir->msg, "release %127s drive=%d", devname.c_str(), &drive) == 2) {
947       dcr = find_device(jcr, devname, drive);
948       if (dcr) {
949          dev = dcr->dev;
950          dev->dlock();                 /* Use P to avoid indefinite block */
951          if (!dev->is_open()) {
952             if (!dev->is_busy()) {
953                unload_autochanger(dcr, -1);
954             }
955             Dmsg0(90, "Device already released\n");
956             dir->fsend(_("3921 Device %s already released.\n"), 
957                dev->print_name());
958
959          } else if (dev->blocked() == BST_WAITING_FOR_SYSOP) {
960             Dmsg2(90, "%d waiter dev_block=%d.\n", dev->num_waiting,
961                dev->blocked());
962             unload_autochanger(dcr, -1);
963             dir->fsend(_("3922 Device %s waiting for sysop.\n"), 
964                dev->print_name());
965
966          } else if (dev->blocked() == BST_UNMOUNTED_WAITING_FOR_SYSOP) {
967             Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
968                dev->blocked());
969             dir->fsend(_("3922 Device %s waiting for mount.\n"), 
970                dev->print_name());
971
972          } else if (dev->blocked() == BST_DOING_ACQUIRE) {
973             dir->fsend(_("3923 Device %s is busy in acquire.\n"), 
974                dev->print_name());
975
976          } else if (dev->blocked() == BST_WRITING_LABEL) {
977             dir->fsend(_("3914 Device %s is being labeled.\n"), 
978                dev->print_name());
979
980          } else if (dev->is_busy()) {
981             send_dir_busy_message(dir, dev);
982          } else {                     /* device not being used */
983             Dmsg0(90, "Device not in use, releasing\n");
984             dcr->release_volume();
985             dir->fsend(_("3022 Device %s released.\n"), 
986                dev->print_name());
987          }
988          dev->dunlock();
989          free_dcr(dcr);
990       } else {
991          dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
992       }
993    } else {
994       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
995       pm_strcpy(jcr->errmsg, dir->msg);
996       dir->fsend(_("3927 Error scanning release command: %s\n"), jcr->errmsg);
997    }
998    dir->signal(BNET_EOD);
999    return true;
1000 }
1001
1002 static pthread_mutex_t bsr_mutex = PTHREAD_MUTEX_INITIALIZER;
1003 static uint32_t bsr_uniq = 0;
1004
1005 static bool get_bootstrap_file(JCR *jcr, BSOCK *sock)
1006 {
1007    POOLMEM *fname = get_pool_memory(PM_FNAME);
1008    FILE *bs;
1009    bool ok = false;
1010
1011    if (jcr->RestoreBootstrap) {
1012       unlink(jcr->RestoreBootstrap);
1013       free_pool_memory(jcr->RestoreBootstrap);
1014    }
1015    P(bsr_mutex);
1016    bsr_uniq++;
1017    Mmsg(fname, "%s/%s.%s.%d.bootstrap", me->working_directory, me->hdr.name,
1018       jcr->Job, bsr_uniq);
1019    V(bsr_mutex);
1020    Dmsg1(400, "bootstrap=%s\n", fname);
1021    jcr->RestoreBootstrap = fname;
1022    bs = fopen(fname, "a+b");           /* create file */
1023    if (!bs) {
1024       berrno be;
1025       Jmsg(jcr, M_FATAL, 0, _("Could not create bootstrap file %s: ERR=%s\n"),
1026          jcr->RestoreBootstrap, be.bstrerror());
1027       goto bail_out;
1028    }
1029    Dmsg0(10, "=== Bootstrap file ===\n");
1030    while (sock->recv() >= 0) {
1031        Dmsg1(10, "%s", sock->msg);
1032        fputs(sock->msg, bs);
1033    }
1034    fclose(bs);
1035    Dmsg0(10, "=== end bootstrap file ===\n");
1036    jcr->bsr = parse_bsr(jcr, jcr->RestoreBootstrap);
1037    if (!jcr->bsr) {
1038       Jmsg(jcr, M_FATAL, 0, _("Error parsing bootstrap file.\n"));
1039       goto bail_out;
1040    }
1041    if (debug_level >= 10) {
1042       dump_bsr(jcr->bsr, true);
1043    }
1044    /* If we got a bootstrap, we are reading, so create read volume list */
1045    create_restore_volume_list(jcr);
1046    ok = true;
1047
1048 bail_out:
1049    unlink(jcr->RestoreBootstrap);
1050    free_pool_memory(jcr->RestoreBootstrap);
1051    jcr->RestoreBootstrap = NULL;
1052    if (!ok) {
1053       sock->fsend(ERROR_bootstrap);
1054       return false;
1055    }
1056    return sock->fsend(OK_bootstrap);
1057 }
1058
1059 static bool bootstrap_cmd(JCR *jcr)
1060 {
1061    return get_bootstrap_file(jcr, jcr->dir_bsock);
1062 }
1063
1064 /*
1065  * Autochanger command from Director
1066  */
1067 static bool changer_cmd(JCR *jcr)
1068 {
1069    POOL_MEM devname;
1070    BSOCK *dir = jcr->dir_bsock;
1071    DEVICE *dev;
1072    DCR *dcr;
1073    const char *cmd = NULL;
1074    bool ok = false;
1075    /*
1076     * A safe_cmd may call autochanger script but does not load/unload
1077     *    slots so it can be done at the same time that the drive is open.
1078     */
1079    bool safe_cmd = false;
1080
1081    if (sscanf(dir->msg, "autochanger listall %127s", devname.c_str()) == 1) {
1082       cmd = "listall";
1083       safe_cmd = ok = true;
1084    } else if (sscanf(dir->msg, "autochanger list %127s", devname.c_str()) == 1) {
1085       cmd = "list";
1086       safe_cmd = ok = true;
1087    } else if (sscanf(dir->msg, "autochanger slots %127s", devname.c_str()) == 1) {
1088       cmd = "slots";
1089       safe_cmd = ok = true;
1090    } else if (sscanf(dir->msg, "autochanger drives %127s", devname.c_str()) == 1) {
1091       cmd = "drives";
1092       safe_cmd = ok = true;
1093    }
1094    if (ok) {
1095       dcr = find_device(jcr, devname, -1);
1096       if (dcr) {
1097          dev = dcr->dev;
1098          dev->dlock();                 /* Use P to avoid indefinite block */
1099          if (!dev->device->changer_res) {
1100             dir->fsend(_("3995 Device %s is not an autochanger.\n"), 
1101                dev->print_name());
1102          /* Under certain "safe" conditions, we can steal the lock */
1103          } else if (safe_cmd || !dev->is_open() || dev->can_steal_lock()) {
1104             autochanger_cmd(dcr, dir, cmd);
1105          } else if (dev->is_busy() || dev->is_blocked()) {
1106             send_dir_busy_message(dir, dev);
1107          } else {                     /* device not being used */
1108             autochanger_cmd(dcr, dir, cmd);
1109          }
1110          dev->dunlock();
1111          free_dcr(dcr);
1112       } else {
1113          dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
1114       }
1115    } else {  /* error on scanf */
1116       pm_strcpy(jcr->errmsg, dir->msg);
1117       dir->fsend(_("3908 Error scanning autocharger drives/list/slots command: %s\n"),
1118          jcr->errmsg);
1119    }
1120    dir->signal(BNET_EOD);
1121    return true;
1122 }
1123
1124 /*
1125  * Read and return the Volume label
1126  */
1127 static bool readlabel_cmd(JCR *jcr)
1128 {
1129    POOL_MEM devname;
1130    BSOCK *dir = jcr->dir_bsock;
1131    DEVICE *dev;
1132    DCR *dcr;
1133    int Slot;
1134    int drive;
1135
1136    if (sscanf(dir->msg, "readlabel %127s Slot=%d drive=%d", devname.c_str(), 
1137        &Slot, &drive) == 3) {
1138       dcr = find_device(jcr, devname, drive);
1139       if (dcr) {
1140          dev = dcr->dev;
1141          dev->dlock();                 /* Use P to avoid indefinite block */
1142          if (!dev->is_open()) {
1143             read_volume_label(jcr, dcr, dev, Slot);
1144             dev->close();
1145          /* Under certain "safe" conditions, we can steal the lock */
1146          } else if (dev->can_steal_lock()) {
1147             read_volume_label(jcr, dcr, dev, Slot);
1148          } else if (dev->is_busy() || dev->is_blocked()) {
1149             send_dir_busy_message(dir, dev);
1150          } else {                     /* device not being used */
1151             read_volume_label(jcr, dcr, dev, Slot);
1152          }
1153          dev->dunlock();
1154          free_dcr(dcr);
1155       } else {
1156          dir->fsend(_("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
1157       }
1158    } else {
1159       pm_strcpy(jcr->errmsg, dir->msg);
1160       dir->fsend(_("3909 Error scanning readlabel command: %s\n"), jcr->errmsg);
1161    }
1162    dir->signal(BNET_EOD);
1163    return true;
1164 }
1165
1166
1167 /*
1168  * Read the tape label
1169  *
1170  *  Enter with the mutex set
1171  */
1172 static void read_volume_label(JCR *jcr, DCR *dcr, DEVICE *dev, int Slot)
1173 {
1174    BSOCK *dir = jcr->dir_bsock;
1175    bsteal_lock_t hold;
1176
1177    dcr->dev = dev;
1178    steal_device_lock(dev, &hold, BST_WRITING_LABEL);
1179
1180    if (!try_autoload_device(jcr, dcr, Slot, "")) {
1181       goto bail_out;                  /* error */
1182    }
1183
1184    dev->clear_labeled();              /* force read of label */
1185    switch (read_dev_volume_label(dcr)) {
1186    case VOL_OK:
1187       /* DO NOT add quotes around the Volume name. It is scanned in the DIR */
1188       dir->fsend(_("3001 Volume=%s Slot=%d\n"), dev->VolHdr.VolumeName, Slot);
1189       Dmsg1(100, "Volume: %s\n", dev->VolHdr.VolumeName);
1190       break;
1191    default:
1192       dir->fsend(_("3902 Cannot mount Volume on Storage Device %s because:\n%s"),
1193                  dev->print_name(), jcr->errmsg);
1194       break;
1195    }
1196
1197 bail_out:
1198    give_back_device_lock(dev, &hold);
1199    return;
1200 }
1201
1202 static bool try_autoload_device(JCR *jcr, DCR *dcr, int slot, const char *VolName)
1203 {
1204    BSOCK *dir = jcr->dir_bsock;
1205
1206    bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
1207    dcr->VolCatInfo.Slot = slot;
1208    dcr->VolCatInfo.InChanger = slot > 0;
1209    if (autoload_device(dcr, 0, dir) < 0) {    /* autoload if possible */
1210       return false;
1211    }
1212    return true;
1213 }
1214
1215 static void send_dir_busy_message(BSOCK *dir, DEVICE *dev)
1216 {
1217    if (dev->is_blocked()) {
1218       switch (dev->blocked()) {
1219       case BST_UNMOUNTED:
1220          dir->fsend(_("3931 Device %s is BLOCKED. user unmounted.\n"),
1221             dev->print_name());
1222          break;
1223       case BST_UNMOUNTED_WAITING_FOR_SYSOP:
1224          dir->fsend(_("3932 Device %s is BLOCKED. user unmounted during wait for media/mount.\n"),
1225              dev->print_name());
1226          break;
1227       case BST_WAITING_FOR_SYSOP:
1228          dir->fsend(_("3933 Device %s is BLOCKED waiting for media.\n"),
1229             dev->print_name());
1230          break;
1231       case BST_DOING_ACQUIRE:
1232          dir->fsend(_("3934 Device %s is being initialized.\n"),
1233             dev->print_name());
1234          break;
1235       case BST_WRITING_LABEL:
1236          dir->fsend(_("3935 Device %s is blocked labeling a Volume.\n"),
1237             dev->print_name());
1238          break;
1239       default:
1240          dir->fsend(_("3935 Device %s is blocked for unknown reason.\n"),
1241             dev->print_name());
1242          break;
1243       }
1244    } else if (dev->can_read()) {
1245        dir->fsend(_("3936 Device %s is busy reading.\n"),
1246                    dev->print_name());;
1247    } else {
1248        dir->fsend(_("3937 Device %s is busy with %d writer(s).\n"),
1249           dev->print_name(), dev->num_writers);
1250    }
1251 }