]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/dircmd.c
kes Change error message 'illegal' to 'invalid' -- bug #707
[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-2006 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 struct s_last_job last_job;
47 extern bool init_done;
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 bootstrap_cmd(JCR *jcr);
73 static bool changer_cmd(JCR *sjcr);
74 static bool do_label(JCR *jcr, int relabel);
75 static DCR *find_device(JCR *jcr, POOL_MEM &dev_name, int drive);
76 static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot);
77 static void label_volume_if_ok(DCR *dcr, char *oldname,
78                                char *newname, char *poolname,
79                                int Slot, int relabel);
80 static bool try_autoload_device(JCR *jcr, int slot, const char *VolName);
81 static void send_dir_busy_message(BSOCK *dir, DEVICE *dev);
82
83 struct s_cmds {
84    const char *cmd;
85    bool (*func)(JCR *jcr);
86    int monitoraccess; /* specify if monitors have access to this function */
87 };
88
89 /*
90  * The following are the recognized commands from the Director.
91  */
92 static struct s_cmds cmds[] = {
93    {"JobId=",      job_cmd,         0},     /* start Job */
94    {"autochanger", changer_cmd,     0},
95    {"bootstrap",   bootstrap_cmd,   0},
96    {"cancel",      cancel_cmd,      0},
97    {"label",       label_cmd,       0},     /* label a tape */
98    {"mount",       mount_cmd,       0},
99    {"readlabel",   readlabel_cmd,   0},
100    {"release",     release_cmd,     0},
101    {"relabel",     relabel_cmd,     0},     /* relabel a tape */
102    {"setdebug=",   setdebug_cmd,    0},     /* set debug level */
103    {"status",      status_cmd,      1},
104    {".status",     qstatus_cmd,     1},
105    {"unmount",     unmount_cmd,     0},
106    {"use storage=", use_cmd,        0},
107    {"run",         run_cmd,         0},
108 // {"query",       query_cmd,       0},
109    {NULL,        NULL}                      /* list terminator */
110 };
111
112
113 /*
114  * Connection request. We accept connections either from the
115  *  Director or a Client (File daemon).
116  *
117  * Note, we are running as a seperate thread of the Storage daemon.
118  *  and it is because a Director has made a connection with
119  *  us on the "Message" channel.
120  *
121  * Basic tasks done here:
122  *  - Create a JCR record
123  *  - If it was from the FD, call handle_filed_connection()
124  *  - Authenticate the Director
125  *  - We wait for a command
126  *  - We execute the command
127  *  - We continue or exit depending on the return status
128  */
129 void *handle_connection_request(void *arg)
130 {
131    BSOCK *bs = (BSOCK *)arg;
132    JCR *jcr;
133    int i;
134    bool found, quit;
135    int bnet_stat = 0;
136    char name[MAX_NAME_LENGTH];
137
138    if (bnet_recv(bs) <= 0) {
139       Emsg0(M_ERROR, 0, _("Connection request failed.\n"));
140       bnet_close(bs);
141       return NULL;
142    }
143
144    /*
145     * Do a sanity check on the message received
146     */
147    if (bs->msglen < 25 || bs->msglen > (int)sizeof(name)-25) {
148       Emsg1(M_ERROR, 0, _("Invalid connection. Len=%d\n"), bs->msglen);
149       bnet_close(bs);
150       return NULL;
151    }
152    /*
153     * See if this is a File daemon connection. If so
154     *   call FD handler.
155     */
156    Dmsg1(110, "Conn: %s", bs->msg);
157    if (sscanf(bs->msg, "Hello Start Job %127s", name) == 1) {
158       handle_filed_connection(bs, name);
159       return NULL;
160    }
161
162    /* 
163     * This is a connection from the Director, so setup a JCR 
164     */
165    Dmsg0(110, "Start Dir Job\n");
166    jcr = new_jcr(sizeof(JCR), stored_free_jcr); /* create Job Control Record */
167    jcr->dir_bsock = bs;               /* save Director bsock */
168    jcr->dir_bsock->jcr = jcr;
169    jcr->dcrs = New(alist(10, not_owned_by_alist));
170    /* Initialize FD start condition variable */
171    int errstat = pthread_cond_init(&jcr->job_start_wait, NULL);
172    if (errstat != 0) {
173       Jmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), strerror(errstat));
174       goto bail_out;
175    }
176
177    Dmsg0(1000, "stored in start_job\n");
178
179    /*
180     * Authenticate the Director
181     */
182    if (!authenticate_director(jcr)) {
183       Jmsg(jcr, M_FATAL, 0, _("Unable to authenticate Director\n"));
184       goto bail_out;
185    }
186    Dmsg0(90, "Message channel init completed.\n");
187
188    for (quit=false; !quit;) {
189       /* Read command */
190       if ((bnet_stat = bnet_recv(bs)) <= 0) {
191          break;               /* connection terminated */
192       }
193       Dmsg1(199, "<dird: %s\n", bs->msg);
194       /* Ensure that device initialization is complete */
195       while (!init_done) {
196          bmicrosleep(1, 0);
197       }
198       found = false;
199       for (i=0; cmds[i].cmd; i++) {
200         if (strncmp(cmds[i].cmd, bs->msg, strlen(cmds[i].cmd)) == 0) {
201            if ((!cmds[i].monitoraccess) && (jcr->director->monitor)) {
202               Dmsg1(100, "Command %s illegal.\n", cmds[i].cmd);
203               bnet_fsend(bs, illegal_cmd);
204               bnet_sig(bs, BNET_EOD);
205               break;
206            }
207            Dmsg1(200, "Do command: %s\n", cmds[i].cmd);
208            if (!cmds[i].func(jcr)) { /* do command */
209               quit = true; /* error, get out */
210               Dmsg1(190, "Command %s reqeusts quit\n", cmds[i].cmd);
211            }
212            found = true;             /* indicate command found */
213            break;
214         }
215       }
216       if (!found) {                   /* command not found */
217         bnet_fsend(bs, derrmsg);
218         break;
219       }
220    }
221 bail_out:
222    generate_daemon_event(jcr, "JobEnd");
223    dequeue_messages(jcr);             /* send any queued messages */
224    bnet_sig(bs, BNET_TERMINATE);
225    free_jcr(jcr);
226    return NULL;
227 }
228
229 /*
230  * Set debug level as requested by the Director
231  *
232  */
233 static bool setdebug_cmd(JCR *jcr)
234 {
235    BSOCK *dir = jcr->dir_bsock;
236    int level, trace_flag;
237
238    Dmsg1(10, "setdebug_cmd: %s", dir->msg);
239    if (sscanf(dir->msg, "setdebug=%d trace=%d", &level, &trace_flag) != 2 || level < 0) {
240       bnet_fsend(dir, _("3991 Bad setdebug command: %s\n"), dir->msg);
241       return 0;
242    }
243    debug_level = level;
244    set_trace(trace_flag);
245    return bnet_fsend(dir, OKsetdebug, level);
246 }
247
248
249 /*
250  * Cancel a Job
251  */
252 static bool cancel_cmd(JCR *cjcr)
253 {
254    BSOCK *dir = cjcr->dir_bsock;
255    int oldStatus;
256    char Job[MAX_NAME_LENGTH];
257    JCR *jcr;
258
259    if (sscanf(dir->msg, "cancel Job=%127s", Job) == 1) {
260       if (!(jcr=get_jcr_by_full_name(Job))) {
261          bnet_fsend(dir, _("3904 Job %s not found.\n"), Job);
262       } else {
263          jcr->lock();
264          oldStatus = jcr->JobStatus;
265          set_jcr_job_status(jcr, JS_Canceled);
266          if (!jcr->authenticated && oldStatus == JS_WaitFD) {
267             pthread_cond_signal(&jcr->job_start_wait); /* wake waiting thread */
268          }
269          jcr->unlock();
270          if (jcr->file_bsock) {
271             bnet_sig(jcr->file_bsock, BNET_TERMINATE);
272          }
273          /* If thread waiting on mount, wake him */
274          if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->waiting_for_mount()) {
275             pthread_cond_broadcast(&jcr->dcr->dev->wait_next_vol);
276             pthread_cond_broadcast(&wait_device_release);
277          }
278          if (jcr->read_dcr && jcr->read_dcr->dev && jcr->read_dcr->dev->waiting_for_mount()) {
279             pthread_cond_broadcast(&jcr->read_dcr->dev->wait_next_vol);
280             pthread_cond_broadcast(&wait_device_release);
281          }
282          Jmsg(jcr, M_INFO, 0, _("Job marked to be canceled.\n"));
283          bnet_fsend(dir, _("3000 Job %s marked to be canceled.\n"), jcr->Job);
284          free_jcr(jcr);
285       }
286    } else {
287       bnet_fsend(dir, _("3903 Error scanning cancel command.\n"));
288    }
289    bnet_sig(dir, BNET_EOD);
290    return 1;
291 }
292
293 /*
294  * Label a Volume
295  *
296  */
297 static bool label_cmd(JCR *jcr)
298 {
299    return do_label(jcr, 0);
300 }
301
302 static bool relabel_cmd(JCR *jcr)
303 {
304    return do_label(jcr, 1);
305 }
306
307 static bool do_label(JCR *jcr, int relabel)
308 {
309    POOLMEM *newname, *oldname, *poolname, *mtype;
310    POOL_MEM dev_name;
311    BSOCK *dir = jcr->dir_bsock;
312    DCR *dcr;
313    DEVICE *dev;
314    bool ok = false;
315    int slot;
316    int drive;
317
318    newname = get_memory(dir->msglen+1);
319    oldname = get_memory(dir->msglen+1);
320    poolname = get_memory(dir->msglen+1);
321    mtype = get_memory(dir->msglen+1);
322    if (relabel) {
323       if (sscanf(dir->msg, "relabel %127s OldName=%127s NewName=%127s PoolName=%127s "
324                  "MediaType=%127s Slot=%d drive=%d",
325                   dev_name.c_str(), oldname, newname, poolname, mtype, 
326                   &slot, &drive) == 7) {
327          ok = true;
328       }
329    } else {
330       *oldname = 0;
331       if (sscanf(dir->msg, "label %127s VolumeName=%127s PoolName=%127s "
332                  "MediaType=%127s Slot=%d drive=%d", 
333           dev_name.c_str(), newname, poolname, mtype, &slot, &drive) == 6) {
334          ok = true;
335       }
336    }
337    if (ok) {
338       unbash_spaces(newname);
339       unbash_spaces(oldname);
340       unbash_spaces(poolname);
341       unbash_spaces(mtype);
342       dcr = find_device(jcr, dev_name, drive);
343       if (dcr) {
344          dev = dcr->dev;
345          P(dev->mutex);               /* Use P to avoid indefinite block */
346          if (!dev->is_open()) {
347             Dmsg1(400, "Can %slabel. Device is not open\n", relabel?"re":"");
348             label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
349             dev->close();
350          /* Under certain "safe" conditions, we can steal the lock */
351          } else if (dev->can_steal_lock()) {
352             Dmsg0(400, "Can relabel. can_steal_lock\n");
353             label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
354          } else if (dev->is_busy() || dev->is_blocked()) {
355             send_dir_busy_message(dir, dev);
356          } else {                     /* device not being used */
357             Dmsg0(400, "Can relabel. device not used\n");
358             label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
359          }
360          V(dev->mutex);
361          free_dcr(dcr);
362          jcr->dcr = NULL;
363       } else {
364          bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), dev_name.c_str());
365       }
366    } else {
367       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
368       pm_strcpy(jcr->errmsg, dir->msg);
369       bnet_fsend(dir, _("3903 Error scanning label command: %s\n"), jcr->errmsg);
370    }
371    free_memory(oldname);
372    free_memory(newname);
373    free_memory(poolname);
374    free_memory(mtype);
375    bnet_sig(dir, BNET_EOD);
376    return true;
377 }
378
379 /*
380  * Read the tape label and determine if we can safely
381  * label the tape (not a Bacula volume), then label it.
382  *
383  *  Enter with the mutex set
384  */
385 static void label_volume_if_ok(DCR *dcr, char *oldname,
386                                char *newname, char *poolname,
387                                int slot, int relabel)
388 {
389    BSOCK *dir = dcr->jcr->dir_bsock;
390    bsteal_lock_t hold;
391    DEVICE *dev = dcr->dev;
392    int label_status;
393    int mode;
394    const char *volname = (relabel == 1) ? oldname : newname;
395    char ed1[50];
396
397    steal_device_lock(dev, &hold, BST_WRITING_LABEL);
398    Dmsg1(100, "Stole device %s lock, writing label.\n", dev->print_name());
399
400
401    Dmsg0(90, "try_autoload_device - looking for volume_info\n");
402    if (!try_autoload_device(dcr->jcr, slot, volname)) {
403       goto bail_out;                  /* error */
404    }
405
406    /* Ensure that the device is open -- autoload_device() closes it */
407    if (dev->is_tape()) {
408       mode = OPEN_READ_WRITE;
409    } else {
410       mode = CREATE_READ_WRITE;
411    }
412
413    if (relabel) {
414       dev->truncating = true;         /* let open() know we will truncate it */
415    }
416    /* Set old volume name for open if relabeling */
417    bstrncpy(dcr->VolCatInfo.VolCatName, volname, sizeof(dcr->VolCatInfo.VolCatName));
418    if (dev->open(dcr, mode) < 0) {
419       bnet_fsend(dir, _("3910 Unable to open device %s: ERR=%s\n"),
420          dev->print_name(), dev->strerror());
421       goto bail_out;      
422    }
423
424    /* See what we have for a Volume */
425    label_status = read_dev_volume_label(dcr);
426    
427    /* Set new volume name */
428    bstrncpy(dcr->VolCatInfo.VolCatName, newname, sizeof(dcr->VolCatInfo.VolCatName));
429    switch(label_status) {
430    case VOL_NAME_ERROR:
431    case VOL_VERSION_ERROR:
432    case VOL_LABEL_ERROR:
433    case VOL_OK:
434       if (!relabel) {
435          bnet_fsend(dir, _(
436             "3920 Cannot label Volume because it is already labeled: \"%s\"\n"),
437              dev->VolHdr.VolumeName);
438          break;
439       }
440
441       /* Relabel request. If oldname matches, continue */
442       if (strcmp(oldname, dev->VolHdr.VolumeName) != 0) {
443          bnet_fsend(dir, _("3921 Wrong volume mounted.\n"));
444          break;
445       }
446       if (dev->label_type != B_BACULA_LABEL) {
447          bnet_fsend(dir, _("3922 Cannot relabel an ANSI/IBM labeled Volume.\n"));
448          break;
449       }
450       /* Fall through wanted! */
451    case VOL_IO_ERROR:
452    case VOL_NO_LABEL:
453       if (!write_new_volume_label_to_dev(dcr, newname, poolname, 
454            relabel, true /* write dvd now */)) {
455          bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), dev->bstrerror());
456          break;
457       }
458       bstrncpy(dcr->VolumeName, newname, sizeof(dcr->VolumeName));
459       /* The following 3000 OK label. string is scanned in ua_label.c */
460       bnet_fsend(dir, "3000 OK label. VolBytes=%s DVD=%d Volume=\"%s\" Device=%s\n",
461                  edit_uint64(dev->VolCatInfo.VolCatBytes, ed1),
462                  dev->is_dvd()?1:0, newname, dev->print_name());
463       break;
464    case VOL_NO_MEDIA:
465       bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), dev->bstrerror());
466       break;
467    default:
468       bnet_fsend(dir, _("3913 Cannot label Volume. "
469 "Unknown status %d from read_volume_label()\n"), label_status);
470       break;
471    }
472
473 bail_out:
474    if (!dev->is_open()) {
475       free_volume(dev);
476    }
477    give_back_device_lock(dev, &hold);
478    return;
479 }
480
481
482 /*
483  * Read the tape label
484  *
485  *  Enter with the mutex set
486  */
487 static bool read_label(DCR *dcr)
488 {
489    int ok;
490    JCR *jcr = dcr->jcr;
491    BSOCK *dir = jcr->dir_bsock;
492    bsteal_lock_t hold;
493    DEVICE *dev = dcr->dev;
494
495    steal_device_lock(dev, &hold, BST_DOING_ACQUIRE);
496
497    dcr->VolumeName[0] = 0;
498    dev->clear_labeled();              /* force read of label */
499    switch (read_dev_volume_label(dcr)) {
500    case VOL_OK:
501       bnet_fsend(dir, _("3001 Mounted Volume: %s\n"), dev->VolHdr.VolumeName);
502       ok = true;
503       break;
504    default:
505       bnet_fsend(dir, _("3902 Cannot mount Volume on Storage Device %s because:\n%s"),
506          dev->print_name(), jcr->errmsg);
507       ok = false;
508       break;
509    }
510    give_back_device_lock(dev, &hold);
511    return ok;
512 }
513
514 /* 
515  * Searches for device by name, and if found, creates a dcr and
516  *  returns it.
517  */
518 static DCR *find_device(JCR *jcr, POOL_MEM &devname, int drive)
519 {
520    DEVRES *device;
521    AUTOCHANGER *changer;
522    bool found = false;
523    DCR *dcr = NULL;
524
525    unbash_spaces(devname);
526    foreach_res(device, R_DEVICE) {
527       /* Find resource, and make sure we were able to open it */
528       if (fnmatch(device->hdr.name, devname.c_str(), 0) == 0) {
529          if (!device->dev) {
530             device->dev = init_dev(jcr, device);
531          }
532          if (!device->dev) {
533             Jmsg(jcr, M_WARNING, 0, _("\n"
534                "     Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
535                  devname.c_str());
536             continue;
537          }
538          Dmsg1(20, "Found device %s\n", device->hdr.name);
539          found = true;
540          break;
541       }
542    }
543    if (!found) {
544       foreach_res(changer, R_AUTOCHANGER) {
545          /* Find resource, and make sure we were able to open it */
546          if (fnmatch(devname.c_str(), changer->hdr.name, 0) == 0) {
547             /* Try each device in this AutoChanger */
548             foreach_alist(device, changer->device) {
549                Dmsg1(100, "Try changer device %s\n", device->hdr.name);
550                if (!device->dev) {
551                   device->dev = init_dev(jcr, device);
552                }
553                if (!device->dev) {
554                   Dmsg1(100, "Device %s could not be opened. Skipped\n", devname.c_str());
555                   Jmsg(jcr, M_WARNING, 0, _("\n"
556                      "     Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
557                        device->hdr.name, devname.c_str());
558                   continue;
559                }
560                if (!device->dev->autoselect) {
561                   Dmsg1(100, "Device %s not autoselect skipped.\n", devname.c_str());
562                   continue;              /* device is not available */
563                }
564                if (drive < 0 || drive == (int)device->dev->drive_index) {
565                   Dmsg1(20, "Found changer device %s\n", device->hdr.name);
566                   found = true;
567                   break;
568                }
569                Dmsg3(100, "Device %s drive wrong: want=%d got=%d skipping\n",
570                   devname.c_str(), drive, (int)device->dev->drive_index);
571             }
572             break;                    /* we found it but could not open a device */
573          }
574       }
575    }
576
577    if (found) {
578       Dmsg1(100, "Found device %s\n", device->hdr.name);
579       dcr = new_dcr(jcr, device->dev);
580       dcr->device = device;
581       jcr->dcr = dcr;
582    }
583    return dcr;
584 }
585
586
587 /*
588  * Mount command from Director
589  */
590 static bool mount_cmd(JCR *jcr)
591 {
592    POOL_MEM devname;
593    BSOCK *dir = jcr->dir_bsock;
594    DEVICE *dev;
595    DCR *dcr;
596    int drive;
597    int slot = 0;
598    bool ok;
599
600    ok = sscanf(dir->msg, "mount %127s drive=%d slot=%d", devname.c_str(), 
601                &drive, &slot) == 3;
602    if (!ok) {
603       ok = sscanf(dir->msg, "mount %127s drive=%d", devname.c_str(), &drive) == 2;
604    }
605    if (ok) {
606       dcr = find_device(jcr, devname, drive);
607       if (dcr) {
608          dev = dcr->dev;
609          P(dev->mutex);               /* Use P to avoid indefinite block */
610          Dmsg1(100, "mount cmd blocked=%d\n", dev->dev_blocked);
611          switch (dev->dev_blocked) {         /* device blocked? */
612          case BST_WAITING_FOR_SYSOP:
613             /* Someone is waiting, wake him */
614             Dmsg0(100, "Waiting for mount. Attempting to wake thread\n");
615             dev->dev_blocked = BST_MOUNT;
616             bnet_fsend(dir, "3001 OK mount. Device=%s\n", 
617                dev->print_name());
618             pthread_cond_broadcast(&dev->wait_next_vol);
619             pthread_cond_broadcast(&wait_device_release);
620             break;
621
622          /* In both of these two cases, we (the user) unmounted the Volume */
623          case BST_UNMOUNTED_WAITING_FOR_SYSOP:
624          case BST_UNMOUNTED:
625             if (dev->is_autochanger() && slot > 0) {
626                try_autoload_device(jcr, slot, "");
627             }
628             /* We freed the device, so reopen it and wake any waiting threads */
629             if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
630                bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
631                   dev->bstrerror());
632                if (dev->dev_blocked == BST_UNMOUNTED) {
633                   /* We blocked the device, so unblock it */
634                   Dmsg0(100, "Unmounted. Unblocking device\n");
635                   unblock_device(dev);
636                }
637                break;
638             }
639             read_dev_volume_label(dcr);
640             if (dev->dev_blocked == BST_UNMOUNTED) {
641                /* We blocked the device, so unblock it */
642                Dmsg0(100, "Unmounted. Unblocking device\n");
643                read_label(dcr);       /* this should not be necessary */
644                unblock_device(dev);
645             } else {
646                Dmsg0(100, "Unmounted waiting for mount. Attempting to wake thread\n");
647                dev->dev_blocked = BST_MOUNT;
648             }
649             if (dev->is_labeled()) {
650                bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
651                   dev->print_name(), dev->VolHdr.VolumeName);
652             } else {
653                bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
654                                  "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
655                           dev->print_name());
656             }
657             pthread_cond_broadcast(&dev->wait_next_vol);
658             pthread_cond_broadcast(&wait_device_release);
659             break;
660
661          case BST_DOING_ACQUIRE:
662             bnet_fsend(dir, _("3001 Device %s is doing acquire.\n"),
663                        dev->print_name());
664             break;
665
666          case BST_WRITING_LABEL:
667             bnet_fsend(dir, _("3903 Device %s is being labeled.\n"), 
668                dev->print_name());
669             break;
670
671          case BST_NOT_BLOCKED:
672             if (dev->is_autochanger() && slot > 0) {
673                try_autoload_device(jcr, slot, "");
674             }
675             if (dev->is_open()) {
676                if (dev->is_labeled()) {
677                   bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
678                      dev->print_name(), dev->VolHdr.VolumeName);
679                } else {
680                   bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
681                                  "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
682                              dev->print_name());
683                }
684             } else if (dev->is_tape()) {
685                if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
686                   bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
687                      dev->bstrerror());
688                   break;
689                }
690                read_label(dcr);
691                if (dev->is_labeled()) {
692                   bnet_fsend(dir, _("3001 Device %s is already mounted with Volume \"%s\"\n"),
693                      dev->print_name(), dev->VolHdr.VolumeName);
694                } else {
695                   bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
696                                     "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
697                              dev->print_name());
698                }
699             } else if (dev->is_dvd()) {
700                if (dev->mount(1)) {
701                   bnet_fsend(dir, _("3002 Device %s is mounted.\n"), 
702                      dev->print_name());
703                } else {
704                   bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
705                } 
706             } else { /* must be file */
707                bnet_fsend(dir, _("3906 File device %s is always mounted.\n"),
708                   dev->print_name());
709             }
710             break;
711
712          default:
713             bnet_fsend(dir, _("3905 Bizarre wait state %d\n"), dev->dev_blocked);
714             break;
715          }
716          V(dev->mutex);
717          free_dcr(dcr);
718          jcr->dcr = NULL;
719       } else {
720          bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
721       }
722    } else {
723       pm_strcpy(jcr->errmsg, dir->msg);
724       bnet_fsend(dir, _("3909 Error scanning mount command: %s\n"), jcr->errmsg);
725    }
726    bnet_sig(dir, BNET_EOD);
727    return true;
728 }
729
730 /*
731  * unmount command from Director
732  */
733 static bool unmount_cmd(JCR *jcr)
734 {
735    POOL_MEM devname;
736    BSOCK *dir = jcr->dir_bsock;
737    DEVICE *dev;
738    DCR *dcr;
739    int drive;
740
741    if (sscanf(dir->msg, "unmount %127s drive=%d", devname.c_str(), &drive) == 2) {
742       dcr = find_device(jcr, devname, drive);
743       if (dcr) {
744          dev = dcr->dev;
745          P(dev->mutex);               /* Use P to avoid indefinite block */
746          if (!dev->is_open()) {
747             if (!dev->is_busy()) {
748                unload_autochanger(dcr, -1);          
749             }
750             if (dev->is_dvd()) {
751                if (dev->unmount(0)) {
752                   bnet_fsend(dir, _("3002 Device %s unmounted.\n"), 
753                      dev->print_name());
754                } else {
755                   bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
756                } 
757             } else {
758                Dmsg0(90, "Device already unmounted\n");
759                bnet_fsend(dir, _("3901 Device %s is already unmounted.\n"), 
760                   dev->print_name());
761             }
762          } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP) {
763             Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
764                dev->dev_blocked);
765             if (!unload_autochanger(dcr, -1)) {
766                /* ***FIXME**** what is this ????  */
767                dev->close();
768             }
769             if (dev->is_dvd() && !dev->unmount(0)) {
770                bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
771             } else {
772                dev->dev_blocked = BST_UNMOUNTED_WAITING_FOR_SYSOP;
773                bnet_fsend(dir, _("3001 Device %s unmounted.\n"), 
774                   dev->print_name());
775             }
776
777          } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
778             bnet_fsend(dir, _("3902 Device %s is busy in acquire.\n"), 
779                dev->print_name());
780
781          } else if (dev->dev_blocked == BST_WRITING_LABEL) {
782             bnet_fsend(dir, _("3903 Device %s is being labeled.\n"), 
783                dev->print_name());
784
785          } else if (dev->is_busy()) {
786             send_dir_busy_message(dir, dev);
787          } else {                     /* device not being used */
788             Dmsg0(90, "Device not in use, unmounting\n");
789             /* On FreeBSD, I am having ASSERT() failures in block_device()
790              * and I can only imagine that the thread id that we are
791              * leaving in no_wait_id is being re-used. So here,
792              * we simply do it by hand.  Gross, but a solution.
793              */
794             /*  block_device(dev, BST_UNMOUNTED); replace with 2 lines below */
795             dev->dev_blocked = BST_UNMOUNTED;
796             dev->no_wait_id = 0;
797             if (!unload_autochanger(dcr, -1)) {
798                dev->close();
799             }
800             if (dev->is_dvd() && !dev->unmount(0)) {
801                bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
802             } else {
803                bnet_fsend(dir, _("3002 Device %s unmounted.\n"), 
804                   dev->print_name());
805             }
806          }
807          V(dev->mutex);
808          free_dcr(dcr);
809          jcr->dcr = NULL;
810       } else {
811          bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
812       }
813    } else {
814       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
815       pm_strcpy(jcr->errmsg, dir->msg);
816       bnet_fsend(dir, _("3907 Error scanning unmount command: %s\n"), jcr->errmsg);
817    }
818    bnet_sig(dir, BNET_EOD);
819    return true;
820 }
821
822 /*
823  * Release command from Director. This rewinds the device and if
824  *   configured does a offline and ensures that Bacula will
825  *   re-read the label of the tape before continuing. This gives
826  *   the operator the chance to change the tape anytime before the
827  *   next job starts.
828  */
829 static bool release_cmd(JCR *jcr)
830 {
831    POOL_MEM devname;
832    BSOCK *dir = jcr->dir_bsock;
833    DEVICE *dev;
834    DCR *dcr;
835    int drive;
836
837    if (sscanf(dir->msg, "release %127s drive=%d", devname.c_str(), &drive) == 2) {
838       dcr = find_device(jcr, devname, drive);
839       if (dcr) {
840          dev = dcr->dev;
841          P(dev->mutex);               /* Use P to avoid indefinite block */
842          if (!dev->is_open()) {
843             if (!dev->is_busy()) {
844                unload_autochanger(dcr, -1);
845             }
846             Dmsg0(90, "Device already released\n");
847             bnet_fsend(dir, _("3921 Device %s already released.\n"), 
848                dev->print_name());
849
850          } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP) {
851             Dmsg2(90, "%d waiter dev_block=%d.\n", dev->num_waiting,
852                dev->dev_blocked);
853             unload_autochanger(dcr, -1);
854             bnet_fsend(dir, _("3922 Device %s waiting for sysop.\n"), 
855                dev->print_name());
856
857          } else if (dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP) {
858             Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
859                dev->dev_blocked);
860             bnet_fsend(dir, _("3922 Device %s waiting for mount.\n"), 
861                dev->print_name());
862
863          } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
864             bnet_fsend(dir, _("3923 Device %s is busy in acquire.\n"), 
865                dev->print_name());
866
867          } else if (dev->dev_blocked == BST_WRITING_LABEL) {
868             bnet_fsend(dir, _("3914 Device %s is being labeled.\n"), 
869                dev->print_name());
870
871          } else if (dev->is_busy()) {
872             send_dir_busy_message(dir, dev);
873          } else {                     /* device not being used */
874             Dmsg0(90, "Device not in use, releaseing\n");
875             unload_autochanger(dcr, -1);
876             release_volume(dcr);
877             bnet_fsend(dir, _("3022 Device %s released.\n"), 
878                dev->print_name());
879          }
880          V(dev->mutex);
881          free_dcr(dcr);
882          jcr->dcr = NULL;
883       } else {
884          bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
885       }
886    } else {
887       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
888       pm_strcpy(jcr->errmsg, dir->msg);
889       bnet_fsend(dir, _("3927 Error scanning release command: %s\n"), jcr->errmsg);
890    }
891    bnet_sig(dir, BNET_EOD);
892    return true;
893 }
894
895
896 static bool bootstrap_cmd(JCR *jcr)
897 {
898    return get_bootstrap_file(jcr, jcr->dir_bsock);
899 }
900
901 /*
902  * Autochanger command from Director
903  */
904 static bool changer_cmd(JCR *jcr)
905 {
906    POOL_MEM devname;
907    BSOCK *dir = jcr->dir_bsock;
908    DEVICE *dev;
909    DCR *dcr;
910    const char *cmd = NULL;
911    bool ok = false;
912    /*
913     * A safe_cmd may call autochanger script but does not load/unload
914     *    slots so it can be done at the same time that the drive is open.
915     */
916    bool safe_cmd = false;
917
918    if (sscanf(dir->msg, "autochanger list %127s", devname.c_str()) == 1) {
919       cmd = "list";
920       safe_cmd = ok = true;
921    } else if (sscanf(dir->msg, "autochanger slots %127s", devname.c_str()) == 1) {
922       cmd = "slots";
923       safe_cmd = ok = true;
924    } else if (sscanf(dir->msg, "autochanger drives %127s", devname.c_str()) == 1) {
925       cmd = "drives";
926       safe_cmd = ok = true;
927    }
928    if (ok) {
929       dcr = find_device(jcr, devname, -1);
930       if (dcr) {
931          dev = dcr->dev;
932          P(dev->mutex);               /* Use P to avoid indefinite block */
933          if (!dev->device->changer_res) {
934             bnet_fsend(dir, _("3995 Device %s is not an autochanger.\n"), 
935                dev->print_name());
936          /* Under certain "safe" conditions, we can steal the lock */
937          } else if (safe_cmd || !dev->is_open() || dev->can_steal_lock()) {
938             autochanger_cmd(dcr, dir, cmd);
939          } else if (dev->is_busy() || dev->is_blocked()) {
940             send_dir_busy_message(dir, dev);
941          } else {                     /* device not being used */
942             autochanger_cmd(dcr, dir, cmd);
943          }
944          V(dev->mutex);
945          free_dcr(dcr);
946          jcr->dcr = NULL;
947       } else {
948          bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
949       }
950    } else {  /* error on scanf */
951       pm_strcpy(jcr->errmsg, dir->msg);
952       bnet_fsend(dir, _("3908 Error scanning autocharger drives/list/slots command: %s\n"),
953          jcr->errmsg);
954    }
955    bnet_sig(dir, BNET_EOD);
956    return true;
957 }
958
959 /*
960  * Read and return the Volume label
961  */
962 static bool readlabel_cmd(JCR *jcr)
963 {
964    POOL_MEM devname;
965    BSOCK *dir = jcr->dir_bsock;
966    DEVICE *dev;
967    DCR *dcr;
968    int Slot;
969    int drive;
970
971    if (sscanf(dir->msg, "readlabel %127s Slot=%d drive=%d", devname.c_str(), 
972        &Slot, &drive) == 3) {
973       dcr = find_device(jcr, devname, drive);
974       if (dcr) {
975          dev = dcr->dev;
976          P(dev->mutex);               /* Use P to avoid indefinite block */
977          if (!dev->is_open()) {
978             read_volume_label(jcr, dev, Slot);
979             dev->close();
980          /* Under certain "safe" conditions, we can steal the lock */
981          } else if (dev->can_steal_lock()) {
982             read_volume_label(jcr, dev, Slot);
983          } else if (dev->is_busy() || dev->is_blocked()) {
984             send_dir_busy_message(dir, dev);
985          } else {                     /* device not being used */
986             read_volume_label(jcr, dev, Slot);
987          }
988          V(dev->mutex);
989          free_dcr(dcr);
990          jcr->dcr = NULL;
991       } else {
992          bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
993       }
994    } else {
995       pm_strcpy(jcr->errmsg, dir->msg);
996       bnet_fsend(dir, _("3909 Error scanning readlabel command: %s\n"), jcr->errmsg);
997    }
998    bnet_sig(dir, BNET_EOD);
999    return true;
1000 }
1001
1002
1003 /*
1004  * Read the tape label
1005  *
1006  *  Enter with the mutex set
1007  */
1008 static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot)
1009 {
1010    BSOCK *dir = jcr->dir_bsock;
1011    bsteal_lock_t hold;
1012    DCR *dcr = jcr->dcr;
1013
1014    dcr->dev = dev;
1015    steal_device_lock(dev, &hold, BST_WRITING_LABEL);
1016
1017    if (!try_autoload_device(jcr, Slot, "")) {
1018       goto bail_out;                  /* error */
1019    }
1020
1021    dev->clear_labeled();              /* force read of label */
1022    switch (read_dev_volume_label(dcr)) {
1023    case VOL_OK:
1024       /* DO NOT add quotes around the Volume name. It is scanned in the DIR */
1025       bnet_fsend(dir, _("3001 Volume=%s Slot=%d\n"), dev->VolHdr.VolumeName, Slot);
1026       Dmsg1(100, "Volume: %s\n", dev->VolHdr.VolumeName);
1027       break;
1028    default:
1029       bnet_fsend(dir, _("3902 Cannot mount Volume on Storage Device %s because:\n%s"),
1030                  dev->print_name(), jcr->errmsg);
1031       break;
1032    }
1033
1034 bail_out:
1035    give_back_device_lock(dev, &hold);
1036    return;
1037 }
1038
1039 static bool try_autoload_device(JCR *jcr, int slot, const char *VolName)
1040 {
1041    DCR *dcr = jcr->dcr;
1042    BSOCK *dir = jcr->dir_bsock;
1043
1044    bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
1045    dcr->VolCatInfo.Slot = slot;
1046    dcr->VolCatInfo.InChanger = slot > 0;
1047    if (autoload_device(dcr, 0, dir) < 0) {    /* autoload if possible */
1048       return false;
1049    }
1050    return true;
1051 }
1052
1053 static void send_dir_busy_message(BSOCK *dir, DEVICE *dev)
1054 {
1055    if (dev->is_blocked()) {
1056       switch (dev->dev_blocked) {
1057       case BST_UNMOUNTED:
1058          bnet_fsend(dir, _("3931 Device %s is BLOCKED. user unmounted.\n"),
1059             dev->print_name());
1060          break;
1061       case BST_UNMOUNTED_WAITING_FOR_SYSOP:
1062          bnet_fsend(dir, _("3932 Device %s is BLOCKED. user unmounted during wait for media/mount.\n"),
1063              dev->print_name());
1064          break;
1065       case BST_WAITING_FOR_SYSOP:
1066          bnet_fsend(dir, _("3933 Device %s is BLOCKED waiting for media.\n"),
1067             dev->print_name());
1068          break;
1069       case BST_DOING_ACQUIRE:
1070          bnet_fsend(dir, _("3934 Device %s is being initialized.\n"),
1071             dev->print_name());
1072          break;
1073       case BST_WRITING_LABEL:
1074          bnet_fsend(dir, _("3935 Device %s is blocked labeling a Volume.\n"),
1075             dev->print_name());
1076          break;
1077       default:
1078          bnet_fsend(dir, _("3935 Device %s is blocked for unknown reason.\n"),
1079             dev->print_name());
1080          break;
1081       }
1082    } else if (dev->can_read()) {
1083        bnet_fsend(dir, _("3936 Device %s is busy reading.\n"),
1084                    dev->print_name());;
1085    } else {
1086        bnet_fsend(dir, _("3937 Device %s is busy with %d writer(s).\n"),
1087           dev->print_name(), dev->num_writers);
1088    }
1089 }