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