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(000, "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");
612 * Search for a particular storage device with particular storage
613 * characteristics (MediaType).
615 int search_res_for_device(RCTX &rctx)
617 AUTOCHANGER *changer;
618 BSOCK *dir = rctx.jcr->dir_bsock;
622 Dmsg1(110, "Search res for %s\n", rctx.device_name);
623 /* Look through Autochangers first */
624 foreach_res(changer, R_AUTOCHANGER) {
625 Dmsg1(150, "Try match changer res=%s\n", changer->hdr.name);
626 /* Find resource, and make sure we were able to open it */
627 if (fnmatch(rctx.device_name, changer->hdr.name, 0) == 0) {
628 /* Try each device in this AutoChanger */
629 foreach_alist(rctx.device, changer->device) {
630 Dmsg1(110, "Try changer device %s\n", rctx.device->hdr.name);
631 stat = reserve_device(rctx);
632 if (stat != 1) { /* try another device */
636 if (rctx.store->append == SD_APPEND) {
637 Dmsg2(100, "Device %s reserved=%d for append.\n", rctx.device->hdr.name,
638 rctx.jcr->dcr->dev->reserved_device);
640 Dmsg2(100, "Device %s reserved=%d for read.\n", rctx.device->hdr.name,
641 rctx.jcr->read_dcr->dev->reserved_device);
643 if (rctx.notify_dir) {
644 pm_strcpy(dev_name, rctx.device->hdr.name);
645 bash_spaces(dev_name);
646 ok = bnet_fsend(dir, OK_device, dev_name.c_str()); /* Return real device name */
647 Dmsg1(100, ">dird changer: %s", dir->msg);
656 /* Now if requested look through regular devices */
657 if (!rctx.autochanger_only) {
658 foreach_res(rctx.device, R_DEVICE) {
659 Dmsg1(150, "Try match res=%s\n", rctx.device->hdr.name);
660 /* Find resource, and make sure we were able to open it */
661 if (fnmatch(rctx.device_name, rctx.device->hdr.name, 0) == 0) {
662 stat = reserve_device(rctx);
666 if (rctx.notify_dir) {
667 bash_spaces(rctx.device_name);
668 ok = bnet_fsend(dir, OK_device, rctx.device_name);
669 Dmsg1(100, ">dird dev: %s", dir->msg);
677 return -1; /* nothing found */
681 * Try to reserve a specific device.
683 * Returns: 1 -- OK, have DCR
687 static int reserve_device(RCTX &rctx)
691 const int name_len = MAX_NAME_LENGTH;
693 /* Make sure MediaType is OK */
694 Dmsg2(110, "MediaType device=%s request=%s\n",
695 rctx.device->media_type, rctx.store->media_type);
696 if (strcmp(rctx.device->media_type, rctx.store->media_type) != 0) {
700 /* Make sure device exists -- i.e. we can stat() it */
701 if (!rctx.device->dev) {
702 rctx.device->dev = init_dev(rctx.jcr, rctx.device);
704 if (!rctx.device->dev) {
705 if (rctx.device->changer_res) {
706 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
707 " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
708 rctx.device->hdr.name, rctx.device_name);
710 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
711 " Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
714 return -1; /* no use waiting */
717 rctx.suitable_device = true;
718 Dmsg2(110, "Try reserve %s JobId=%u\n", rctx.device->hdr.name,
720 dcr = new_dcr(rctx.jcr, rctx.device->dev);
722 BSOCK *dir = rctx.jcr->dir_bsock;
723 bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), rctx.device_name);
724 Dmsg1(100, ">dird: %s", dir->msg);
727 bstrncpy(dcr->pool_name, rctx.store->pool_name, name_len);
728 bstrncpy(dcr->pool_type, rctx.store->pool_type, name_len);
729 bstrncpy(dcr->media_type, rctx.store->media_type, name_len);
730 bstrncpy(dcr->dev_name, rctx.device_name, name_len);
731 if (rctx.store->append == SD_APPEND) {
732 if (rctx.exact_match && !rctx.have_volume) {
733 dcr->any_volume = true;
734 if (dir_find_next_appendable_volume(dcr)) {
735 bstrncpy(rctx.VolumeName, dcr->VolumeName, sizeof(rctx.VolumeName));
736 Dmsg2(100, "JobId=%u looking for Volume=%s\n", rctx.jcr->JobId, rctx.VolumeName);
737 rctx.have_volume = true;
739 Dmsg0(100, "No next volume found\n");
740 rctx.VolumeName[0] = 0;
743 ok = reserve_device_for_append(dcr, rctx);
746 Dmsg5(100, "Reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
747 dcr->dev->reserved_device,
748 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
751 ok = reserve_device_for_read(dcr);
753 rctx.jcr->read_dcr = dcr;
754 Dmsg5(100, "Read reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
755 dcr->dev->reserved_device,
756 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
761 Dmsg0(110, "Not OK.\n");
768 * We "reserve" the drive by setting the ST_READ bit. No one else
769 * should touch the drive until that is cleared.
770 * This allows the DIR to "reserve" the device before actually
773 static bool reserve_device_for_read(DCR *dcr)
775 DEVICE *dev = dcr->dev;
781 /* Get locks in correct order */
782 unlock_reservations();
786 if (is_device_unmounted(dev)) {
787 Dmsg1(200, "Device %s is BLOCKED due to user unmount.\n", dev->print_name());
788 Mmsg(jcr->errmsg, _("3601 JobId=%u device %s is BLOCKED due to user unmount.\n"),
789 jcr->JobId, dev->print_name());
790 queue_reserve_message(jcr);
794 if (dev->is_busy()) {
795 Dmsg4(200, "Device %s is busy ST_READ=%d num_writers=%d reserved=%d.\n", dev->print_name(),
796 dev->state & ST_READ?1:0, dev->num_writers, dev->reserved_device);
797 Mmsg(jcr->errmsg, _("3602 JobId=%u device %s is busy (already reading/writing).\n"),
798 jcr->JobId, dev->print_name());
799 queue_reserve_message(jcr);
806 dev->reserved_device++;
807 Dmsg3(100, "Inc reserve=%d dev=%s %p\n", dev->reserved_device,
808 dev->print_name(), dev);
809 dcr->reserved_device = true;
818 * We reserve the device for appending by incrementing the
819 * reserved_device. We do virtually all the same work that
820 * is done in acquire_device_for_append(), but we do
821 * not attempt to mount the device. This routine allows
822 * the DIR to reserve multiple devices before *really*
823 * starting the job. It also permits the SD to refuse
824 * certain devices (not up, ...).
826 * Note, in reserving a device, if the device is for the
827 * same pool and the same pool type, then it is acceptable.
828 * The Media Type has already been checked. If we are
829 * the first tor reserve the device, we put the pool
830 * name and pool type in the device record.
832 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
835 DEVICE *dev = dcr->dev;
840 /* Get locks in correct order */
841 unlock_reservations();
845 /* If device is being read, we cannot write it */
846 if (dev->can_read()) {
847 Mmsg(jcr->errmsg, _("3603 JobId=%u device %s is busy reading.\n"),
848 jcr->JobId, dev->print_name());
849 Dmsg1(110, "%s", jcr->errmsg);
850 queue_reserve_message(jcr);
854 /* If device is unmounted, we are out of luck */
855 if (is_device_unmounted(dev)) {
856 Mmsg(jcr->errmsg, _("3604 JobId=%u device %s is BLOCKED due to user unmount.\n"),
857 jcr->JobId, dev->print_name());
858 Dmsg1(110, "%s", jcr->errmsg);
859 queue_reserve_message(jcr);
863 Dmsg1(110, "reserve_append device is %s\n", dev->is_tape()?"tape":"disk");
865 /* Now do detailed tests ... */
866 if (can_reserve_drive(dcr, rctx) != 1) {
867 Dmsg0(110, "can_reserve_drive!=1\n");
871 dev->reserved_device++;
872 Dmsg3(100, "Inc reserve=%d dev=%s %p\n", dev->reserved_device,
873 dev->print_name(), dev);
874 dcr->reserved_device = true;
883 * Returns: 1 if drive can be reserved
884 * 0 if we should wait
885 * -1 on error or impossibility
887 static int can_reserve_drive(DCR *dcr, RCTX &rctx)
889 DEVICE *dev = dcr->dev;
892 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
893 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
894 rctx.autochanger_only, rctx.any_drive);
896 /* setting any_drive overrides PreferMountedVols flag */
897 if (!rctx.any_drive) {
899 * When PreferMountedVols is set, we keep track of the
900 * drive in use that has the least number of writers, then if
901 * no unmounted drive is found, we try that drive. This
902 * helps spread the load to the least used drives.
904 if (rctx.try_low_use_drive && dev == rctx.low_use_drive) {
905 Dmsg3(110, "OK dev=%s == low_drive=%s. JobId=%u\n",
906 dev->print_name(), rctx.low_use_drive->print_name(), jcr->JobId);
909 /* If he wants a free drive, but this one is busy, no go */
910 if (!rctx.PreferMountedVols && dev->is_busy()) {
911 /* Save least used drive */
912 if ((dev->num_writers + dev->reserved_device) < rctx.num_writers) {
913 rctx.num_writers = dev->num_writers + dev->reserved_device;
914 rctx.low_use_drive = dev;
915 Dmsg2(110, "set low use drive=%s num_writers=%d\n", dev->print_name(),
918 Dmsg1(110, "not low use num_writers=%d\n", dev->num_writers+
919 dev->reserved_device);
921 Dmsg1(110, "failed: !prefMnt && busy. JobId=%u\n", jcr->JobId);
922 Mmsg(jcr->errmsg, _("3605 JobId=%u wants free drive but device %s is busy.\n"),
923 jcr->JobId, dev->print_name());
924 queue_reserve_message(jcr);
928 /* Check for prefer mounted volumes */
929 if (rctx.PreferMountedVols && !dev->VolHdr.VolumeName[0] && dev->is_tape()) {
930 Mmsg(jcr->errmsg, _("3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n"),
931 jcr->JobId, dev->print_name());
932 queue_reserve_message(jcr);
933 Dmsg1(110, "failed: want mounted -- no vol JobId=%u\n", jcr->JobId);
934 return 0; /* No volume mounted */
937 /* Check for exact Volume name match */
938 if (rctx.exact_match && rctx.have_volume &&
939 strcmp(dev->VolHdr.VolumeName, rctx.VolumeName) != 0) {
940 Mmsg(jcr->errmsg, _("3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n"),
941 jcr->JobId, rctx.VolumeName, dev->VolHdr.VolumeName,
943 queue_reserve_message(jcr);
944 Dmsg2(110, "failed: Not exact match have=%s want=%s\n",
945 dev->VolHdr.VolumeName, rctx.VolumeName);
950 /* Check for unused autochanger drive */
951 if (rctx.autochanger_only && dev->num_writers == 0 &&
952 dev->VolHdr.VolumeName[0] == 0) {
953 /* Device is available but not yet reserved, reserve it for us */
954 Dmsg2(100, "OK Res Unused autochanger %s JobId=%u.\n",
955 dev->print_name(), jcr->JobId);
956 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
957 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
958 return 1; /* reserve drive */
962 * Handle the case that there are no writers
964 if (dev->num_writers == 0) {
965 /* Now check if there are any reservations on the drive */
966 if (dev->reserved_device) {
967 /* Now check if we want the same Pool and pool type */
968 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
969 strcmp(dev->pool_type, dcr->pool_type) == 0) {
970 /* OK, compatible device */
971 Dmsg2(100, "OK dev: %s num_writers=0, reserved, pool matches JobId=%u\n",
972 dev->print_name(), jcr->JobId);
975 /* Drive Pool not suitable for us */
976 Mmsg(jcr->errmsg, _("3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" on drive %s.\n"),
977 jcr->JobId, dcr->pool_name, dev->pool_name, dev->print_name());
978 queue_reserve_message(jcr);
979 Dmsg2(110, "failed: busy num_writers=0, reserved, pool=%s wanted=%s\n",
980 dev->pool_name, dcr->pool_name);
983 } else if (dev->can_append()) {
984 /* Device in append mode, check if changing pool */
985 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
986 strcmp(dev->pool_type, dcr->pool_type) == 0) {
987 Dmsg2(100, "OK dev: %s num_writers=0, can_append, pool matches. JobId=%u\n",
988 dev->print_name(), jcr->JobId);
989 /* OK, compatible device */
992 /* Changing pool, unload old tape if any in drive */
993 Dmsg0(100, "OK dev: num_writers=0, not reserved, pool change, unload changer\n");
994 unload_autochanger(dcr, 0);
997 /* Device is available but not yet reserved, reserve it for us */
998 Dmsg2(100, "OK Dev avail reserved %s JobId=%u\n", dev->print_name(),
1000 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1001 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1002 return 1; /* reserve drive */
1006 * Check if the device is in append mode with writers (i.e.
1007 * available if pool is the same).
1009 if (dev->can_append() || dev->num_writers > 0) {
1010 /* Yes, now check if we want the same Pool and pool type */
1011 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1012 strcmp(dev->pool_type, dcr->pool_type) == 0) {
1013 Dmsg2(100, "OK dev: %s num_writers>=0, can_append, pool matches. JobId=%u\n",
1014 dev->print_name(), jcr->JobId);
1015 /* OK, compatible device */
1018 /* Drive Pool not suitable for us */
1019 Mmsg(jcr->errmsg, _("3609 JobId=%u wants Pool=\"%s\" but has Pool=\"%s\" on drive %s.\n"),
1020 jcr->JobId, dcr->pool_name, dev->pool_name, dev->print_name());
1021 queue_reserve_message(jcr);
1022 Dmsg2(110, "failed: busy num_writers>0, can_append, pool=%s wanted=%s\n",
1023 dev->pool_name, dcr->pool_name);
1024 return 0; /* wait */
1027 Pmsg0(000, _("Logic error!!!! Should not get here.\n"));
1028 Mmsg(jcr->errmsg, _("3910 JobId=%u Logic error!!!! drive %s Should not get here.\n"),
1029 jcr->JobId, dev->print_name());
1030 queue_reserve_message(jcr);
1031 Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
1032 return -1; /* error, should not get here */
1034 Mmsg(jcr->errmsg, _("3911 JobId=%u failed reserve drive %s.\n"),
1035 jcr->JobId, dev->print_name());
1036 queue_reserve_message(jcr);
1037 Dmsg2(110, "failed: No reserve %s JobId=%u\n", dev->print_name(), jcr->JobId);
1042 * search_lock is already set on entering this routine
1044 static void queue_reserve_message(JCR *jcr)
1047 alist *msgs = jcr->reserve_msgs;
1054 * Look for duplicate message. If found, do
1057 for (i=msgs->size()-1; i >= 0; i--) {
1058 msg = (char *)msgs->get(i);
1062 /* Comparison based on 4 digit message number */
1063 if (strncmp(msg, jcr->errmsg, 4) == 0) {
1067 /* Message unique, so insert it */
1068 jcr->reserve_msgs->push(bstrdup(jcr->errmsg));
1072 * Send any reservation messages queued for this jcr
1074 void send_drive_reserve_messages(JCR *jcr, void sendit(const char *msg, int len, void *sarg), void *arg)
1080 lock_reservations();
1081 msgs = jcr->reserve_msgs;
1082 if (!msgs || msgs->size() == 0) {
1083 unlock_reservations();
1086 for (i=msgs->size()-1; i >= 0; i--) {
1087 msg = (char *)msgs->get(i);
1089 sendit(" ", 3, arg);
1090 sendit(msg, strlen(msg), arg);
1095 unlock_reservations();