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