2 * Drive reservation functions for Storage Daemon
6 * Split from job.c and acquire.c June 2005
12 Bacula® - The Network Backup Solution
14 Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
16 The main author of Bacula is Kern Sibbald, with contributions from
17 many others, a complete list can be found in the file AUTHORS.
18 This program is Free Software; you can redistribute it and/or
19 modify it under the terms of version two of the GNU General Public
20 License as published by the Free Software Foundation plus additions
21 that are listed in the file LICENSE.
23 This program is distributed in the hope that it will be useful, but
24 WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 General Public License for more details.
28 You should have received a copy of the GNU General Public License
29 along with this program; if not, write to the Free Software
30 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
33 Bacula® is a registered trademark of John Walker.
34 The licensor of Bacula is the Free Software Foundation Europe
35 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
36 Switzerland, email:ftf@fsfeurope.org.
42 static dlist *vol_list = NULL;
43 static pthread_mutex_t vol_list_lock = PTHREAD_MUTEX_INITIALIZER;
45 /* Forward referenced functions */
46 static int can_reserve_drive(DCR *dcr, RCTX &rctx);
47 static int reserve_device(RCTX &rctx);
48 static bool reserve_device_for_read(DCR *dcr);
49 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx);
50 static bool use_storage_cmd(JCR *jcr);
51 static void queue_reserve_message(JCR *jcr);
53 /* Requests from the Director daemon */
54 static char use_storage[] = "use storage=%127s media_type=%127s "
55 "pool_name=%127s pool_type=%127s append=%d copy=%d stripe=%d\n";
56 static char use_device[] = "use device=%127s\n";
58 /* Responses sent to Director daemon */
59 static char OK_device[] = "3000 OK use device device=%s\n";
60 static char NO_device[] = "3924 Device \"%s\" not in SD Device resources.\n";
61 static char BAD_use[] = "3913 Bad use command: %s\n";
63 bool use_cmd(JCR *jcr)
66 * Get the device, media, and pool information
68 if (!use_storage_cmd(jcr)) {
69 set_jcr_job_status(jcr, JS_ErrorTerminated);
70 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
76 static int my_compare(void *item1, void *item2)
78 return strcmp(((VOLRES *)item1)->vol_name, ((VOLRES *)item2)->vol_name);
81 static brwlock_t reservation_lock;
83 void init_reservations_lock()
86 if ((errstat=rwl_init(&reservation_lock)) != 0) {
88 Emsg1(M_ABORT, 0, _("Unable to initialize reservation lock. ERR=%s\n"),
89 be.strerror(errstat));
94 void term_reservations_lock()
96 rwl_destroy(&reservation_lock);
99 /* This applies to a drive and to Volumes */
100 void lock_reservations()
103 if ((errstat=rwl_writelock(&reservation_lock)) != 0) {
105 Emsg2(M_ABORT, 0, "rwl_writelock failure. stat=%d: ERR=%s\n",
106 errstat, be.strerror(errstat));
110 void unlock_reservations()
113 if ((errstat=rwl_writeunlock(&reservation_lock)) != 0) {
115 Emsg2(M_ABORT, 0, "rwl_writeunlock failure. stat=%d: ERR=%s\n",
116 errstat, be.strerror(errstat));
122 * Put a new Volume entry in the Volume list. This
123 * effectively reserves the volume so that it will
124 * not be mounted again.
126 * Return: VOLRES entry on success
127 * NULL if the Volume is already in the list
129 VOLRES *new_volume(DCR *dcr, const char *VolumeName)
133 Dmsg1(400, "new_volume %s\n", VolumeName);
135 * We lock the reservations system here to ensure
136 * when adding a new volume that no newly scheduled
137 * job can reserve it.
143 foreach_dlist(vol, vol_list) {
144 if (vol && vol->dev == dcr->dev) {
145 vol_list->remove(vol);
154 vol = (VOLRES *)malloc(sizeof(VOLRES));
155 memset(vol, 0, sizeof(VOLRES));
156 vol->vol_name = bstrdup(VolumeName);
159 Dmsg2(100, "New Vol=%s dev=%s\n", VolumeName, dcr->dev->print_name());
160 nvol = (VOLRES *)vol_list->binary_insert(vol, my_compare);
166 DEVICE *dev = nvol->dev;
167 if (!dev->is_busy()) {
168 Dmsg3(100, "Swap vol=%s from dev=%s to %s\n", VolumeName,
169 dev->print_name(), dcr->dev->print_name());
170 nvol->dev = dcr->dev;
171 dev->VolHdr.VolumeName[0] = 0;
173 Dmsg3(100, "!!!! could not swap vol=%s from dev=%s to %s\n", VolumeName,
174 dev->print_name(), dcr->dev->print_name());
179 unlock_reservations();
184 * Search for a Volume name in the Volume list.
186 * Returns: VOLRES entry on success
187 * NULL if the Volume is not in the list
189 VOLRES *find_volume(const char *VolumeName)
192 /* Do not lock reservations here */
194 vol.vol_name = bstrdup(VolumeName);
195 fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare);
202 * Free a Volume from the Volume list
204 * Returns: true if the Volume found and removed from the list
205 * false if the Volume is not in the list
207 bool free_volume(DEVICE *dev)
212 if (dev->VolHdr.VolumeName[0] == 0) {
213 Dmsg1(100, "free_volume: no vol on dev %s\n", dev->print_name());
215 * Our device has no VolumeName listed, but
216 * search the list for any Volume attached to
217 * this device and remove it.
219 foreach_dlist(fvol, vol_list) {
220 if (fvol && fvol->dev == dev) {
221 vol_list->remove(fvol);
222 if (fvol->vol_name) {
223 Dmsg2(100, "free_volume %s dev=%s\n", fvol->vol_name, dev->print_name());
224 free(fvol->vol_name);
232 Dmsg1(400, "free_volume %s\n", dev->VolHdr.VolumeName);
233 vol.vol_name = bstrdup(dev->VolHdr.VolumeName);
234 fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare);
236 vol_list->remove(fvol);
237 Dmsg2(100, "free_volume %s dev=%s\n", fvol->vol_name, dev->print_name());
238 free(fvol->vol_name);
242 dev->VolHdr.VolumeName[0] = 0;
248 /* Free volume reserved by this dcr but not attached to a dev */
249 void free_unused_volume(DCR *dcr)
254 for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
255 if (vol->dcr == dcr && (vol->dev == NULL ||
256 strcmp(vol->vol_name, vol->dev->VolHdr.VolumeName) != 0)) {
257 vol_list->remove(vol);
258 Dmsg1(100, "free_unused_volume %s\n", vol->vol_name);
268 * List Volumes -- this should be moved to status.c
270 void list_volumes(void sendit(const char *msg, int len, void *sarg), void *arg)
276 msg = (char *)get_pool_memory(PM_MESSAGE);
279 for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
281 len = Mmsg(msg, "%s on device %s\n", vol->vol_name, vol->dev->print_name());
282 sendit(msg, len, arg);
284 len = Mmsg(msg, "%s\n", vol->vol_name);
285 sendit(msg, len, arg);
290 free_pool_memory(msg);
293 /* Create the Volume list */
294 void create_volume_list()
296 VOLRES *dummy = NULL;
297 if (vol_list == NULL) {
298 vol_list = New(dlist(dummy, &dummy->link));
302 /* Release all Volumes from the list */
303 void free_volume_list()
310 for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
311 Dmsg3(100, "Unreleased Volume=%s dcr=0x%x dev=0x%x\n", vol->vol_name,
319 bool is_volume_in_use(DCR *dcr)
321 VOLRES *vol = find_volume(dcr->VolumeName);
323 Dmsg1(100, "Vol=%s not in use.\n", dcr->VolumeName);
324 return false; /* vol not in list */
326 if (!vol->dev) { /* vol not attached to device */
327 Dmsg1(100, "Vol=%s has no dev.\n", dcr->VolumeName);
330 if (dcr->dev == vol->dev) { /* same device OK */
331 Dmsg1(100, "Vol=%s on same dev.\n", dcr->VolumeName);
334 if (!vol->dev->is_busy()) {
335 Dmsg2(100, "Vol=%s dev=%s not busy.\n", dcr->VolumeName, vol->dev->print_name());
338 Dmsg2(100, "Vol=%s used by %s.\n", dcr->VolumeName, vol->dev->print_name());
344 * We get the following type of information:
346 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=1 copy=0 strip=0
350 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=0 copy=0 strip=0
354 static bool use_storage_cmd(JCR *jcr)
356 POOL_MEM store_name, dev_name, media_type, pool_name, pool_type;
357 BSOCK *dir = jcr->dir_bsock;
367 memset(&rctx, 0, sizeof(RCTX));
370 * If there are multiple devices, the director sends us
371 * use_device for each device that it wants to use.
373 dirstore = New(alist(10, not_owned_by_alist));
374 // Dmsg2(000, "dirstore=%p JobId=%u\n", dirstore, jcr->JobId);
375 msgs = jcr->reserve_msgs = New(alist(10, not_owned_by_alist));
377 Dmsg1(100, "<dird: %s", dir->msg);
378 ok = sscanf(dir->msg, use_storage, store_name.c_str(),
379 media_type.c_str(), pool_name.c_str(),
380 pool_type.c_str(), &append, &Copy, &Stripe) == 7;
385 jcr->write_store = dirstore;
387 jcr->read_store = dirstore;
389 rctx.append = append;
390 unbash_spaces(store_name);
391 unbash_spaces(media_type);
392 unbash_spaces(pool_name);
393 unbash_spaces(pool_type);
394 store = new DIRSTORE;
395 dirstore->append(store);
396 memset(store, 0, sizeof(DIRSTORE));
397 store->device = New(alist(10));
398 bstrncpy(store->name, store_name, sizeof(store->name));
399 bstrncpy(store->media_type, media_type, sizeof(store->media_type));
400 bstrncpy(store->pool_name, pool_name, sizeof(store->pool_name));
401 bstrncpy(store->pool_type, pool_type, sizeof(store->pool_type));
402 store->append = append;
404 /* Now get all devices */
405 while (bnet_recv(dir) >= 0) {
406 Dmsg1(100, "<dird device: %s", dir->msg);
407 ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
411 unbash_spaces(dev_name);
412 store->device->append(bstrdup(dev_name.c_str()));
414 } while (ok && bnet_recv(dir) >= 0);
417 /* This loop is debug code and can be removed */
418 /* ***FIXME**** remove after 1.38 release */
420 foreach_alist(store, dirstore) {
421 Dmsg5(110, "Storage=%s media_type=%s pool=%s pool_type=%s append=%d\n",
422 store->name, store->media_type, store->pool_name,
423 store->pool_type, store->append);
424 foreach_alist(device_name, store->device) {
425 Dmsg1(110, " Device=%s\n", device_name);
430 init_jcr_device_wait_timers(jcr);
432 * At this point, we have a list of all the Director's Storage
433 * resources indicated for this Job, which include Pool, PoolType,
434 * storage name, and Media type.
435 * Then for each of the Storage resources, we have a list of
436 * device names that were given.
438 * Wiffle through them and find one that can do the backup.
441 bool first = true; /* print wait message once */
443 rctx.notify_dir = true;
445 for ( ; !fail && !job_canceled(jcr); ) {
446 while ((msg = (char *)msgs->pop())) {
449 rctx.suitable_device = false;
450 rctx.have_volume = false;
451 rctx.any_drive = false;
452 if (!jcr->PreferMountedVols) {
453 /* Look for unused drives in autochangers */
454 rctx.num_writers = 20000000; /* start with impossible number */
455 rctx.low_use_drive = NULL;
456 rctx.PreferMountedVols = false;
457 rctx.exact_match = false;
458 rctx.autochanger_only = true;
459 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
460 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
461 rctx.autochanger_only, rctx.any_drive);
462 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
465 /* Look through all drives possibly for low_use drive */
466 if (rctx.low_use_drive) {
467 rctx.try_low_use_drive = true;
468 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
471 rctx.try_low_use_drive = false;
473 rctx.autochanger_only = false;
474 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
475 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
476 rctx.autochanger_only, rctx.any_drive);
477 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
481 /* Look for an exact match all drives */
482 rctx.PreferMountedVols = true;
483 rctx.exact_match = true;
484 rctx.autochanger_only = false;
485 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
486 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
487 rctx.autochanger_only, rctx.any_drive);
488 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
491 /* Look for any mounted drive */
492 rctx.exact_match = false;
493 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
494 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
495 rctx.autochanger_only, rctx.any_drive);
496 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
500 rctx.any_drive = true;
501 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
502 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
503 rctx.autochanger_only, rctx.any_drive);
504 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
507 /* Keep reservations locked *except* during wait_for_device() */
508 unlock_reservations();
509 if (!rctx.suitable_device || !wait_for_device(jcr, first)) {
510 Dmsg0(100, "Fail. !suitable_device || !wait_for_device\n");
515 bnet_sig(dir, BNET_HEARTBEAT); /* Inform Dir that we are alive */
517 unlock_reservations();
520 * If we get here, there are no suitable devices available, which
521 * means nothing configured. If a device is suitable but busy
522 * with another Volume, we will not come here.
524 unbash_spaces(dir->msg);
525 pm_strcpy(jcr->errmsg, dir->msg);
526 Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
527 Jmsg(jcr, M_FATAL, 0, _("\n"
528 " Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"),
529 dev_name.c_str(), media_type.c_str());
530 bnet_fsend(dir, NO_device, dev_name.c_str());
532 Dmsg1(100, ">dird: %s", dir->msg);
535 unbash_spaces(dir->msg);
536 pm_strcpy(jcr->errmsg, dir->msg);
537 Jmsg(jcr, M_FATAL, 0, _("Failed command: %s\n"), jcr->errmsg);
538 bnet_fsend(dir, BAD_use, jcr->errmsg);
539 Dmsg1(100, ">dird: %s", dir->msg);
546 void release_msgs(JCR *jcr)
548 alist *msgs = jcr->reserve_msgs;
555 while ((msg = (char *)msgs->pop())) {
559 jcr->reserve_msgs = NULL;
560 unlock_reservations();
564 * Search for a device suitable for this job.
566 bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx)
574 dirstore = jcr->write_store;
576 dirstore = jcr->read_store;
579 * For each storage device that the user specified, we
580 * search and see if there is a resource for that device.
582 Dmsg4(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d\n",
583 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
584 rctx.autochanger_only);
586 foreach_alist(store, dirstore) {
588 foreach_alist(device_name, store->device) {
590 rctx.device_name = device_name;
591 stat = search_res_for_device(rctx);
592 if (stat == 1) { /* found available device */
593 Dmsg1(100, "Suitable device found=%s\n", device_name);
596 } else if (stat == 0) { /* device busy */
597 Dmsg1(110, "Suitable device found=%s, not used: busy\n", device_name);
599 /* otherwise error */
600 Dmsg0(110, "No suitable device found.\n");
611 * Search for a particular storage device with particular storage
612 * characteristics (MediaType).
614 int search_res_for_device(RCTX &rctx)
616 AUTOCHANGER *changer;
617 BSOCK *dir = rctx.jcr->dir_bsock;
621 Dmsg1(110, "Search res for %s\n", rctx.device_name);
622 /* Look through Autochangers first */
623 foreach_res(changer, R_AUTOCHANGER) {
624 Dmsg1(150, "Try match changer res=%s\n", changer->hdr.name);
625 /* Find resource, and make sure we were able to open it */
626 if (fnmatch(rctx.device_name, changer->hdr.name, 0) == 0) {
627 /* Try each device in this AutoChanger */
628 foreach_alist(rctx.device, changer->device) {
629 Dmsg1(110, "Try changer device %s\n", rctx.device->hdr.name);
630 stat = reserve_device(rctx);
631 if (stat != 1) { /* try another device */
635 if (rctx.store->append == SD_APPEND) {
636 Dmsg2(100, "Device %s reserved=%d for append.\n", rctx.device->hdr.name,
637 rctx.jcr->dcr->dev->reserved_device);
639 Dmsg2(100, "Device %s reserved=%d for read.\n", rctx.device->hdr.name,
640 rctx.jcr->read_dcr->dev->reserved_device);
642 if (rctx.notify_dir) {
643 pm_strcpy(dev_name, rctx.device->hdr.name);
644 bash_spaces(dev_name);
645 ok = bnet_fsend(dir, OK_device, dev_name.c_str()); /* Return real device name */
646 Dmsg1(100, ">dird changer: %s", dir->msg);
655 /* Now if requested look through regular devices */
656 if (!rctx.autochanger_only) {
657 foreach_res(rctx.device, R_DEVICE) {
658 Dmsg1(150, "Try match res=%s\n", rctx.device->hdr.name);
659 /* Find resource, and make sure we were able to open it */
660 if (fnmatch(rctx.device_name, rctx.device->hdr.name, 0) == 0) {
661 stat = reserve_device(rctx);
665 if (rctx.notify_dir) {
666 bash_spaces(rctx.device_name);
667 ok = bnet_fsend(dir, OK_device, rctx.device_name);
668 Dmsg1(100, ">dird dev: %s", dir->msg);
676 return -1; /* nothing found */
680 * Try to reserve a specific device.
682 * Returns: 1 -- OK, have DCR
686 static int reserve_device(RCTX &rctx)
690 const int name_len = MAX_NAME_LENGTH;
692 /* Make sure MediaType is OK */
693 Dmsg2(110, "MediaType device=%s request=%s\n",
694 rctx.device->media_type, rctx.store->media_type);
695 if (strcmp(rctx.device->media_type, rctx.store->media_type) != 0) {
699 /* Make sure device exists -- i.e. we can stat() it */
700 if (!rctx.device->dev) {
701 rctx.device->dev = init_dev(rctx.jcr, rctx.device);
703 if (!rctx.device->dev) {
704 if (rctx.device->changer_res) {
705 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
706 " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
707 rctx.device->hdr.name, rctx.device_name);
709 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
710 " Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
713 return -1; /* no use waiting */
716 rctx.suitable_device = true;
717 Dmsg2(110, "Try reserve %s JobId=%u\n", rctx.device->hdr.name,
719 dcr = new_dcr(rctx.jcr, rctx.device->dev);
721 BSOCK *dir = rctx.jcr->dir_bsock;
722 bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), rctx.device_name);
723 Dmsg1(100, ">dird: %s", dir->msg);
726 bstrncpy(dcr->pool_name, rctx.store->pool_name, name_len);
727 bstrncpy(dcr->pool_type, rctx.store->pool_type, name_len);
728 bstrncpy(dcr->media_type, rctx.store->media_type, name_len);
729 bstrncpy(dcr->dev_name, rctx.device_name, name_len);
730 if (rctx.store->append == SD_APPEND) {
731 if (rctx.exact_match && !rctx.have_volume) {
732 dcr->any_volume = true;
733 if (dir_find_next_appendable_volume(dcr)) {
734 bstrncpy(rctx.VolumeName, dcr->VolumeName, sizeof(rctx.VolumeName));
735 Dmsg2(100, "JobId=%u looking for Volume=%s\n", rctx.jcr->JobId, rctx.VolumeName);
736 rctx.have_volume = true;
738 Dmsg0(100, "No next volume found\n");
739 rctx.VolumeName[0] = 0;
742 ok = reserve_device_for_append(dcr, rctx);
745 Dmsg5(100, "Reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
746 dcr->dev->reserved_device,
747 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
750 ok = reserve_device_for_read(dcr);
752 rctx.jcr->read_dcr = dcr;
753 Dmsg5(100, "Read reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
754 dcr->dev->reserved_device,
755 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
760 Dmsg0(110, "Not OK.\n");
767 * We "reserve" the drive by setting the ST_READ bit. No one else
768 * should touch the drive until that is cleared.
769 * This allows the DIR to "reserve" the device before actually
772 static bool reserve_device_for_read(DCR *dcr)
774 DEVICE *dev = dcr->dev;
780 /* Get locks in correct order */
781 unlock_reservations();
785 if (is_device_unmounted(dev)) {
786 Dmsg1(200, "Device %s is BLOCKED due to user unmount.\n", dev->print_name());
787 Mmsg(jcr->errmsg, _("3601 JobId=%u device %s is BLOCKED due to user unmount.\n"),
788 jcr->JobId, dev->print_name());
789 queue_reserve_message(jcr);
793 if (dev->is_busy()) {
794 Dmsg4(200, "Device %s is busy ST_READ=%d num_writers=%d reserved=%d.\n", dev->print_name(),
795 dev->state & ST_READ?1:0, dev->num_writers, dev->reserved_device);
796 Mmsg(jcr->errmsg, _("3602 JobId=%u device %s is busy (already reading/writing).\n"),
797 jcr->JobId, dev->print_name());
798 queue_reserve_message(jcr);
805 dev->reserved_device++;
806 Dmsg3(100, "Inc reserve=%d dev=%s %p\n", dev->reserved_device,
807 dev->print_name(), dev);
808 dcr->reserved_device = true;
817 * We reserve the device for appending by incrementing the
818 * reserved_device. We do virtually all the same work that
819 * is done in acquire_device_for_append(), but we do
820 * not attempt to mount the device. This routine allows
821 * the DIR to reserve multiple devices before *really*
822 * starting the job. It also permits the SD to refuse
823 * certain devices (not up, ...).
825 * Note, in reserving a device, if the device is for the
826 * same pool and the same pool type, then it is acceptable.
827 * The Media Type has already been checked. If we are
828 * the first tor reserve the device, we put the pool
829 * name and pool type in the device record.
831 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
834 DEVICE *dev = dcr->dev;
839 /* Get locks in correct order */
840 unlock_reservations();
844 /* If device is being read, we cannot write it */
845 if (dev->can_read()) {
846 Mmsg(jcr->errmsg, _("3603 JobId=%u device %s is busy reading.\n"),
847 jcr->JobId, dev->print_name());
848 Dmsg1(110, "%s", jcr->errmsg);
849 queue_reserve_message(jcr);
853 /* If device is unmounted, we are out of luck */
854 if (is_device_unmounted(dev)) {
855 Mmsg(jcr->errmsg, _("3604 JobId=%u device %s is BLOCKED due to user unmount.\n"),
856 jcr->JobId, dev->print_name());
857 Dmsg1(110, "%s", jcr->errmsg);
858 queue_reserve_message(jcr);
862 Dmsg1(110, "reserve_append device is %s\n", dev->is_tape()?"tape":"disk");
864 /* Now do detailed tests ... */
865 if (can_reserve_drive(dcr, rctx) != 1) {
866 Dmsg0(110, "can_reserve_drive!=1\n");
870 dev->reserved_device++;
871 Dmsg3(100, "Inc reserve=%d dev=%s %p\n", dev->reserved_device,
872 dev->print_name(), dev);
873 dcr->reserved_device = true;
882 * Returns: 1 if drive can be reserved
883 * 0 if we should wait
884 * -1 on error or impossibility
886 static int can_reserve_drive(DCR *dcr, RCTX &rctx)
888 DEVICE *dev = dcr->dev;
891 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
892 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
893 rctx.autochanger_only, rctx.any_drive);
895 /* setting any_drive overrides PreferMountedVols flag */
896 if (!rctx.any_drive) {
898 * When PreferMountedVols is set, we keep track of the
899 * drive in use that has the least number of writers, then if
900 * no unmounted drive is found, we try that drive. This
901 * helps spread the load to the least used drives.
903 if (rctx.try_low_use_drive && dev == rctx.low_use_drive) {
904 Dmsg3(110, "OK dev=%s == low_drive=%s. JobId=%u\n",
905 dev->print_name(), rctx.low_use_drive->print_name(), jcr->JobId);
908 /* If he wants a free drive, but this one is busy, no go */
909 if (!rctx.PreferMountedVols && dev->is_busy()) {
910 /* Save least used drive */
911 if ((dev->num_writers + dev->reserved_device) < rctx.num_writers) {
912 rctx.num_writers = dev->num_writers + dev->reserved_device;
913 rctx.low_use_drive = dev;
914 Dmsg2(110, "set low use drive=%s num_writers=%d\n", dev->print_name(),
917 Dmsg1(110, "not low use num_writers=%d\n", dev->num_writers+
918 dev->reserved_device);
920 Dmsg1(110, "failed: !prefMnt && busy. JobId=%u\n", jcr->JobId);
921 Mmsg(jcr->errmsg, _("3605 JobId=%u wants free drive but device %s is busy.\n"),
922 jcr->JobId, dev->print_name());
923 queue_reserve_message(jcr);
927 /* Check for prefer mounted volumes */
928 if (rctx.PreferMountedVols && !dev->VolHdr.VolumeName[0] && dev->is_tape()) {
929 Mmsg(jcr->errmsg, _("3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n"),
930 jcr->JobId, dev->print_name());
931 queue_reserve_message(jcr);
932 Dmsg1(110, "failed: want mounted -- no vol JobId=%u\n", jcr->JobId);
933 return 0; /* No volume mounted */
936 /* Check for exact Volume name match */
937 if (rctx.exact_match && rctx.have_volume &&
938 strcmp(dev->VolHdr.VolumeName, rctx.VolumeName) != 0) {
939 Mmsg(jcr->errmsg, _("3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n"),
940 jcr->JobId, rctx.VolumeName, dev->VolHdr.VolumeName,
942 queue_reserve_message(jcr);
943 Dmsg2(110, "failed: Not exact match have=%s want=%s\n",
944 dev->VolHdr.VolumeName, rctx.VolumeName);
949 /* Check for unused autochanger drive */
950 if (rctx.autochanger_only && dev->num_writers == 0 &&
951 dev->VolHdr.VolumeName[0] == 0) {
952 /* Device is available but not yet reserved, reserve it for us */
953 Dmsg2(100, "OK Res Unused autochanger %s JobId=%u.\n",
954 dev->print_name(), jcr->JobId);
955 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
956 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
957 return 1; /* reserve drive */
961 * Handle the case that there are no writers
963 if (dev->num_writers == 0) {
964 /* Now check if there are any reservations on the drive */
965 if (dev->reserved_device) {
966 /* Now check if we want the same Pool and pool type */
967 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
968 strcmp(dev->pool_type, dcr->pool_type) == 0) {
969 /* OK, compatible device */
970 Dmsg2(100, "OK dev: %s num_writers=0, reserved, pool matches JobId=%u\n",
971 dev->print_name(), jcr->JobId);
974 /* Drive Pool not suitable for us */
975 Mmsg(jcr->errmsg, _("3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" on drive %s.\n"),
976 jcr->JobId, dcr->pool_name, dev->pool_name, dev->print_name());
977 queue_reserve_message(jcr);
978 Dmsg2(110, "failed: busy num_writers=0, reserved, pool=%s wanted=%s\n",
979 dev->pool_name, dcr->pool_name);
982 } else if (dev->can_append()) {
983 /* Device in append mode, check if changing pool */
984 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
985 strcmp(dev->pool_type, dcr->pool_type) == 0) {
986 Dmsg2(100, "OK dev: %s num_writers=0, can_append, pool matches. JobId=%u\n",
987 dev->print_name(), jcr->JobId);
988 /* OK, compatible device */
991 /* Changing pool, unload old tape if any in drive */
992 Dmsg0(100, "OK dev: num_writers=0, not reserved, pool change, unload changer\n");
993 unload_autochanger(dcr, 0);
996 /* Device is available but not yet reserved, reserve it for us */
997 Dmsg2(100, "OK Dev avail reserved %s JobId=%u\n", dev->print_name(),
999 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1000 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1001 return 1; /* reserve drive */
1005 * Check if the device is in append mode with writers (i.e.
1006 * available if pool is the same).
1008 if (dev->can_append() || dev->num_writers > 0) {
1009 /* Yes, now check if we want the same Pool and pool type */
1010 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1011 strcmp(dev->pool_type, dcr->pool_type) == 0) {
1012 Dmsg2(100, "OK dev: %s num_writers>=0, can_append, pool matches. JobId=%u\n",
1013 dev->print_name(), jcr->JobId);
1014 /* OK, compatible device */
1017 /* Drive Pool not suitable for us */
1018 Mmsg(jcr->errmsg, _("3609 JobId=%u wants Pool=\"%s\" but has Pool=\"%s\" on drive %s.\n"),
1019 jcr->JobId, dcr->pool_name, dev->pool_name, dev->print_name());
1020 queue_reserve_message(jcr);
1021 Dmsg2(110, "failed: busy num_writers>0, can_append, pool=%s wanted=%s\n",
1022 dev->pool_name, dcr->pool_name);
1023 return 0; /* wait */
1026 Pmsg0(000, _("Logic error!!!! Should not get here.\n"));
1027 Mmsg(jcr->errmsg, _("3910 JobId=%u Logic error!!!! drive %s Should not get here.\n"),
1028 jcr->JobId, dev->print_name());
1029 queue_reserve_message(jcr);
1030 Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
1031 return -1; /* error, should not get here */
1033 Mmsg(jcr->errmsg, _("3911 JobId=%u failed reserve drive %s.\n"),
1034 jcr->JobId, dev->print_name());
1035 queue_reserve_message(jcr);
1036 Dmsg2(110, "failed: No reserve %s JobId=%u\n", dev->print_name(), jcr->JobId);
1041 * search_lock is already set on entering this routine
1043 static void queue_reserve_message(JCR *jcr)
1046 alist *msgs = jcr->reserve_msgs;
1053 * Look for duplicate message. If found, do
1056 for (i=msgs->size()-1; i >= 0; i--) {
1057 msg = (char *)msgs->get(i);
1061 /* Comparison based on 4 digit message number */
1062 if (strncmp(msg, jcr->errmsg, 4) == 0) {
1066 /* Message unique, so insert it */
1067 jcr->reserve_msgs->push(bstrdup(jcr->errmsg));
1071 * Send any reservation messages queued for this jcr
1073 void send_drive_reserve_messages(JCR *jcr, void sendit(const char *msg, int len, void *sarg), void *arg)
1079 lock_reservations();
1080 msgs = jcr->reserve_msgs;
1081 if (!msgs || msgs->size() == 0) {
1082 unlock_reservations();
1085 for (i=msgs->size()-1; i >= 0; i--) {
1086 msg = (char *)msgs->get(i);
1088 sendit(" ", 3, arg);
1089 sendit(msg, strlen(msg), arg);
1094 unlock_reservations();