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