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