]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/dircmd.c
d876eff448ef0b58b1a669b4c5e203a754ad08e7
[bacula/bacula] / bacula / src / stored / dircmd.c
1 /*
2  *  This file handles accepting Director Commands
3  *
4  *    Most Director commands are handled here, with the
5  *    exception of the Job command command and subsequent
6  *    subcommands that are handled
7  *    in job.c.
8  *
9  *    N.B. in this file, in general we must use P(dev->mutex) rather
10  *      than lock_device(dev) so that we can examine the blocked
11  *      state rather than blocking ourselves. In some "safe" cases,
12  *      we can do things to a blocked device. CAREFUL!!!!
13  *
14  *    File daemon commands are handled in fdcmd.c
15  *
16  *     Kern Sibbald, May MMI
17  *
18  *   Version $Id$
19  *
20  */
21 /*
22    Copyright (C) 2001-2005 Kern Sibbald
23
24    This program is free software; you can redistribute it and/or
25    modify it under the terms of the GNU General Public License
26    version 2 as ammended with additional clauses defined in the
27    file LICENSE in the main source directory.
28
29    This program is distributed in the hope that it will be useful,
30    but WITHOUT ANY WARRANTY; without even the implied warranty of
31    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
32    the file LICENSE for additional details.
33
34  */
35
36 #include "bacula.h"
37 #include "stored.h"
38
39 /* Exported variables */
40
41 /* Imported variables */
42 extern BSOCK *filed_chan;
43 extern int r_first, r_last;
44 extern struct s_res resources[];
45 extern char my_name[];
46 extern time_t daemon_start_time;
47 extern struct s_last_job last_job;
48
49 /* Static variables */
50 static char derrmsg[]     = "3900 Invalid command\n";
51 static char OKsetdebug[]  = "3000 OK setdebug=%d\n";
52 static char illegal_cmd[] = "3997 Illegal command for a Director with Monitor directive enabled\n";
53
54 /* Imported functions */
55 extern void terminate_child();
56 extern bool job_cmd(JCR *jcr);
57 extern bool use_cmd(JCR *jcr);
58 extern bool run_cmd(JCR *jcr);
59 extern bool status_cmd(JCR *sjcr);
60 extern bool qstatus_cmd(JCR *jcr);
61 //extern bool query_cmd(JCR *jcr);
62
63 /* Forward referenced functions */
64 static bool label_cmd(JCR *jcr);
65 static bool relabel_cmd(JCR *jcr);
66 static bool readlabel_cmd(JCR *jcr);
67 static bool release_cmd(JCR *jcr);
68 static bool setdebug_cmd(JCR *jcr);
69 static bool cancel_cmd(JCR *cjcr);
70 static bool mount_cmd(JCR *jcr);
71 static bool unmount_cmd(JCR *jcr);
72 static bool autochanger_cmd(JCR *sjcr);
73 static bool do_label(JCR *jcr, int relabel);
74 static DEVICE *find_device(JCR *jcr, POOL_MEM &dev_name);
75 static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot);
76 static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *oldname,
77                                char *newname, char *poolname,
78                                int Slot, int relabel);
79 static bool try_autoload_device(JCR *jcr, int slot, const char *VolName);
80 static void send_dir_busy_message(BSOCK *dir, DEVICE *dev);
81
82 struct s_cmds {
83    const char *cmd;
84    bool (*func)(JCR *jcr);
85    int monitoraccess; /* specify if monitors have access to this function */
86 };
87
88 /*
89  * The following are the recognized commands from the Director.
90  */
91 static struct s_cmds cmds[] = {
92    {"JobId=",      job_cmd,         0},     /* start Job */
93    {"autochanger", autochanger_cmd, 0},
94    {"bootstrap",   bootstrap_cmd,   0},
95    {"cancel",      cancel_cmd,      0},
96    {"label",       label_cmd,       0},     /* label a tape */
97    {"mount",       mount_cmd,       0},
98    {"readlabel",   readlabel_cmd,   0},
99    {"release",     release_cmd,     0},
100    {"relabel",     relabel_cmd,     0},     /* relabel a tape */
101    {"setdebug=",   setdebug_cmd,    0},     /* set debug level */
102    {"status",      status_cmd,      1},
103    {".status",     qstatus_cmd,     1},
104    {"unmount",     unmount_cmd,     0},
105    {"use storage=", use_cmd,        0},
106    {"run",         run_cmd,         0},
107 // {"query",       query_cmd,       0},
108    {NULL,        NULL}                      /* list terminator */
109 };
110
111
112 /*
113  * Connection request. We accept connections either from the
114  *  Director or a Client (File daemon).
115  *
116  * Note, we are running as a seperate thread of the Storage daemon.
117  *  and it is because a Director has made a connection with
118  *  us on the "Message" channel.
119  *
120  * Basic tasks done here:
121  *  - Create a JCR record
122  *  - If it was from the FD, call handle_filed_connection()
123  *  - Authenticate the Director
124  *  - We wait for a command
125  *  - We execute the command
126  *  - We continue or exit depending on the return status
127  */
128 void *handle_connection_request(void *arg)
129 {
130    BSOCK *bs = (BSOCK *)arg;
131    JCR *jcr;
132    int i;
133    bool found, quit;
134    int bnet_stat = 0;
135    char name[MAX_NAME_LENGTH];
136
137    if (bnet_recv(bs) <= 0) {
138       Emsg0(M_ERROR, 0, _("Connection request failed.\n"));
139       bnet_close(bs);
140       return NULL;
141    }
142
143    /*
144     * Do a sanity check on the message received
145     */
146    if (bs->msglen < 25 || bs->msglen > (int)sizeof(name)-25) {
147       Emsg1(M_ERROR, 0, _("Invalid connection. Len=%d\n"), bs->msglen);
148       bnet_close(bs);
149       return NULL;
150    }
151    /*
152     * See if this is a File daemon connection. If so
153     *   call FD handler.
154     */
155    Dmsg1(110, "Conn: %s", bs->msg);
156    if (sscanf(bs->msg, "Hello Start Job %127s", name) == 1) {
157       handle_filed_connection(bs, name);
158       return NULL;
159    }
160
161    /* 
162     * This is a connection from the Director, so setup a JCR 
163     */
164    Dmsg0(110, "Start Dir Job\n");
165    jcr = new_jcr(sizeof(JCR), stored_free_jcr); /* create Job Control Record */
166    jcr->dir_bsock = bs;               /* save Director bsock */
167    jcr->dir_bsock->jcr = jcr;
168    jcr->dcrs = New(alist(10, not_owned_by_alist));
169    /* Initialize FD start condition variable */
170    int errstat = pthread_cond_init(&jcr->job_start_wait, NULL);
171    if (errstat != 0) {
172       Jmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), strerror(errstat));
173       goto bail_out;
174    }
175
176    Dmsg0(1000, "stored in start_job\n");
177
178    /*
179     * Authenticate the Director
180     */
181    if (!authenticate_director(jcr)) {
182       Jmsg(jcr, M_FATAL, 0, _("Unable to authenticate Director\n"));
183       goto bail_out;
184    }
185    Dmsg0(90, "Message channel init completed.\n");
186
187    for (quit=false; !quit;) {
188       /* Read command */
189       if ((bnet_stat = bnet_recv(bs)) <= 0) {
190          break;               /* connection terminated */
191       }
192       Dmsg1(199, "<dird: %s\n", bs->msg);
193       found = false;
194       for (i=0; cmds[i].cmd; i++) {
195         if (strncmp(cmds[i].cmd, bs->msg, strlen(cmds[i].cmd)) == 0) {
196            if ((!cmds[i].monitoraccess) && (jcr->director->monitor)) {
197               Dmsg1(100, "Command %s illegal.\n", cmds[i].cmd);
198               bnet_fsend(bs, illegal_cmd);
199               bnet_sig(bs, BNET_EOD);
200               break;
201            }
202            Dmsg1(200, "Do command: %s\n", cmds[i].cmd);
203            if (!cmds[i].func(jcr)) { /* do command */
204               quit = true; /* error, get out */
205               Dmsg1(190, "Command %s requsts quit\n", cmds[i].cmd);
206            }
207            found = true;             /* indicate command found */
208            break;
209         }
210       }
211       if (!found) {                   /* command not found */
212         bnet_fsend(bs, derrmsg);
213         break;
214       }
215    }
216 bail_out:
217    generate_daemon_event(jcr, "JobEnd");
218    dequeue_messages(jcr);             /* send any queued messages */
219    bnet_sig(bs, BNET_TERMINATE);
220    free_jcr(jcr);
221    return NULL;
222 }
223
224 /*
225  * Set debug level as requested by the Director
226  *
227  */
228 static bool setdebug_cmd(JCR *jcr)
229 {
230    BSOCK *dir = jcr->dir_bsock;
231    int level, trace_flag;
232
233    Dmsg1(10, "setdebug_cmd: %s", dir->msg);
234    if (sscanf(dir->msg, "setdebug=%d trace=%d", &level, &trace_flag) != 2 || level < 0) {
235       bnet_fsend(dir, "3991 Bad setdebug command: %s\n", dir->msg);
236       return 0;
237    }
238    debug_level = level;
239    set_trace(trace_flag);
240    return bnet_fsend(dir, OKsetdebug, level);
241 }
242
243
244 /*
245  * Cancel a Job
246  */
247 static bool cancel_cmd(JCR *cjcr)
248 {
249    BSOCK *dir = cjcr->dir_bsock;
250    int oldStatus;
251    char Job[MAX_NAME_LENGTH];
252    JCR *jcr;
253
254    if (sscanf(dir->msg, "cancel Job=%127s", Job) == 1) {
255       if (!(jcr=get_jcr_by_full_name(Job))) {
256          bnet_fsend(dir, _("3902 Job %s not found.\n"), Job);
257       } else {
258          P(jcr->mutex);
259          oldStatus = jcr->JobStatus;
260          set_jcr_job_status(jcr, JS_Canceled);
261          if (!jcr->authenticated && oldStatus == JS_WaitFD) {
262             pthread_cond_signal(&jcr->job_start_wait); /* wake waiting thread */
263          }
264          V(jcr->mutex);
265          if (jcr->file_bsock) {
266             bnet_sig(jcr->file_bsock, BNET_TERMINATE);
267          }
268          /* If thread waiting on mount, wake him */
269          if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->waiting_for_mount()) {
270              pthread_cond_signal(&jcr->dcr->dev->wait_next_vol);
271              pthread_cond_broadcast(&wait_device_release);
272          }
273          bnet_fsend(dir, _("3000 Job %s marked to be canceled.\n"), jcr->Job);
274          free_jcr(jcr);
275       }
276    } else {
277       bnet_fsend(dir, _("3903 Error scanning cancel command.\n"));
278    }
279    bnet_sig(dir, BNET_EOD);
280    return 1;
281 }
282
283 /*
284  * Label a Volume
285  *
286  */
287 static bool label_cmd(JCR *jcr)
288 {
289    return do_label(jcr, 0);
290 }
291
292 static bool relabel_cmd(JCR *jcr)
293 {
294    return do_label(jcr, 1);
295 }
296
297 static bool do_label(JCR *jcr, int relabel)
298 {
299    POOLMEM *newname, *oldname, *poolname, *mtype;
300    POOL_MEM dev_name;
301    BSOCK *dir = jcr->dir_bsock;
302    DEVICE *dev;
303    bool ok = false;
304    int slot;
305
306    newname = get_memory(dir->msglen+1);
307    oldname = get_memory(dir->msglen+1);
308    poolname = get_memory(dir->msglen+1);
309    mtype = get_memory(dir->msglen+1);
310    if (relabel) {
311       if (sscanf(dir->msg, "relabel %127s OldName=%127s NewName=%127s PoolName=%127s MediaType=%127s Slot=%d",
312           dev_name.c_str(), oldname, newname, poolname, mtype, &slot) == 6) {
313          ok = true;
314       }
315    } else {
316       *oldname = 0;
317       if (sscanf(dir->msg, "label %127s VolumeName=%127s PoolName=%127s MediaType=%127s Slot=%d",
318           dev_name.c_str(), newname, poolname, mtype, &slot) == 5) {
319          ok = true;
320       }
321    }
322    if (ok) {
323       unbash_spaces(newname);
324       unbash_spaces(oldname);
325       unbash_spaces(poolname);
326       unbash_spaces(mtype);
327       dev = find_device(jcr, dev_name);
328       if (dev) {
329          /******FIXME**** compare MediaTypes */
330          P(dev->mutex);               /* Use P to avoid indefinite block */
331          if (!dev->is_open()) {
332             label_volume_if_ok(jcr, dev, oldname, newname, poolname, slot, relabel);
333             force_close_device(dev);
334          /* Under certain "safe" conditions, we can steal the lock */
335          } else if (dev->can_steal_lock()) {
336             label_volume_if_ok(jcr, dev, oldname, newname, poolname, slot, relabel);
337          } else if (dev->is_busy()) {
338             send_dir_busy_message(dir, dev);
339          } else {                     /* device not being used */
340             label_volume_if_ok(jcr, dev, oldname, newname, poolname, slot, relabel);
341          }
342          V(dev->mutex);
343       } else {
344          bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), dev_name.c_str());
345       }
346    } else {
347       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
348       pm_strcpy(jcr->errmsg, dir->msg);
349       bnet_fsend(dir, _("3903 Error scanning label command: %s\n"), jcr->errmsg);
350    }
351    free_memory(oldname);
352    free_memory(newname);
353    free_memory(poolname);
354    free_memory(mtype);
355    bnet_sig(dir, BNET_EOD);
356    return true;
357 }
358
359 /*
360  * Read the tape label and determine if we can safely
361  * label the tape (not a Bacula volume), then label it.
362  *
363  *  Enter with the mutex set
364  */
365 static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *oldname,
366                                char *newname, char *poolname,
367                                int slot, int relabel)
368 {
369    BSOCK *dir = jcr->dir_bsock;
370    bsteal_lock_t hold;
371    DCR *dcr = jcr->dcr;
372    int label_status;
373
374    dcr->dev = dev;
375    steal_device_lock(dev, &hold, BST_WRITING_LABEL);
376
377    /* Note, try_autoload_device() opens the device */
378    if (!try_autoload_device(jcr, slot, newname)) {
379       goto bail_out;                  /* error */
380    }
381
382    /* See what we have for a Volume */
383    label_status = read_dev_volume_label(dcr);
384    
385    switch(label_status) {
386    case VOL_NAME_ERROR:
387    case VOL_VERSION_ERROR:
388    case VOL_LABEL_ERROR:
389    case VOL_OK:
390       if (!relabel) {
391          bnet_fsend(dir, _(
392             "3920 Cannot label Volume because it is already labeled: \"%s\"\n"),
393              dev->VolHdr.VolumeName);
394          break;
395       }
396       /* Relabel request. If oldname matches, continue */
397       if (strcmp(oldname, dev->VolHdr.VolumeName) != 0) {
398          bnet_fsend(dir, _("3921 Wrong volume mounted.\n"));
399          break;
400       }
401       if (dev->label_type != B_BACULA_LABEL) {
402          bnet_fsend(dir, _("3922 Cannot relabel an ANSI/IBM labeled Volume.\n"));
403          break;
404       }
405       /* Fall through wanted! */
406    case VOL_IO_ERROR:
407    case VOL_NO_LABEL:
408       if (!write_new_volume_label_to_dev(dcr, newname, poolname)) {
409          bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), strerror_dev(dev));
410          break;
411       }
412       bstrncpy(dcr->VolumeName, newname, sizeof(dcr->VolumeName));
413       /* The following 3000 OK label. string is scanned in ua_label.c */
414       bnet_fsend(dir, "3000 OK label. Volume=%s Device=%s\n",
415          newname, dev->print_name());
416       break;
417    case VOL_NO_MEDIA:
418       bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), strerror_dev(dev));
419       break;
420    default:
421       bnet_fsend(dir, _("3913 Cannot label Volume. "
422 "Unknown status %d from read_volume_label()\n"), label_status);
423       break;
424    }
425
426 bail_out:
427    if (!dev->is_open()) {
428       free_volume(dev);
429    }
430    give_back_device_lock(dev, &hold);
431    return;
432 }
433
434
435 /*
436  * Read the tape label
437  *
438  *  Enter with the mutex set
439  */
440 static bool read_label(DCR *dcr)
441 {
442    int ok;
443    JCR *jcr = dcr->jcr;
444    BSOCK *dir = jcr->dir_bsock;
445    bsteal_lock_t hold;
446    DEVICE *dev = dcr->dev;
447
448    steal_device_lock(dev, &hold, BST_DOING_ACQUIRE);
449
450    dcr->VolumeName[0] = 0;
451    dev->clear_labeled();              /* force read of label */
452    switch (read_dev_volume_label(dcr)) {
453    case VOL_OK:
454       bnet_fsend(dir, _("3001 Mounted Volume: %s\n"), dev->VolHdr.VolumeName);
455       ok = true;
456       break;
457    default:
458       bnet_fsend(dir, _("3902 Cannot mount Volume on Storage Device %s because:\n%s"),
459          dev->print_name(), jcr->errmsg);
460       ok = false;
461       break;
462    }
463    give_back_device_lock(dev, &hold);
464    return ok;
465 }
466
467 static DEVICE *find_device(JCR *jcr, POOL_MEM &devname)
468 {
469    DEVRES *device;
470    AUTOCHANGER *changer;
471    bool found = false;
472
473    unbash_spaces(devname);
474 // LockRes();
475    foreach_res(device, R_DEVICE) {
476       /* Find resource, and make sure we were able to open it */
477       if (fnmatch(device->hdr.name, devname.c_str(), 0) == 0) {
478          if (!device->dev) {
479             device->dev = init_dev(jcr, device);
480          }
481          if (!device->dev) {
482             Jmsg(jcr, M_WARNING, 0, _("\n"
483                "     Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
484                  devname.c_str());
485             continue;
486          }
487          Dmsg1(20, "Found device %s\n", device->hdr.name);
488          found = true;
489          break;
490       }
491    }
492    foreach_res(changer, R_AUTOCHANGER) {
493       /* Find resource, and make sure we were able to open it */
494       if (fnmatch(devname.c_str(), changer->hdr.name, 0) == 0) {
495          /* Try each device in this AutoChanger */
496          foreach_alist(device, changer->device) {
497             Dmsg1(100, "Try changer device %s\n", device->hdr.name);
498             if (!device->dev) {
499                device->dev = init_dev(jcr, device);
500             }
501             if (!device->dev) {
502                Dmsg1(100, "Device %s could not be opened. Skipped\n", devname.c_str());
503                Jmsg(jcr, M_WARNING, 0, _("\n"
504                   "     Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
505                     device->hdr.name, devname.c_str());
506                continue;
507             }
508             if (!device->dev->autoselect) {
509                continue;              /* device is not available */
510             }
511             Dmsg1(20, "Found changer device %s\n", device->hdr.name);
512             found = true;
513             break;
514          }
515          break;                    /* we found it but could not open a device */
516       }
517    }
518
519    if (found) {
520       jcr->dcr = new_dcr(jcr, device->dev);
521 //    UnlockRes();
522       jcr->dcr->device = device;
523       return jcr->dcr->dev;
524    }
525 // UnlockRes();
526    return NULL;
527 }
528
529
530 /*
531  * Mount command from Director
532  */
533 static bool mount_cmd(JCR *jcr)
534 {
535    POOL_MEM devname;
536    BSOCK *dir = jcr->dir_bsock;
537    DEVICE *dev;
538    DCR *dcr;
539
540    if (sscanf(dir->msg, "mount %127s", devname.c_str()) == 1) {
541       dev = find_device(jcr, devname);
542       dcr = jcr->dcr;
543       if (dev) {
544          P(dev->mutex);               /* Use P to avoid indefinite block */
545          switch (dev->dev_blocked) {         /* device blocked? */
546          case BST_WAITING_FOR_SYSOP:
547             /* Someone is waiting, wake him */
548             Dmsg0(100, "Waiting for mount. Attempting to wake thread\n");
549             dev->dev_blocked = BST_MOUNT;
550             bnet_fsend(dir, "3001 OK mount. Device=%s\n", 
551                dev->print_name());
552             pthread_cond_broadcast(&dev->wait_next_vol);
553             pthread_cond_broadcast(&wait_device_release);
554             break;
555
556          /* In both of these two cases, we (the user) unmounted the Volume */
557          case BST_UNMOUNTED_WAITING_FOR_SYSOP:
558          case BST_UNMOUNTED:
559             /* We freed the device, so reopen it and wake any waiting threads */
560             if (dev->open(NULL, OPEN_READ_WRITE) < 0) {
561                bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
562                   strerror_dev(dev));
563                break;
564             }
565             read_dev_volume_label(dcr);
566             if (dev->dev_blocked == BST_UNMOUNTED) {
567                /* We blocked the device, so unblock it */
568                Dmsg0(100, "Unmounted. Unblocking device\n");
569                read_label(dcr);       /* this should not be necessary */
570                unblock_device(dev);
571             } else {
572                Dmsg0(100, "Unmounted waiting for mount. Attempting to wake thread\n");
573                dev->dev_blocked = BST_MOUNT;
574             }
575             if (dev->is_labeled()) {
576                bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
577                   dev->print_name(), dev->VolHdr.VolumeName);
578             } else {
579                bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
580                                  "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
581                           dev->print_name());
582             }
583             pthread_cond_broadcast(&dev->wait_next_vol);
584             pthread_cond_broadcast(&wait_device_release);
585             break;
586
587          case BST_DOING_ACQUIRE:
588             bnet_fsend(dir, _("3001 Device %s is mounted; doing acquire.\n"),
589                        dev->print_name());
590             break;
591
592          case BST_WRITING_LABEL:
593             bnet_fsend(dir, _("3903 Device %s is being labeled.\n"), 
594                dev->print_name());
595             break;
596
597          case BST_NOT_BLOCKED:
598             if (dev->is_open()) {
599                if (dev->is_labeled()) {
600                   bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
601                      dev->print_name(), dev->VolHdr.VolumeName);
602                } else {
603                   bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
604                                  "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
605                              dev->print_name());
606                }
607             } else if (dev->is_tape()) {
608                if (dev->open(NULL, OPEN_READ_WRITE) < 0) {
609                   bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
610                      strerror_dev(dev));
611                   break;
612                }
613                read_label(dcr);
614                if (dev->is_labeled()) {
615                   bnet_fsend(dir, _("3001 Device %s is already mounted with Volume \"%s\"\n"),
616                      dev->print_name(), dev->VolHdr.VolumeName);
617                } else {
618                   bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
619                                     "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
620                              dev->print_name());
621                }
622             } else if (dev->is_dvd()) {
623                if (mount_dev(dev, 1)) {
624                   bnet_fsend(dir, _("3002 Device %s is mounted.\n"), 
625                      dev->print_name());
626                } else {
627                   bnet_fsend(dir, "3907 %s", strerror_dev(dev));
628                } 
629             } else { /* must be file */
630                bnet_fsend(dir, _("3906 File device %s is always mounted.\n"),
631                   dev->print_name());
632             }
633             break;
634
635          default:
636             bnet_fsend(dir, _("3905 Bizarre wait state %d\n"), dev->dev_blocked);
637             break;
638          }
639          V(dev->mutex);
640       } else {
641          bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), devname.c_str());
642       }
643    } else {
644       pm_strcpy(jcr->errmsg, dir->msg);
645       bnet_fsend(dir, _("3909 Error scanning mount command: %s\n"), jcr->errmsg);
646    }
647    bnet_sig(dir, BNET_EOD);
648    return true;
649 }
650
651 /*
652  * unmount command from Director
653  */
654 static bool unmount_cmd(JCR *jcr)
655 {
656    POOL_MEM devname;
657    BSOCK *dir = jcr->dir_bsock;
658    DEVICE *dev;
659
660    if (sscanf(dir->msg, "unmount %127s", devname.c_str()) == 1) {
661       dev = find_device(jcr, devname);
662       if (dev) {
663          P(dev->mutex);               /* Use P to avoid indefinite block */
664          if (!dev->is_open()) {
665             Dmsg0(90, "Device already unmounted\n");
666             bnet_fsend(dir, _("3901 Device %s is already unmounted.\n"), 
667                dev->print_name());
668
669          } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP) {
670             Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
671                dev->dev_blocked);
672             offline_or_rewind_dev(dev);
673             force_close_device(dev);
674             dev->dev_blocked = BST_UNMOUNTED_WAITING_FOR_SYSOP;
675             bnet_fsend(dir, _("3001 Device %s unmounted.\n"), 
676                dev->print_name());
677
678          } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
679             bnet_fsend(dir, _("3902 Device %s is busy in acquire.\n"), 
680                dev->print_name());
681
682          } else if (dev->dev_blocked == BST_WRITING_LABEL) {
683             bnet_fsend(dir, _("3903 Device %s is being labeled.\n"), 
684                dev->print_name());
685
686          } else if (dev->is_busy()) {
687             send_dir_busy_message(dir, dev);
688          } else {                     /* device not being used */
689             Dmsg0(90, "Device not in use, unmounting\n");
690             /* On FreeBSD, I am having ASSERT() failures in block_device()
691              * and I can only imagine that the thread id that we are
692              * leaving in no_wait_id is being re-used. So here,
693              * we simply do it by hand.  Gross, but a solution.
694              */
695             /*  block_device(dev, BST_UNMOUNTED); replace with 2 lines below */
696             dev->dev_blocked = BST_UNMOUNTED;
697             dev->no_wait_id = 0;
698             offline_or_rewind_dev(dev);
699             force_close_device(dev);
700             bnet_fsend(dir, _("3002 Device %s unmounted.\n"), 
701                dev->print_name());
702          }
703          V(dev->mutex);
704       } else {
705          bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), devname.c_str());
706       }
707    } else {
708       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
709       pm_strcpy(jcr->errmsg, dir->msg);
710       bnet_fsend(dir, _("3907 Error scanning unmount command: %s\n"), jcr->errmsg);
711    }
712    bnet_sig(dir, BNET_EOD);
713    return true;
714 }
715
716 /*
717  * Release command from Director. This rewinds the device and if
718  *   configured does a offline and ensures that Bacula will
719  *   re-read the label of the tape before continuing. This gives
720  *   the operator the chance to change the tape anytime before the
721  *   next job starts.
722  */
723 static bool release_cmd(JCR *jcr)
724 {
725    POOL_MEM devname;
726    BSOCK *dir = jcr->dir_bsock;
727    DEVICE *dev;
728
729    if (sscanf(dir->msg, "release %127s", devname.c_str()) == 1) {
730       dev = find_device(jcr, devname);
731       if (dev) {
732          P(dev->mutex);               /* Use P to avoid indefinite block */
733          if (!dev->is_open()) {
734             Dmsg0(90, "Device already released\n");
735             bnet_fsend(dir, _("3911 Device %s already released.\n"), 
736                dev->print_name());
737
738          } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP ||
739                     dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP) {
740             Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
741                dev->dev_blocked);
742             bnet_fsend(dir, _("3912 Device %s waiting for mount.\n"), 
743                dev->print_name());
744
745          } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
746             bnet_fsend(dir, _("3913 Device %s is busy in acquire.\n"), 
747                dev->print_name());
748
749          } else if (dev->dev_blocked == BST_WRITING_LABEL) {
750             bnet_fsend(dir, _("3914 Device %s is being labeled.\n"), 
751                dev->print_name());
752
753          } else if (dev->is_busy()) {
754             send_dir_busy_message(dir, dev);
755          } else {                     /* device not being used */
756             Dmsg0(90, "Device not in use, unmounting\n");
757             release_volume(jcr->dcr);
758             bnet_fsend(dir, _("3012 Device %s released.\n"), 
759                dev->print_name());
760          }
761          V(dev->mutex);
762       } else {
763          bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), devname.c_str());
764       }
765    } else {
766       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
767       pm_strcpy(jcr->errmsg, dir->msg);
768       bnet_fsend(dir, _("3917 Error scanning release command: %s\n"), jcr->errmsg);
769    }
770    bnet_sig(dir, BNET_EOD);
771    return true;
772 }
773
774
775
776 /*
777  * Autochanger command from Director
778  */
779 static bool autochanger_cmd(JCR *jcr)
780 {
781    POOL_MEM devname;
782    BSOCK *dir = jcr->dir_bsock;
783    DEVICE *dev;
784    DCR *dcr;
785    const char *cmd = NULL;
786    bool ok = false;
787
788    if (sscanf(dir->msg, "autochanger list %127s ", devname.c_str()) == 1) {
789       cmd = "list";
790       ok = true;
791    } else if (sscanf(dir->msg, "autochanger slots %127s ", devname.c_str()) == 1) {
792       cmd = "slots";
793       ok = true;
794    }
795    if (ok) {
796       dev = find_device(jcr, devname);
797       dcr = jcr->dcr;
798       if (dev) {
799          P(dev->mutex);               /* Use P to avoid indefinite block */
800          if (!dev->is_tape()) {
801             bnet_fsend(dir, _("3995 Device %s is not an autochanger.\n"), 
802                dev->print_name());
803          } else if (!dev->is_open()) {
804             autochanger_cmd(dcr, dir, cmd);
805          /* Under certain "safe" conditions, we can steal the lock */
806          } else if (dev->can_steal_lock()) {
807             autochanger_cmd(dcr, dir, cmd);
808          } else if (dev->is_busy()) {
809             send_dir_busy_message(dir, dev);
810          } else {                     /* device not being used */
811             autochanger_cmd(dcr, dir, cmd);
812          }
813          V(dev->mutex);
814       } else {
815          bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), devname.c_str());
816       }
817    } else {  /* error on scanf */
818       pm_strcpy(jcr->errmsg, dir->msg);
819       bnet_fsend(dir, _("3908 Error scanning autocharger list/slots command: %s\n"),
820          jcr->errmsg);
821    }
822    bnet_sig(dir, BNET_EOD);
823    return true;
824 }
825
826 /*
827  * Read and return the Volume label
828  */
829 static bool readlabel_cmd(JCR *jcr)
830 {
831    POOL_MEM devname;
832    BSOCK *dir = jcr->dir_bsock;
833    DEVICE *dev;
834    int Slot;
835
836    if (sscanf(dir->msg, "readlabel %127s Slot=%d", devname.c_str(), &Slot) == 2) {
837       dev = find_device(jcr, devname);
838       if (dev) {
839          P(dev->mutex);               /* Use P to avoid indefinite block */
840          if (!dev->is_open()) {
841             read_volume_label(jcr, dev, Slot);
842             force_close_device(dev);
843          /* Under certain "safe" conditions, we can steal the lock */
844          } else if (dev->can_steal_lock()) {
845             read_volume_label(jcr, dev, Slot);
846          } else if (dev->is_busy()) {
847             send_dir_busy_message(dir, dev);
848          } else {                     /* device not being used */
849             read_volume_label(jcr, dev, Slot);
850          }
851          V(dev->mutex);
852       } else {
853          bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), devname.c_str());
854       }
855    } else {
856       pm_strcpy(jcr->errmsg, dir->msg);
857       bnet_fsend(dir, _("3909 Error scanning readlabel command: %s\n"), jcr->errmsg);
858    }
859    bnet_sig(dir, BNET_EOD);
860    return true;
861 }
862
863 /*
864  * Read the tape label
865  *
866  *  Enter with the mutex set
867  */
868 static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot)
869 {
870    BSOCK *dir = jcr->dir_bsock;
871    bsteal_lock_t hold;
872    DCR *dcr = jcr->dcr;
873
874    dcr->dev = dev;
875    steal_device_lock(dev, &hold, BST_WRITING_LABEL);
876
877    if (!try_autoload_device(jcr, Slot, "")) {
878       goto bail_out;                  /* error */
879    }
880
881    dev->clear_labeled();              /* force read of label */
882    switch (read_dev_volume_label(dcr)) {
883    case VOL_OK:
884       /* DO NOT add quotes around the Volume name. It is scanned in the DIR */
885       bnet_fsend(dir, _("3001 Volume=%s Slot=%d\n"), dev->VolHdr.VolumeName, Slot);
886       Dmsg1(100, "Volume: %s\n", dev->VolHdr.VolumeName);
887       break;
888    default:
889       bnet_fsend(dir, _("3902 Cannot mount Volume on Storage Device %s because:\n%s"),
890                  dev->print_name(), jcr->errmsg);
891       break;
892    }
893
894 bail_out:
895    give_back_device_lock(dev, &hold);
896    return;
897 }
898
899 static bool try_autoload_device(JCR *jcr, int slot, const char *VolName)
900 {
901    DCR *dcr = jcr->dcr;
902    BSOCK *dir = jcr->dir_bsock;
903    DEVICE *dev = dcr->dev;
904
905    bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
906    dcr->VolCatInfo.Slot = slot;
907    dcr->VolCatInfo.InChanger = slot > 0;
908    if (autoload_device(dcr, 0, dir) < 0) {    /* autoload if possible */
909       return false;
910    }
911
912    /* Ensure that the device is open -- autoload_device() closes it */
913    for ( ; !dev->is_open(); ) {
914       if (dev->open(dcr, OPEN_READ_WRITE) < 0) {
915          bnet_fsend(dir, _("3910 Unable to open device %s: ERR=%s\n"),
916             dev->print_name(), dev->strerror());
917          return false;
918       }
919    }
920    return true;
921 }
922
923 static void send_dir_busy_message(BSOCK *dir, DEVICE *dev)
924 {
925    if (dev->can_read()) {
926        bnet_fsend(dir, _("3911 Device %s is busy reading.\n"),
927                    dev->print_name());;
928    } else {
929        bnet_fsend(dir, _("3912 Device %s is busy with %d writer(s).\n"),
930           dev->print_name(), dev->num_writers);
931    }
932 }