]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/dircmd.c
- Correct a NULL pointer reference in the mount command.
[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 amended 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    foreach_res(device, R_DEVICE) {
479       /* Find resource, and make sure we were able to open it */
480       if (fnmatch(device->hdr.name, devname.c_str(), 0) == 0) {
481          if (!device->dev) {
482             device->dev = init_dev(jcr, device);
483          }
484          if (!device->dev) {
485             Jmsg(jcr, M_WARNING, 0, _("\n"
486                "     Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
487                  devname.c_str());
488             continue;
489          }
490          Dmsg1(20, "Found device %s\n", device->hdr.name);
491          found = true;
492          break;
493       }
494    }
495    foreach_res(changer, R_AUTOCHANGER) {
496       /* Find resource, and make sure we were able to open it */
497       if (fnmatch(devname.c_str(), changer->hdr.name, 0) == 0) {
498          /* Try each device in this AutoChanger */
499          foreach_alist(device, changer->device) {
500             Dmsg1(100, "Try changer device %s\n", device->hdr.name);
501             if (!device->dev) {
502                device->dev = init_dev(jcr, device);
503             }
504             if (!device->dev) {
505                Dmsg1(100, "Device %s could not be opened. Skipped\n", devname.c_str());
506                Jmsg(jcr, M_WARNING, 0, _("\n"
507                   "     Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
508                     device->hdr.name, devname.c_str());
509                continue;
510             }
511             if (!device->dev->autoselect) {
512                continue;              /* device is not available */
513             }
514             Dmsg1(20, "Found changer device %s\n", device->hdr.name);
515             found = true;
516             break;
517          }
518          break;                    /* we found it but could not open a device */
519       }
520    }
521
522    if (found) {
523       jcr->dcr = new_dcr(jcr, device->dev);
524       jcr->dcr->device = device;
525       return jcr->dcr->dev;
526    }
527    return NULL;
528 }
529
530
531 /*
532  * Mount command from Director
533  */
534 static bool mount_cmd(JCR *jcr)
535 {
536    POOL_MEM devname;
537    BSOCK *dir = jcr->dir_bsock;
538    DEVICE *dev;
539    DCR *dcr;
540
541    if (sscanf(dir->msg, "mount %127s", devname.c_str()) == 1) {
542       dev = find_device(jcr, devname);
543       dcr = jcr->dcr;
544       if (dev) {
545          P(dev->mutex);               /* Use P to avoid indefinite block */
546          switch (dev->dev_blocked) {         /* device blocked? */
547          case BST_WAITING_FOR_SYSOP:
548             /* Someone is waiting, wake him */
549             Dmsg0(100, "Waiting for mount. Attempting to wake thread\n");
550             dev->dev_blocked = BST_MOUNT;
551             bnet_fsend(dir, "3001 OK mount. Device=%s\n", 
552                dev->print_name());
553             pthread_cond_broadcast(&dev->wait_next_vol);
554             pthread_cond_broadcast(&wait_device_release);
555             break;
556
557          /* In both of these two cases, we (the user) unmounted the Volume */
558          case BST_UNMOUNTED_WAITING_FOR_SYSOP:
559          case BST_UNMOUNTED:
560             /* We freed the device, so reopen it and wake any waiting threads */
561             if (dev->open(dcr, OPEN_READ_WRITE) < 0) {
562                bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
563                   strerror_dev(dev));
564                break;
565             }
566             read_dev_volume_label(dcr);
567             if (dev->dev_blocked == BST_UNMOUNTED) {
568                /* We blocked the device, so unblock it */
569                Dmsg0(100, "Unmounted. Unblocking device\n");
570                read_label(dcr);       /* this should not be necessary */
571                unblock_device(dev);
572             } else {
573                Dmsg0(100, "Unmounted waiting for mount. Attempting to wake thread\n");
574                dev->dev_blocked = BST_MOUNT;
575             }
576             if (dev->is_labeled()) {
577                bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
578                   dev->print_name(), dev->VolHdr.VolumeName);
579             } else {
580                bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
581                                  "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
582                           dev->print_name());
583             }
584             pthread_cond_broadcast(&dev->wait_next_vol);
585             pthread_cond_broadcast(&wait_device_release);
586             break;
587
588          case BST_DOING_ACQUIRE:
589             bnet_fsend(dir, _("3001 Device %s is doing acquire.\n"),
590                        dev->print_name());
591             break;
592
593          case BST_WRITING_LABEL:
594             bnet_fsend(dir, _("3903 Device %s is being labeled.\n"), 
595                dev->print_name());
596             break;
597
598          case BST_NOT_BLOCKED:
599             if (dev->is_open()) {
600                if (dev->is_labeled()) {
601                   bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
602                      dev->print_name(), dev->VolHdr.VolumeName);
603                } else {
604                   bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
605                                  "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
606                              dev->print_name());
607                }
608             } else if (dev->is_tape()) {
609                if (dev->open(dcr, OPEN_READ_WRITE) < 0) {
610                   bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
611                      strerror_dev(dev));
612                   break;
613                }
614                read_label(dcr);
615                if (dev->is_labeled()) {
616                   bnet_fsend(dir, _("3001 Device %s is already mounted with Volume \"%s\"\n"),
617                      dev->print_name(), dev->VolHdr.VolumeName);
618                } else {
619                   bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
620                                     "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
621                              dev->print_name());
622                }
623             } else if (dev->is_dvd()) {
624                if (mount_dev(dev, 1)) {
625                   bnet_fsend(dir, _("3002 Device %s is mounted.\n"), 
626                      dev->print_name());
627                } else {
628                   bnet_fsend(dir, "3907 %s", strerror_dev(dev));
629                } 
630             } else { /* must be file */
631                bnet_fsend(dir, _("3906 File device %s is always mounted.\n"),
632                   dev->print_name());
633             }
634             break;
635
636          default:
637             bnet_fsend(dir, _("3905 Bizarre wait state %d\n"), dev->dev_blocked);
638             break;
639          }
640          V(dev->mutex);
641       } else {
642          bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), devname.c_str());
643       }
644    } else {
645       pm_strcpy(jcr->errmsg, dir->msg);
646       bnet_fsend(dir, _("3909 Error scanning mount command: %s\n"), jcr->errmsg);
647    }
648    bnet_sig(dir, BNET_EOD);
649    return true;
650 }
651
652 /*
653  * unmount command from Director
654  */
655 static bool unmount_cmd(JCR *jcr)
656 {
657    POOL_MEM devname;
658    BSOCK *dir = jcr->dir_bsock;
659    DEVICE *dev;
660
661    if (sscanf(dir->msg, "unmount %127s", devname.c_str()) == 1) {
662       dev = find_device(jcr, devname);
663       if (dev) {
664          P(dev->mutex);               /* Use P to avoid indefinite block */
665          if (!dev->is_open()) {
666             Dmsg0(90, "Device already unmounted\n");
667             bnet_fsend(dir, _("3901 Device %s is already unmounted.\n"), 
668                dev->print_name());
669
670          } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP) {
671             Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
672                dev->dev_blocked);
673             offline_or_rewind_dev(dev);
674             force_close_device(dev);
675             dev->dev_blocked = BST_UNMOUNTED_WAITING_FOR_SYSOP;
676             bnet_fsend(dir, _("3001 Device %s unmounted.\n"), 
677                dev->print_name());
678
679          } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
680             bnet_fsend(dir, _("3902 Device %s is busy in acquire.\n"), 
681                dev->print_name());
682
683          } else if (dev->dev_blocked == BST_WRITING_LABEL) {
684             bnet_fsend(dir, _("3903 Device %s is being labeled.\n"), 
685                dev->print_name());
686
687          } else if (dev->is_busy()) {
688             send_dir_busy_message(dir, dev);
689          } else {                     /* device not being used */
690             Dmsg0(90, "Device not in use, unmounting\n");
691             /* On FreeBSD, I am having ASSERT() failures in block_device()
692              * and I can only imagine that the thread id that we are
693              * leaving in no_wait_id is being re-used. So here,
694              * we simply do it by hand.  Gross, but a solution.
695              */
696             /*  block_device(dev, BST_UNMOUNTED); replace with 2 lines below */
697             dev->dev_blocked = BST_UNMOUNTED;
698             dev->no_wait_id = 0;
699             offline_or_rewind_dev(dev);
700             force_close_device(dev);
701             bnet_fsend(dir, _("3002 Device %s unmounted.\n"), 
702                dev->print_name());
703          }
704          V(dev->mutex);
705       } else {
706          bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), devname.c_str());
707       }
708    } else {
709       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
710       pm_strcpy(jcr->errmsg, dir->msg);
711       bnet_fsend(dir, _("3907 Error scanning unmount command: %s\n"), jcr->errmsg);
712    }
713    bnet_sig(dir, BNET_EOD);
714    return true;
715 }
716
717 /*
718  * Release command from Director. This rewinds the device and if
719  *   configured does a offline and ensures that Bacula will
720  *   re-read the label of the tape before continuing. This gives
721  *   the operator the chance to change the tape anytime before the
722  *   next job starts.
723  */
724 static bool release_cmd(JCR *jcr)
725 {
726    POOL_MEM devname;
727    BSOCK *dir = jcr->dir_bsock;
728    DEVICE *dev;
729
730    if (sscanf(dir->msg, "release %127s", devname.c_str()) == 1) {
731       dev = find_device(jcr, devname);
732       if (dev) {
733          P(dev->mutex);               /* Use P to avoid indefinite block */
734          if (!dev->is_open()) {
735             Dmsg0(90, "Device already released\n");
736             bnet_fsend(dir, _("3911 Device %s already released.\n"), 
737                dev->print_name());
738
739          } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP ||
740                     dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP) {
741             Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
742                dev->dev_blocked);
743             bnet_fsend(dir, _("3912 Device %s waiting for mount.\n"), 
744                dev->print_name());
745
746          } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
747             bnet_fsend(dir, _("3913 Device %s is busy in acquire.\n"), 
748                dev->print_name());
749
750          } else if (dev->dev_blocked == BST_WRITING_LABEL) {
751             bnet_fsend(dir, _("3914 Device %s is being labeled.\n"), 
752                dev->print_name());
753
754          } else if (dev->is_busy()) {
755             send_dir_busy_message(dir, dev);
756          } else {                     /* device not being used */
757             Dmsg0(90, "Device not in use, unmounting\n");
758             release_volume(jcr->dcr);
759             bnet_fsend(dir, _("3012 Device %s released.\n"), 
760                dev->print_name());
761          }
762          V(dev->mutex);
763       } else {
764          bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), devname.c_str());
765       }
766    } else {
767       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
768       pm_strcpy(jcr->errmsg, dir->msg);
769       bnet_fsend(dir, _("3917 Error scanning release command: %s\n"), jcr->errmsg);
770    }
771    bnet_sig(dir, BNET_EOD);
772    return true;
773 }
774
775
776
777 /*
778  * Autochanger command from Director
779  */
780 static bool autochanger_cmd(JCR *jcr)
781 {
782    POOL_MEM devname;
783    BSOCK *dir = jcr->dir_bsock;
784    DEVICE *dev;
785    DCR *dcr;
786    const char *cmd = NULL;
787    bool ok = false;
788
789    if (sscanf(dir->msg, "autochanger list %127s ", devname.c_str()) == 1) {
790       cmd = "list";
791       ok = true;
792    } else if (sscanf(dir->msg, "autochanger slots %127s ", devname.c_str()) == 1) {
793       cmd = "slots";
794       ok = true;
795    }
796    if (ok) {
797       dev = find_device(jcr, devname);
798       dcr = jcr->dcr;
799       if (dev) {
800          P(dev->mutex);               /* Use P to avoid indefinite block */
801          if (!dev->is_tape()) {
802             bnet_fsend(dir, _("3995 Device %s is not an autochanger.\n"), 
803                dev->print_name());
804          } else if (!dev->is_open()) {
805             autochanger_cmd(dcr, dir, cmd);
806          /* Under certain "safe" conditions, we can steal the lock */
807          } else if (dev->can_steal_lock()) {
808             autochanger_cmd(dcr, dir, cmd);
809          } else if (dev->is_busy() || dev->is_blocked()) {
810             send_dir_busy_message(dir, dev);
811          } else {                     /* device not being used */
812             autochanger_cmd(dcr, dir, cmd);
813          }
814          V(dev->mutex);
815       } else {
816          bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), devname.c_str());
817       }
818    } else {  /* error on scanf */
819       pm_strcpy(jcr->errmsg, dir->msg);
820       bnet_fsend(dir, _("3908 Error scanning autocharger list/slots command: %s\n"),
821          jcr->errmsg);
822    }
823    bnet_sig(dir, BNET_EOD);
824    return true;
825 }
826
827 /*
828  * Read and return the Volume label
829  */
830 static bool readlabel_cmd(JCR *jcr)
831 {
832    POOL_MEM devname;
833    BSOCK *dir = jcr->dir_bsock;
834    DEVICE *dev;
835    int Slot;
836
837    if (sscanf(dir->msg, "readlabel %127s Slot=%d", devname.c_str(), &Slot) == 2) {
838       dev = find_device(jcr, devname);
839       if (dev) {
840          P(dev->mutex);               /* Use P to avoid indefinite block */
841          if (!dev->is_open()) {
842             read_volume_label(jcr, dev, Slot);
843             force_close_device(dev);
844          /* Under certain "safe" conditions, we can steal the lock */
845          } else if (dev->can_steal_lock()) {
846             read_volume_label(jcr, dev, Slot);
847          } else if (dev->is_busy() || dev->is_blocked()) {
848             send_dir_busy_message(dir, dev);
849          } else {                     /* device not being used */
850             read_volume_label(jcr, dev, Slot);
851          }
852          V(dev->mutex);
853       } else {
854          bnet_fsend(dir, _("3999 Device \"%s\" not found\n"), devname.c_str());
855       }
856    } else {
857       pm_strcpy(jcr->errmsg, dir->msg);
858       bnet_fsend(dir, _("3909 Error scanning readlabel command: %s\n"), jcr->errmsg);
859    }
860    bnet_sig(dir, BNET_EOD);
861    return true;
862 }
863
864 /*
865  * Read the tape label
866  *
867  *  Enter with the mutex set
868  */
869 static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot)
870 {
871    BSOCK *dir = jcr->dir_bsock;
872    bsteal_lock_t hold;
873    DCR *dcr = jcr->dcr;
874
875    dcr->dev = dev;
876    steal_device_lock(dev, &hold, BST_WRITING_LABEL);
877
878    if (!try_autoload_device(jcr, Slot, "")) {
879       goto bail_out;                  /* error */
880    }
881
882    dev->clear_labeled();              /* force read of label */
883    switch (read_dev_volume_label(dcr)) {
884    case VOL_OK:
885       /* DO NOT add quotes around the Volume name. It is scanned in the DIR */
886       bnet_fsend(dir, _("3001 Volume=%s Slot=%d\n"), dev->VolHdr.VolumeName, Slot);
887       Dmsg1(100, "Volume: %s\n", dev->VolHdr.VolumeName);
888       break;
889    default:
890       bnet_fsend(dir, _("3902 Cannot mount Volume on Storage Device %s because:\n%s"),
891                  dev->print_name(), jcr->errmsg);
892       break;
893    }
894
895 bail_out:
896    give_back_device_lock(dev, &hold);
897    return;
898 }
899
900 static bool try_autoload_device(JCR *jcr, int slot, const char *VolName)
901 {
902    DCR *dcr = jcr->dcr;
903    BSOCK *dir = jcr->dir_bsock;
904    DEVICE *dev = dcr->dev;
905
906    bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
907    dcr->VolCatInfo.Slot = slot;
908    dcr->VolCatInfo.InChanger = slot > 0;
909    if (autoload_device(dcr, 0, dir) < 0) {    /* autoload if possible */
910       return false;
911    }
912
913    /* Ensure that the device is open -- autoload_device() closes it */
914    for ( ; !dev->is_open(); ) {
915       if (dev->open(dcr, OPEN_READ_WRITE) < 0) {
916          bnet_fsend(dir, _("3910 Unable to open device %s: ERR=%s\n"),
917             dev->print_name(), dev->strerror());
918          return false;
919       }
920    }
921    return true;
922 }
923
924 static void send_dir_busy_message(BSOCK *dir, DEVICE *dev)
925 {
926    if (dev->can_read()) {
927        bnet_fsend(dir, _("3911 Device %s is busy reading.\n"),
928                    dev->print_name());;
929    } else {
930        bnet_fsend(dir, _("3912 Device %s is busy with %d writer(s).\n"),
931           dev->print_name(), dev->num_writers);
932    }
933 }