]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/dircmd.c
11Apr07
[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             pthread_cond_broadcast(&wait_device_release);
311          }
312          if (jcr->read_dcr && jcr->read_dcr->dev && jcr->read_dcr->dev->waiting_for_mount()) {
313             pthread_cond_broadcast(&jcr->read_dcr->dev->wait_next_vol);
314             pthread_cond_broadcast(&wait_device_release);
315          }
316          Jmsg(jcr, M_INFO, 0, _("Job %s marked to be canceled.\n"), jcr->Job);
317          bnet_fsend(dir, _("3000 Job %s marked to be canceled.\n"), jcr->Job);
318          free_jcr(jcr);
319       }
320    } else {
321       bnet_fsend(dir, _("3903 Error scanning cancel command.\n"));
322    }
323    bnet_sig(dir, BNET_EOD);
324    return 1;
325 }
326
327 /*
328  * Label a Volume
329  *
330  */
331 static bool label_cmd(JCR *jcr)
332 {
333    return do_label(jcr, 0);
334 }
335
336 static bool relabel_cmd(JCR *jcr)
337 {
338    return do_label(jcr, 1);
339 }
340
341 static bool do_label(JCR *jcr, int relabel)
342 {
343    POOLMEM *newname, *oldname, *poolname, *mtype;
344    POOL_MEM dev_name;
345    BSOCK *dir = jcr->dir_bsock;
346    DCR *dcr;
347    DEVICE *dev;
348    bool ok = false;
349    int slot;
350    int drive;
351
352    newname = get_memory(dir->msglen+1);
353    oldname = get_memory(dir->msglen+1);
354    poolname = get_memory(dir->msglen+1);
355    mtype = get_memory(dir->msglen+1);
356    if (relabel) {
357       if (sscanf(dir->msg, "relabel %127s OldName=%127s NewName=%127s PoolName=%127s "
358                  "MediaType=%127s Slot=%d drive=%d",
359                   dev_name.c_str(), oldname, newname, poolname, mtype, 
360                   &slot, &drive) == 7) {
361          ok = true;
362       }
363    } else {
364       *oldname = 0;
365       if (sscanf(dir->msg, "label %127s VolumeName=%127s PoolName=%127s "
366                  "MediaType=%127s Slot=%d drive=%d", 
367           dev_name.c_str(), newname, poolname, mtype, &slot, &drive) == 6) {
368          ok = true;
369       }
370    }
371    if (ok) {
372       unbash_spaces(newname);
373       unbash_spaces(oldname);
374       unbash_spaces(poolname);
375       unbash_spaces(mtype);
376       dcr = find_device(jcr, dev_name, drive);
377       if (dcr) {
378          dev = dcr->dev;
379          dev->dlock();                 /* Use P to avoid indefinite block */
380          if (!dev->is_open()) {
381             Dmsg1(400, "Can %slabel. Device is not open\n", relabel?"re":"");
382             label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
383             dev->close();
384          /* Under certain "safe" conditions, we can steal the lock */
385          } else if (dev->can_steal_lock()) {
386             Dmsg0(400, "Can relabel. can_steal_lock\n");
387             label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
388          } else if (dev->is_busy() || dev->is_blocked()) {
389             send_dir_busy_message(dir, dev);
390          } else {                     /* device not being used */
391             Dmsg0(400, "Can relabel. device not used\n");
392             label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
393          }
394          dev->dunlock();
395          free_dcr(dcr);
396          jcr->dcr = NULL;
397       } else {
398          bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), dev_name.c_str());
399       }
400    } else {
401       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
402       pm_strcpy(jcr->errmsg, dir->msg);
403       bnet_fsend(dir, _("3903 Error scanning label command: %s\n"), jcr->errmsg);
404    }
405    free_memory(oldname);
406    free_memory(newname);
407    free_memory(poolname);
408    free_memory(mtype);
409    bnet_sig(dir, BNET_EOD);
410    return true;
411 }
412
413 /*
414  * Read the tape label and determine if we can safely
415  * label the tape (not a Bacula volume), then label it.
416  *
417  *  Enter with the mutex set
418  */
419 static void label_volume_if_ok(DCR *dcr, char *oldname,
420                                char *newname, char *poolname,
421                                int slot, int relabel)
422 {
423    BSOCK *dir = dcr->jcr->dir_bsock;
424    bsteal_lock_t hold;
425    DEVICE *dev = dcr->dev;
426    int label_status;
427    int mode;
428    const char *volname = (relabel == 1) ? oldname : newname;
429    char ed1[50];
430
431    steal_device_lock(dev, &hold, BST_WRITING_LABEL);
432    Dmsg1(100, "Stole device %s lock, writing label.\n", dev->print_name());
433
434
435    Dmsg0(90, "try_autoload_device - looking for volume_info\n");
436    if (!try_autoload_device(dcr->jcr, slot, volname)) {
437       goto bail_out;                  /* error */
438    }
439
440    /* Ensure that the device is open -- autoload_device() closes it */
441    if (dev->is_tape()) {
442       mode = OPEN_READ_WRITE;
443    } else {
444       mode = CREATE_READ_WRITE;
445    }
446
447    if (relabel) {
448       dev->truncating = true;         /* let open() know we will truncate it */
449    }
450    /* Set old volume name for open if relabeling */
451    bstrncpy(dcr->VolCatInfo.VolCatName, volname, sizeof(dcr->VolCatInfo.VolCatName));
452    if (dev->open(dcr, mode) < 0) {
453       bnet_fsend(dir, _("3910 Unable to open device %s: ERR=%s\n"),
454          dev->print_name(), dev->strerror());
455       goto bail_out;      
456    }
457
458    /* See what we have for a Volume */
459    label_status = read_dev_volume_label(dcr);
460    
461    /* Set new volume name */
462    bstrncpy(dcr->VolCatInfo.VolCatName, newname, sizeof(dcr->VolCatInfo.VolCatName));
463    switch(label_status) {
464    case VOL_NAME_ERROR:
465    case VOL_VERSION_ERROR:
466    case VOL_LABEL_ERROR:
467    case VOL_OK:
468       if (!relabel) {
469          bnet_fsend(dir, _(
470             "3920 Cannot label Volume because it is already labeled: \"%s\"\n"),
471              dev->VolHdr.VolumeName);
472          break;
473       }
474
475       /* Relabel request. If oldname matches, continue */
476       if (strcmp(oldname, dev->VolHdr.VolumeName) != 0) {
477          bnet_fsend(dir, _("3921 Wrong volume mounted.\n"));
478          break;
479       }
480       if (dev->label_type != B_BACULA_LABEL) {
481          bnet_fsend(dir, _("3922 Cannot relabel an ANSI/IBM labeled Volume.\n"));
482          break;
483       }
484       /* Fall through wanted! */
485    case VOL_IO_ERROR:
486    case VOL_NO_LABEL:
487       if (!write_new_volume_label_to_dev(dcr, newname, poolname, 
488            relabel, true /* write dvd now */)) {
489          bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), dev->bstrerror());
490          break;
491       }
492       bstrncpy(dcr->VolumeName, newname, sizeof(dcr->VolumeName));
493       /* The following 3000 OK label. string is scanned in ua_label.c */
494       bnet_fsend(dir, "3000 OK label. VolBytes=%s DVD=%d Volume=\"%s\" Device=%s\n",
495                  edit_uint64(dev->VolCatInfo.VolCatBytes, ed1),
496                  dev->is_dvd()?1:0, newname, dev->print_name());
497       break;
498    case VOL_NO_MEDIA:
499       bnet_fsend(dir, _("3914 Failed to label Volume (no media): ERR=%s\n"), dev->bstrerror());
500       break;
501    default:
502       bnet_fsend(dir, _("3913 Cannot label Volume. "
503 "Unknown status %d from read_volume_label()\n"), label_status);
504       break;
505    }
506
507 bail_out:
508    if (!dev->is_open()) {
509       dev->clear_volhdr();
510    }
511    give_back_device_lock(dev, &hold);
512    return;
513 }
514
515
516 /*
517  * Read the tape label
518  *
519  *  Enter with the mutex set
520  */
521 static bool read_label(DCR *dcr)
522 {
523    int ok;
524    JCR *jcr = dcr->jcr;
525    BSOCK *dir = jcr->dir_bsock;
526    bsteal_lock_t hold;
527    DEVICE *dev = dcr->dev;
528
529    steal_device_lock(dev, &hold, BST_DOING_ACQUIRE);
530
531    dcr->VolumeName[0] = 0;
532    dev->clear_labeled();              /* force read of label */
533    switch (read_dev_volume_label(dcr)) {
534    case VOL_OK:
535       bnet_fsend(dir, _("3001 Mounted Volume: %s\n"), dev->VolHdr.VolumeName);
536       ok = true;
537       break;
538    default:
539       bnet_fsend(dir, _("3902 Cannot mount Volume on Storage Device %s because:\n%s"),
540          dev->print_name(), jcr->errmsg);
541       ok = false;
542       break;
543    }
544    give_back_device_lock(dev, &hold);
545    return ok;
546 }
547
548 /* 
549  * Searches for device by name, and if found, creates a dcr and
550  *  returns it.
551  */
552 static DCR *find_device(JCR *jcr, POOL_MEM &devname, int drive)
553 {
554    DEVRES *device;
555    AUTOCHANGER *changer;
556    bool found = false;
557    DCR *dcr = NULL;
558
559    unbash_spaces(devname);
560    foreach_res(device, R_DEVICE) {
561       /* Find resource, and make sure we were able to open it */
562       if (fnmatch(device->hdr.name, devname.c_str(), 0) == 0) {
563          if (!device->dev) {
564             device->dev = init_dev(jcr, device);
565          }
566          if (!device->dev) {
567             Jmsg(jcr, M_WARNING, 0, _("\n"
568                "     Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
569                  devname.c_str());
570             continue;
571          }
572          Dmsg1(20, "Found device %s\n", device->hdr.name);
573          found = true;
574          break;
575       }
576    }
577    if (!found) {
578       foreach_res(changer, R_AUTOCHANGER) {
579          /* Find resource, and make sure we were able to open it */
580          if (fnmatch(devname.c_str(), changer->hdr.name, 0) == 0) {
581             /* Try each device in this AutoChanger */
582             foreach_alist(device, changer->device) {
583                Dmsg1(100, "Try changer device %s\n", device->hdr.name);
584                if (!device->dev) {
585                   device->dev = init_dev(jcr, device);
586                }
587                if (!device->dev) {
588                   Dmsg1(100, "Device %s could not be opened. Skipped\n", devname.c_str());
589                   Jmsg(jcr, M_WARNING, 0, _("\n"
590                      "     Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
591                        device->hdr.name, devname.c_str());
592                   continue;
593                }
594                if (!device->dev->autoselect) {
595                   Dmsg1(100, "Device %s not autoselect skipped.\n", devname.c_str());
596                   continue;              /* device is not available */
597                }
598                if (drive < 0 || drive == (int)device->dev->drive_index) {
599                   Dmsg1(20, "Found changer device %s\n", device->hdr.name);
600                   found = true;
601                   break;
602                }
603                Dmsg3(100, "Device %s drive wrong: want=%d got=%d skipping\n",
604                   devname.c_str(), drive, (int)device->dev->drive_index);
605             }
606             break;                    /* we found it but could not open a device */
607          }
608       }
609    }
610
611    if (found) {
612       Dmsg1(100, "Found device %s\n", device->hdr.name);
613       dcr = new_dcr(jcr, device->dev);
614       dcr->device = device;
615       jcr->dcr = dcr;
616    }
617    return dcr;
618 }
619
620
621 /*
622  * Mount command from Director
623  */
624 static bool mount_cmd(JCR *jcr)
625 {
626    POOL_MEM devname;
627    BSOCK *dir = jcr->dir_bsock;
628    DEVICE *dev;
629    DCR *dcr;
630    int drive;
631    int slot = 0;
632    bool ok;
633
634    ok = sscanf(dir->msg, "mount %127s drive=%d slot=%d", devname.c_str(), 
635                &drive, &slot) == 3;
636    if (!ok) {
637       ok = sscanf(dir->msg, "mount %127s drive=%d", devname.c_str(), &drive) == 2;
638    }
639    if (ok) {
640       dcr = find_device(jcr, devname, drive);
641       if (dcr) {
642          dev = dcr->dev;
643          dev->dlock();                 /* Use P to avoid indefinite block */
644          Dmsg1(100, "mount cmd blocked=%d\n", dev->blocked());
645          switch (dev->blocked()) {         /* device blocked? */
646          case BST_WAITING_FOR_SYSOP:
647             /* Someone is waiting, wake him */
648             Dmsg0(100, "Waiting for mount. Attempting to wake thread\n");
649             dev->set_blocked(BST_MOUNT);
650             bnet_fsend(dir, "3001 OK mount. Device=%s\n", 
651                dev->print_name());
652             pthread_cond_broadcast(&dev->wait_next_vol);
653             pthread_cond_broadcast(&wait_device_release);
654             break;
655
656          /* In both of these two cases, we (the user) unmounted the Volume */
657          case BST_UNMOUNTED_WAITING_FOR_SYSOP:
658          case BST_UNMOUNTED:
659             if (dev->is_autochanger() && slot > 0) {
660                try_autoload_device(jcr, slot, "");
661             }
662             /* We freed the device, so reopen it and wake any waiting threads */
663             if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
664                bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
665                   dev->bstrerror());
666                if (dev->blocked() == BST_UNMOUNTED) {
667                   /* We blocked the device, so unblock it */
668                   Dmsg0(100, "Unmounted. Unblocking device\n");
669                   unblock_device(dev);
670                }
671                break;
672             }
673             read_dev_volume_label(dcr);
674             if (dev->blocked() == BST_UNMOUNTED) {
675                /* We blocked the device, so unblock it */
676                Dmsg0(100, "Unmounted. Unblocking device\n");
677                read_label(dcr);       /* this should not be necessary */
678                unblock_device(dev);
679             } else {
680                Dmsg0(100, "Unmounted waiting for mount. Attempting to wake thread\n");
681                dev->set_blocked(BST_MOUNT);
682             }
683             if (dev->is_labeled()) {
684                bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
685                   dev->print_name(), dev->VolHdr.VolumeName);
686             } else {
687                bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
688                                  "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
689                           dev->print_name());
690             }
691             pthread_cond_broadcast(&dev->wait_next_vol);
692             pthread_cond_broadcast(&wait_device_release);
693             break;
694
695          case BST_DOING_ACQUIRE:
696             bnet_fsend(dir, _("3001 Device %s is doing acquire.\n"),
697                        dev->print_name());
698             break;
699
700          case BST_WRITING_LABEL:
701             bnet_fsend(dir, _("3903 Device %s is being labeled.\n"), 
702                dev->print_name());
703             break;
704
705          case BST_NOT_BLOCKED:
706             if (dev->is_autochanger() && slot > 0) {
707                try_autoload_device(jcr, slot, "");
708             }
709             if (dev->is_open()) {
710                if (dev->is_labeled()) {
711                   bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
712                      dev->print_name(), dev->VolHdr.VolumeName);
713                } else {
714                   bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
715                                  "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
716                              dev->print_name());
717                }
718             } else if (dev->is_tape()) {
719                if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
720                   bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
721                      dev->bstrerror());
722                   break;
723                }
724                read_label(dcr);
725                if (dev->is_labeled()) {
726                   bnet_fsend(dir, _("3001 Device %s is already mounted with Volume \"%s\"\n"),
727                      dev->print_name(), dev->VolHdr.VolumeName);
728                } else {
729                   bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
730                                     "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
731                              dev->print_name());
732                }
733             } else if (dev->is_dvd()) {
734                if (dev->mount(1)) {
735                   bnet_fsend(dir, _("3002 Device %s is mounted.\n"), 
736                      dev->print_name());
737                } else {
738                   bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
739                } 
740             } else { /* must be file */
741                bnet_fsend(dir, _("3906 File device %s is always mounted.\n"),
742                   dev->print_name());
743             }
744             break;
745
746          default:
747             bnet_fsend(dir, _("3905 Bizarre wait state %d\n"), dev->blocked());
748             break;
749          }
750          dev->dunlock();
751          free_dcr(dcr);
752          jcr->dcr = NULL;
753       } else {
754          bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
755       }
756    } else {
757       pm_strcpy(jcr->errmsg, dir->msg);
758       bnet_fsend(dir, _("3909 Error scanning mount command: %s\n"), jcr->errmsg);
759    }
760    bnet_sig(dir, BNET_EOD);
761    return true;
762 }
763
764 /*
765  * unmount command from Director
766  */
767 static bool unmount_cmd(JCR *jcr)
768 {
769    POOL_MEM devname;
770    BSOCK *dir = jcr->dir_bsock;
771    DEVICE *dev;
772    DCR *dcr;
773    int drive;
774
775    if (sscanf(dir->msg, "unmount %127s drive=%d", devname.c_str(), &drive) == 2) {
776       dcr = find_device(jcr, devname, drive);
777       if (dcr) {
778          dev = dcr->dev;
779          dev->dlock();                 /* Use P to avoid indefinite block */
780          if (!dev->is_open()) {
781             if (!dev->is_busy()) {
782                unload_autochanger(dcr, -1);          
783             }
784             if (dev->is_dvd()) {
785                if (dev->unmount(0)) {
786                   bnet_fsend(dir, _("3002 Device %s unmounted.\n"), 
787                      dev->print_name());
788                } else {
789                   bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
790                } 
791             } else {
792                Dmsg0(90, "Device already unmounted\n");
793                bnet_fsend(dir, _("3901 Device %s is already unmounted.\n"), 
794                   dev->print_name());
795             }
796          } else if (dev->blocked() == BST_WAITING_FOR_SYSOP) {
797             Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
798                dev->blocked());
799             if (!unload_autochanger(dcr, -1)) {
800                /* ***FIXME**** what is this ????  */
801                dev->close();
802             }
803             if (dev->is_dvd() && !dev->unmount(0)) {
804                bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
805             } else {
806                dev->set_blocked(BST_UNMOUNTED_WAITING_FOR_SYSOP);
807                bnet_fsend(dir, _("3001 Device %s unmounted.\n"), 
808                   dev->print_name());
809             }
810
811          } else if (dev->blocked() == BST_DOING_ACQUIRE) {
812             bnet_fsend(dir, _("3902 Device %s is busy in acquire.\n"), 
813                dev->print_name());
814
815          } else if (dev->blocked() == BST_WRITING_LABEL) {
816             bnet_fsend(dir, _("3903 Device %s is being labeled.\n"), 
817                dev->print_name());
818
819          } else if (dev->is_busy()) {
820             send_dir_busy_message(dir, dev);
821          } else {                     /* device not being used */
822             Dmsg0(90, "Device not in use, unmounting\n");
823             /* On FreeBSD, I am having ASSERT() failures in block_device()
824              * and I can only imagine that the thread id that we are
825              * leaving in no_wait_id is being re-used. So here,
826              * we simply do it by hand.  Gross, but a solution.
827              */
828             /*  block_device(dev, BST_UNMOUNTED); replace with 2 lines below */
829             dev->set_blocked(BST_UNMOUNTED);
830             dev->no_wait_id = 0;
831             if (!unload_autochanger(dcr, -1)) {
832                dev->close();
833             }
834             if (dev->is_dvd() && !dev->unmount(0)) {
835                bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
836             } else {
837                bnet_fsend(dir, _("3002 Device %s unmounted.\n"), 
838                   dev->print_name());
839             }
840          }
841          dev->dunlock();
842          free_dcr(dcr);
843          jcr->dcr = NULL;
844       } else {
845          bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
846       }
847    } else {
848       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
849       pm_strcpy(jcr->errmsg, dir->msg);
850       bnet_fsend(dir, _("3907 Error scanning unmount command: %s\n"), jcr->errmsg);
851    }
852    bnet_sig(dir, BNET_EOD);
853    return true;
854 }
855
856 /*
857  * Release command from Director. This rewinds the device and if
858  *   configured does a offline and ensures that Bacula will
859  *   re-read the label of the tape before continuing. This gives
860  *   the operator the chance to change the tape anytime before the
861  *   next job starts.
862  */
863 static bool release_cmd(JCR *jcr)
864 {
865    POOL_MEM devname;
866    BSOCK *dir = jcr->dir_bsock;
867    DEVICE *dev;
868    DCR *dcr;
869    int drive;
870
871    if (sscanf(dir->msg, "release %127s drive=%d", devname.c_str(), &drive) == 2) {
872       dcr = find_device(jcr, devname, drive);
873       if (dcr) {
874          dev = dcr->dev;
875          dev->dlock();                 /* Use P to avoid indefinite block */
876          if (!dev->is_open()) {
877             if (!dev->is_busy()) {
878                unload_autochanger(dcr, -1);
879             }
880             Dmsg0(90, "Device already released\n");
881             bnet_fsend(dir, _("3921 Device %s already released.\n"), 
882                dev->print_name());
883
884          } else if (dev->blocked() == BST_WAITING_FOR_SYSOP) {
885             Dmsg2(90, "%d waiter dev_block=%d.\n", dev->num_waiting,
886                dev->blocked());
887             unload_autochanger(dcr, -1);
888             bnet_fsend(dir, _("3922 Device %s waiting for sysop.\n"), 
889                dev->print_name());
890
891          } else if (dev->blocked() == BST_UNMOUNTED_WAITING_FOR_SYSOP) {
892             Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
893                dev->blocked());
894             bnet_fsend(dir, _("3922 Device %s waiting for mount.\n"), 
895                dev->print_name());
896
897          } else if (dev->blocked() == BST_DOING_ACQUIRE) {
898             bnet_fsend(dir, _("3923 Device %s is busy in acquire.\n"), 
899                dev->print_name());
900
901          } else if (dev->blocked() == BST_WRITING_LABEL) {
902             bnet_fsend(dir, _("3914 Device %s is being labeled.\n"), 
903                dev->print_name());
904
905          } else if (dev->is_busy()) {
906             send_dir_busy_message(dir, dev);
907          } else {                     /* device not being used */
908             Dmsg0(90, "Device not in use, releaseing\n");
909             unload_autochanger(dcr, -1);
910             release_volume(dcr);
911             bnet_fsend(dir, _("3022 Device %s released.\n"), 
912                dev->print_name());
913          }
914          dev->dunlock();
915          free_dcr(dcr);
916          jcr->dcr = NULL;
917       } else {
918          bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
919       }
920    } else {
921       /* NB dir->msg gets clobbered in bnet_fsend, so save command */
922       pm_strcpy(jcr->errmsg, dir->msg);
923       bnet_fsend(dir, _("3927 Error scanning release command: %s\n"), jcr->errmsg);
924    }
925    bnet_sig(dir, BNET_EOD);
926    return true;
927 }
928
929
930 static bool bootstrap_cmd(JCR *jcr)
931 {
932    return get_bootstrap_file(jcr, jcr->dir_bsock);
933 }
934
935 /*
936  * Autochanger command from Director
937  */
938 static bool changer_cmd(JCR *jcr)
939 {
940    POOL_MEM devname;
941    BSOCK *dir = jcr->dir_bsock;
942    DEVICE *dev;
943    DCR *dcr;
944    const char *cmd = NULL;
945    bool ok = false;
946    /*
947     * A safe_cmd may call autochanger script but does not load/unload
948     *    slots so it can be done at the same time that the drive is open.
949     */
950    bool safe_cmd = false;
951
952    if (sscanf(dir->msg, "autochanger list %127s", devname.c_str()) == 1) {
953       cmd = "list";
954       safe_cmd = ok = true;
955    } else if (sscanf(dir->msg, "autochanger slots %127s", devname.c_str()) == 1) {
956       cmd = "slots";
957       safe_cmd = ok = true;
958    } else if (sscanf(dir->msg, "autochanger drives %127s", devname.c_str()) == 1) {
959       cmd = "drives";
960       safe_cmd = ok = true;
961    }
962    if (ok) {
963       dcr = find_device(jcr, devname, -1);
964       if (dcr) {
965          dev = dcr->dev;
966          dev->dlock();                 /* Use P to avoid indefinite block */
967          if (!dev->device->changer_res) {
968             bnet_fsend(dir, _("3995 Device %s is not an autochanger.\n"), 
969                dev->print_name());
970          /* Under certain "safe" conditions, we can steal the lock */
971          } else if (safe_cmd || !dev->is_open() || dev->can_steal_lock()) {
972             autochanger_cmd(dcr, dir, cmd);
973          } else if (dev->is_busy() || dev->is_blocked()) {
974             send_dir_busy_message(dir, dev);
975          } else {                     /* device not being used */
976             autochanger_cmd(dcr, dir, cmd);
977          }
978          dev->dunlock();
979          free_dcr(dcr);
980          jcr->dcr = NULL;
981       } else {
982          bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
983       }
984    } else {  /* error on scanf */
985       pm_strcpy(jcr->errmsg, dir->msg);
986       bnet_fsend(dir, _("3908 Error scanning autocharger drives/list/slots command: %s\n"),
987          jcr->errmsg);
988    }
989    dir->signal(BNET_EOD);
990    return true;
991 }
992
993 /*
994  * Read and return the Volume label
995  */
996 static bool readlabel_cmd(JCR *jcr)
997 {
998    POOL_MEM devname;
999    BSOCK *dir = jcr->dir_bsock;
1000    DEVICE *dev;
1001    DCR *dcr;
1002    int Slot;
1003    int drive;
1004
1005    if (sscanf(dir->msg, "readlabel %127s Slot=%d drive=%d", devname.c_str(), 
1006        &Slot, &drive) == 3) {
1007       dcr = find_device(jcr, devname, drive);
1008       if (dcr) {
1009          dev = dcr->dev;
1010          dev->dlock();                 /* Use P to avoid indefinite block */
1011          if (!dev->is_open()) {
1012             read_volume_label(jcr, dev, Slot);
1013             dev->close();
1014          /* Under certain "safe" conditions, we can steal the lock */
1015          } else if (dev->can_steal_lock()) {
1016             read_volume_label(jcr, dev, Slot);
1017          } else if (dev->is_busy() || dev->is_blocked()) {
1018             send_dir_busy_message(dir, dev);
1019          } else {                     /* device not being used */
1020             read_volume_label(jcr, dev, Slot);
1021          }
1022          dev->dunlock();
1023          free_dcr(dcr);
1024          jcr->dcr = NULL;
1025       } else {
1026          bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
1027       }
1028    } else {
1029       pm_strcpy(jcr->errmsg, dir->msg);
1030       bnet_fsend(dir, _("3909 Error scanning readlabel command: %s\n"), jcr->errmsg);
1031    }
1032    dir->signal(BNET_EOD);
1033    return true;
1034 }
1035
1036
1037 /*
1038  * Read the tape label
1039  *
1040  *  Enter with the mutex set
1041  */
1042 static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot)
1043 {
1044    BSOCK *dir = jcr->dir_bsock;
1045    bsteal_lock_t hold;
1046    DCR *dcr = jcr->dcr;
1047
1048    dcr->dev = dev;
1049    steal_device_lock(dev, &hold, BST_WRITING_LABEL);
1050
1051    if (!try_autoload_device(jcr, Slot, "")) {
1052       goto bail_out;                  /* error */
1053    }
1054
1055    dev->clear_labeled();              /* force read of label */
1056    switch (read_dev_volume_label(dcr)) {
1057    case VOL_OK:
1058       /* DO NOT add quotes around the Volume name. It is scanned in the DIR */
1059       bnet_fsend(dir, _("3001 Volume=%s Slot=%d\n"), dev->VolHdr.VolumeName, Slot);
1060       Dmsg1(100, "Volume: %s\n", dev->VolHdr.VolumeName);
1061       break;
1062    default:
1063       bnet_fsend(dir, _("3902 Cannot mount Volume on Storage Device %s because:\n%s"),
1064                  dev->print_name(), jcr->errmsg);
1065       break;
1066    }
1067
1068 bail_out:
1069    give_back_device_lock(dev, &hold);
1070    return;
1071 }
1072
1073 static bool try_autoload_device(JCR *jcr, int slot, const char *VolName)
1074 {
1075    DCR *dcr = jcr->dcr;
1076    BSOCK *dir = jcr->dir_bsock;
1077
1078    bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
1079    dcr->VolCatInfo.Slot = slot;
1080    dcr->VolCatInfo.InChanger = slot > 0;
1081    if (autoload_device(dcr, 0, dir) < 0) {    /* autoload if possible */
1082       return false;
1083    }
1084    return true;
1085 }
1086
1087 static void send_dir_busy_message(BSOCK *dir, DEVICE *dev)
1088 {
1089    if (dev->is_blocked()) {
1090       switch (dev->blocked()) {
1091       case BST_UNMOUNTED:
1092          bnet_fsend(dir, _("3931 Device %s is BLOCKED. user unmounted.\n"),
1093             dev->print_name());
1094          break;
1095       case BST_UNMOUNTED_WAITING_FOR_SYSOP:
1096          bnet_fsend(dir, _("3932 Device %s is BLOCKED. user unmounted during wait for media/mount.\n"),
1097              dev->print_name());
1098          break;
1099       case BST_WAITING_FOR_SYSOP:
1100          bnet_fsend(dir, _("3933 Device %s is BLOCKED waiting for media.\n"),
1101             dev->print_name());
1102          break;
1103       case BST_DOING_ACQUIRE:
1104          bnet_fsend(dir, _("3934 Device %s is being initialized.\n"),
1105             dev->print_name());
1106          break;
1107       case BST_WRITING_LABEL:
1108          bnet_fsend(dir, _("3935 Device %s is blocked labeling a Volume.\n"),
1109             dev->print_name());
1110          break;
1111       default:
1112          bnet_fsend(dir, _("3935 Device %s is blocked for unknown reason.\n"),
1113             dev->print_name());
1114          break;
1115       }
1116    } else if (dev->can_read()) {
1117        bnet_fsend(dir, _("3936 Device %s is busy reading.\n"),
1118                    dev->print_name());;
1119    } else {
1120        bnet_fsend(dir, _("3937 Device %s is busy with %d writer(s).\n"),
1121           dev->print_name(), dev->num_writers);
1122    }
1123 }