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