]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/dircmd.c
ecc2b14402b3395426bba18592e7b4593dad9f98
[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          P(dev->mutex);               /* Use P to avoid indefinite block */
330          if (!dev->is_open()) {
331             Dmsg0(400, "Can relabel. Device is not open\n");
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             Dmsg0(400, "Can relabel. can_steal_lock\n");
337             label_volume_if_ok(jcr, dev, oldname, newname, poolname, slot, relabel);
338          } else if (dev->is_busy() || dev->is_blocked()) {
339             send_dir_busy_message(dir, dev);
340          } else {                     /* device not being used */
341             Dmsg0(400, "Can relabel. device not used\n");
342             label_volume_if_ok(jcr, dev, oldname, newname, poolname, slot, relabel);
343          }
344          V(dev->mutex);
345       } else {
346          bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), dev_name.c_str());
347       }
348    } else {
349       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
350       pm_strcpy(jcr->errmsg, dir->msg);
351       bnet_fsend(dir, _("3903 Error scanning label command: %s\n"), jcr->errmsg);
352    }
353    free_memory(oldname);
354    free_memory(newname);
355    free_memory(poolname);
356    free_memory(mtype);
357    bnet_sig(dir, BNET_EOD);
358    return true;
359 }
360
361 /*
362  * Read the tape label and determine if we can safely
363  * label the tape (not a Bacula volume), then label it.
364  *
365  *  Enter with the mutex set
366  */
367 static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *oldname,
368                                char *newname, char *poolname,
369                                int slot, int relabel)
370 {
371    BSOCK *dir = jcr->dir_bsock;
372    bsteal_lock_t hold;
373    DCR *dcr = jcr->dcr;
374    int label_status;
375
376    dcr->dev = dev;
377    steal_device_lock(dev, &hold, BST_WRITING_LABEL);
378    Dmsg1(100, "Stole device %s lock, writing label.\n", dev->print_name());
379
380    /* Note, try_autoload_device() opens the device */
381    if (!try_autoload_device(jcr, slot, newname)) {
382       goto bail_out;                  /* error */
383    }
384
385    /* See what we have for a Volume */
386    label_status = read_dev_volume_label(dcr);
387    
388    switch(label_status) {
389    case VOL_NAME_ERROR:
390    case VOL_VERSION_ERROR:
391    case VOL_LABEL_ERROR:
392    case VOL_OK:
393       if (!relabel) {
394          bnet_fsend(dir, _(
395             "3920 Cannot label Volume because it is already labeled: \"%s\"\n"),
396              dev->VolHdr.VolumeName);
397          break;
398       }
399       /* Relabel request. If oldname matches, continue */
400       if (strcmp(oldname, dev->VolHdr.VolumeName) != 0) {
401          bnet_fsend(dir, _("3921 Wrong volume mounted.\n"));
402          break;
403       }
404       if (dev->label_type != B_BACULA_LABEL) {
405          bnet_fsend(dir, _("3922 Cannot relabel an ANSI/IBM labeled Volume.\n"));
406          break;
407       }
408       free_volume(dev);               /* release old volume name */
409       /* Fall through wanted! */
410    case VOL_IO_ERROR:
411    case VOL_NO_LABEL:
412       if (!write_new_volume_label_to_dev(dcr, newname, poolname)) {
413          bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), strerror_dev(dev));
414          break;
415       }
416       bstrncpy(dcr->VolumeName, newname, sizeof(dcr->VolumeName));
417       /* The following 3000 OK label. string is scanned in ua_label.c */
418       bnet_fsend(dir, "3000 OK label. Volume=%s Device=%s\n",
419          newname, dev->print_name());
420       break;
421    case VOL_NO_MEDIA:
422       bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), strerror_dev(dev));
423       break;
424    default:
425       bnet_fsend(dir, _("3913 Cannot label Volume. "
426 "Unknown status %d from read_volume_label()\n"), label_status);
427       break;
428    }
429
430 bail_out:
431    if (!dev->is_open()) {
432       free_volume(dev);
433    }
434    give_back_device_lock(dev, &hold);
435    return;
436 }
437
438
439 /*
440  * Read the tape label
441  *
442  *  Enter with the mutex set
443  */
444 static bool read_label(DCR *dcr)
445 {
446    int ok;
447    JCR *jcr = dcr->jcr;
448    BSOCK *dir = jcr->dir_bsock;
449    bsteal_lock_t hold;
450    DEVICE *dev = dcr->dev;
451
452    steal_device_lock(dev, &hold, BST_DOING_ACQUIRE);
453
454    dcr->VolumeName[0] = 0;
455    dev->clear_labeled();              /* force read of label */
456    switch (read_dev_volume_label(dcr)) {
457    case VOL_OK:
458       bnet_fsend(dir, _("3001 Mounted Volume: %s\n"), dev->VolHdr.VolumeName);
459       ok = true;
460       break;
461    default:
462       bnet_fsend(dir, _("3902 Cannot mount Volume on Storage Device %s because:\n%s"),
463          dev->print_name(), jcr->errmsg);
464       ok = false;
465       break;
466    }
467    give_back_device_lock(dev, &hold);
468    return ok;
469 }
470
471 static DEVICE *find_device(JCR *jcr, POOL_MEM &devname)
472 {
473    DEVRES *device;
474    AUTOCHANGER *changer;
475    bool found = false;
476
477    unbash_spaces(devname);
478 // LockRes();
479    foreach_res(device, R_DEVICE) {
480       /* Find resource, and make sure we were able to open it */
481       if (fnmatch(device->hdr.name, devname.c_str(), 0) == 0) {
482          if (!device->dev) {
483             device->dev = init_dev(jcr, device);
484          }
485          if (!device->dev) {
486             Jmsg(jcr, M_WARNING, 0, _("\n"
487                "     Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
488                  devname.c_str());
489             continue;
490          }
491          Dmsg1(20, "Found device %s\n", device->hdr.name);
492          found = true;
493          break;
494       }
495    }
496    foreach_res(changer, R_AUTOCHANGER) {
497       /* Find resource, and make sure we were able to open it */
498       if (fnmatch(devname.c_str(), changer->hdr.name, 0) == 0) {
499          /* Try each device in this AutoChanger */
500          foreach_alist(device, changer->device) {
501             Dmsg1(100, "Try changer device %s\n", device->hdr.name);
502             if (!device->dev) {
503                device->dev = init_dev(jcr, device);
504             }
505             if (!device->dev) {
506                Dmsg1(100, "Device %s could not be opened. Skipped\n", devname.c_str());
507                Jmsg(jcr, M_WARNING, 0, _("\n"
508                   "     Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
509                     device->hdr.name, devname.c_str());
510                continue;
511             }
512             if (!device->dev->autoselect) {
513                continue;              /* device is not available */
514             }
515             Dmsg1(20, "Found changer device %s\n", device->hdr.name);
516             found = true;
517             break;
518          }
519          break;                    /* we found it but could not open a device */
520       }
521    }
522
523    if (found) {
524       jcr->dcr = new_dcr(jcr, device->dev);
525 //    UnlockRes();
526       jcr->dcr->device = device;
527       return jcr->dcr->dev;
528    }
529 // UnlockRes();
530    return NULL;
531 }
532
533
534 /*
535  * Mount command from Director
536  */
537 static bool mount_cmd(JCR *jcr)
538 {
539    POOL_MEM devname;
540    BSOCK *dir = jcr->dir_bsock;
541    DEVICE *dev;
542    DCR *dcr;
543
544    if (sscanf(dir->msg, "mount %127s", devname.c_str()) == 1) {
545       dev = find_device(jcr, devname);
546       dcr = jcr->dcr;
547       if (dev) {
548          P(dev->mutex);               /* Use P to avoid indefinite block */
549          switch (dev->dev_blocked) {         /* device blocked? */
550          case BST_WAITING_FOR_SYSOP:
551             /* Someone is waiting, wake him */
552             Dmsg0(100, "Waiting for mount. Attempting to wake thread\n");
553             dev->dev_blocked = BST_MOUNT;
554             bnet_fsend(dir, "3001 OK mount. Device=%s\n", 
555                dev->print_name());
556             pthread_cond_broadcast(&dev->wait_next_vol);
557             pthread_cond_broadcast(&wait_device_release);
558             break;
559
560          /* In both of these two cases, we (the user) unmounted the Volume */
561          case BST_UNMOUNTED_WAITING_FOR_SYSOP:
562          case BST_UNMOUNTED:
563             /* We freed the device, so reopen it and wake any waiting threads */
564             if (dev->open(dcr, OPEN_READ_WRITE) < 0) {
565                bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
566                   strerror_dev(dev));
567                break;
568             }
569             read_dev_volume_label(dcr);
570             if (dev->dev_blocked == BST_UNMOUNTED) {
571                /* We blocked the device, so unblock it */
572                Dmsg0(100, "Unmounted. Unblocking device\n");
573                read_label(dcr);       /* this should not be necessary */
574                unblock_device(dev);
575             } else {
576                Dmsg0(100, "Unmounted waiting for mount. Attempting to wake thread\n");
577                dev->dev_blocked = BST_MOUNT;
578             }
579             if (dev->is_labeled()) {
580                bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
581                   dev->print_name(), dev->VolHdr.VolumeName);
582             } else {
583                bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
584                                  "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
585                           dev->print_name());
586             }
587             pthread_cond_broadcast(&dev->wait_next_vol);
588             pthread_cond_broadcast(&wait_device_release);
589             break;
590
591          case BST_DOING_ACQUIRE:
592             bnet_fsend(dir, _("3001 Device %s is doing acquire.\n"),
593                        dev->print_name());
594             break;
595
596          case BST_WRITING_LABEL:
597             bnet_fsend(dir, _("3903 Device %s is being labeled.\n"), 
598                dev->print_name());
599             break;
600
601          case BST_NOT_BLOCKED:
602             if (dev->is_open()) {
603                if (dev->is_labeled()) {
604                   bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
605                      dev->print_name(), dev->VolHdr.VolumeName);
606                } else {
607                   bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
608                                  "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
609                              dev->print_name());
610                }
611             } else if (dev->is_tape()) {
612                if (dev->open(NULL, OPEN_READ_WRITE) < 0) {
613                   bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
614                      strerror_dev(dev));
615                   break;
616                }
617                read_label(dcr);
618                if (dev->is_labeled()) {
619                   bnet_fsend(dir, _("3001 Device %s is already mounted with Volume \"%s\"\n"),
620                      dev->print_name(), dev->VolHdr.VolumeName);
621                } else {
622                   bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
623                                     "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
624                              dev->print_name());
625                }
626             } else if (dev->is_dvd()) {
627                if (mount_dev(dev, 1)) {
628                   bnet_fsend(dir, _("3002 Device %s is mounted.\n"), 
629                      dev->print_name());
630                } else {
631                   bnet_fsend(dir, "3907 %s", strerror_dev(dev));
632                } 
633             } else { /* must be file */
634                bnet_fsend(dir, _("3906 File device %s is always mounted.\n"),
635                   dev->print_name());
636             }
637             break;
638
639          default:
640             bnet_fsend(dir, _("3905 Bizarre wait state %d\n"), dev->dev_blocked);
641             break;
642          }
643          V(dev->mutex);
644       } else {
645          bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), devname.c_str());
646       }
647    } else {
648       pm_strcpy(jcr->errmsg, dir->msg);
649       bnet_fsend(dir, _("3909 Error scanning mount command: %s\n"), jcr->errmsg);
650    }
651    bnet_sig(dir, BNET_EOD);
652    return true;
653 }
654
655 /*
656  * unmount command from Director
657  */
658 static bool unmount_cmd(JCR *jcr)
659 {
660    POOL_MEM devname;
661    BSOCK *dir = jcr->dir_bsock;
662    DEVICE *dev;
663
664    if (sscanf(dir->msg, "unmount %127s", devname.c_str()) == 1) {
665       dev = find_device(jcr, devname);
666       if (dev) {
667          P(dev->mutex);               /* Use P to avoid indefinite block */
668          if (!dev->is_open()) {
669             Dmsg0(90, "Device already unmounted\n");
670             bnet_fsend(dir, _("3901 Device %s is already unmounted.\n"), 
671                dev->print_name());
672
673          } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP) {
674             Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
675                dev->dev_blocked);
676             offline_or_rewind_dev(dev);
677             force_close_device(dev);
678             dev->dev_blocked = BST_UNMOUNTED_WAITING_FOR_SYSOP;
679             bnet_fsend(dir, _("3001 Device %s unmounted.\n"), 
680                dev->print_name());
681
682          } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
683             bnet_fsend(dir, _("3902 Device %s is busy in acquire.\n"), 
684                dev->print_name());
685
686          } else if (dev->dev_blocked == BST_WRITING_LABEL) {
687             bnet_fsend(dir, _("3903 Device %s is being labeled.\n"), 
688                dev->print_name());
689
690          } else if (dev->is_busy()) {
691             send_dir_busy_message(dir, dev);
692          } else {                     /* device not being used */
693             Dmsg0(90, "Device not in use, unmounting\n");
694             /* On FreeBSD, I am having ASSERT() failures in block_device()
695              * and I can only imagine that the thread id that we are
696              * leaving in no_wait_id is being re-used. So here,
697              * we simply do it by hand.  Gross, but a solution.
698              */
699             /*  block_device(dev, BST_UNMOUNTED); replace with 2 lines below */
700             dev->dev_blocked = BST_UNMOUNTED;
701             dev->no_wait_id = 0;
702             offline_or_rewind_dev(dev);
703             force_close_device(dev);
704             bnet_fsend(dir, _("3002 Device %s unmounted.\n"), 
705                dev->print_name());
706          }
707          V(dev->mutex);
708       } else {
709          bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), devname.c_str());
710       }
711    } else {
712       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
713       pm_strcpy(jcr->errmsg, dir->msg);
714       bnet_fsend(dir, _("3907 Error scanning unmount command: %s\n"), jcr->errmsg);
715    }
716    bnet_sig(dir, BNET_EOD);
717    return true;
718 }
719
720 /*
721  * Release command from Director. This rewinds the device and if
722  *   configured does a offline and ensures that Bacula will
723  *   re-read the label of the tape before continuing. This gives
724  *   the operator the chance to change the tape anytime before the
725  *   next job starts.
726  */
727 static bool release_cmd(JCR *jcr)
728 {
729    POOL_MEM devname;
730    BSOCK *dir = jcr->dir_bsock;
731    DEVICE *dev;
732
733    if (sscanf(dir->msg, "release %127s", devname.c_str()) == 1) {
734       dev = find_device(jcr, devname);
735       if (dev) {
736          P(dev->mutex);               /* Use P to avoid indefinite block */
737          if (!dev->is_open()) {
738             Dmsg0(90, "Device already released\n");
739             bnet_fsend(dir, _("3911 Device %s already released.\n"), 
740                dev->print_name());
741
742          } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP ||
743                     dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP) {
744             Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
745                dev->dev_blocked);
746             bnet_fsend(dir, _("3912 Device %s waiting for mount.\n"), 
747                dev->print_name());
748
749          } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
750             bnet_fsend(dir, _("3913 Device %s is busy in acquire.\n"), 
751                dev->print_name());
752
753          } else if (dev->dev_blocked == BST_WRITING_LABEL) {
754             bnet_fsend(dir, _("3914 Device %s is being labeled.\n"), 
755                dev->print_name());
756
757          } else if (dev->is_busy()) {
758             send_dir_busy_message(dir, dev);
759          } else {                     /* device not being used */
760             Dmsg0(90, "Device not in use, unmounting\n");
761             release_volume(jcr->dcr);
762             bnet_fsend(dir, _("3012 Device %s released.\n"), 
763                dev->print_name());
764          }
765          V(dev->mutex);
766       } else {
767          bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), devname.c_str());
768       }
769    } else {
770       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
771       pm_strcpy(jcr->errmsg, dir->msg);
772       bnet_fsend(dir, _("3917 Error scanning release command: %s\n"), jcr->errmsg);
773    }
774    bnet_sig(dir, BNET_EOD);
775    return true;
776 }
777
778
779
780 /*
781  * Autochanger command from Director
782  */
783 static bool autochanger_cmd(JCR *jcr)
784 {
785    POOL_MEM devname;
786    BSOCK *dir = jcr->dir_bsock;
787    DEVICE *dev;
788    DCR *dcr;
789    const char *cmd = NULL;
790    bool ok = false;
791
792    if (sscanf(dir->msg, "autochanger list %127s ", devname.c_str()) == 1) {
793       cmd = "list";
794       ok = true;
795    } else if (sscanf(dir->msg, "autochanger slots %127s ", devname.c_str()) == 1) {
796       cmd = "slots";
797       ok = true;
798    }
799    if (ok) {
800       dev = find_device(jcr, devname);
801       dcr = jcr->dcr;
802       if (dev) {
803          P(dev->mutex);               /* Use P to avoid indefinite block */
804          if (!dev->is_tape()) {
805             bnet_fsend(dir, _("3995 Device %s is not an autochanger.\n"), 
806                dev->print_name());
807          } else if (!dev->is_open()) {
808             autochanger_cmd(dcr, dir, cmd);
809          /* Under certain "safe" conditions, we can steal the lock */
810          } else if (dev->can_steal_lock()) {
811             autochanger_cmd(dcr, dir, cmd);
812          } else if (dev->is_busy()) {
813             send_dir_busy_message(dir, dev);
814          } else {                     /* device not being used */
815             autochanger_cmd(dcr, dir, cmd);
816          }
817          V(dev->mutex);
818       } else {
819          bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), devname.c_str());
820       }
821    } else {  /* error on scanf */
822       pm_strcpy(jcr->errmsg, dir->msg);
823       bnet_fsend(dir, _("3908 Error scanning autocharger list/slots command: %s\n"),
824          jcr->errmsg);
825    }
826    bnet_sig(dir, BNET_EOD);
827    return true;
828 }
829
830 /*
831  * Read and return the Volume label
832  */
833 static bool readlabel_cmd(JCR *jcr)
834 {
835    POOL_MEM devname;
836    BSOCK *dir = jcr->dir_bsock;
837    DEVICE *dev;
838    int Slot;
839
840    if (sscanf(dir->msg, "readlabel %127s Slot=%d", devname.c_str(), &Slot) == 2) {
841       dev = find_device(jcr, devname);
842       if (dev) {
843          P(dev->mutex);               /* Use P to avoid indefinite block */
844          if (!dev->is_open()) {
845             read_volume_label(jcr, dev, Slot);
846             force_close_device(dev);
847          /* Under certain "safe" conditions, we can steal the lock */
848          } else if (dev->can_steal_lock()) {
849             read_volume_label(jcr, dev, Slot);
850          } else if (dev->is_busy()) {
851             send_dir_busy_message(dir, dev);
852          } else {                     /* device not being used */
853             read_volume_label(jcr, dev, Slot);
854          }
855          V(dev->mutex);
856       } else {
857          bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), devname.c_str());
858       }
859    } else {
860       pm_strcpy(jcr->errmsg, dir->msg);
861       bnet_fsend(dir, _("3909 Error scanning readlabel command: %s\n"), jcr->errmsg);
862    }
863    bnet_sig(dir, BNET_EOD);
864    return true;
865 }
866
867 /*
868  * Read the tape label
869  *
870  *  Enter with the mutex set
871  */
872 static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot)
873 {
874    BSOCK *dir = jcr->dir_bsock;
875    bsteal_lock_t hold;
876    DCR *dcr = jcr->dcr;
877
878    dcr->dev = dev;
879    steal_device_lock(dev, &hold, BST_WRITING_LABEL);
880
881    if (!try_autoload_device(jcr, Slot, "")) {
882       goto bail_out;                  /* error */
883    }
884
885    dev->clear_labeled();              /* force read of label */
886    switch (read_dev_volume_label(dcr)) {
887    case VOL_OK:
888       /* DO NOT add quotes around the Volume name. It is scanned in the DIR */
889       bnet_fsend(dir, _("3001 Volume=%s Slot=%d\n"), dev->VolHdr.VolumeName, Slot);
890       Dmsg1(100, "Volume: %s\n", dev->VolHdr.VolumeName);
891       break;
892    default:
893       bnet_fsend(dir, _("3902 Cannot mount Volume on Storage Device %s because:\n%s"),
894                  dev->print_name(), jcr->errmsg);
895       break;
896    }
897
898 bail_out:
899    give_back_device_lock(dev, &hold);
900    return;
901 }
902
903 static bool try_autoload_device(JCR *jcr, int slot, const char *VolName)
904 {
905    DCR *dcr = jcr->dcr;
906    BSOCK *dir = jcr->dir_bsock;
907    DEVICE *dev = dcr->dev;
908
909    bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
910    dcr->VolCatInfo.Slot = slot;
911    dcr->VolCatInfo.InChanger = slot > 0;
912    if (autoload_device(dcr, 0, dir) < 0) {    /* autoload if possible */
913       return false;
914    }
915
916    /* Ensure that the device is open -- autoload_device() closes it */
917    for ( ; !dev->is_open(); ) {
918       if (dev->open(dcr, OPEN_READ_WRITE) < 0) {
919          bnet_fsend(dir, _("3910 Unable to open device %s: ERR=%s\n"),
920             dev->print_name(), dev->strerror());
921          return false;
922       }
923    }
924    return true;
925 }
926
927 static void send_dir_busy_message(BSOCK *dir, DEVICE *dev)
928 {
929    if (dev->can_read()) {
930        bnet_fsend(dir, _("3911 Device %s is busy reading.\n"),
931                    dev->print_name());;
932    } else {
933        bnet_fsend(dir, _("3912 Device %s is busy with %d writer(s).\n"),
934           dev->print_name(), dev->num_writers);
935    }
936 }