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