2 * Drive reservation functions for Storage Daemon
6 * Split from job.c and acquire.c June 2005
12 Copyright (C) 2000-2006 Kern Sibbald
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License
16 version 2 as amended with additional clauses defined in the
17 file LICENSE in the main source directory.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 the file LICENSE for additional details.
29 static dlist *vol_list = NULL;
30 static pthread_mutex_t vol_list_lock = PTHREAD_MUTEX_INITIALIZER;
32 /* Forward referenced functions */
33 static int can_reserve_drive(DCR *dcr, RCTX &rctx);
34 static int reserve_device(RCTX &rctx);
35 static bool reserve_device_for_read(DCR *dcr);
36 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx);
37 static bool use_storage_cmd(JCR *jcr);
38 static void queue_reserve_message(JCR *jcr);
40 /* Requests from the Director daemon */
41 static char use_storage[] = "use storage=%127s media_type=%127s "
42 "pool_name=%127s pool_type=%127s append=%d copy=%d stripe=%d\n";
43 static char use_device[] = "use device=%127s\n";
45 /* Responses sent to Director daemon */
46 static char OK_device[] = "3000 OK use device device=%s\n";
47 static char NO_device[] = "3924 Device \"%s\" not in SD Device resources.\n";
48 static char BAD_use[] = "3913 Bad use command: %s\n";
50 bool use_cmd(JCR *jcr)
53 * Get the device, media, and pool information
55 if (!use_storage_cmd(jcr)) {
56 set_jcr_job_status(jcr, JS_ErrorTerminated);
57 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
63 static int my_compare(void *item1, void *item2)
65 return strcmp(((VOLRES *)item1)->vol_name, ((VOLRES *)item2)->vol_name);
68 static brwlock_t reservation_lock;
70 void init_reservations_lock()
73 if ((errstat=rwl_init(&reservation_lock)) != 0) {
75 Emsg1(M_ABORT, 0, _("Unable to initialize reservation lock. ERR=%s\n"),
76 be.strerror(errstat));
81 void term_reservations_lock()
83 rwl_destroy(&reservation_lock);
86 /* This applies to a drive and to Volumes */
87 void lock_reservations()
90 if ((errstat=rwl_writelock(&reservation_lock)) != 0) {
92 Emsg2(M_ABORT, 0, "rwl_writelock failure. stat=%d: ERR=%s\n",
93 errstat, be.strerror(errstat));
97 void unlock_reservations()
100 if ((errstat=rwl_writeunlock(&reservation_lock)) != 0) {
102 Emsg2(M_ABORT, 0, "rwl_writeunlock failure. stat=%d: ERR=%s\n",
103 errstat, be.strerror(errstat));
109 * Put a new Volume entry in the Volume list. This
110 * effectively reserves the volume so that it will
111 * not be mounted again.
113 * Return: VOLRES entry on success
114 * NULL if the Volume is already in the list
116 VOLRES *new_volume(DCR *dcr, const char *VolumeName)
120 Dmsg1(400, "new_volume %s\n", VolumeName);
122 * We lock the reservations system here to ensure
123 * when adding a new volume that no newly scheduled
124 * job can reserve it.
130 foreach_dlist(vol, vol_list) {
131 if (vol && vol->dev == dcr->dev) {
132 vol_list->remove(vol);
141 vol = (VOLRES *)malloc(sizeof(VOLRES));
142 memset(vol, 0, sizeof(VOLRES));
143 vol->vol_name = bstrdup(VolumeName);
146 Dmsg2(100, "New Vol=%s dev=%s\n", VolumeName, dcr->dev->print_name());
147 nvol = (VOLRES *)vol_list->binary_insert(vol, my_compare);
153 DEVICE *dev = nvol->dev;
154 if (!dev->is_busy()) {
155 Dmsg3(100, "Swap vol=%s from dev=%s to %s\n", VolumeName,
156 dev->print_name(), dcr->dev->print_name());
157 nvol->dev = dcr->dev;
158 dev->VolHdr.VolumeName[0] = 0;
160 Dmsg3(100, "!!!! could not swap vol=%s from dev=%s to %s\n", VolumeName,
161 dev->print_name(), dcr->dev->print_name());
166 unlock_reservations();
171 * Search for a Volume name in the Volume list.
173 * Returns: VOLRES entry on success
174 * NULL if the Volume is not in the list
176 VOLRES *find_volume(const char *VolumeName)
179 /* Do not lock reservations here */
181 vol.vol_name = bstrdup(VolumeName);
182 fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare);
189 * Free a Volume from the Volume list
191 * Returns: true if the Volume found and removed from the list
192 * false if the Volume is not in the list
194 bool free_volume(DEVICE *dev)
199 if (dev->VolHdr.VolumeName[0] == 0) {
200 Dmsg1(100, "free_volume: no vol on dev %s\n", dev->print_name());
202 * Our device has no VolumeName listed, but
203 * search the list for any Volume attached to
204 * this device and remove it.
206 foreach_dlist(fvol, vol_list) {
207 if (fvol && fvol->dev == dev) {
208 vol_list->remove(fvol);
209 if (fvol->vol_name) {
210 Dmsg2(100, "free_volume %s dev=%s\n", fvol->vol_name, dev->print_name());
211 free(fvol->vol_name);
219 Dmsg1(400, "free_volume %s\n", dev->VolHdr.VolumeName);
220 vol.vol_name = bstrdup(dev->VolHdr.VolumeName);
221 fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare);
223 vol_list->remove(fvol);
224 Dmsg2(100, "free_volume %s dev=%s\n", fvol->vol_name, dev->print_name());
225 free(fvol->vol_name);
229 dev->VolHdr.VolumeName[0] = 0;
235 /* Free volume reserved by this dcr but not attached to a dev */
236 void free_unused_volume(DCR *dcr)
241 for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
242 if (vol->dcr == dcr && (vol->dev == NULL ||
243 strcmp(vol->vol_name, vol->dev->VolHdr.VolumeName) != 0)) {
244 vol_list->remove(vol);
245 Dmsg1(100, "free_unused_volume %s\n", vol->vol_name);
255 * List Volumes -- this should be moved to status.c
257 void list_volumes(void sendit(const char *msg, int len, void *sarg), void *arg)
263 msg = (char *)get_pool_memory(PM_MESSAGE);
266 for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
268 len = Mmsg(msg, "%s on device %s\n", vol->vol_name, vol->dev->print_name());
269 sendit(msg, len, arg);
271 len = Mmsg(msg, "%s\n", vol->vol_name);
272 sendit(msg, len, arg);
277 free_pool_memory(msg);
280 /* Create the Volume list */
281 void create_volume_list()
283 VOLRES *dummy = NULL;
284 if (vol_list == NULL) {
285 vol_list = New(dlist(dummy, &dummy->link));
289 /* Release all Volumes from the list */
290 void free_volume_list()
297 for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
298 Dmsg3(000, "Unreleased Volume=%s dcr=0x%x dev=0x%x\n", vol->vol_name,
306 bool is_volume_in_use(DCR *dcr)
308 VOLRES *vol = find_volume(dcr->VolumeName);
310 Dmsg1(100, "Vol=%s not in use.\n", dcr->VolumeName);
311 return false; /* vol not in list */
313 if (!vol->dev) { /* vol not attached to device */
314 Dmsg1(100, "Vol=%s has no dev.\n", dcr->VolumeName);
317 if (dcr->dev == vol->dev) { /* same device OK */
318 Dmsg1(100, "Vol=%s on same dev.\n", dcr->VolumeName);
321 if (!vol->dev->is_busy()) {
322 Dmsg2(100, "Vol=%s dev=%s not busy.\n", dcr->VolumeName, vol->dev->print_name());
325 Dmsg2(100, "Vol=%s used by %s.\n", dcr->VolumeName, vol->dev->print_name());
331 * We get the following type of information:
333 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=1 copy=0 strip=0
337 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=0 copy=0 strip=0
341 static bool use_storage_cmd(JCR *jcr)
343 POOL_MEM store_name, dev_name, media_type, pool_name, pool_type;
344 BSOCK *dir = jcr->dir_bsock;
354 memset(&rctx, 0, sizeof(RCTX));
357 * If there are multiple devices, the director sends us
358 * use_device for each device that it wants to use.
360 dirstore = New(alist(10, not_owned_by_alist));
361 // Dmsg2(000, "dirstore=%p JobId=%u\n", dirstore, jcr->JobId);
362 msgs = jcr->reserve_msgs = New(alist(10, not_owned_by_alist));
364 Dmsg1(100, "<dird: %s", dir->msg);
365 ok = sscanf(dir->msg, use_storage, store_name.c_str(),
366 media_type.c_str(), pool_name.c_str(),
367 pool_type.c_str(), &append, &Copy, &Stripe) == 7;
372 jcr->write_store = dirstore;
374 jcr->read_store = dirstore;
376 rctx.append = append;
377 unbash_spaces(store_name);
378 unbash_spaces(media_type);
379 unbash_spaces(pool_name);
380 unbash_spaces(pool_type);
381 store = new DIRSTORE;
382 dirstore->append(store);
383 memset(store, 0, sizeof(DIRSTORE));
384 store->device = New(alist(10));
385 bstrncpy(store->name, store_name, sizeof(store->name));
386 bstrncpy(store->media_type, media_type, sizeof(store->media_type));
387 bstrncpy(store->pool_name, pool_name, sizeof(store->pool_name));
388 bstrncpy(store->pool_type, pool_type, sizeof(store->pool_type));
389 store->append = append;
391 /* Now get all devices */
392 while (bnet_recv(dir) >= 0) {
393 Dmsg1(100, "<dird device: %s", dir->msg);
394 ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
398 unbash_spaces(dev_name);
399 store->device->append(bstrdup(dev_name.c_str()));
401 } while (ok && bnet_recv(dir) >= 0);
404 /* This loop is debug code and can be removed */
405 /* ***FIXME**** remove after 1.38 release */
407 foreach_alist(store, dirstore) {
408 Dmsg5(110, "Storage=%s media_type=%s pool=%s pool_type=%s append=%d\n",
409 store->name, store->media_type, store->pool_name,
410 store->pool_type, store->append);
411 foreach_alist(device_name, store->device) {
412 Dmsg1(110, " Device=%s\n", device_name);
417 init_jcr_device_wait_timers(jcr);
419 * At this point, we have a list of all the Director's Storage
420 * resources indicated for this Job, which include Pool, PoolType,
421 * storage name, and Media type.
422 * Then for each of the Storage resources, we have a list of
423 * device names that were given.
425 * Wiffle through them and find one that can do the backup.
428 bool first = true; /* print wait message once */
430 rctx.notify_dir = true;
432 for ( ; !fail && !job_canceled(jcr); ) {
433 while ((msg = (char *)msgs->pop())) {
436 rctx.suitable_device = false;
437 rctx.have_volume = false;
438 rctx.any_drive = false;
439 if (!jcr->PreferMountedVols) {
440 /* Look for unused drives in autochangers */
441 rctx.num_writers = 20000000; /* start with impossible number */
442 rctx.low_use_drive = NULL;
443 rctx.PreferMountedVols = false;
444 rctx.exact_match = false;
445 rctx.autochanger_only = true;
446 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
447 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
448 rctx.autochanger_only, rctx.any_drive);
449 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
452 /* Look through all drives possibly for low_use drive */
453 if (rctx.low_use_drive) {
454 rctx.try_low_use_drive = true;
455 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
458 rctx.try_low_use_drive = false;
460 rctx.autochanger_only = false;
461 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
462 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
463 rctx.autochanger_only, rctx.any_drive);
464 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
468 /* Look for an exact match all drives */
469 rctx.PreferMountedVols = true;
470 rctx.exact_match = true;
471 rctx.autochanger_only = false;
472 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
473 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
474 rctx.autochanger_only, rctx.any_drive);
475 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
478 /* Look for any mounted drive */
479 rctx.exact_match = false;
480 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
481 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
482 rctx.autochanger_only, rctx.any_drive);
483 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
487 rctx.any_drive = true;
488 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
489 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
490 rctx.autochanger_only, rctx.any_drive);
491 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
494 /* Keep reservations locked *except* during wait_for_device() */
495 unlock_reservations();
496 if (!rctx.suitable_device || !wait_for_device(jcr, first)) {
497 Dmsg0(100, "Fail. !suitable_device || !wait_for_device\n");
502 bnet_sig(dir, BNET_HEARTBEAT); /* Inform Dir that we are alive */
504 unlock_reservations();
507 * If we get here, there are no suitable devices available, which
508 * means nothing configured. If a device is suitable but busy
509 * with another Volume, we will not come here.
511 unbash_spaces(dir->msg);
512 pm_strcpy(jcr->errmsg, dir->msg);
513 Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
514 Jmsg(jcr, M_FATAL, 0, _("\n"
515 " Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"),
516 dev_name.c_str(), media_type.c_str());
517 bnet_fsend(dir, NO_device, dev_name.c_str());
519 Dmsg1(100, ">dird: %s", dir->msg);
522 unbash_spaces(dir->msg);
523 pm_strcpy(jcr->errmsg, dir->msg);
524 Jmsg(jcr, M_FATAL, 0, _("Failed command: %s\n"), jcr->errmsg);
525 bnet_fsend(dir, BAD_use, jcr->errmsg);
526 Dmsg1(100, ">dird: %s", dir->msg);
533 void release_msgs(JCR *jcr)
535 alist *msgs = jcr->reserve_msgs;
542 while ((msg = (char *)msgs->pop())) {
546 jcr->reserve_msgs = NULL;
547 unlock_reservations();
551 * Search for a device suitable for this job.
553 bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx)
561 dirstore = jcr->write_store;
563 dirstore = jcr->read_store;
566 * For each storage device that the user specified, we
567 * search and see if there is a resource for that device.
569 Dmsg4(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d\n",
570 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
571 rctx.autochanger_only);
573 foreach_alist(store, dirstore) {
575 foreach_alist(device_name, store->device) {
577 rctx.device_name = device_name;
578 stat = search_res_for_device(rctx);
579 if (stat == 1) { /* found available device */
580 Dmsg1(100, "Suitable device found=%s\n", device_name);
583 } else if (stat == 0) { /* device busy */
584 Dmsg1(110, "Suitable device found=%s, not used: busy\n", device_name);
586 /* otherwise error */
587 Dmsg0(110, "No suitable device found.\n");
599 * Search for a particular storage device with particular storage
600 * characteristics (MediaType).
602 int search_res_for_device(RCTX &rctx)
604 AUTOCHANGER *changer;
605 BSOCK *dir = rctx.jcr->dir_bsock;
609 Dmsg1(110, "Search res for %s\n", rctx.device_name);
610 /* Look through Autochangers first */
611 foreach_res(changer, R_AUTOCHANGER) {
612 Dmsg1(150, "Try match changer res=%s\n", changer->hdr.name);
613 /* Find resource, and make sure we were able to open it */
614 if (fnmatch(rctx.device_name, changer->hdr.name, 0) == 0) {
615 /* Try each device in this AutoChanger */
616 foreach_alist(rctx.device, changer->device) {
617 Dmsg1(110, "Try changer device %s\n", rctx.device->hdr.name);
618 stat = reserve_device(rctx);
619 if (stat != 1) { /* try another device */
623 if (rctx.store->append == SD_APPEND) {
624 Dmsg2(100, "Device %s reserved=%d for append.\n", rctx.device->hdr.name,
625 rctx.jcr->dcr->dev->reserved_device);
627 Dmsg2(100, "Device %s reserved=%d for read.\n", rctx.device->hdr.name,
628 rctx.jcr->read_dcr->dev->reserved_device);
630 if (rctx.notify_dir) {
631 pm_strcpy(dev_name, rctx.device->hdr.name);
632 bash_spaces(dev_name);
633 ok = bnet_fsend(dir, OK_device, dev_name.c_str()); /* Return real device name */
634 Dmsg1(100, ">dird changer: %s", dir->msg);
643 /* Now if requested look through regular devices */
644 if (!rctx.autochanger_only) {
645 foreach_res(rctx.device, R_DEVICE) {
646 Dmsg1(150, "Try match res=%s\n", rctx.device->hdr.name);
647 /* Find resource, and make sure we were able to open it */
648 if (fnmatch(rctx.device_name, rctx.device->hdr.name, 0) == 0) {
649 stat = reserve_device(rctx);
653 if (rctx.notify_dir) {
654 bash_spaces(rctx.device_name);
655 ok = bnet_fsend(dir, OK_device, rctx.device_name);
656 Dmsg1(100, ">dird dev: %s", dir->msg);
664 return -1; /* nothing found */
668 * Try to reserve a specific device.
670 * Returns: 1 -- OK, have DCR
674 static int reserve_device(RCTX &rctx)
678 const int name_len = MAX_NAME_LENGTH;
680 /* Make sure MediaType is OK */
681 Dmsg2(110, "MediaType device=%s request=%s\n",
682 rctx.device->media_type, rctx.store->media_type);
683 if (strcmp(rctx.device->media_type, rctx.store->media_type) != 0) {
687 /* Make sure device exists -- i.e. we can stat() it */
688 if (!rctx.device->dev) {
689 rctx.device->dev = init_dev(rctx.jcr, rctx.device);
691 if (!rctx.device->dev) {
692 if (rctx.device->changer_res) {
693 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
694 " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
695 rctx.device->hdr.name, rctx.device_name);
697 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
698 " Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
701 return -1; /* no use waiting */
704 rctx.suitable_device = true;
705 Dmsg2(110, "Try reserve %s JobId=%u\n", rctx.device->hdr.name,
707 dcr = new_dcr(rctx.jcr, rctx.device->dev);
709 BSOCK *dir = rctx.jcr->dir_bsock;
710 bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), rctx.device_name);
711 Dmsg1(100, ">dird: %s", dir->msg);
714 bstrncpy(dcr->pool_name, rctx.store->pool_name, name_len);
715 bstrncpy(dcr->pool_type, rctx.store->pool_type, name_len);
716 bstrncpy(dcr->media_type, rctx.store->media_type, name_len);
717 bstrncpy(dcr->dev_name, rctx.device_name, name_len);
718 if (rctx.store->append == SD_APPEND) {
719 if (rctx.exact_match && !rctx.have_volume) {
720 dcr->any_volume = true;
721 if (dir_find_next_appendable_volume(dcr)) {
722 bstrncpy(rctx.VolumeName, dcr->VolumeName, sizeof(rctx.VolumeName));
723 Dmsg2(100, "JobId=%u looking for Volume=%s\n", rctx.jcr->JobId, rctx.VolumeName);
724 rctx.have_volume = true;
726 Dmsg0(100, "No next volume found\n");
727 rctx.VolumeName[0] = 0;
730 ok = reserve_device_for_append(dcr, rctx);
733 Dmsg5(100, "Reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
734 dcr->dev->reserved_device,
735 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
738 ok = reserve_device_for_read(dcr);
740 rctx.jcr->read_dcr = dcr;
741 Dmsg5(100, "Read reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
742 dcr->dev->reserved_device,
743 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
748 Dmsg0(110, "Not OK.\n");
755 * We "reserve" the drive by setting the ST_READ bit. No one else
756 * should touch the drive until that is cleared.
757 * This allows the DIR to "reserve" the device before actually
760 static bool reserve_device_for_read(DCR *dcr)
762 DEVICE *dev = dcr->dev;
768 /* Get locks in correct order */
769 unlock_reservations();
773 if (is_device_unmounted(dev)) {
774 Dmsg1(200, "Device %s is BLOCKED due to user unmount.\n", dev->print_name());
775 Mmsg(jcr->errmsg, _("3601 JobId=%u device %s is BLOCKED due to user unmount.\n"),
776 jcr->JobId, dev->print_name());
777 queue_reserve_message(jcr);
781 if (dev->is_busy()) {
782 Dmsg4(200, "Device %s is busy ST_READ=%d num_writers=%d reserved=%d.\n", dev->print_name(),
783 dev->state & ST_READ?1:0, dev->num_writers, dev->reserved_device);
784 Mmsg(jcr->errmsg, _("3602 JobId=%u device %s is busy (already reading/writing).\n"),
785 jcr->JobId, dev->print_name());
786 queue_reserve_message(jcr);
793 dev->reserved_device++;
794 Dmsg3(100, "Inc reserve=%d dev=%s %p\n", dev->reserved_device,
795 dev->print_name(), dev);
796 dcr->reserved_device = true;
805 * We reserve the device for appending by incrementing the
806 * reserved_device. We do virtually all the same work that
807 * is done in acquire_device_for_append(), but we do
808 * not attempt to mount the device. This routine allows
809 * the DIR to reserve multiple devices before *really*
810 * starting the job. It also permits the SD to refuse
811 * certain devices (not up, ...).
813 * Note, in reserving a device, if the device is for the
814 * same pool and the same pool type, then it is acceptable.
815 * The Media Type has already been checked. If we are
816 * the first tor reserve the device, we put the pool
817 * name and pool type in the device record.
819 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
822 DEVICE *dev = dcr->dev;
829 /* If device is being read, we cannot write it */
830 if (dev->can_read()) {
831 Mmsg(jcr->errmsg, _("3603 JobId=%u device %s is busy reading.\n"),
832 jcr->JobId, dev->print_name());
833 Dmsg1(110, "%s", jcr->errmsg);
834 queue_reserve_message(jcr);
838 /* If device is unmounted, we are out of luck */
839 if (is_device_unmounted(dev)) {
840 Mmsg(jcr->errmsg, _("3604 JobId=%u device %s is BLOCKED due to user unmount.\n"),
841 jcr->JobId, dev->print_name());
842 Dmsg1(110, "%s", jcr->errmsg);
843 queue_reserve_message(jcr);
847 Dmsg1(110, "reserve_append device is %s\n", dev->is_tape()?"tape":"disk");
849 /* Now do detailed tests ... */
850 if (can_reserve_drive(dcr, rctx) != 1) {
851 Dmsg0(110, "can_reserve_drive!=1\n");
855 dev->reserved_device++;
856 Dmsg3(100, "Inc reserve=%d dev=%s %p\n", dev->reserved_device,
857 dev->print_name(), dev);
858 dcr->reserved_device = true;
867 * Returns: 1 if drive can be reserved
868 * 0 if we should wait
869 * -1 on error or impossibility
871 static int can_reserve_drive(DCR *dcr, RCTX &rctx)
873 DEVICE *dev = dcr->dev;
876 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
877 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
878 rctx.autochanger_only, rctx.any_drive);
880 /* setting any_drive overrides PreferMountedVols flag */
881 if (!rctx.any_drive) {
883 * When PreferMountedVols is set, we keep track of the
884 * drive in use that has the least number of writers, then if
885 * no unmounted drive is found, we try that drive. This
886 * helps spread the load to the least used drives.
888 if (rctx.try_low_use_drive && dev == rctx.low_use_drive) {
889 Dmsg3(110, "OK dev=%s == low_drive=%s. JobId=%u\n",
890 dev->print_name(), rctx.low_use_drive->print_name(), jcr->JobId);
893 /* If he wants a free drive, but this one is busy, no go */
894 if (!rctx.PreferMountedVols && dev->is_busy()) {
895 /* Save least used drive */
896 if ((dev->num_writers + dev->reserved_device) < rctx.num_writers) {
897 rctx.num_writers = dev->num_writers + dev->reserved_device;
898 rctx.low_use_drive = dev;
899 Dmsg2(110, "set low use drive=%s num_writers=%d\n", dev->print_name(),
902 Dmsg1(110, "not low use num_writers=%d\n", dev->num_writers+
903 dev->reserved_device);
905 Dmsg1(110, "failed: !prefMnt && busy. JobId=%u\n", jcr->JobId);
906 Mmsg(jcr->errmsg, _("3605 JobId=%u wants free drive but device %s is busy.\n"),
907 jcr->JobId, dev->print_name());
908 queue_reserve_message(jcr);
912 /* Check for prefer mounted volumes */
913 if (rctx.PreferMountedVols && !dev->VolHdr.VolumeName[0] && dev->is_tape()) {
914 Mmsg(jcr->errmsg, _("3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n"),
915 jcr->JobId, dev->print_name());
916 queue_reserve_message(jcr);
917 Dmsg1(110, "failed: want mounted -- no vol JobId=%u\n", jcr->JobId);
918 return 0; /* No volume mounted */
921 /* Check for exact Volume name match */
922 if (rctx.exact_match && rctx.have_volume &&
923 strcmp(dev->VolHdr.VolumeName, rctx.VolumeName) != 0) {
924 Mmsg(jcr->errmsg, _("3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n"),
925 jcr->JobId, rctx.VolumeName, dev->VolHdr.VolumeName,
927 queue_reserve_message(jcr);
928 Dmsg2(110, "failed: Not exact match have=%s want=%s\n",
929 dev->VolHdr.VolumeName, rctx.VolumeName);
934 /* Check for unused autochanger drive */
935 if (rctx.autochanger_only && dev->num_writers == 0 &&
936 dev->VolHdr.VolumeName[0] == 0) {
937 /* Device is available but not yet reserved, reserve it for us */
938 Dmsg2(100, "OK Res Unused autochanger %s JobId=%u.\n",
939 dev->print_name(), jcr->JobId);
940 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
941 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
942 return 1; /* reserve drive */
946 * Handle the case that there are no writers
948 if (dev->num_writers == 0) {
949 /* Now check if there are any reservations on the drive */
950 if (dev->reserved_device) {
951 /* Now check if we want the same Pool and pool type */
952 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
953 strcmp(dev->pool_type, dcr->pool_type) == 0) {
954 /* OK, compatible device */
955 Dmsg2(100, "OK dev: %s num_writers=0, reserved, pool matches JobId=%u\n",
956 dev->print_name(), jcr->JobId);
959 /* Drive Pool not suitable for us */
960 Mmsg(jcr->errmsg, _("3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" on drive %s.\n"),
961 jcr->JobId, dcr->pool_name, dev->pool_name, dev->print_name());
962 queue_reserve_message(jcr);
963 Dmsg2(110, "failed: busy num_writers=0, reserved, pool=%s wanted=%s\n",
964 dev->pool_name, dcr->pool_name);
967 } else if (dev->can_append()) {
968 /* Device in append mode, check if changing pool */
969 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
970 strcmp(dev->pool_type, dcr->pool_type) == 0) {
971 Dmsg2(100, "OK dev: %s num_writers=0, can_append, pool matches. JobId=%u\n",
972 dev->print_name(), jcr->JobId);
973 /* OK, compatible device */
976 /* Changing pool, unload old tape if any in drive */
977 Dmsg0(100, "OK dev: num_writers=0, not reserved, pool change, unload changer\n");
978 unload_autochanger(dcr, 0);
981 /* Device is available but not yet reserved, reserve it for us */
982 Dmsg2(100, "OK Dev avail reserved %s JobId=%u\n", dev->print_name(),
984 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
985 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
986 return 1; /* reserve drive */
990 * Check if the device is in append mode with writers (i.e.
991 * available if pool is the same).
993 if (dev->can_append() || dev->num_writers > 0) {
994 /* Yes, now check if we want the same Pool and pool type */
995 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
996 strcmp(dev->pool_type, dcr->pool_type) == 0) {
997 Dmsg2(100, "OK dev: %s num_writers>=0, can_append, pool matches. JobId=%u\n",
998 dev->print_name(), jcr->JobId);
999 /* OK, compatible device */
1002 /* Drive Pool not suitable for us */
1003 Mmsg(jcr->errmsg, _("3609 JobId=%u wants Pool=\"%s\" but has Pool=\"%s\" on drive %s.\n"),
1004 jcr->JobId, dcr->pool_name, dev->pool_name, dev->print_name());
1005 queue_reserve_message(jcr);
1006 Dmsg2(110, "failed: busy num_writers>0, can_append, pool=%s wanted=%s\n",
1007 dev->pool_name, dcr->pool_name);
1008 return 0; /* wait */
1011 Pmsg0(000, _("Logic error!!!! Should not get here.\n"));
1012 Mmsg(jcr->errmsg, _("3910 JobId=%u Logic error!!!! drive %s Should not get here.\n"),
1013 jcr->JobId, dev->print_name());
1014 queue_reserve_message(jcr);
1015 Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
1016 return -1; /* error, should not get here */
1018 Mmsg(jcr->errmsg, _("3911 JobId=%u failed reserve drive %s.\n"),
1019 jcr->JobId, dev->print_name());
1020 queue_reserve_message(jcr);
1021 Dmsg2(110, "failed: No reserve %s JobId=%u\n", dev->print_name(), jcr->JobId);
1026 * search_lock is already set on entering this routine
1028 static void queue_reserve_message(JCR *jcr)
1031 alist *msgs = jcr->reserve_msgs;
1038 * Look for duplicate message. If found, do
1041 for (i=msgs->size()-1; i >= 0; i--) {
1042 msg = (char *)msgs->get(i);
1046 /* Comparison based on 4 digit message number */
1047 if (strncmp(msg, jcr->errmsg, 4) == 0) {
1051 /* Message unique, so insert it */
1052 jcr->reserve_msgs->push(bstrdup(jcr->errmsg));
1056 * Send any reservation messages queued for this jcr
1058 void send_drive_reserve_messages(JCR *jcr, void sendit(const char *msg, int len, void *sarg), void *arg)
1064 lock_reservations();
1065 msgs = jcr->reserve_msgs;
1066 if (!msgs || msgs->size() == 0) {
1067 unlock_reservations();
1070 for (i=msgs->size()-1; i >= 0; i--) {
1071 msg = (char *)msgs->get(i);
1073 sendit(" ", 3, arg);
1074 sendit(msg, strlen(msg), arg);
1079 unlock_reservations();