2 * This file handles accepting Director Commands
4 * Most Director commands are handled here, with the
5 * exception of the Job command command and subsequent
6 * subcommands that are handled
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!!!!
15 * File daemon commands are handled in fdcmd.c
17 * Kern Sibbald, May MMI
23 Copyright (C) 2001-2006 Kern Sibbald
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.
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.
40 /* Exported variables */
42 /* Imported variables */
43 extern BSOCK *filed_chan;
44 extern int r_first, r_last;
45 extern struct s_res resources[];
46 extern char my_name[];
47 extern time_t daemon_start_time;
48 extern struct s_last_job last_job;
49 extern bool init_done;
51 /* Static variables */
52 static char derrmsg[] = "3900 Invalid command\n";
53 static char OKsetdebug[] = "3000 OK setdebug=%d\n";
54 static char illegal_cmd[] = "3997 Illegal command for a Director with Monitor directive enabled\n";
56 /* Imported functions */
57 extern void terminate_child();
58 extern bool job_cmd(JCR *jcr);
59 extern bool use_cmd(JCR *jcr);
60 extern bool run_cmd(JCR *jcr);
61 extern bool status_cmd(JCR *sjcr);
62 extern bool qstatus_cmd(JCR *jcr);
63 //extern bool query_cmd(JCR *jcr);
65 /* Forward referenced functions */
66 static bool label_cmd(JCR *jcr);
67 static bool relabel_cmd(JCR *jcr);
68 static bool readlabel_cmd(JCR *jcr);
69 static bool release_cmd(JCR *jcr);
70 static bool setdebug_cmd(JCR *jcr);
71 static bool cancel_cmd(JCR *cjcr);
72 static bool mount_cmd(JCR *jcr);
73 static bool unmount_cmd(JCR *jcr);
74 static bool bootstrap_cmd(JCR *jcr);
75 static bool changer_cmd(JCR *sjcr);
76 static bool do_label(JCR *jcr, int relabel);
77 static DCR *find_device(JCR *jcr, POOL_MEM &dev_name, int drive);
78 static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot);
79 static void label_volume_if_ok(DCR *dcr, char *oldname,
80 char *newname, char *poolname,
81 int Slot, int relabel);
82 static bool try_autoload_device(JCR *jcr, int slot, const char *VolName);
83 static void send_dir_busy_message(BSOCK *dir, DEVICE *dev);
87 bool (*func)(JCR *jcr);
88 int monitoraccess; /* specify if monitors have access to this function */
92 * The following are the recognized commands from the Director.
94 static struct s_cmds cmds[] = {
95 {"JobId=", job_cmd, 0}, /* start Job */
96 {"autochanger", changer_cmd, 0},
97 {"bootstrap", bootstrap_cmd, 0},
98 {"cancel", cancel_cmd, 0},
99 {"label", label_cmd, 0}, /* label a tape */
100 {"mount", mount_cmd, 0},
101 {"readlabel", readlabel_cmd, 0},
102 {"release", release_cmd, 0},
103 {"relabel", relabel_cmd, 0}, /* relabel a tape */
104 {"setdebug=", setdebug_cmd, 0}, /* set debug level */
105 {"status", status_cmd, 1},
106 {".status", qstatus_cmd, 1},
107 {"unmount", unmount_cmd, 0},
108 {"use storage=", use_cmd, 0},
110 // {"query", query_cmd, 0},
111 {NULL, NULL} /* list terminator */
116 * Connection request. We accept connections either from the
117 * Director or a Client (File daemon).
119 * Note, we are running as a seperate thread of the Storage daemon.
120 * and it is because a Director has made a connection with
121 * us on the "Message" channel.
123 * Basic tasks done here:
124 * - Create a JCR record
125 * - If it was from the FD, call handle_filed_connection()
126 * - Authenticate the Director
127 * - We wait for a command
128 * - We execute the command
129 * - We continue or exit depending on the return status
131 void *handle_connection_request(void *arg)
133 BSOCK *bs = (BSOCK *)arg;
138 char name[MAX_NAME_LENGTH];
140 if (bnet_recv(bs) <= 0) {
141 Emsg0(M_ERROR, 0, _("Connection request failed.\n"));
147 * Do a sanity check on the message received
149 if (bs->msglen < 25 || bs->msglen > (int)sizeof(name)-25) {
150 Emsg1(M_ERROR, 0, _("Invalid connection. Len=%d\n"), bs->msglen);
155 * See if this is a File daemon connection. If so
158 Dmsg1(110, "Conn: %s", bs->msg);
159 if (sscanf(bs->msg, "Hello Start Job %127s", name) == 1) {
160 handle_filed_connection(bs, name);
165 * This is a connection from the Director, so setup a JCR
167 Dmsg0(110, "Start Dir Job\n");
168 jcr = new_jcr(sizeof(JCR), stored_free_jcr); /* create Job Control Record */
169 jcr->dir_bsock = bs; /* save Director bsock */
170 jcr->dir_bsock->jcr = jcr;
171 jcr->dcrs = New(alist(10, not_owned_by_alist));
172 /* Initialize FD start condition variable */
173 int errstat = pthread_cond_init(&jcr->job_start_wait, NULL);
175 Jmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), strerror(errstat));
179 Dmsg0(1000, "stored in start_job\n");
182 * Authenticate the Director
184 if (!authenticate_director(jcr)) {
185 Jmsg(jcr, M_FATAL, 0, _("Unable to authenticate Director\n"));
188 Dmsg0(90, "Message channel init completed.\n");
190 for (quit=false; !quit;) {
192 if ((bnet_stat = bnet_recv(bs)) <= 0) {
193 break; /* connection terminated */
195 Dmsg1(199, "<dird: %s\n", bs->msg);
196 /* Ensure that device initialization is complete */
201 for (i=0; cmds[i].cmd; i++) {
202 if (strncmp(cmds[i].cmd, bs->msg, strlen(cmds[i].cmd)) == 0) {
203 if ((!cmds[i].monitoraccess) && (jcr->director->monitor)) {
204 Dmsg1(100, "Command %s illegal.\n", cmds[i].cmd);
205 bnet_fsend(bs, illegal_cmd);
206 bnet_sig(bs, BNET_EOD);
209 Dmsg1(200, "Do command: %s\n", cmds[i].cmd);
210 if (!cmds[i].func(jcr)) { /* do command */
211 quit = true; /* error, get out */
212 Dmsg1(190, "Command %s reqeusts quit\n", cmds[i].cmd);
214 found = true; /* indicate command found */
218 if (!found) { /* command not found */
219 bnet_fsend(bs, derrmsg);
224 generate_daemon_event(jcr, "JobEnd");
225 dequeue_messages(jcr); /* send any queued messages */
226 bnet_sig(bs, BNET_TERMINATE);
232 * Set debug level as requested by the Director
235 static bool setdebug_cmd(JCR *jcr)
237 BSOCK *dir = jcr->dir_bsock;
238 int level, trace_flag;
240 Dmsg1(10, "setdebug_cmd: %s", dir->msg);
241 if (sscanf(dir->msg, "setdebug=%d trace=%d", &level, &trace_flag) != 2 || level < 0) {
242 bnet_fsend(dir, _("3991 Bad setdebug command: %s\n"), dir->msg);
246 set_trace(trace_flag);
247 return bnet_fsend(dir, OKsetdebug, level);
254 static bool cancel_cmd(JCR *cjcr)
256 BSOCK *dir = cjcr->dir_bsock;
258 char Job[MAX_NAME_LENGTH];
261 if (sscanf(dir->msg, "cancel Job=%127s", Job) == 1) {
262 if (!(jcr=get_jcr_by_full_name(Job))) {
263 bnet_fsend(dir, _("3904 Job %s not found.\n"), Job);
266 oldStatus = jcr->JobStatus;
267 set_jcr_job_status(jcr, JS_Canceled);
268 if (!jcr->authenticated && oldStatus == JS_WaitFD) {
269 pthread_cond_signal(&jcr->job_start_wait); /* wake waiting thread */
272 if (jcr->file_bsock) {
273 bnet_sig(jcr->file_bsock, BNET_TERMINATE);
275 /* If thread waiting on mount, wake him */
276 if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->waiting_for_mount()) {
277 pthread_cond_broadcast(&jcr->dcr->dev->wait_next_vol);
278 pthread_cond_broadcast(&wait_device_release);
280 if (jcr->read_dcr && jcr->read_dcr->dev && jcr->read_dcr->dev->waiting_for_mount()) {
281 pthread_cond_broadcast(&jcr->read_dcr->dev->wait_next_vol);
282 pthread_cond_broadcast(&wait_device_release);
284 bnet_fsend(dir, _("3000 Job %s marked to be canceled.\n"), jcr->Job);
288 bnet_fsend(dir, _("3903 Error scanning cancel command.\n"));
290 bnet_sig(dir, BNET_EOD);
298 static bool label_cmd(JCR *jcr)
300 return do_label(jcr, 0);
303 static bool relabel_cmd(JCR *jcr)
305 return do_label(jcr, 1);
308 static bool do_label(JCR *jcr, int relabel)
310 POOLMEM *newname, *oldname, *poolname, *mtype;
312 BSOCK *dir = jcr->dir_bsock;
319 newname = get_memory(dir->msglen+1);
320 oldname = get_memory(dir->msglen+1);
321 poolname = get_memory(dir->msglen+1);
322 mtype = get_memory(dir->msglen+1);
324 if (sscanf(dir->msg, "relabel %127s OldName=%127s NewName=%127s PoolName=%127s "
325 "MediaType=%127s Slot=%d drive=%d",
326 dev_name.c_str(), oldname, newname, poolname, mtype,
327 &slot, &drive) == 7) {
332 if (sscanf(dir->msg, "label %127s VolumeName=%127s PoolName=%127s "
333 "MediaType=%127s Slot=%d drive=%d",
334 dev_name.c_str(), newname, poolname, mtype, &slot, &drive) == 6) {
339 unbash_spaces(newname);
340 unbash_spaces(oldname);
341 unbash_spaces(poolname);
342 unbash_spaces(mtype);
343 dcr = find_device(jcr, dev_name, drive);
346 P(dev->mutex); /* Use P to avoid indefinite block */
347 if (!dev->is_open()) {
348 Dmsg1(400, "Can %slabel. Device is not open\n", relabel?"re":"");
349 label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
351 /* Under certain "safe" conditions, we can steal the lock */
352 } else if (dev->can_steal_lock()) {
353 Dmsg0(400, "Can relabel. can_steal_lock\n");
354 label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
355 } else if (dev->is_busy() || dev->is_blocked()) {
356 send_dir_busy_message(dir, dev);
357 } else { /* device not being used */
358 Dmsg0(400, "Can relabel. device not used\n");
359 label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
365 bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), dev_name.c_str());
368 /* NB dir->msg gets clobbered in bnet_fsend, so save command */
369 pm_strcpy(jcr->errmsg, dir->msg);
370 bnet_fsend(dir, _("3903 Error scanning label command: %s\n"), jcr->errmsg);
372 free_memory(oldname);
373 free_memory(newname);
374 free_memory(poolname);
376 bnet_sig(dir, BNET_EOD);
381 * Read the tape label and determine if we can safely
382 * label the tape (not a Bacula volume), then label it.
384 * Enter with the mutex set
386 static void label_volume_if_ok(DCR *dcr, char *oldname,
387 char *newname, char *poolname,
388 int slot, int relabel)
390 BSOCK *dir = dcr->jcr->dir_bsock;
392 DEVICE *dev = dcr->dev;
396 steal_device_lock(dev, &hold, BST_WRITING_LABEL);
397 Dmsg1(100, "Stole device %s lock, writing label.\n", dev->print_name());
399 Dmsg0(90, "try_autoload_device - looking for volume_info\n");
400 if (relabel && dev->is_dvd()) {
401 dcr->VolCatInfo.VolCatParts=1;
404 if (!try_autoload_device(dcr->jcr, slot, (relabel == 0) ? newname : oldname)) {
405 goto bail_out; /* error */
408 /* Ensure that the device is open -- autoload_device() closes it */
409 if (dev->is_tape()) {
410 mode = OPEN_READ_WRITE;
412 mode = CREATE_READ_WRITE;
414 if (dev->open(dcr, mode) < 0) {
415 bnet_fsend(dir, _("3910 Unable to open device %s: ERR=%s\n"),
416 dev->print_name(), dev->strerror());
420 /* See what we have for a Volume */
421 label_status = read_dev_volume_label(dcr);
423 switch(label_status) {
425 case VOL_VERSION_ERROR:
426 case VOL_LABEL_ERROR:
430 "3920 Cannot label Volume because it is already labeled: \"%s\"\n"),
431 dev->VolHdr.VolumeName);
435 /* Relabel request. If oldname matches, continue */
436 if (strcmp(oldname, dev->VolHdr.VolumeName) != 0) {
437 bnet_fsend(dir, _("3921 Wrong volume mounted.\n"));
440 if (dev->label_type != B_BACULA_LABEL) {
441 bnet_fsend(dir, _("3922 Cannot relabel an ANSI/IBM labeled Volume.\n"));
444 if (relabel && dev->is_dvd()) {
445 /* Change the partition file name */
446 bstrncpy(dcr->VolumeName, newname, sizeof(dcr->VolumeName));
447 if (!dev->truncate(dcr)) {
448 bnet_fsend(dir, _("3912 Failed to truncate previous DVD volume.\n"));
452 free_volume(dev); /* release old volume name */
453 /* Fall through wanted! */
456 if (!write_new_volume_label_to_dev(dcr, newname, poolname, true /* write dvd now */)) {
457 bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), dev->bstrerror());
460 bstrncpy(dcr->VolumeName, newname, sizeof(dcr->VolumeName));
461 /* The following 3000 OK label. string is scanned in ua_label.c */
462 bnet_fsend(dir, "3000 OK label. DVD=%d Volume=\"%s\" Device=\"%s\"\n",
463 dev->is_dvd()?1:0, newname, dev->print_name());
466 bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), dev->bstrerror());
469 bnet_fsend(dir, _("3913 Cannot label Volume. "
470 "Unknown status %d from read_volume_label()\n"), label_status);
475 if (!dev->is_open()) {
478 give_back_device_lock(dev, &hold);
484 * Read the tape label
486 * Enter with the mutex set
488 static bool read_label(DCR *dcr)
492 BSOCK *dir = jcr->dir_bsock;
494 DEVICE *dev = dcr->dev;
496 steal_device_lock(dev, &hold, BST_DOING_ACQUIRE);
498 dcr->VolumeName[0] = 0;
499 dev->clear_labeled(); /* force read of label */
500 switch (read_dev_volume_label(dcr)) {
502 bnet_fsend(dir, _("3001 Mounted Volume: %s\n"), dev->VolHdr.VolumeName);
506 bnet_fsend(dir, _("3902 Cannot mount Volume on Storage Device %s because:\n%s"),
507 dev->print_name(), jcr->errmsg);
511 give_back_device_lock(dev, &hold);
516 * Searches for device by name, and if found, creates a dcr and
519 static DCR *find_device(JCR *jcr, POOL_MEM &devname, int drive)
522 AUTOCHANGER *changer;
526 unbash_spaces(devname);
527 foreach_res(device, R_DEVICE) {
528 /* Find resource, and make sure we were able to open it */
529 if (fnmatch(device->hdr.name, devname.c_str(), 0) == 0) {
531 device->dev = init_dev(jcr, device);
534 Jmsg(jcr, M_WARNING, 0, _("\n"
535 " Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
539 Dmsg1(20, "Found device %s\n", device->hdr.name);
545 foreach_res(changer, R_AUTOCHANGER) {
546 /* Find resource, and make sure we were able to open it */
547 if (fnmatch(devname.c_str(), changer->hdr.name, 0) == 0) {
548 /* Try each device in this AutoChanger */
549 foreach_alist(device, changer->device) {
550 Dmsg1(100, "Try changer device %s\n", device->hdr.name);
552 device->dev = init_dev(jcr, device);
555 Dmsg1(100, "Device %s could not be opened. Skipped\n", devname.c_str());
556 Jmsg(jcr, M_WARNING, 0, _("\n"
557 " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
558 device->hdr.name, devname.c_str());
561 if (!device->dev->autoselect) {
562 Dmsg1(100, "Device %s not autoselect skipped.\n", devname.c_str());
563 continue; /* device is not available */
565 if (drive < 0 || drive == (int)device->dev->drive_index) {
566 Dmsg1(20, "Found changer device %s\n", device->hdr.name);
570 Dmsg3(100, "Device %s drive wrong: want=%d got=%d skipping\n",
571 devname.c_str(), drive, (int)device->dev->drive_index);
573 break; /* we found it but could not open a device */
579 Dmsg1(100, "Found device %s\n", device->hdr.name);
580 dcr = new_dcr(jcr, device->dev);
581 dcr->device = device;
589 * Mount command from Director
591 static bool mount_cmd(JCR *jcr)
594 BSOCK *dir = jcr->dir_bsock;
601 ok = sscanf(dir->msg, "mount %127s drive=%d slot=%d", devname.c_str(),
604 ok = sscanf(dir->msg, "mount %127s drive=%d", devname.c_str(), &drive) == 2;
607 dcr = find_device(jcr, devname, drive);
610 P(dev->mutex); /* Use P to avoid indefinite block */
611 Dmsg1(100, "mount cmd blocked=%d\n", dev->dev_blocked);
612 switch (dev->dev_blocked) { /* device blocked? */
613 case BST_WAITING_FOR_SYSOP:
614 /* Someone is waiting, wake him */
615 Dmsg0(100, "Waiting for mount. Attempting to wake thread\n");
616 dev->dev_blocked = BST_MOUNT;
617 bnet_fsend(dir, "3001 OK mount. Device=%s\n",
619 pthread_cond_broadcast(&dev->wait_next_vol);
620 pthread_cond_broadcast(&wait_device_release);
623 /* In both of these two cases, we (the user) unmounted the Volume */
624 case BST_UNMOUNTED_WAITING_FOR_SYSOP:
626 if (dev->is_autochanger() && slot > 0) {
627 try_autoload_device(jcr, slot, "");
629 /* We freed the device, so reopen it and wake any waiting threads */
630 if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
631 bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
633 if (dev->dev_blocked == BST_UNMOUNTED) {
634 /* We blocked the device, so unblock it */
635 Dmsg0(100, "Unmounted. Unblocking device\n");
640 read_dev_volume_label(dcr);
641 if (dev->dev_blocked == BST_UNMOUNTED) {
642 /* We blocked the device, so unblock it */
643 Dmsg0(100, "Unmounted. Unblocking device\n");
644 read_label(dcr); /* this should not be necessary */
647 Dmsg0(100, "Unmounted waiting for mount. Attempting to wake thread\n");
648 dev->dev_blocked = BST_MOUNT;
650 if (dev->is_labeled()) {
651 bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
652 dev->print_name(), dev->VolHdr.VolumeName);
654 bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
655 "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
658 pthread_cond_broadcast(&dev->wait_next_vol);
659 pthread_cond_broadcast(&wait_device_release);
662 case BST_DOING_ACQUIRE:
663 bnet_fsend(dir, _("3001 Device %s is doing acquire.\n"),
667 case BST_WRITING_LABEL:
668 bnet_fsend(dir, _("3903 Device %s is being labeled.\n"),
672 case BST_NOT_BLOCKED:
673 if (dev->is_autochanger() && slot > 0) {
674 try_autoload_device(jcr, slot, "");
676 if (dev->is_open()) {
677 if (dev->is_labeled()) {
678 bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
679 dev->print_name(), dev->VolHdr.VolumeName);
681 bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
682 "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
685 } else if (dev->is_tape()) {
686 if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
687 bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
692 if (dev->is_labeled()) {
693 bnet_fsend(dir, _("3001 Device %s is already mounted with Volume \"%s\"\n"),
694 dev->print_name(), dev->VolHdr.VolumeName);
696 bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
697 "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
700 } else if (dev->is_dvd()) {
701 if (mount_dvd(dev, 1)) {
702 bnet_fsend(dir, _("3002 Device %s is mounted.\n"),
705 bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
707 } else { /* must be file */
708 bnet_fsend(dir, _("3906 File device %s is always mounted.\n"),
714 bnet_fsend(dir, _("3905 Bizarre wait state %d\n"), dev->dev_blocked);
721 bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
724 pm_strcpy(jcr->errmsg, dir->msg);
725 bnet_fsend(dir, _("3909 Error scanning mount command: %s\n"), jcr->errmsg);
727 bnet_sig(dir, BNET_EOD);
732 * unmount command from Director
734 static bool unmount_cmd(JCR *jcr)
737 BSOCK *dir = jcr->dir_bsock;
742 if (sscanf(dir->msg, "unmount %127s drive=%d", devname.c_str(), &drive) == 2) {
743 dcr = find_device(jcr, devname, drive);
746 P(dev->mutex); /* Use P to avoid indefinite block */
747 if (!dev->is_open()) {
748 if (!dev->is_busy()) {
749 unload_autochanger(jcr->dcr, -1);
752 if (unmount_dvd(dev, 0)) {
753 bnet_fsend(dir, _("3002 Device %s unmounted.\n"),
756 bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
759 Dmsg0(90, "Device already unmounted\n");
760 bnet_fsend(dir, _("3901 Device %s is already unmounted.\n"),
763 } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP) {
764 Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
766 if (!unload_autochanger(jcr->dcr, -1)) {
769 if (dev->is_dvd() && !unmount_dvd(dev, 0)) {
770 bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
772 dev->dev_blocked = BST_UNMOUNTED_WAITING_FOR_SYSOP;
773 bnet_fsend(dir, _("3001 Device %s unmounted.\n"),
777 } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
778 bnet_fsend(dir, _("3902 Device %s is busy in acquire.\n"),
781 } else if (dev->dev_blocked == BST_WRITING_LABEL) {
782 bnet_fsend(dir, _("3903 Device %s is being labeled.\n"),
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.
794 /* block_device(dev, BST_UNMOUNTED); replace with 2 lines below */
795 dev->dev_blocked = BST_UNMOUNTED;
797 if (!unload_autochanger(jcr->dcr, -1)) {
800 if (dev->is_dvd() && !unmount_dvd(dev, 0)) {
801 bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
803 bnet_fsend(dir, _("3002 Device %s unmounted.\n"),
811 bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
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);
818 bnet_sig(dir, BNET_EOD);
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
829 static bool release_cmd(JCR *jcr)
832 BSOCK *dir = jcr->dir_bsock;
837 if (sscanf(dir->msg, "release %127s drive=%d", devname.c_str(), &drive) == 2) {
838 dcr = find_device(jcr, devname, drive);
841 P(dev->mutex); /* Use P to avoid indefinite block */
842 if (!dev->is_open()) {
843 Dmsg0(90, "Device already released\n");
844 bnet_fsend(dir, _("3921 Device %s already released.\n"),
847 } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP ||
848 dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP) {
849 Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
851 bnet_fsend(dir, _("3922 Device %s waiting for mount.\n"),
854 } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
855 bnet_fsend(dir, _("3923 Device %s is busy in acquire.\n"),
858 } else if (dev->dev_blocked == BST_WRITING_LABEL) {
859 bnet_fsend(dir, _("3914 Device %s is being labeled.\n"),
862 } else if (dev->is_busy()) {
863 send_dir_busy_message(dir, dev);
864 } else { /* device not being used */
865 Dmsg0(90, "Device not in use, unmounting\n");
866 release_volume(jcr->dcr);
867 bnet_fsend(dir, _("3022 Device %s released.\n"),
874 bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
877 /* NB dir->msg gets clobbered in bnet_fsend, so save command */
878 pm_strcpy(jcr->errmsg, dir->msg);
879 bnet_fsend(dir, _("3927 Error scanning release command: %s\n"), jcr->errmsg);
881 bnet_sig(dir, BNET_EOD);
886 static bool bootstrap_cmd(JCR *jcr)
888 return get_bootstrap_file(jcr, jcr->dir_bsock);
892 * Autochanger command from Director
894 static bool changer_cmd(JCR *jcr)
897 BSOCK *dir = jcr->dir_bsock;
900 const char *cmd = NULL;
904 if (sscanf(dir->msg, "autochanger list %127s", devname.c_str()) == 1) {
907 } else if (sscanf(dir->msg, "autochanger slots %127s", devname.c_str()) == 1) {
910 } else if (sscanf(dir->msg, "autochanger drives %127s", devname.c_str()) == 1) {
915 dcr = find_device(jcr, devname, -1);
918 P(dev->mutex); /* Use P to avoid indefinite block */
919 if (!dev->device->changer_res) {
920 bnet_fsend(dir, _("3995 Device %s is not an autochanger.\n"),
922 /* Under certain "safe" conditions, we can steal the lock */
923 } else if (dolist || !dev->is_open() || dev->can_steal_lock()) {
924 autochanger_cmd(dcr, dir, cmd);
925 } else if (dev->is_busy() || dev->is_blocked()) {
926 send_dir_busy_message(dir, dev);
927 } else { /* device not being used */
928 autochanger_cmd(dcr, dir, cmd);
934 bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
936 } else { /* error on scanf */
937 pm_strcpy(jcr->errmsg, dir->msg);
938 bnet_fsend(dir, _("3908 Error scanning autocharger drives/list/slots command: %s\n"),
941 bnet_sig(dir, BNET_EOD);
946 * Read and return the Volume label
948 static bool readlabel_cmd(JCR *jcr)
951 BSOCK *dir = jcr->dir_bsock;
957 if (sscanf(dir->msg, "readlabel %127s Slot=%d drive=%d", devname.c_str(),
958 &Slot, &drive) == 3) {
959 dcr = find_device(jcr, devname, drive);
962 P(dev->mutex); /* Use P to avoid indefinite block */
963 if (!dev->is_open()) {
964 read_volume_label(jcr, dev, Slot);
966 /* Under certain "safe" conditions, we can steal the lock */
967 } else if (dev->can_steal_lock()) {
968 read_volume_label(jcr, dev, Slot);
969 } else if (dev->is_busy() || dev->is_blocked()) {
970 send_dir_busy_message(dir, dev);
971 } else { /* device not being used */
972 read_volume_label(jcr, dev, Slot);
978 bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
981 pm_strcpy(jcr->errmsg, dir->msg);
982 bnet_fsend(dir, _("3909 Error scanning readlabel command: %s\n"), jcr->errmsg);
984 bnet_sig(dir, BNET_EOD);
990 * Read the tape label
992 * Enter with the mutex set
994 static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot)
996 BSOCK *dir = jcr->dir_bsock;
1001 steal_device_lock(dev, &hold, BST_WRITING_LABEL);
1003 if (!try_autoload_device(jcr, Slot, "")) {
1004 goto bail_out; /* error */
1007 dev->clear_labeled(); /* force read of label */
1008 switch (read_dev_volume_label(dcr)) {
1010 /* DO NOT add quotes around the Volume name. It is scanned in the DIR */
1011 bnet_fsend(dir, _("3001 Volume=%s Slot=%d\n"), dev->VolHdr.VolumeName, Slot);
1012 Dmsg1(100, "Volume: %s\n", dev->VolHdr.VolumeName);
1015 bnet_fsend(dir, _("3902 Cannot mount Volume on Storage Device %s because:\n%s"),
1016 dev->print_name(), jcr->errmsg);
1021 give_back_device_lock(dev, &hold);
1025 static bool try_autoload_device(JCR *jcr, int slot, const char *VolName)
1027 DCR *dcr = jcr->dcr;
1028 BSOCK *dir = jcr->dir_bsock;
1030 bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
1031 dcr->VolCatInfo.Slot = slot;
1032 dcr->VolCatInfo.InChanger = slot > 0;
1033 if (autoload_device(dcr, 0, dir) < 0) { /* autoload if possible */
1039 static void send_dir_busy_message(BSOCK *dir, DEVICE *dev)
1041 if (dev->is_blocked()) {
1042 switch (dev->dev_blocked) {
1044 bnet_fsend(dir, _("3931 Device %s is BLOCKED. user unmounted.\n"),
1047 case BST_UNMOUNTED_WAITING_FOR_SYSOP:
1048 bnet_fsend(dir, _("3932 Device %s is BLOCKED. user unmounted during wait for media/mount.\n"),
1051 case BST_WAITING_FOR_SYSOP:
1052 bnet_fsend(dir, _("3933 Device %s is BLOCKED waiting for media.\n"),
1055 case BST_DOING_ACQUIRE:
1056 bnet_fsend(dir, _("3934 Device %s is being initialized.\n"),
1059 case BST_WRITING_LABEL:
1060 bnet_fsend(dir, _("3935 Device %s is blocked labeling a Volume.\n"),
1064 bnet_fsend(dir, _("3935 Device %s is blocked for unknown reason.\n"),
1068 } else if (dev->can_read()) {
1069 bnet_fsend(dir, _("3936 Device %s is busy reading.\n"),
1070 dev->print_name());;
1072 bnet_fsend(dir, _("3937 Device %s is busy with %d writer(s).\n"),
1073 dev->print_name(), dev->num_writers);