2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of John Walker.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
29 * Drive reservation functions for Storage Daemon
33 * Split from job.c and acquire.c June 2005
42 const int dbglvl = 50;
44 static dlist *vol_list = NULL;
45 static brwlock_t reservation_lock;
46 static brwlock_t vol_list_lock;
48 /* Forward referenced functions */
49 static int can_reserve_drive(DCR *dcr, RCTX &rctx);
50 static int reserve_device(RCTX &rctx);
51 static bool reserve_device_for_read(DCR *dcr);
52 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx);
53 static bool use_storage_cmd(JCR *jcr);
54 static void queue_reserve_message(JCR *jcr);
55 static void pop_reserve_messages(JCR *jcr);
57 /* Requests from the Director daemon */
58 static char use_storage[] = "use storage=%127s media_type=%127s "
59 "pool_name=%127s pool_type=%127s append=%d copy=%d stripe=%d\n";
60 static char use_device[] = "use device=%127s\n";
62 /* Responses sent to Director daemon */
63 static char OK_device[] = "3000 OK use device device=%s\n";
64 static char NO_device[] = "3924 Device \"%s\" not in SD Device resources.\n";
65 static char BAD_use[] = "3913 Bad use command: %s\n";
67 bool use_cmd(JCR *jcr)
70 * Get the device, media, and pool information
72 if (!use_storage_cmd(jcr)) {
73 set_jcr_job_status(jcr, JS_ErrorTerminated);
74 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
80 static int my_compare(void *item1, void *item2)
82 return strcmp(((VOLRES *)item1)->vol_name, ((VOLRES *)item2)->vol_name);
86 * This allows a given thread to recursively call lock_reservations.
87 * It must, of course, call unlock_... the same number of times.
89 void init_reservations_lock()
92 if ((errstat=rwl_init(&reservation_lock)) != 0) {
94 Emsg1(M_ABORT, 0, _("Unable to initialize reservation lock. ERR=%s\n"),
95 be.bstrerror(errstat));
98 if ((errstat=rwl_init(&vol_list_lock)) != 0) {
100 Emsg1(M_ABORT, 0, _("Unable to initialize volume list lock. ERR=%s\n"),
101 be.bstrerror(errstat));
105 void term_reservations_lock()
107 rwl_destroy(&reservation_lock);
108 rwl_destroy(&vol_list_lock);
111 int reservations_lock_count = 0;
113 /* This applies to a drive and to Volumes */
114 void _lock_reservations()
117 reservations_lock_count++;
118 if ((errstat=rwl_writelock(&reservation_lock)) != 0) {
120 Emsg2(M_ABORT, 0, "rwl_writelock failure. stat=%d: ERR=%s\n",
121 errstat, be.bstrerror(errstat));
125 void _unlock_reservations()
128 reservations_lock_count--;
129 if ((errstat=rwl_writeunlock(&reservation_lock)) != 0) {
131 Emsg2(M_ABORT, 0, "rwl_writeunlock failure. stat=%d: ERR=%s\n",
132 errstat, be.bstrerror(errstat));
136 int vol_list_lock_count = 0;
139 * This allows a given thread to recursively call to lock_volumes()
144 vol_list_lock_count++;
145 if ((errstat=rwl_writelock(&vol_list_lock)) != 0) {
147 Emsg2(M_ABORT, 0, "rwl_writelock failure. stat=%d: ERR=%s\n",
148 errstat, be.bstrerror(errstat));
152 void _unlock_volumes()
155 vol_list_lock_count--;
156 if ((errstat=rwl_writeunlock(&vol_list_lock)) != 0) {
158 Emsg2(M_ABORT, 0, "rwl_writeunlock failure. stat=%d: ERR=%s\n",
159 errstat, be.bstrerror(errstat));
165 * List Volumes -- this should be moved to status.c
172 static void debug_list_volumes(const char *imsg)
175 POOL_MEM msg(PM_MESSAGE);
178 foreach_dlist(vol, vol_list) {
180 Mmsg(msg, "List from %s: %s at %p on device %s\n", imsg,
181 vol->vol_name, vol->vol_name, vol->dev->print_name());
183 Mmsg(msg, "List from %s: %s at %p no dev\n", imsg, vol->vol_name, vol->vol_name);
185 Dmsg1(dbglvl, "%s", msg.c_str());
190 foreach_dlist(vol, vol_list) {
191 if (vol->dev == dev) {
192 Dmsg0(dbglvl, "Two Volumes on same device.\n");
199 // Dmsg2(dbglvl, "List from %s: %d volumes\n", imsg, count);
205 * List Volumes -- this should be moved to status.c
207 void list_volumes(void sendit(const char *msg, int len, void *sarg), void *arg)
210 POOL_MEM msg(PM_MESSAGE);
214 foreach_dlist(vol, vol_list) {
215 DEVICE *dev = vol->dev;
217 len = Mmsg(msg, "%s on device %s\n", vol->vol_name, dev->print_name());
218 sendit(msg.c_str(), len, arg);
219 len = Mmsg(msg, " Reader=%d writers=%d reserved=%d released=%d\n",
220 dev->can_read()?1:0, dev->num_writers, dev->reserved_device, vol->released);
221 sendit(msg.c_str(), len, arg);
223 len = Mmsg(msg, "%s no device. released=%d\n", vol->vol_name, vol->released);
224 sendit(msg.c_str(), len, arg);
231 * Create a Volume item to put in the Volume list
232 * Ensure that the device points to it.
234 static VOLRES *new_vol_item(DCR *dcr, const char *VolumeName)
237 vol = (VOLRES *)malloc(sizeof(VOLRES));
238 memset(vol, 0, sizeof(VOLRES));
239 vol->vol_name = bstrdup(VolumeName);
241 Dmsg3(dbglvl, "new Vol=%s at %p dev=%s\n",
242 VolumeName, vol->vol_name, vol->dev->print_name());
246 static void free_vol_item(VOLRES *vol)
250 vol->dev->vol = NULL;
257 * Put a new Volume entry in the Volume list. This
258 * effectively reserves the volume so that it will
259 * not be mounted again.
261 * If the device has any current volume associated with it,
262 * and it is a different Volume, and the device is not busy,
263 * we release the old Volume item and insert the new one.
265 * It is assumed that the device is free and locked so that
266 * we can change the device structure.
268 * Some details of the Volume list handling:
270 * 1. The Volume list entry must be attached to the drive (rather than
271 * attached to a job as it currently is. I.e. the drive that "owns"
272 * the volume (reserved, in use, mounted)
273 * must point to the volume (still to be maintained in a list).
275 * 2. The Volume is entered in the list when a drive is reserved.
277 * 3. When a drive is in use, the device code must appropriately update the
278 * volume name as it changes (currently the list is static -- an entry is
279 * removed when the Volume is no longer reserved, in use or mounted).
280 * The new code must keep the same list entry as long as the drive
281 * has any volume associated with it but the volume name in the list
282 * must be updated when the drive has a different volume mounted.
284 * 4. A job that has reserved a volume, can un-reserve the volume, and if the
285 * volume is not mounted, and not reserved, and not in use, it will be
286 * removed from the list.
288 * 5. If a job wants to reserve a drive with a different Volume from the one on
289 * the drive, it can re-use the drive for the new Volume.
291 * 6. If a job wants a Volume that is in a different drive, it can either use the
292 * other drive or take the volume, only if the other drive is not in use or
295 * One nice aspect of this is that the reserve use count and the writer use count
296 * already exist and are correctly programmed and will need no changes -- use
297 * counts are always very tricky.
299 * The old code had a concept of "reserving" a Volume, but was changed
300 * to reserving and using a drive. A volume is must be attached to (owned by) a
301 * drive and can move from drive to drive or be unused given certain specific
302 * conditions of the drive. The key is that the drive must "own" the Volume.
303 * The old code had the job (dcr) owning the volume (more or less). The job was
304 * to change the insertion and removal of the volumes from the list to be based
305 * on the drive rather than the job.
307 * Return: VOLRES entry on success
308 * NULL volume busy on another drive
310 VOLRES *reserve_volume(DCR *dcr, const char *VolumeName)
313 DEVICE *dev = dcr->dev;
317 Dmsg1(dbglvl, "reserve_volume %s\n", VolumeName);
319 * We lock the reservations system here to ensure
320 * when adding a new volume that no newly scheduled
321 * job can reserve it.
324 debug_list_volumes("begin reserve_volume");
326 * First, remove any old volume attached to this device as it
332 * Make sure we don't remove the current volume we are inserting
333 * because it was probably inserted by another job.
335 if (strcmp(vol->vol_name, VolumeName) == 0) {
336 Dmsg1(dbglvl, "OK, vol=%s on device.\n", VolumeName);
337 goto get_out; /* Volume already on this device */
339 /* Don't release a volume if it is in use */
341 if (!vol->released) {
342 vol = NULL; /* vol in use */
346 Dmsg2(dbglvl, "reserve_vol free vol=%s at %p\n", vol->vol_name, vol->vol_name);
347 unload_autochanger(dcr, -1); /* unload the volume */
349 debug_list_volumes("reserve_vol free");
353 /* Create a new Volume entry */
354 nvol = new_vol_item(dcr, VolumeName);
357 * Now try to insert the new Volume
359 vol = (VOLRES *)vol_list->binary_insert(nvol, my_compare);
361 Dmsg2(dbglvl, "Found vol=%s dev-same=%d\n", vol->vol_name, dev==vol->dev);
363 * At this point, a Volume with this name already is in the list,
364 * so we simply release our new Volume entry. Note, this should
365 * only happen if we are moving the volume from one drive to another.
367 Dmsg2(dbglvl, "reserve_vol free-tmp vol=%s at %p\n",
368 vol->vol_name, vol->vol_name);
370 * Clear dev pointer so that free_vol_item() doesn't
371 * take away our volume.
373 nvol->dev = NULL; /* don't zap dev entry */
376 /* Check if we are trying to use the Volume on a different drive */
377 if (dev != vol->dev) {
378 /* Caller wants to switch Volume to another device */
379 if (!vol->dev->is_busy()) {
380 /* OK to move it -- I'm not sure this will work */
381 Dmsg3(dbglvl, "==== Swap vol=%s from dev=%s to %s\n", VolumeName,
382 vol->dev->print_name(), dev->print_name());
383 vol->dev->vol = NULL; /* take vol from old drive */
384 vol->dev->VolHdr.VolumeName[0] = 0;
385 vol->dev = dev; /* point vol at new drive */
386 dev->vol = vol; /* point dev at vol */
387 dev->VolHdr.VolumeName[0] = 0;
389 Dmsg3(dbglvl, "Volume busy could not swap vol=%s from dev=%s to %s\n",
390 VolumeName, vol->dev->print_name(), dev->print_name());
391 vol = NULL; /* device busy */
400 vol->released = false;
402 debug_list_volumes("end new volume");
408 * Switch from current device to given device
411 void switch_device(DCR *dcr, DEVICE *dev)
413 // lock_reservations();
417 memcpy(&save_dcr, dcr, sizeof(save_dcr));
418 clean_device(dcr); /* clean up the dcr */
420 dcr->dev = dev; /* get new device pointer */
421 Jmsg(dcr->jcr, M_INFO, 0, _("Device switch. New device %s chosen.\n"),
422 dcr->dev->print_name());
424 bstrncpy(dcr->VolumeName, save_dcr.VolumeName, sizeof(dcr->VolumeName));
425 bstrncpy(dcr->media_type, save_dcr.media_type, sizeof(dcr->media_type));
426 dcr->VolCatInfo.Slot = save_dcr.VolCatInfo.Slot;
427 bstrncpy(dcr->pool_name, save_dcr.pool_name, sizeof(dcr->pool_name));
428 bstrncpy(dcr->pool_type, save_dcr.pool_type, sizeof(dcr->pool_type));
429 bstrncpy(dcr->dev_name, save_dcr.dev_name, sizeof(dcr->dev_name));
431 dev->reserved_device++;
432 dcr->reserved_device = true;
438 * Search for a Volume name in the Volume list.
440 * Returns: VOLRES entry on success
441 * NULL if the Volume is not in the list
443 VOLRES *find_volume(DCR *dcr)
446 /* Do not lock reservations here */
448 vol.vol_name = bstrdup(dcr->VolumeName);
449 fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare);
451 Dmsg2(dbglvl, "find_vol=%s found=%d\n", dcr->VolumeName, fvol!=NULL);
452 debug_list_volumes("find_volume");
458 * Remove any reservation from a drive and tell the system
459 * that the volume is unused at least by us.
461 void unreserve_device(DCR *dcr)
463 DEVICE *dev = dcr->dev;
464 if (dcr->reserved_device) {
465 dcr->reserved_device = false;
466 dev->reserved_device--;
467 Dmsg2(dbglvl, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
468 dcr->reserved_device = false;
469 /* If we set read mode in reserving, remove it */
470 if (dev->can_read()) {
473 if (dev->num_writers < 0) {
474 Jmsg1(dcr->jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers);
475 dev->num_writers = 0;
483 * Free a Volume from the Volume list if it is no longer used
484 * Note, for tape drives we want to remember where the Volume
485 * was when last used, so rather than free the volume entry,
486 * we simply mark it "released" so when the drive is really
487 * needed for another volume, we can reuse it.
489 * Returns: true if the Volume found and "removed" from the list
490 * false if the Volume is not in the list or is in use
492 bool volume_unused(DCR *dcr)
494 DEVICE *dev = dcr->dev;
496 if (dev->vol == NULL) {
497 Dmsg1(dbglvl, "vol_unused: no vol on %s\n", dev->print_name());
498 debug_list_volumes("null vol cannot unreserve_volume");
502 if (dev->is_busy()) {
503 Dmsg1(dbglvl, "vol_unused: busy on %s\n", dev->print_name());
504 debug_list_volumes("dev busy cannot unreserve_volume");
509 * If this is a tape, we do not free the volume, rather we wait
510 * until the autoloader unloads it, or until another tape is
511 * explicitly read in this drive. This allows the SD to remember
512 * where the tapes are or last were.
514 dev->vol->released = true;
515 if (dev->is_tape() || dev->is_autochanger()) {
518 return free_volume(dev);
523 * Unconditionally release the volume entry
525 bool free_volume(DEVICE *dev)
529 if (dev->vol == NULL) {
530 Dmsg1(dbglvl, "No vol on dev %s\n", dev->print_name());
536 vol_list->remove(vol);
537 Dmsg2(dbglvl, "free_volume %s dev=%s\n", vol->vol_name, dev->print_name());
539 debug_list_volumes("free_volume");
545 /* Create the Volume list */
546 void create_volume_list()
549 if (vol_list == NULL) {
550 vol_list = New(dlist(vol, &vol->link));
554 /* Release all Volumes from the list */
555 void free_volume_list()
562 foreach_dlist(vol, vol_list) {
564 Dmsg2(dbglvl, "free vol_list Volume=%s dev=%s\n", vol->vol_name, vol->dev->print_name());
566 Dmsg1(dbglvl, "free vol_list Volume=%s No dev\n", vol->vol_name);
569 vol->vol_name = NULL;
576 bool is_volume_in_use(DCR *dcr)
578 VOLRES *vol = find_volume(dcr);
580 Dmsg1(dbglvl, "Vol=%s not in use.\n", dcr->VolumeName);
581 return false; /* vol not in list */
583 ASSERT(vol->dev != NULL);
585 if (dcr->dev == vol->dev) { /* same device OK */
586 Dmsg1(dbglvl, "Vol=%s on same dev.\n", dcr->VolumeName);
589 Dmsg3(dbglvl, "Vol=%s on %s we have %s\n", dcr->VolumeName,
590 vol->dev->print_name(), dcr->dev->print_name());
592 if (!vol->dev->is_busy()) {
593 Dmsg2(dbglvl, "Vol=%s dev=%s not busy.\n", dcr->VolumeName, vol->dev->print_name());
596 Dmsg2(dbglvl, "Vol=%s dev=%s busy.\n", dcr->VolumeName, vol->dev->print_name());
598 Dmsg2(dbglvl, "Vol=%s in use by %s.\n", dcr->VolumeName, vol->dev->print_name());
604 * We get the following type of information:
606 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=1 copy=0 strip=0
610 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=0 copy=0 strip=0
614 static bool use_storage_cmd(JCR *jcr)
616 POOL_MEM store_name, dev_name, media_type, pool_name, pool_type;
617 BSOCK *dir = jcr->dir_bsock;
625 memset(&rctx, 0, sizeof(RCTX));
628 * If there are multiple devices, the director sends us
629 * use_device for each device that it wants to use.
631 dirstore = New(alist(10, not_owned_by_alist));
632 jcr->reserve_msgs = New(alist(10, not_owned_by_alist));
634 Dmsg1(dbglvl, "<dird: %s", dir->msg);
635 ok = sscanf(dir->msg, use_storage, store_name.c_str(),
636 media_type.c_str(), pool_name.c_str(),
637 pool_type.c_str(), &append, &Copy, &Stripe) == 7;
642 jcr->write_store = dirstore;
644 jcr->read_store = dirstore;
646 rctx.append = append;
647 unbash_spaces(store_name);
648 unbash_spaces(media_type);
649 unbash_spaces(pool_name);
650 unbash_spaces(pool_type);
651 store = new DIRSTORE;
652 dirstore->append(store);
653 memset(store, 0, sizeof(DIRSTORE));
654 store->device = New(alist(10));
655 bstrncpy(store->name, store_name, sizeof(store->name));
656 bstrncpy(store->media_type, media_type, sizeof(store->media_type));
657 bstrncpy(store->pool_name, pool_name, sizeof(store->pool_name));
658 bstrncpy(store->pool_type, pool_type, sizeof(store->pool_type));
659 store->append = append;
661 /* Now get all devices */
662 while (dir->recv() >= 0) {
663 Dmsg1(dbglvl, "<dird device: %s", dir->msg);
664 ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
668 unbash_spaces(dev_name);
669 store->device->append(bstrdup(dev_name.c_str()));
671 } while (ok && dir->recv() >= 0);
673 /* Developer debug code */
675 if (debug_level >= dbglvl) {
676 foreach_alist(store, dirstore) {
677 Dmsg5(dbglvl, "Storage=%s media_type=%s pool=%s pool_type=%s append=%d\n",
678 store->name, store->media_type, store->pool_name,
679 store->pool_type, store->append);
680 foreach_alist(device_name, store->device) {
681 Dmsg1(dbglvl, " Device=%s\n", device_name);
686 init_jcr_device_wait_timers(jcr);
687 jcr->dcr = new_dcr(jcr, NULL, NULL); /* get a dcr */
689 BSOCK *dir = jcr->dir_bsock;
690 dir->fsend(_("3939 Could not get dcr\n"));
691 Dmsg1(dbglvl, ">dird: %s", dir->msg);
695 * At this point, we have a list of all the Director's Storage
696 * resources indicated for this Job, which include Pool, PoolType,
697 * storage name, and Media type.
698 * Then for each of the Storage resources, we have a list of
699 * device names that were given.
701 * Wiffle through them and find one that can do the backup.
704 int wait_for_device_retries = 0;
707 rctx.notify_dir = true;
710 for ( ; !fail && !job_canceled(jcr); ) {
711 pop_reserve_messages(jcr);
712 rctx.suitable_device = false;
713 rctx.have_volume = false;
714 rctx.VolumeName[0] = 0;
715 rctx.any_drive = false;
716 if (!jcr->PreferMountedVols) {
718 * Here we try to find a drive that is not used.
719 * This will maximize the use of available drives.
722 rctx.num_writers = 20000000; /* start with impossible number */
723 rctx.low_use_drive = NULL;
724 rctx.PreferMountedVols = false;
725 rctx.exact_match = false;
726 rctx.autochanger_only = true;
727 Dmsg5(dbglvl, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
728 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
729 rctx.autochanger_only, rctx.any_drive);
730 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
733 /* Look through all drives possibly for low_use drive */
734 if (rctx.low_use_drive) {
735 rctx.try_low_use_drive = true;
736 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
739 rctx.try_low_use_drive = false;
741 rctx.autochanger_only = false;
742 Dmsg5(dbglvl, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
743 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
744 rctx.autochanger_only, rctx.any_drive);
745 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
750 * Now we look for a drive that may or may not be in
753 /* Look for an exact Volume match all drives */
754 rctx.PreferMountedVols = true;
755 rctx.exact_match = true;
756 rctx.autochanger_only = false;
757 Dmsg5(dbglvl, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
758 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
759 rctx.autochanger_only, rctx.any_drive);
760 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
763 /* Look for any mounted drive */
764 rctx.exact_match = false;
765 Dmsg5(dbglvl, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
766 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
767 rctx.autochanger_only, rctx.any_drive);
768 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
772 rctx.any_drive = true;
773 Dmsg5(dbglvl, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
774 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
775 rctx.autochanger_only, rctx.any_drive);
776 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
779 /* Keep reservations locked *except* during wait_for_device() */
780 unlock_reservations();
782 * The idea of looping on repeat a few times it to ensure
783 * that if there is some subtle timing problem between two
784 * jobs, we will simply try again, and most likely succeed.
785 * This can happen if one job reserves a drive or finishes using
786 * a drive at the same time a second job wants it.
788 if (repeat++ > 1) { /* try algorithm 3 times */
789 bmicrosleep(30, 0); /* wait a bit */
790 Dmsg0(dbglvl, "repeat reserve algorithm\n");
791 } else if (!rctx.suitable_device || !wait_for_device(jcr, wait_for_device_retries)) {
792 Dmsg0(dbglvl, "Fail. !suitable_device || !wait_for_device\n");
796 dir->signal(BNET_HEARTBEAT); /* Inform Dir that we are alive */
798 unlock_reservations();
801 * If we get here, there are no suitable devices available, which
802 * means nothing configured. If a device is suitable but busy
803 * with another Volume, we will not come here.
805 unbash_spaces(dir->msg);
806 pm_strcpy(jcr->errmsg, dir->msg);
807 Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
808 Jmsg(jcr, M_FATAL, 0, _("\n"
809 " Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"),
810 dev_name.c_str(), media_type.c_str());
811 dir->fsend(NO_device, dev_name.c_str());
813 Dmsg1(dbglvl, ">dird: %s", dir->msg);
816 unbash_spaces(dir->msg);
817 pm_strcpy(jcr->errmsg, dir->msg);
818 Jmsg(jcr, M_FATAL, 0, _("Failed command: %s\n"), jcr->errmsg);
819 dir->fsend(BAD_use, jcr->errmsg);
820 Dmsg1(dbglvl, ">dird: %s", dir->msg);
823 release_reserve_messages(jcr);
829 * Walk through the autochanger resources and check if
830 * the volume is in one of them.
832 * Returns: true if volume is in device
835 static bool is_vol_in_autochanger(RCTX &rctx, VOLRES *vol)
837 AUTOCHANGER *changer = vol->dev->device->changer_res;
839 /* Find resource, and make sure we were able to open it */
840 if (strcmp(rctx.device_name, changer->hdr.name) == 0) {
841 Dmsg1(dbglvl, "Found changer device %s\n", vol->dev->device->hdr.name);
844 Dmsg1(dbglvl, "Incorrect changer device %s\n", changer->hdr.name);
849 * Search for a device suitable for this job.
851 bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx)
860 dirstore = jcr->write_store;
862 dirstore = jcr->read_store;
864 Dmsg4(dbglvl, "PrefMnt=%d exact=%d suitable=%d chgronly=%d\n",
865 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
866 rctx.autochanger_only);
869 * If the appropriate conditions of this if are met, namely that
870 * we are appending and the user wants mounted drive (or we
871 * force try a mounted drive because they are all busy), we
872 * start by looking at all the Volumes in the volume list.
874 if (!vol_list->empty() && rctx.append && rctx.PreferMountedVols) {
875 dlist *temp_vol_list, *save_vol_list;
878 Dmsg0(dbglvl, "lock volumes\n");
881 * Create a temporary copy of the volume list. We do this,
882 * to avoid having the volume list locked during the
883 * call to reserve_device(), which would cause a deadlock.
884 * Note, we may want to add an update counter on the vol_list
885 * so that if it is modified while we are traversing the copy
886 * we can take note and act accordingly (probably redo the
887 * search at least a few times).
889 Dmsg0(dbglvl, "duplicate vol list\n");
890 temp_vol_list = New(dlist(vol, &vol->link));
891 foreach_dlist(vol, vol_list) {
893 VOLRES *tvol = (VOLRES *)malloc(sizeof(VOLRES));
894 memset(tvol, 0, sizeof(VOLRES));
895 tvol->vol_name = bstrdup(vol->vol_name);
896 tvol->dev = vol->dev;
897 nvol = (VOLRES *)temp_vol_list->binary_insert(tvol, my_compare);
899 tvol->dev = NULL; /* don't zap dev entry */
901 Pmsg0(000, "Logic error. Duplicating vol list hit duplicate.\n");
902 Jmsg(jcr, M_WARNING, 0, "Logic error. Duplicating vol list hit duplicate.\n");
905 Dmsg0(dbglvl, "unlock volumes\n");
908 /* Look through reserved volumes for one we can use */
909 Dmsg0(dbglvl, "look for vol in vol list\n");
910 foreach_dlist(vol, temp_vol_list) {
912 Dmsg1(dbglvl, "vol=%s no dev\n", vol->vol_name);
915 /* Check with Director if this Volume is OK */
916 bstrncpy(dcr->VolumeName, vol->vol_name, sizeof(dcr->VolumeName));
917 if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE)) {
921 Dmsg1(dbglvl, "vol=%s OK for this job\n", vol->vol_name);
922 foreach_alist(store, dirstore) {
925 foreach_alist(device_name, store->device) {
926 /* Found a device, try to use it */
927 rctx.device_name = device_name;
928 rctx.device = vol->dev->device;
930 if (vol->dev->is_autochanger()) {
931 Dmsg1(dbglvl, "vol=%s is in changer\n", vol->vol_name);
932 if (!is_vol_in_autochanger(rctx, vol)) {
935 } else if (strcmp(device_name, vol->dev->device->hdr.name) != 0) {
936 Dmsg2(dbglvl, "device=%s not suitable want %s\n",
937 vol->dev->device->hdr.name, device_name);
941 bstrncpy(rctx.VolumeName, vol->vol_name, sizeof(rctx.VolumeName));
942 rctx.have_volume = true;
943 /* Try reserving this device and volume */
944 Dmsg2(dbglvl, "try vol=%s on device=%s\n", rctx.VolumeName, device_name);
945 stat = reserve_device(rctx);
946 if (stat == 1) { /* found available device */
947 Dmsg1(dbglvl, "Suitable device found=%s\n", device_name);
950 } else if (stat == 0) { /* device busy */
951 Dmsg1(dbglvl, "Suitable device=%s, busy: not use\n", device_name);
953 /* otherwise error */
954 Dmsg0(dbglvl, "No suitable device found.\n");
956 rctx.have_volume = false;
965 } /* end for loop over reserved volumes */
967 Dmsg0(dbglvl, "lock volumes\n");
969 save_vol_list = vol_list;
970 vol_list = temp_vol_list;
971 free_volume_list(); /* release temp_vol_list */
972 vol_list = save_vol_list;
973 Dmsg0(dbglvl, "deleted temp vol list\n");
974 Dmsg0(dbglvl, "unlock volumes\n");
976 debug_list_volumes("=== After free temp table\n");
979 Dmsg1(dbglvl, "got vol %s from in-use vols list\n", rctx.VolumeName);
984 * No reserved volume we can use, so now search for an available device.
986 * For each storage device that the user specified, we
987 * search and see if there is a resource for that device.
989 foreach_alist(store, dirstore) {
991 foreach_alist(device_name, store->device) {
993 rctx.device_name = device_name;
994 stat = search_res_for_device(rctx);
995 if (stat == 1) { /* found available device */
996 Dmsg1(dbglvl, "available device found=%s\n", device_name);
999 } else if (stat == 0) { /* device busy */
1000 Dmsg1(dbglvl, "Suitable device=%s, busy: not use\n", device_name);
1002 /* otherwise error */
1003 Dmsg0(dbglvl, "No suitable device found.\n");
1014 * Search for a particular storage device with particular storage
1015 * characteristics (MediaType).
1017 int search_res_for_device(RCTX &rctx)
1019 AUTOCHANGER *changer;
1022 Dmsg1(dbglvl, "search res for %s\n", rctx.device_name);
1023 /* Look through Autochangers first */
1024 foreach_res(changer, R_AUTOCHANGER) {
1025 Dmsg1(dbglvl, "Try match changer res=%s\n", changer->hdr.name);
1026 /* Find resource, and make sure we were able to open it */
1027 if (strcmp(rctx.device_name, changer->hdr.name) == 0) {
1028 /* Try each device in this AutoChanger */
1029 foreach_alist(rctx.device, changer->device) {
1030 Dmsg1(dbglvl, "Try changer device %s\n", rctx.device->hdr.name);
1031 stat = reserve_device(rctx);
1032 if (stat != 1) { /* try another device */
1036 if (rctx.store->append == SD_APPEND) {
1037 Dmsg2(dbglvl, "Device %s reserved=%d for append.\n",
1038 rctx.device->hdr.name, rctx.jcr->dcr->dev->reserved_device);
1040 Dmsg2(dbglvl, "Device %s reserved=%d for read.\n",
1041 rctx.device->hdr.name, rctx.jcr->read_dcr->dev->reserved_device);
1048 /* Now if requested look through regular devices */
1049 if (!rctx.autochanger_only) {
1050 foreach_res(rctx.device, R_DEVICE) {
1051 Dmsg1(dbglvl, "Try match res=%s\n", rctx.device->hdr.name);
1052 /* Find resource, and make sure we were able to open it */
1053 if (strcmp(rctx.device_name, rctx.device->hdr.name) == 0) {
1054 stat = reserve_device(rctx);
1055 if (stat != 1) { /* try another device */
1059 if (rctx.store->append == SD_APPEND) {
1060 Dmsg2(dbglvl, "Device %s reserved=%d for append.\n",
1061 rctx.device->hdr.name, rctx.jcr->dcr->dev->reserved_device);
1063 Dmsg2(dbglvl, "Device %s reserved=%d for read.\n",
1064 rctx.device->hdr.name, rctx.jcr->read_dcr->dev->reserved_device);
1070 return -1; /* nothing found */
1074 * Try to reserve a specific device.
1076 * Returns: 1 -- OK, have DCR
1080 static int reserve_device(RCTX &rctx)
1084 const int name_len = MAX_NAME_LENGTH;
1086 /* Make sure MediaType is OK */
1087 Dmsg2(dbglvl, "chk MediaType device=%s request=%s\n",
1088 rctx.device->media_type, rctx.store->media_type);
1089 if (strcmp(rctx.device->media_type, rctx.store->media_type) != 0) {
1093 /* Make sure device exists -- i.e. we can stat() it */
1094 if (!rctx.device->dev) {
1095 rctx.device->dev = init_dev(rctx.jcr, rctx.device);
1097 if (!rctx.device->dev) {
1098 if (rctx.device->changer_res) {
1099 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
1100 " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
1101 rctx.device->hdr.name, rctx.device_name);
1103 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
1104 " Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
1107 return -1; /* no use waiting */
1110 rctx.suitable_device = true;
1111 Dmsg1(dbglvl, "try reserve %s\n", rctx.device->hdr.name);
1112 rctx.jcr->dcr = dcr = new_dcr(rctx.jcr, rctx.jcr->dcr, rctx.device->dev);
1114 BSOCK *dir = rctx.jcr->dir_bsock;
1115 dir->fsend(_("3926 Could not get dcr for device: %s\n"), rctx.device_name);
1116 Dmsg1(dbglvl, ">dird: %s", dir->msg);
1119 bstrncpy(dcr->pool_name, rctx.store->pool_name, name_len);
1120 bstrncpy(dcr->pool_type, rctx.store->pool_type, name_len);
1121 bstrncpy(dcr->media_type, rctx.store->media_type, name_len);
1122 bstrncpy(dcr->dev_name, rctx.device_name, name_len);
1123 if (rctx.store->append == SD_APPEND) {
1124 Dmsg2(dbglvl, "have_vol=%d vol=%s\n", rctx.have_volume, rctx.VolumeName);
1125 ok = reserve_device_for_append(dcr, rctx);
1130 rctx.jcr->dcr = dcr;
1131 Dmsg5(dbglvl, "Reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
1132 dcr->dev->reserved_device,
1133 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
1134 if (!rctx.have_volume) {
1135 dcr->any_volume = true;
1136 if (dir_find_next_appendable_volume(dcr)) {
1137 bstrncpy(rctx.VolumeName, dcr->VolumeName, sizeof(rctx.VolumeName));
1138 Dmsg1(dbglvl, "looking for Volume=%s\n", rctx.VolumeName);
1139 rctx.have_volume = true;
1141 Dmsg0(dbglvl, "No next volume found\n");
1142 rctx.have_volume = false;
1143 rctx.VolumeName[0] = 0;
1145 * If there is at least one volume that is valid and in use,
1146 * but we get here, check if we are running with prefers
1147 * non-mounted drives. In that case, we have selected a
1148 * non-used drive and our one and only volume is mounted
1149 * elsewhere, so we bail out and retry using that drive.
1151 if (dcr->volume_in_use && !rctx.PreferMountedVols) {
1152 rctx.PreferMountedVols = true;
1153 if (dcr->VolumeName[0]) {
1159 * Note. Under some circumstances, the Director can hand us
1160 * a Volume name that is no the same as the one on the current
1161 * drive, and in that case, the call above to find the next
1162 * volume will fail because in attempting to reserve the Volume
1163 * the code will realize that we already have a tape mounted,
1164 * and it will fail. This *should* only happen if there are
1165 * writers, thus the following test. In that case, we simply
1166 * bail out, and continue waiting, rather than plunging on
1167 * and hoping that the operator can resolve the problem.
1169 if (dcr->dev->num_writers != 0) {
1170 if (dcr->VolumeName[0]) {
1178 ok = reserve_device_for_read(dcr);
1180 rctx.jcr->read_dcr = dcr;
1181 Dmsg5(dbglvl, "Read reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
1182 dcr->dev->reserved_device,
1183 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
1189 if (rctx.notify_dir) {
1191 BSOCK *dir = rctx.jcr->dir_bsock;
1192 pm_strcpy(dev_name, rctx.device->hdr.name);
1193 bash_spaces(dev_name);
1194 ok = dir->fsend(OK_device, dev_name.c_str()); /* Return real device name */
1195 Dmsg1(dbglvl, ">dird: %s", dir->msg);
1202 rctx.have_volume = false;
1204 Dmsg0(dbglvl, "Not OK.\n");
1209 * We "reserve" the drive by setting the ST_READ bit. No one else
1210 * should touch the drive until that is cleared.
1211 * This allows the DIR to "reserve" the device before actually
1214 static bool reserve_device_for_read(DCR *dcr)
1216 DEVICE *dev = dcr->dev;
1217 JCR *jcr = dcr->jcr;
1224 if (is_device_unmounted(dev)) {
1225 Dmsg1(dbglvl, "Device %s is BLOCKED due to user unmount.\n", dev->print_name());
1226 Mmsg(jcr->errmsg, _("3601 JobId=%u device %s is BLOCKED due to user unmount.\n"),
1227 jcr->JobId, dev->print_name());
1228 queue_reserve_message(jcr);
1232 if (dev->is_busy()) {
1233 Dmsg4(dbglvl, "Device %s is busy ST_READ=%d num_writers=%d reserved=%d.\n",
1235 dev->state & ST_READ?1:0, dev->num_writers, dev->reserved_device);
1236 Mmsg(jcr->errmsg, _("3602 JobId=%u device %s is busy (already reading/writing).\n"),
1237 jcr->JobId, dev->print_name());
1238 queue_reserve_message(jcr);
1242 dev->clear_append();
1245 dev->reserved_device++;
1246 Dmsg3(dbglvl, "Inc reserve=%d dev=%s %p\n", dev->reserved_device, dev->print_name(), dev);
1247 dcr->reserved_device = true;
1256 * We reserve the device for appending by incrementing the
1257 * reserved_device. We do virtually all the same work that
1258 * is done in acquire_device_for_append(), but we do
1259 * not attempt to mount the device. This routine allows
1260 * the DIR to reserve multiple devices before *really*
1261 * starting the job. It also permits the SD to refuse
1262 * certain devices (not up, ...).
1264 * Note, in reserving a device, if the device is for the
1265 * same pool and the same pool type, then it is acceptable.
1266 * The Media Type has already been checked. If we are
1267 * the first tor reserve the device, we put the pool
1268 * name and pool type in the device record.
1270 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
1272 JCR *jcr = dcr->jcr;
1273 DEVICE *dev = dcr->dev;
1280 /* If device is being read, we cannot write it */
1281 if (dev->can_read()) {
1282 Mmsg(jcr->errmsg, _("3603 JobId=%u device %s is busy reading.\n"),
1283 jcr->JobId, dev->print_name());
1284 Dmsg1(dbglvl, "%s", jcr->errmsg);
1285 queue_reserve_message(jcr);
1289 /* If device is unmounted, we are out of luck */
1290 if (is_device_unmounted(dev)) {
1291 Mmsg(jcr->errmsg, _("3604 JobId=%u device %s is BLOCKED due to user unmount.\n"),
1292 jcr->JobId, dev->print_name());
1293 Dmsg1(dbglvl, "%s", jcr->errmsg);
1294 queue_reserve_message(jcr);
1298 Dmsg1(dbglvl, "reserve_append device is %s\n", dev->print_name());
1300 /* Now do detailed tests ... */
1301 if (can_reserve_drive(dcr, rctx) != 1) {
1302 Dmsg0(dbglvl, "can_reserve_drive!=1\n");
1306 dev->reserved_device++;
1307 Dmsg3(dbglvl, "Inc reserve=%d dev=%s %p\n", dev->reserved_device,
1308 dev->print_name(), dev);
1309 dcr->reserved_device = true;
1317 static int is_pool_ok(DCR *dcr)
1319 DEVICE *dev = dcr->dev;
1320 JCR *jcr = dcr->jcr;
1322 /* Now check if we want the same Pool and pool type */
1323 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1324 strcmp(dev->pool_type, dcr->pool_type) == 0) {
1325 /* OK, compatible device */
1326 Dmsg1(dbglvl, "OK dev: %s num_writers=0, reserved, pool matches\n", dev->print_name());
1329 /* Drive Pool not suitable for us */
1330 Mmsg(jcr->errmsg, _(
1331 "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %s.\n"),
1332 (uint32_t)jcr->JobId, dcr->pool_name, dev->pool_name,
1333 dev->reserved_device, dev->print_name());
1334 queue_reserve_message(jcr);
1335 Dmsg2(dbglvl, "failed: busy num_writers=0, reserved, pool=%s wanted=%s\n",
1336 dev->pool_name, dcr->pool_name);
1341 static bool is_max_jobs_ok(DCR *dcr)
1343 DEVICE *dev = dcr->dev;
1344 JCR *jcr = dcr->jcr;
1346 Dmsg4(dbglvl, "MaxJobs=%d Jobs=%d reserves=%d Vol=%s\n",
1347 dcr->VolCatInfo.VolCatMaxJobs,
1348 dcr->VolCatInfo.VolCatJobs, dev->reserved_device,
1350 if (dcr->VolCatInfo.VolCatMaxJobs > 0 && dcr->VolCatInfo.VolCatMaxJobs <=
1351 (dcr->VolCatInfo.VolCatJobs + dev->reserved_device)) {
1352 /* Max Job Vols depassed or already reserved */
1353 Mmsg(jcr->errmsg, _("3610 JobId=%u Volume max jobs exceeded on drive %s.\n"),
1354 (uint32_t)jcr->JobId, dev->print_name());
1355 queue_reserve_message(jcr);
1356 Dmsg1(dbglvl, "reserve dev failed: %s", jcr->errmsg);
1357 return false; /* wait */
1363 * Returns: 1 if drive can be reserved
1364 * 0 if we should wait
1365 * -1 on error or impossibility
1367 static int can_reserve_drive(DCR *dcr, RCTX &rctx)
1369 DEVICE *dev = dcr->dev;
1370 JCR *jcr = dcr->jcr;
1372 Dmsg5(dbglvl, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
1373 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
1374 rctx.autochanger_only, rctx.any_drive);
1376 /* Check for max jobs on this Volume */
1377 if (!is_max_jobs_ok(dcr)) {
1381 /* setting any_drive overrides PreferMountedVols flag */
1382 if (!rctx.any_drive) {
1384 * When PreferMountedVols is set, we keep track of the
1385 * drive in use that has the least number of writers, then if
1386 * no unmounted drive is found, we try that drive. This
1387 * helps spread the load to the least used drives.
1389 if (rctx.try_low_use_drive && dev == rctx.low_use_drive) {
1390 Dmsg2(dbglvl, "OK dev=%s == low_drive=%s.\n",
1391 dev->print_name(), rctx.low_use_drive->print_name());
1394 /* If he wants a free drive, but this one is busy, no go */
1395 if (!rctx.PreferMountedVols && dev->is_busy()) {
1396 /* Save least used drive */
1397 if ((dev->num_writers + dev->reserved_device) < rctx.num_writers) {
1398 rctx.num_writers = dev->num_writers + dev->reserved_device;
1399 rctx.low_use_drive = dev;
1400 Dmsg2(dbglvl, "set low use drive=%s num_writers=%d\n",
1401 dev->print_name(), rctx.num_writers);
1403 Dmsg1(dbglvl, "not low use num_writers=%d\n", dev->num_writers+dev->reserved_device);
1405 Dmsg0(dbglvl, "failed: !prefMnt && busy.\n");
1406 Mmsg(jcr->errmsg, _("3605 JobId=%u wants free drive but device %s is busy.\n"),
1407 jcr->JobId, dev->print_name());
1408 queue_reserve_message(jcr);
1412 /* Check for prefer mounted volumes */
1413 if (rctx.PreferMountedVols && !dev->vol && dev->is_tape()) {
1414 Mmsg(jcr->errmsg, _("3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n"),
1415 jcr->JobId, dev->print_name());
1416 queue_reserve_message(jcr);
1417 Dmsg0(dbglvl, "failed: want mounted -- no vol\n");
1418 return 0; /* No volume mounted */
1421 /* Check for exact Volume name match */
1422 /* ***FIXME*** for Disk, we can accept any volume that goes with this
1425 if (rctx.exact_match && rctx.have_volume) {
1427 Dmsg5(dbglvl, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
1428 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
1429 rctx.autochanger_only, rctx.any_drive);
1430 Dmsg4(dbglvl, "have_vol=%d have=%s resvol=%s want=%s\n",
1431 rctx.have_volume, dev->VolHdr.VolumeName,
1432 dev->vol?dev->vol->vol_name:"*none*", rctx.VolumeName);
1433 ok = strcmp(dev->VolHdr.VolumeName, rctx.VolumeName) == 0 ||
1434 (dev->vol && strcmp(dev->vol->vol_name, rctx.VolumeName) == 0);
1436 Mmsg(jcr->errmsg, _("3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n"),
1437 jcr->JobId, rctx.VolumeName, dev->VolHdr.VolumeName,
1439 queue_reserve_message(jcr);
1440 Dmsg3(dbglvl, "not OK: dev have=%s resvol=%s want=%s\n",
1441 dev->VolHdr.VolumeName, dev->vol?dev->vol->vol_name:"*none*", rctx.VolumeName);
1444 if (is_volume_in_use(dcr)) {
1445 return 0; /* fail if volume on another drive */
1450 /* Check for unused autochanger drive */
1451 if (rctx.autochanger_only && !dev->is_busy() &&
1452 dev->VolHdr.VolumeName[0] == 0) {
1453 /* Device is available but not yet reserved, reserve it for us */
1454 Dmsg1(dbglvl, "OK Res Unused autochanger %s.\n", dev->print_name());
1455 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1456 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1457 return 1; /* reserve drive */
1461 * Handle the case that there are no writers
1463 if (dev->num_writers == 0) {
1464 /* Now check if there are any reservations on the drive */
1465 if (dev->reserved_device) {
1466 return is_pool_ok(dcr);
1467 } else if (dev->can_append()) {
1468 if (is_pool_ok(dcr)) {
1471 /* Changing pool, unload old tape if any in drive */
1472 Dmsg0(dbglvl, "OK dev: num_writers=0, not reserved, pool change, unload changer\n");
1473 unload_autochanger(dcr, 0);
1476 /* Device is available but not yet reserved, reserve it for us */
1477 Dmsg1(dbglvl, "OK Dev avail reserved %s\n", dev->print_name());
1478 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1479 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1480 return 1; /* reserve drive */
1484 * Check if the device is in append mode with writers (i.e.
1485 * available if pool is the same).
1487 if (dev->can_append() || dev->num_writers > 0) {
1488 return is_pool_ok(dcr);
1490 Pmsg1(000, _("Logic error!!!! JobId=%u Should not get here.\n"), (int)jcr->JobId);
1491 Mmsg(jcr->errmsg, _("3910 JobId=%u Logic error!!!! drive %s Should not get here.\n"),
1492 jcr->JobId, dev->print_name());
1493 queue_reserve_message(jcr);
1494 Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
1495 return -1; /* error, should not get here */
1497 Mmsg(jcr->errmsg, _("3911 JobId=%u failed reserve drive %s.\n"),
1498 jcr->JobId, dev->print_name());
1499 queue_reserve_message(jcr);
1500 Dmsg1(dbglvl, "failed: No reserve %s\n", dev->print_name());
1508 * Queue a reservation error or failure message for this jcr
1510 static void queue_reserve_message(JCR *jcr)
1518 msgs = jcr->reserve_msgs;
1523 * Look for duplicate message. If found, do
1526 for (i=msgs->size()-1; i >= 0; i--) {
1527 msg = (char *)msgs->get(i);
1531 /* Comparison based on 4 digit message number */
1532 if (strncmp(msg, jcr->errmsg, 4) == 0) {
1536 /* Message unique, so insert it */
1537 jcr->reserve_msgs->push(bstrdup(jcr->errmsg));
1544 * Send any reservation messages queued for this jcr
1546 void send_drive_reserve_messages(JCR *jcr, void sendit(const char *msg, int len, void *sarg), void *arg)
1553 msgs = jcr->reserve_msgs;
1554 if (!msgs || msgs->size() == 0) {
1557 for (i=msgs->size()-1; i >= 0; i--) {
1558 msg = (char *)msgs->get(i);
1560 sendit(" ", 3, arg);
1561 sendit(msg, strlen(msg), arg);
1572 * Pop and release any reservations messages
1574 static void pop_reserve_messages(JCR *jcr)
1580 msgs = jcr->reserve_msgs;
1584 while ((msg = (char *)msgs->pop())) {
1592 * Also called from acquire.c
1594 void release_reserve_messages(JCR *jcr)
1596 pop_reserve_messages(jcr);
1598 if (!jcr->reserve_msgs) {
1601 delete jcr->reserve_msgs;
1602 jcr->reserve_msgs = NULL;