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-2005 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 changer_cmd(JCR *sjcr);
75 static bool do_label(JCR *jcr, int relabel);
76 static DCR *find_device(JCR *jcr, POOL_MEM &dev_name, int drive);
77 static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot);
78 static void label_volume_if_ok(DCR *dcr, char *oldname,
79 char *newname, char *poolname,
80 int Slot, int relabel);
81 static bool try_autoload_device(JCR *jcr, int slot, const char *VolName);
82 static void send_dir_busy_message(BSOCK *dir, DEVICE *dev);
86 bool (*func)(JCR *jcr);
87 int monitoraccess; /* specify if monitors have access to this function */
91 * The following are the recognized commands from the Director.
93 static struct s_cmds cmds[] = {
94 {"JobId=", job_cmd, 0}, /* start Job */
95 {"autochanger", changer_cmd, 0},
96 {"bootstrap", bootstrap_cmd, 0},
97 {"cancel", cancel_cmd, 0},
98 {"label", label_cmd, 0}, /* label a tape */
99 {"mount", mount_cmd, 0},
100 {"readlabel", readlabel_cmd, 0},
101 {"release", release_cmd, 0},
102 {"relabel", relabel_cmd, 0}, /* relabel a tape */
103 {"setdebug=", setdebug_cmd, 0}, /* set debug level */
104 {"status", status_cmd, 1},
105 {".status", qstatus_cmd, 1},
106 {"unmount", unmount_cmd, 0},
107 {"use storage=", use_cmd, 0},
109 // {"query", query_cmd, 0},
110 {NULL, NULL} /* list terminator */
115 * Connection request. We accept connections either from the
116 * Director or a Client (File daemon).
118 * Note, we are running as a seperate thread of the Storage daemon.
119 * and it is because a Director has made a connection with
120 * us on the "Message" channel.
122 * Basic tasks done here:
123 * - Create a JCR record
124 * - If it was from the FD, call handle_filed_connection()
125 * - Authenticate the Director
126 * - We wait for a command
127 * - We execute the command
128 * - We continue or exit depending on the return status
130 void *handle_connection_request(void *arg)
132 BSOCK *bs = (BSOCK *)arg;
137 char name[MAX_NAME_LENGTH];
139 if (bnet_recv(bs) <= 0) {
140 Emsg0(M_ERROR, 0, _("Connection request failed.\n"));
146 * Do a sanity check on the message received
148 if (bs->msglen < 25 || bs->msglen > (int)sizeof(name)-25) {
149 Emsg1(M_ERROR, 0, _("Invalid connection. Len=%d\n"), bs->msglen);
154 * See if this is a File daemon connection. If so
157 Dmsg1(110, "Conn: %s", bs->msg);
158 if (sscanf(bs->msg, "Hello Start Job %127s", name) == 1) {
159 handle_filed_connection(bs, name);
164 * This is a connection from the Director, so setup a JCR
166 Dmsg0(110, "Start Dir Job\n");
167 jcr = new_jcr(sizeof(JCR), stored_free_jcr); /* create Job Control Record */
168 jcr->dir_bsock = bs; /* save Director bsock */
169 jcr->dir_bsock->jcr = jcr;
170 jcr->dcrs = New(alist(10, not_owned_by_alist));
171 /* Initialize FD start condition variable */
172 int errstat = pthread_cond_init(&jcr->job_start_wait, NULL);
174 Jmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), strerror(errstat));
178 Dmsg0(1000, "stored in start_job\n");
181 * Authenticate the Director
183 if (!authenticate_director(jcr)) {
184 Jmsg(jcr, M_FATAL, 0, _("Unable to authenticate Director\n"));
187 Dmsg0(90, "Message channel init completed.\n");
189 for (quit=false; !quit;) {
191 if ((bnet_stat = bnet_recv(bs)) <= 0) {
192 break; /* connection terminated */
194 Dmsg1(199, "<dird: %s\n", bs->msg);
195 /* Ensure that device initialization is complete */
200 for (i=0; cmds[i].cmd; i++) {
201 if (strncmp(cmds[i].cmd, bs->msg, strlen(cmds[i].cmd)) == 0) {
202 if ((!cmds[i].monitoraccess) && (jcr->director->monitor)) {
203 Dmsg1(100, "Command %s illegal.\n", cmds[i].cmd);
204 bnet_fsend(bs, illegal_cmd);
205 bnet_sig(bs, BNET_EOD);
208 Dmsg1(200, "Do command: %s\n", cmds[i].cmd);
209 if (!cmds[i].func(jcr)) { /* do command */
210 quit = true; /* error, get out */
211 Dmsg1(190, "Command %s requsts quit\n", cmds[i].cmd);
213 found = true; /* indicate command found */
217 if (!found) { /* command not found */
218 bnet_fsend(bs, derrmsg);
223 generate_daemon_event(jcr, "JobEnd");
224 dequeue_messages(jcr); /* send any queued messages */
225 bnet_sig(bs, BNET_TERMINATE);
231 * Set debug level as requested by the Director
234 static bool setdebug_cmd(JCR *jcr)
236 BSOCK *dir = jcr->dir_bsock;
237 int level, trace_flag;
239 Dmsg1(10, "setdebug_cmd: %s", dir->msg);
240 if (sscanf(dir->msg, "setdebug=%d trace=%d", &level, &trace_flag) != 2 || level < 0) {
241 bnet_fsend(dir, _("3991 Bad setdebug command: %s\n"), dir->msg);
245 set_trace(trace_flag);
246 return bnet_fsend(dir, OKsetdebug, level);
253 static bool cancel_cmd(JCR *cjcr)
255 BSOCK *dir = cjcr->dir_bsock;
257 char Job[MAX_NAME_LENGTH];
260 if (sscanf(dir->msg, "cancel Job=%127s", Job) == 1) {
261 if (!(jcr=get_jcr_by_full_name(Job))) {
262 bnet_fsend(dir, _("3902 Job %s not found.\n"), Job);
265 oldStatus = jcr->JobStatus;
266 set_jcr_job_status(jcr, JS_Canceled);
267 if (!jcr->authenticated && oldStatus == JS_WaitFD) {
268 pthread_cond_signal(&jcr->job_start_wait); /* wake waiting thread */
271 if (jcr->file_bsock) {
272 bnet_sig(jcr->file_bsock, BNET_TERMINATE);
274 /* If thread waiting on mount, wake him */
275 if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->waiting_for_mount()) {
276 pthread_cond_signal(&jcr->dcr->dev->wait_next_vol);
277 pthread_cond_broadcast(&wait_device_release);
279 if (jcr->read_dcr && jcr->read_dcr->dev && jcr->read_dcr->dev->waiting_for_mount()) {
280 pthread_cond_signal(&jcr->read_dcr->dev->wait_next_vol);
281 pthread_cond_broadcast(&wait_device_release);
283 bnet_fsend(dir, _("3000 Job %s marked to be canceled.\n"), jcr->Job);
287 bnet_fsend(dir, _("3903 Error scanning cancel command.\n"));
289 bnet_sig(dir, BNET_EOD);
297 static bool label_cmd(JCR *jcr)
299 return do_label(jcr, 0);
302 static bool relabel_cmd(JCR *jcr)
304 return do_label(jcr, 1);
307 static bool do_label(JCR *jcr, int relabel)
309 POOLMEM *newname, *oldname, *poolname, *mtype;
311 BSOCK *dir = jcr->dir_bsock;
318 newname = get_memory(dir->msglen+1);
319 oldname = get_memory(dir->msglen+1);
320 poolname = get_memory(dir->msglen+1);
321 mtype = get_memory(dir->msglen+1);
323 if (sscanf(dir->msg, "relabel %127s OldName=%127s NewName=%127s PoolName=%127s "
324 "MediaType=%127s Slot=%d drive=%d",
325 dev_name.c_str(), oldname, newname, poolname, mtype,
326 &slot, &drive) == 7) {
331 if (sscanf(dir->msg, "label %127s VolumeName=%127s PoolName=%127s "
332 "MediaType=%127s Slot=%d drive=%d",
333 dev_name.c_str(), newname, poolname, mtype, &slot, &drive) == 6) {
338 unbash_spaces(newname);
339 unbash_spaces(oldname);
340 unbash_spaces(poolname);
341 unbash_spaces(mtype);
342 dcr = find_device(jcr, dev_name, drive);
345 P(dev->mutex); /* Use P to avoid indefinite block */
346 if (!dev->is_open()) {
347 Dmsg0(400, "Can relabel. Device is not open\n");
348 label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
349 force_close_device(dev);
350 /* Under certain "safe" conditions, we can steal the lock */
351 } else if (dev->can_steal_lock()) {
352 Dmsg0(400, "Can relabel. can_steal_lock\n");
353 label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
354 } else if (dev->is_busy() || dev->is_blocked()) {
355 send_dir_busy_message(dir, dev);
356 } else { /* device not being used */
357 Dmsg0(400, "Can relabel. device not used\n");
358 label_volume_if_ok(dcr, oldname, newname, poolname, slot, relabel);
364 bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), dev_name.c_str());
367 /* NB dir->msg gets clobbered in bnet_fsend, so save command */
368 pm_strcpy(jcr->errmsg, dir->msg);
369 bnet_fsend(dir, _("3903 Error scanning label command: %s\n"), jcr->errmsg);
371 free_memory(oldname);
372 free_memory(newname);
373 free_memory(poolname);
375 bnet_sig(dir, BNET_EOD);
380 * Read the tape label and determine if we can safely
381 * label the tape (not a Bacula volume), then label it.
383 * Enter with the mutex set
385 static void label_volume_if_ok(DCR *dcr, char *oldname,
386 char *newname, char *poolname,
387 int slot, int relabel)
389 BSOCK *dir = dcr->jcr->dir_bsock;
391 DEVICE *dev = dcr->dev;
394 steal_device_lock(dev, &hold, BST_WRITING_LABEL);
395 Dmsg1(100, "Stole device %s lock, writing label.\n", dev->print_name());
397 /* Note, try_autoload_device() opens the device */
398 if (!try_autoload_device(dcr->jcr, slot, newname)) {
399 goto bail_out; /* error */
402 /* See what we have for a Volume */
403 label_status = read_dev_volume_label(dcr);
405 switch(label_status) {
407 case VOL_VERSION_ERROR:
408 case VOL_LABEL_ERROR:
412 "3920 Cannot label Volume because it is already labeled: \"%s\"\n"),
413 dev->VolHdr.VolumeName);
417 /* Relabel request. If oldname matches, continue */
418 if (strcmp(oldname, dev->VolHdr.VolumeName) != 0) {
419 bnet_fsend(dir, _("3921 Wrong volume mounted.\n"));
422 if (dev->label_type != B_BACULA_LABEL) {
423 bnet_fsend(dir, _("3922 Cannot relabel an ANSI/IBM labeled Volume.\n"));
426 free_volume(dev); /* release old volume name */
427 /* Fall through wanted! */
430 if (!write_new_volume_label_to_dev(dcr, newname, poolname)) {
431 bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), strerror_dev(dev));
434 bstrncpy(dcr->VolumeName, newname, sizeof(dcr->VolumeName));
435 /* The following 3000 OK label. string is scanned in ua_label.c */
436 bnet_fsend(dir, "3000 OK label. Volume=%s Device=%s\n",
437 newname, dev->print_name());
440 bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), strerror_dev(dev));
443 bnet_fsend(dir, _("3913 Cannot label Volume. "
444 "Unknown status %d from read_volume_label()\n"), label_status);
449 if (!dev->is_open()) {
452 give_back_device_lock(dev, &hold);
458 * Read the tape label
460 * Enter with the mutex set
462 static bool read_label(DCR *dcr)
466 BSOCK *dir = jcr->dir_bsock;
468 DEVICE *dev = dcr->dev;
470 steal_device_lock(dev, &hold, BST_DOING_ACQUIRE);
472 dcr->VolumeName[0] = 0;
473 dev->clear_labeled(); /* force read of label */
474 switch (read_dev_volume_label(dcr)) {
476 bnet_fsend(dir, _("3001 Mounted Volume: %s\n"), dev->VolHdr.VolumeName);
480 bnet_fsend(dir, _("3902 Cannot mount Volume on Storage Device %s because:\n%s"),
481 dev->print_name(), jcr->errmsg);
485 give_back_device_lock(dev, &hold);
490 * Searches for device by name, and if found, creates a dcr and
493 static DCR *find_device(JCR *jcr, POOL_MEM &devname, int drive)
496 AUTOCHANGER *changer;
500 unbash_spaces(devname);
501 foreach_res(device, R_DEVICE) {
502 /* Find resource, and make sure we were able to open it */
503 if (fnmatch(device->hdr.name, devname.c_str(), 0) == 0) {
505 device->dev = init_dev(jcr, device);
508 Jmsg(jcr, M_WARNING, 0, _("\n"
509 " Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
513 Dmsg1(20, "Found device %s\n", device->hdr.name);
518 foreach_res(changer, R_AUTOCHANGER) {
519 /* Find resource, and make sure we were able to open it */
520 if (fnmatch(devname.c_str(), changer->hdr.name, 0) == 0) {
521 /* Try each device in this AutoChanger */
522 foreach_alist(device, changer->device) {
523 Dmsg1(100, "Try changer device %s\n", device->hdr.name);
525 device->dev = init_dev(jcr, device);
528 Dmsg1(100, "Device %s could not be opened. Skipped\n", devname.c_str());
529 Jmsg(jcr, M_WARNING, 0, _("\n"
530 " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
531 device->hdr.name, devname.c_str());
534 if (!device->dev->autoselect) {
535 Dmsg1(100, "Device %s not autoselect skipped.\n", devname.c_str());
536 continue; /* device is not available */
538 if (drive < 0 || drive == (int)device->dev->drive_index) {
539 Dmsg1(20, "Found changer device %s\n", device->hdr.name);
543 Dmsg3(100, "Device %s drive wrong: want=%d got=%d skipping\n",
544 devname.c_str(), drive, (int)device->dev->drive_index);
546 break; /* we found it but could not open a device */
551 Dmsg1(100, "Found changer device %s\n", device->hdr.name);
552 dcr = new_dcr(jcr, device->dev);
553 dcr->device = device;
561 * Mount command from Director
563 static bool mount_cmd(JCR *jcr)
566 BSOCK *dir = jcr->dir_bsock;
571 if (sscanf(dir->msg, "mount %127s drive=%d", devname.c_str(), &drive) == 2) {
572 dcr = find_device(jcr, devname, drive);
575 P(dev->mutex); /* Use P to avoid indefinite block */
576 switch (dev->dev_blocked) { /* device blocked? */
577 case BST_WAITING_FOR_SYSOP:
578 /* Someone is waiting, wake him */
579 Dmsg0(100, "Waiting for mount. Attempting to wake thread\n");
580 dev->dev_blocked = BST_MOUNT;
581 bnet_fsend(dir, "3001 OK mount. Device=%s\n",
583 pthread_cond_broadcast(&dev->wait_next_vol);
584 pthread_cond_broadcast(&wait_device_release);
587 /* In both of these two cases, we (the user) unmounted the Volume */
588 case BST_UNMOUNTED_WAITING_FOR_SYSOP:
590 /* We freed the device, so reopen it and wake any waiting threads */
591 dev->open_nowait = true;
592 if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
593 bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
595 dev->open_nowait = false;
596 if (dev->dev_blocked == BST_UNMOUNTED) {
597 /* We blocked the device, so unblock it */
598 Dmsg0(100, "Unmounted. Unblocking device\n");
603 dev->open_nowait = false;
604 read_dev_volume_label(dcr);
605 if (dev->dev_blocked == BST_UNMOUNTED) {
606 /* We blocked the device, so unblock it */
607 Dmsg0(100, "Unmounted. Unblocking device\n");
608 read_label(dcr); /* this should not be necessary */
611 Dmsg0(100, "Unmounted waiting for mount. Attempting to wake thread\n");
612 dev->dev_blocked = BST_MOUNT;
614 if (dev->is_labeled()) {
615 bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
616 dev->print_name(), dev->VolHdr.VolumeName);
618 bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
619 "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
622 pthread_cond_broadcast(&dev->wait_next_vol);
623 pthread_cond_broadcast(&wait_device_release);
626 case BST_DOING_ACQUIRE:
627 bnet_fsend(dir, _("3001 Device %s is doing acquire.\n"),
631 case BST_WRITING_LABEL:
632 bnet_fsend(dir, _("3903 Device %s is being labeled.\n"),
636 case BST_NOT_BLOCKED:
637 if (dev->is_open()) {
638 if (dev->is_labeled()) {
639 bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
640 dev->print_name(), dev->VolHdr.VolumeName);
642 bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
643 "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
646 } else if (dev->is_tape()) {
647 dev->open_nowait = true;
648 if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
649 bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
651 dev->open_nowait = false;
654 dev->open_nowait = false;
656 if (dev->is_labeled()) {
657 bnet_fsend(dir, _("3001 Device %s is already mounted with Volume \"%s\"\n"),
658 dev->print_name(), dev->VolHdr.VolumeName);
660 bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
661 "If this is not a blank tape, try unmounting and remounting the Volume.\n"),
664 } else if (dev->is_dvd()) {
665 if (mount_dev(dev, 1)) {
666 bnet_fsend(dir, _("3002 Device %s is mounted.\n"),
669 bnet_fsend(dir, _("3907 %s"), strerror_dev(dev));
671 } else { /* must be file */
672 bnet_fsend(dir, _("3906 File device %s is always mounted.\n"),
678 bnet_fsend(dir, _("3905 Bizarre wait state %d\n"), dev->dev_blocked);
685 bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
688 pm_strcpy(jcr->errmsg, dir->msg);
689 bnet_fsend(dir, _("3909 Error scanning mount command: %s\n"), jcr->errmsg);
691 bnet_sig(dir, BNET_EOD);
696 * unmount command from Director
698 static bool unmount_cmd(JCR *jcr)
701 BSOCK *dir = jcr->dir_bsock;
706 if (sscanf(dir->msg, "unmount %127s drive=%d", devname.c_str(), &drive) == 2) {
707 dcr = find_device(jcr, devname, drive);
710 P(dev->mutex); /* Use P to avoid indefinite block */
711 if (!dev->is_open()) {
712 if (!dev->is_busy()) {
713 unload_autochanger(jcr->dcr, -1);
715 Dmsg0(90, "Device already unmounted\n");
716 bnet_fsend(dir, _("3901 Device %s is already unmounted.\n"),
719 } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP) {
720 Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
722 if (!unload_autochanger(jcr->dcr, -1)) {
723 offline_or_rewind_dev(dev);
724 force_close_device(dev);
726 dev->dev_blocked = BST_UNMOUNTED_WAITING_FOR_SYSOP;
727 bnet_fsend(dir, _("3001 Device %s unmounted.\n"),
730 } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
731 bnet_fsend(dir, _("3902 Device %s is busy in acquire.\n"),
734 } else if (dev->dev_blocked == BST_WRITING_LABEL) {
735 bnet_fsend(dir, _("3903 Device %s is being labeled.\n"),
738 } else if (dev->is_busy()) {
739 send_dir_busy_message(dir, dev);
740 } else { /* device not being used */
741 Dmsg0(90, "Device not in use, unmounting\n");
742 /* On FreeBSD, I am having ASSERT() failures in block_device()
743 * and I can only imagine that the thread id that we are
744 * leaving in no_wait_id is being re-used. So here,
745 * we simply do it by hand. Gross, but a solution.
747 /* block_device(dev, BST_UNMOUNTED); replace with 2 lines below */
748 dev->dev_blocked = BST_UNMOUNTED;
750 if (!unload_autochanger(jcr->dcr, -1)) {
751 offline_or_rewind_dev(dev);
752 force_close_device(dev);
754 bnet_fsend(dir, _("3002 Device %s unmounted.\n"),
761 bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
764 /* NB dir->msg gets clobbered in bnet_fsend, so save command */
765 pm_strcpy(jcr->errmsg, dir->msg);
766 bnet_fsend(dir, _("3907 Error scanning unmount command: %s\n"), jcr->errmsg);
768 bnet_sig(dir, BNET_EOD);
773 * Release command from Director. This rewinds the device and if
774 * configured does a offline and ensures that Bacula will
775 * re-read the label of the tape before continuing. This gives
776 * the operator the chance to change the tape anytime before the
779 static bool release_cmd(JCR *jcr)
782 BSOCK *dir = jcr->dir_bsock;
787 if (sscanf(dir->msg, "release %127s drive=%d", devname.c_str(), &drive) == 2) {
788 dcr = find_device(jcr, devname, drive);
791 P(dev->mutex); /* Use P to avoid indefinite block */
792 if (!dev->is_open()) {
793 Dmsg0(90, "Device already released\n");
794 bnet_fsend(dir, _("3921 Device %s already released.\n"),
797 } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP ||
798 dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP) {
799 Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
801 bnet_fsend(dir, _("3922 Device %s waiting for mount.\n"),
804 } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
805 bnet_fsend(dir, _("3923 Device %s is busy in acquire.\n"),
808 } else if (dev->dev_blocked == BST_WRITING_LABEL) {
809 bnet_fsend(dir, _("3914 Device %s is being labeled.\n"),
812 } else if (dev->is_busy()) {
813 send_dir_busy_message(dir, dev);
814 } else { /* device not being used */
815 Dmsg0(90, "Device not in use, unmounting\n");
816 release_volume(jcr->dcr);
817 bnet_fsend(dir, _("3022 Device %s released.\n"),
824 bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
827 /* NB dir->msg gets clobbered in bnet_fsend, so save command */
828 pm_strcpy(jcr->errmsg, dir->msg);
829 bnet_fsend(dir, _("3927 Error scanning release command: %s\n"), jcr->errmsg);
831 bnet_sig(dir, BNET_EOD);
838 * Autochanger command from Director
840 static bool changer_cmd(JCR *jcr)
843 BSOCK *dir = jcr->dir_bsock;
846 const char *cmd = NULL;
849 if (sscanf(dir->msg, "autochanger list %127s", devname.c_str()) == 1) {
852 } else if (sscanf(dir->msg, "autochanger slots %127s", devname.c_str()) == 1) {
855 } else if (sscanf(dir->msg, "autochanger drives %127s", devname.c_str()) == 1) {
860 dcr = find_device(jcr, devname, -1);
863 P(dev->mutex); /* Use P to avoid indefinite block */
864 if (!dev->is_tape()) {
865 bnet_fsend(dir, _("3995 Device %s is not an autochanger.\n"),
867 /* Under certain "safe" conditions, we can steal the lock */
868 } else if (!dev->is_open() || dev->can_steal_lock()) {
869 autochanger_cmd(dcr, dir, cmd);
870 } else if (dev->is_busy() || dev->is_blocked()) {
871 send_dir_busy_message(dir, dev);
872 } else { /* device not being used */
873 autochanger_cmd(dcr, dir, cmd);
879 bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
881 } else { /* error on scanf */
882 pm_strcpy(jcr->errmsg, dir->msg);
883 bnet_fsend(dir, _("3908 Error scanning autocharger drives/list/slots command: %s\n"),
886 bnet_sig(dir, BNET_EOD);
891 * Read and return the Volume label
893 static bool readlabel_cmd(JCR *jcr)
896 BSOCK *dir = jcr->dir_bsock;
902 if (sscanf(dir->msg, "readlabel %127s Slot=%d drive=%d", devname.c_str(),
903 &Slot, &drive) == 3) {
904 dcr = find_device(jcr, devname, drive);
907 P(dev->mutex); /* Use P to avoid indefinite block */
908 if (!dev->is_open()) {
909 read_volume_label(jcr, dev, Slot);
910 force_close_device(dev);
911 /* Under certain "safe" conditions, we can steal the lock */
912 } else if (dev->can_steal_lock()) {
913 read_volume_label(jcr, dev, Slot);
914 } else if (dev->is_busy() || dev->is_blocked()) {
915 send_dir_busy_message(dir, dev);
916 } else { /* device not being used */
917 read_volume_label(jcr, dev, Slot);
923 bnet_fsend(dir, _("3999 Device \"%s\" not found or could not be opened.\n"), devname.c_str());
926 pm_strcpy(jcr->errmsg, dir->msg);
927 bnet_fsend(dir, _("3909 Error scanning readlabel command: %s\n"), jcr->errmsg);
929 bnet_sig(dir, BNET_EOD);
934 * Read the tape label
936 * Enter with the mutex set
938 static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot)
940 BSOCK *dir = jcr->dir_bsock;
945 steal_device_lock(dev, &hold, BST_WRITING_LABEL);
947 if (!try_autoload_device(jcr, Slot, "")) {
948 goto bail_out; /* error */
951 dev->clear_labeled(); /* force read of label */
952 switch (read_dev_volume_label(dcr)) {
954 /* DO NOT add quotes around the Volume name. It is scanned in the DIR */
955 bnet_fsend(dir, _("3001 Volume=%s Slot=%d\n"), dev->VolHdr.VolumeName, Slot);
956 Dmsg1(100, "Volume: %s\n", dev->VolHdr.VolumeName);
959 bnet_fsend(dir, _("3902 Cannot mount Volume on Storage Device %s because:\n%s"),
960 dev->print_name(), jcr->errmsg);
965 give_back_device_lock(dev, &hold);
969 static bool try_autoload_device(JCR *jcr, int slot, const char *VolName)
972 BSOCK *dir = jcr->dir_bsock;
973 DEVICE *dev = dcr->dev;
975 bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
976 dcr->VolCatInfo.Slot = slot;
977 dcr->VolCatInfo.InChanger = slot > 0;
978 if (autoload_device(dcr, 0, dir) < 0) { /* autoload if possible */
982 /* Ensure that the device is open -- autoload_device() closes it */
983 if (dev->open(dcr, OPEN_READ_WRITE) < 0) {
984 bnet_fsend(dir, _("3910 Unable to open device %s: ERR=%s\n"),
985 dev->print_name(), dev->strerror());
991 static void send_dir_busy_message(BSOCK *dir, DEVICE *dev)
993 if (dev->is_blocked()) {
994 switch (dev->dev_blocked) {
996 bnet_fsend(dir, _("3931 Device %s is BLOCKED. user unmounted.\n"),
999 case BST_UNMOUNTED_WAITING_FOR_SYSOP:
1000 bnet_fsend(dir, _("3932 Device %s is BLOCKED. user unmounted during wait for media/mount.\n"),
1003 case BST_WAITING_FOR_SYSOP:
1004 bnet_fsend(dir, _("3933 Device %s is BLOCKED waiting for media.\n"),
1007 case BST_DOING_ACQUIRE:
1008 bnet_fsend(dir, _("3934 Device %s is being initialized.\n"),
1011 case BST_WRITING_LABEL:
1012 bnet_fsend(dir, _("3935 Device %s is blocked labeling a Volume.\n"),
1016 bnet_fsend(dir, _("3935 Device %s is blocked for unknown reason.\n"),
1020 } else if (dev->can_read()) {
1021 bnet_fsend(dir, _("3936 Device %s is busy reading.\n"),
1022 dev->print_name());;
1024 bnet_fsend(dir, _("3937 Device %s is busy with %d writer(s).\n"),
1025 dev->print_name(), dev->num_writers);