2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2007 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 #define jid() ((int)get_jobid_from_tid())
44 const int dbglvl = 50;
46 static dlist *vol_list = NULL;
47 static brwlock_t reservation_lock;
48 static brwlock_t vol_list_lock;
50 /* Forward referenced functions */
51 static int can_reserve_drive(DCR *dcr, RCTX &rctx);
52 static int reserve_device(RCTX &rctx);
53 static bool reserve_device_for_read(DCR *dcr);
54 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx);
55 static bool use_storage_cmd(JCR *jcr);
56 static void queue_reserve_message(JCR *jcr);
57 static void pop_reserve_messages(JCR *jcr);
59 /* Requests from the Director daemon */
60 static char use_storage[] = "use storage=%127s media_type=%127s "
61 "pool_name=%127s pool_type=%127s append=%d copy=%d stripe=%d\n";
62 static char use_device[] = "use device=%127s\n";
64 /* Responses sent to Director daemon */
65 static char OK_device[] = "3000 OK use device device=%s\n";
66 static char NO_device[] = "3924 Device \"%s\" not in SD Device resources.\n";
67 static char BAD_use[] = "3913 Bad use command: %s\n";
69 bool use_cmd(JCR *jcr)
72 * Get the device, media, and pool information
74 if (!use_storage_cmd(jcr)) {
75 set_jcr_job_status(jcr, JS_ErrorTerminated);
76 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
82 static int my_compare(void *item1, void *item2)
84 return strcmp(((VOLRES *)item1)->vol_name, ((VOLRES *)item2)->vol_name);
88 void init_reservations_lock()
91 if ((errstat=rwl_init(&reservation_lock)) != 0) {
93 Emsg1(M_ABORT, 0, _("Unable to initialize reservation lock. ERR=%s\n"),
94 be.bstrerror(errstat));
97 if ((errstat=rwl_init(&vol_list_lock)) != 0) {
99 Emsg1(M_ABORT, 0, _("Unable to initialize volume list lock. ERR=%s\n"),
100 be.bstrerror(errstat));
104 void term_reservations_lock()
106 rwl_destroy(&reservation_lock);
107 rwl_destroy(&vol_list_lock);
110 int reservations_lock_count = 0;
112 /* This applies to a drive and to Volumes */
113 void _lock_reservations()
116 reservations_lock_count++;
117 if ((errstat=rwl_writelock(&reservation_lock)) != 0) {
119 Emsg2(M_ABORT, 0, "rwl_writelock failure. stat=%d: ERR=%s\n",
120 errstat, be.bstrerror(errstat));
124 void _unlock_reservations()
127 reservations_lock_count--;
128 if ((errstat=rwl_writeunlock(&reservation_lock)) != 0) {
130 Emsg2(M_ABORT, 0, "rwl_writeunlock failure. stat=%d: ERR=%s\n",
131 errstat, be.bstrerror(errstat));
135 int vol_list_lock_count = 0;
140 vol_list_lock_count++;
141 if ((errstat=rwl_writelock(&vol_list_lock)) != 0) {
143 Emsg2(M_ABORT, 0, "rwl_writelock failure. stat=%d: ERR=%s\n",
144 errstat, be.bstrerror(errstat));
148 void _unlock_volumes()
151 vol_list_lock_count--;
152 if ((errstat=rwl_writeunlock(&vol_list_lock)) != 0) {
154 Emsg2(M_ABORT, 0, "rwl_writeunlock failure. stat=%d: ERR=%s\n",
155 errstat, be.bstrerror(errstat));
161 * List Volumes -- this should be moved to status.c
168 static void debug_list_volumes(const char *imsg)
171 POOL_MEM msg(PM_MESSAGE);
174 foreach_dlist(vol, vol_list) {
176 Mmsg(msg, "List from %s: %s at %p on device %s\n", imsg,
177 vol->vol_name, vol->vol_name, vol->dev->print_name());
179 Mmsg(msg, "List from %s: %s at %p no dev\n", imsg, vol->vol_name, vol->vol_name);
181 Dmsg2(dbglvl, "jid=%u %s", jid(), msg.c_str());
186 foreach_dlist(vol, vol_list) {
187 if (vol->dev == dev) {
188 Dmsg0(000, "Two Volumes on same device.\n");
195 // Dmsg2(dbglvl, "List from %s: %d volumes\n", imsg, count);
201 * List Volumes -- this should be moved to status.c
203 void list_volumes(void sendit(const char *msg, int len, void *sarg), void *arg)
206 POOL_MEM msg(PM_MESSAGE);
210 foreach_dlist(vol, vol_list) {
211 DEVICE *dev = vol->dev;
213 len = Mmsg(msg, "%s on device %s\n", vol->vol_name, dev->print_name());
214 sendit(msg.c_str(), len, arg);
215 len = Mmsg(msg, " Reader=%d writers=%d reserved=%d\n", dev->can_read()?1:0,
216 dev->num_writers, dev->reserved_device);
217 sendit(msg.c_str(), len, arg);
219 len = Mmsg(msg, "%s no dev\n", vol->vol_name);
220 sendit(msg.c_str(), len, arg);
227 * Create a Volume item to put in the Volume list
228 * Ensure that the device points to it.
230 static VOLRES *new_vol_item(DCR *dcr, const char *VolumeName)
233 vol = (VOLRES *)malloc(sizeof(VOLRES));
234 memset(vol, 0, sizeof(VOLRES));
235 vol->vol_name = bstrdup(VolumeName);
237 Dmsg4(dbglvl, "jid=%u new Vol=%s at %p dev=%s\n", (int)dcr->jcr->JobId,
238 VolumeName, vol->vol_name, vol->dev->print_name());
242 static void free_vol_item(VOLRES *vol)
246 vol->dev->vol = NULL;
253 * Put a new Volume entry in the Volume list. This
254 * effectively reserves the volume so that it will
255 * not be mounted again.
257 * If the device has any current volume associated with it,
258 * and it is a different Volume, and the device is not busy,
259 * we release the old Volume item and insert the new one.
261 * It is assumed that the device is free and locked so that
262 * we can change the device structure.
264 * Some details of the Volume list handling:
266 * 1. The Volume list entry must be attached to the drive (rather than
267 * attached to a job as it currently is. I.e. the drive that "owns"
268 * the volume (reserved, in use, mounted)
269 * must point to the volume (still to be maintained in a list).
271 * 2. The Volume is entered in the list when a drive is reserved.
273 * 3. When a drive is in use, the device code must appropriately update the
274 * volume name as it changes (currently the list is static -- an entry is
275 * removed when the Volume is no longer reserved, in use or mounted).
276 * The new code must keep the same list entry as long as the drive
277 * has any volume associated with it but the volume name in the list
278 * must be updated when the drive has a different volume mounted.
280 * 4. A job that has reserved a volume, can un-reserve the volume, and if the
281 * volume is not mounted, and not reserved, and not in use, it will be
282 * removed from the list.
284 * 5. If a job wants to reserve a drive with a different Volume from the one on
285 * the drive, it can re-use the drive for the new Volume.
287 * 6. If a job wants a Volume that is in a different drive, it can either use the
288 * other drive or take the volume, only if the other drive is not in use or
291 * One nice aspect of this is that the reserve use count and the writer use count
292 * already exist and are correctly programmed and will need no changes -- use
293 * counts are always very tricky.
295 * The old code had a concept of "reserving" a Volume, but it needs to be changed
296 * to reserving and using a drive. A volume is must be attached to (owned by) a
297 * drive and can move from drive to drive or be unused given certain specific
298 * conditions of the drive. The key is that the drive must "own" the Volume.
299 * The old code has the job (dcr) owning the volume (more or less). The job is
300 * to change the insertion and removal of the volumes from the list to be based
301 * on the drive rather than the job.
303 * Return: VOLRES entry on success
304 * NULL volume busy on another drive
306 VOLRES *reserve_volume(DCR *dcr, const char *VolumeName)
309 DEVICE *dev = dcr->dev;
313 Dmsg2(dbglvl, "jid=%u reserve_volume %s\n", jid(), VolumeName);
315 * We lock the reservations system here to ensure
316 * when adding a new volume that no newly scheduled
317 * job can reserve it.
320 debug_list_volumes("begin reserve_volume");
322 * First, remove any old volume attached to this device as it
328 * Make sure we don't remove the current volume we are inserting
329 * because it was probably inserted by another job.
331 if (strcmp(vol->vol_name, VolumeName) == 0) {
332 goto get_out; /* Volume already on this device */
334 Dmsg3(dbglvl, "jid=%u reserve_vol free vol=%s at %p\n",
335 (int)dcr->jcr->JobId, vol->vol_name, vol->vol_name);
336 debug_list_volumes("reserve_vol free");
337 vol_list->remove(vol);
342 /* Create a new Volume entry */
343 nvol = new_vol_item(dcr, VolumeName);
346 * Now try to insert the new Volume
348 vol = (VOLRES *)vol_list->binary_insert(nvol, my_compare);
350 Dmsg3(dbglvl, "jid=%u Found vol=%s dev-same=%d\n", jid(), vol->vol_name, dev==vol->dev);
352 * At this point, a Volume with this name already is in the list,
353 * so we simply release our new Volume entry. Note, this should
354 * only happen if we are moving the volume from one drive to another.
356 Dmsg3(dbglvl, "jid=%u reserve_vol free-tmp vol=%s at %p\n",
357 (int)dcr->jcr->JobId, vol->vol_name, vol->vol_name);
359 * Clear dev pointer so that free_vol_item() doesn't
360 * take away our volume.
362 nvol->dev = NULL; /* don't zap dev entry */
365 /* Check if we are trying to use the Volume on a different drive */
366 if (dev != vol->dev) {
367 /* Caller wants to switch Volume to another device */
368 if (!vol->dev->is_busy()) {
369 /* OK to move it -- I'm not sure this will work */
370 Dmsg4(dbglvl, "==== jid=%u Swap vol=%s from dev=%s to %s\n", jid(), VolumeName,
371 vol->dev->print_name(), dev->print_name());
372 vol->dev->vol = NULL; /* take vol from old drive */
373 vol->dev->VolHdr.VolumeName[0] = 0;
374 vol->dev = dev; /* point vol at new drive */
375 dev->vol = vol; /* point dev at vol */
376 dev->VolHdr.VolumeName[0] = 0;
378 Dmsg4(dbglvl, "jid=%u Volume busy could not swap vol=%s from dev=%s to %s\n",
379 jid(), VolumeName, vol->dev->print_name(), dev->print_name());
380 vol = NULL; /* device busy */
387 debug_list_volumes("end new volume");
393 * Search for a Volume name in the Volume list.
395 * Returns: VOLRES entry on success
396 * NULL if the Volume is not in the list
398 VOLRES *find_volume(DCR *dcr)
401 /* Do not lock reservations here */
403 vol.vol_name = bstrdup(dcr->VolumeName);
404 fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare);
406 Dmsg3(dbglvl, "jid=%u find_vol=%s found=%d\n", jid(), dcr->VolumeName, fvol!=NULL);
407 debug_list_volumes("find_volume");
413 * Remove any reservation from a drive and tell the system
414 * that the volume is unused at least by us.
416 void unreserve_device(DCR *dcr)
418 DEVICE *dev = dcr->dev;
419 if (dcr->reserved_device) {
420 dcr->reserved_device = false;
421 dev->reserved_device--;
422 Dmsg3(dbglvl, "jid=%u Dec reserve=%d dev=%s\n", jid(), dev->reserved_device, dev->print_name());
423 dcr->reserved_device = false;
424 /* If we set read mode in reserving, remove it */
425 if (dev->can_read()) {
428 if (dev->num_writers < 0) {
429 Jmsg1(dcr->jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers);
430 dev->num_writers = 0;
438 * Free a Volume from the Volume list if it is no longer used
440 * Returns: true if the Volume found and removed from the list
441 * false if the Volume is not in the list or is in use
443 bool volume_unused(DCR *dcr)
445 DEVICE *dev = dcr->dev;
447 if (dev->vol == NULL) {
448 Dmsg2(dbglvl, "jid=%u vol_unused: no vol on %s\n", (int)dcr->jcr->JobId, dev->print_name());
449 debug_list_volumes("null vol cannot unreserve_volume");
453 if (dev->is_busy()) {
454 Dmsg2(dbglvl, "jid=%u vol_unused: no vol on %s\n", (int)dcr->jcr->JobId, dev->print_name());
455 debug_list_volumes("dev busy cannot unreserve_volume");
460 * If this is a tape, we do not free the volume, rather we wait
461 * until the autoloader unloads it, or until another tape is
462 * explicitly read in this drive. This allows the SD to remember
463 * where the tapes are or last were.
465 if (dev->is_tape() || dev->is_autochanger()) {
468 return free_volume(dev);
473 * Unconditionally release the volume
475 bool free_volume(DEVICE *dev)
479 if (dev->vol == NULL) {
480 Dmsg2(dbglvl, "jid=%u No vol on dev %s\n", jid(), dev->print_name());
486 vol_list->remove(vol);
487 Dmsg3(dbglvl, "jid=%u free_volume %s dev=%s\n", jid(), vol->vol_name, dev->print_name());
489 debug_list_volumes("free_volume");
495 /* Create the Volume list */
496 void create_volume_list()
499 if (vol_list == NULL) {
500 vol_list = New(dlist(vol, &vol->link));
504 /* Release all Volumes from the list */
505 void free_volume_list()
512 foreach_dlist(vol, vol_list) {
514 Dmsg3(dbglvl, "jid=%u free vol_list Volume=%s dev=%s\n", jid(),
515 vol->vol_name, vol->dev->print_name());
517 Dmsg3(dbglvl, "jid=%u free vol_list Volume=%s dev=%p\n", jid(),
518 vol->vol_name, vol->dev);
521 vol->vol_name = NULL;
528 bool is_volume_in_use(DCR *dcr)
530 VOLRES *vol = find_volume(dcr);
532 Dmsg2(dbglvl, "jid=%u Vol=%s not in use.\n", jid(), dcr->VolumeName);
533 return false; /* vol not in list */
535 ASSERT(vol->dev != NULL);
537 if (dcr->dev == vol->dev) { /* same device OK */
538 Dmsg2(dbglvl, "jid=%u Vol=%s on same dev.\n", jid(), dcr->VolumeName);
541 Dmsg4(dbglvl, "jid=%u Vol=%s on %s we have %s\n", jid(), dcr->VolumeName,
542 vol->dev->print_name(), dcr->dev->print_name());
544 if (!vol->dev->is_busy()) {
545 Dmsg3(dbglvl, "jid=%u Vol=%s dev=%s not busy.\n", jid(), dcr->VolumeName, vol->dev->print_name());
548 Dmsg3(dbglvl, "jid=%u Vol=%s dev=%s busy.\n", jid(), dcr->VolumeName, vol->dev->print_name());
550 Dmsg3(dbglvl, "jid=%u Vol=%s in use by %s.\n", jid(), dcr->VolumeName, vol->dev->print_name());
556 * We get the following type of information:
558 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=1 copy=0 strip=0
562 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=0 copy=0 strip=0
566 static bool use_storage_cmd(JCR *jcr)
568 POOL_MEM store_name, dev_name, media_type, pool_name, pool_type;
569 BSOCK *dir = jcr->dir_bsock;
577 memset(&rctx, 0, sizeof(RCTX));
580 * If there are multiple devices, the director sends us
581 * use_device for each device that it wants to use.
583 dirstore = New(alist(10, not_owned_by_alist));
584 jcr->reserve_msgs = New(alist(10, not_owned_by_alist));
586 Dmsg2(dbglvl, "jid=%u <dird: %s", jid(), dir->msg);
587 ok = sscanf(dir->msg, use_storage, store_name.c_str(),
588 media_type.c_str(), pool_name.c_str(),
589 pool_type.c_str(), &append, &Copy, &Stripe) == 7;
594 jcr->write_store = dirstore;
596 jcr->read_store = dirstore;
598 rctx.append = append;
599 unbash_spaces(store_name);
600 unbash_spaces(media_type);
601 unbash_spaces(pool_name);
602 unbash_spaces(pool_type);
603 store = new DIRSTORE;
604 dirstore->append(store);
605 memset(store, 0, sizeof(DIRSTORE));
606 store->device = New(alist(10));
607 bstrncpy(store->name, store_name, sizeof(store->name));
608 bstrncpy(store->media_type, media_type, sizeof(store->media_type));
609 bstrncpy(store->pool_name, pool_name, sizeof(store->pool_name));
610 bstrncpy(store->pool_type, pool_type, sizeof(store->pool_type));
611 store->append = append;
613 /* Now get all devices */
614 while (dir->recv() >= 0) {
615 Dmsg2(dbglvl, "jid=%u <dird device: %s", jid(), dir->msg);
616 ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
620 unbash_spaces(dev_name);
621 store->device->append(bstrdup(dev_name.c_str()));
623 } while (ok && dir->recv() >= 0);
625 /* Developer debug code */
627 if (debug_level >= dbglvl) {
628 foreach_alist(store, dirstore) {
629 Dmsg6(dbglvl, "jid=%u Storage=%s media_type=%s pool=%s pool_type=%s append=%d\n",
630 (int)rctx.jcr->JobId,
631 store->name, store->media_type, store->pool_name,
632 store->pool_type, store->append);
633 foreach_alist(device_name, store->device) {
634 Dmsg2(dbglvl, "jid=%u Device=%s\n", jid(), device_name);
639 init_jcr_device_wait_timers(jcr);
640 jcr->dcr = new_dcr(jcr, NULL, NULL); /* get a dcr */
642 BSOCK *dir = jcr->dir_bsock;
643 dir->fsend(_("3939 Could not get dcr\n"));
644 Dmsg1(dbglvl, ">dird: %s", dir->msg);
648 * At this point, we have a list of all the Director's Storage
649 * resources indicated for this Job, which include Pool, PoolType,
650 * storage name, and Media type.
651 * Then for each of the Storage resources, we have a list of
652 * device names that were given.
654 * Wiffle through them and find one that can do the backup.
657 int wait_for_device_retries = 0;
660 rctx.notify_dir = true;
663 for ( ; !fail && !job_canceled(jcr); ) {
664 pop_reserve_messages(jcr);
665 rctx.suitable_device = false;
666 rctx.have_volume = false;
667 rctx.VolumeName[0] = 0;
668 rctx.any_drive = false;
669 if (!jcr->PreferMountedVols) {
671 * Here we try to find a drive that is not used.
672 * This will maximize the use of available drives.
675 rctx.num_writers = 20000000; /* start with impossible number */
676 rctx.low_use_drive = NULL;
677 rctx.PreferMountedVols = false;
678 rctx.exact_match = false;
679 rctx.autochanger_only = true;
680 Dmsg6(dbglvl, "jid=%u PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
681 (int)rctx.jcr->JobId,
682 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
683 rctx.autochanger_only, rctx.any_drive);
684 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
687 /* Look through all drives possibly for low_use drive */
688 if (rctx.low_use_drive) {
689 rctx.try_low_use_drive = true;
690 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
693 rctx.try_low_use_drive = false;
695 rctx.autochanger_only = false;
696 Dmsg6(dbglvl, "jid=%u PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
697 (int)rctx.jcr->JobId,
698 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
699 rctx.autochanger_only, rctx.any_drive);
700 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
705 * Now we look for a drive that may or may not be in
708 /* Look for an exact Volume match all drives */
709 rctx.PreferMountedVols = true;
710 rctx.exact_match = true;
711 rctx.autochanger_only = false;
712 Dmsg6(dbglvl, "jid=%u PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
713 (int)rctx.jcr->JobId,
714 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
715 rctx.autochanger_only, rctx.any_drive);
716 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
719 /* Look for any mounted drive */
720 rctx.exact_match = false;
721 Dmsg6(dbglvl, "jid=%u PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
722 (int)rctx.jcr->JobId,
723 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
724 rctx.autochanger_only, rctx.any_drive);
725 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
729 rctx.any_drive = true;
730 Dmsg6(dbglvl, "jid=%u PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
731 (int)rctx.jcr->JobId,
732 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
733 rctx.autochanger_only, rctx.any_drive);
734 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
737 /* Keep reservations locked *except* during wait_for_device() */
738 unlock_reservations();
740 * The idea of looping on repeat a few times it to ensure
741 * that if there is some subtle timing problem between two
742 * jobs, we will simply try again, and most likely succeed.
743 * This can happen if one job reserves a drive or finishes using
744 * a drive at the same time a second job wants it.
746 if (repeat++ > 1) { /* try algorithm 3 times */
747 bmicrosleep(30, 0); /* wait a bit */
748 Dmsg1(dbglvl, "jid=%u repeat reserve algorithm\n", (int)rctx.jcr->JobId);
749 } else if (!rctx.suitable_device || !wait_for_device(jcr, wait_for_device_retries)) {
750 Dmsg1(dbglvl, "jid=%u Fail. !suitable_device || !wait_for_device\n",
751 (int)rctx.jcr->JobId);
755 dir->signal(BNET_HEARTBEAT); /* Inform Dir that we are alive */
757 unlock_reservations();
760 * If we get here, there are no suitable devices available, which
761 * means nothing configured. If a device is suitable but busy
762 * with another Volume, we will not come here.
764 unbash_spaces(dir->msg);
765 pm_strcpy(jcr->errmsg, dir->msg);
766 Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
767 Jmsg(jcr, M_FATAL, 0, _("\n"
768 " Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"),
769 dev_name.c_str(), media_type.c_str());
770 dir->fsend(NO_device, dev_name.c_str());
772 Dmsg2(dbglvl, "jid=%u >dird: %s", jid(), dir->msg);
775 unbash_spaces(dir->msg);
776 pm_strcpy(jcr->errmsg, dir->msg);
777 Jmsg(jcr, M_FATAL, 0, _("Failed command: %s\n"), jcr->errmsg);
778 dir->fsend(BAD_use, jcr->errmsg);
779 Dmsg2(dbglvl, "jid=%u >dird: %s", jid(), dir->msg);
782 release_reserve_messages(jcr);
788 * Walk through the autochanger resources and check if
789 * the volume is in one of them.
791 * Returns: true if volume is in device
794 static bool is_vol_in_autochanger(RCTX &rctx, VOLRES *vol)
796 AUTOCHANGER *changer = vol->dev->device->changer_res;
798 /* Find resource, and make sure we were able to open it */
799 if (strcmp(rctx.device_name, changer->hdr.name) == 0) {
800 Dmsg2(dbglvl, "jid=%u Found changer device %s\n",
801 (int)rctx.jcr->JobId, vol->dev->device->hdr.name);
804 Dmsg2(dbglvl, "jid=%u Incorrect changer device %s\n",
805 (int)rctx.jcr->JobId, changer->hdr.name);
810 * Search for a device suitable for this job.
812 bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx)
821 dirstore = jcr->write_store;
823 dirstore = jcr->read_store;
825 Dmsg5(dbglvl, "jid=%u PrefMnt=%d exact=%d suitable=%d chgronly=%d\n",
826 (int)rctx.jcr->JobId,
827 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
828 rctx.autochanger_only);
831 * If the appropriate conditions of this if are met, namely that
832 * we are appending and the user wants mounted drive (or we
833 * force try a mounted drive because they are all busy), we
834 * start by looking at all the Volumes in the volume list.
836 if (!vol_list->empty() && rctx.append && rctx.PreferMountedVols) {
837 dlist *temp_vol_list, *save_vol_list;
842 * Create a temporary copy of the volume list. We do this,
843 * to avoid having the volume list locked during the
844 * call to reserve_device(), which would cause a deadlock.
845 * Note, we may want to add an update counter on the vol_list
846 * so that if it is modified while we are traversing the copy
847 * we can take note and act accordingly (probably redo the
848 * search at least a few times).
850 Dmsg1(dbglvl, "jid=%u duplicate vol list\n", (int)rctx.jcr->JobId);
851 temp_vol_list = New(dlist(vol, &vol->link));
852 foreach_dlist(vol, vol_list) {
854 VOLRES *tvol = (VOLRES *)malloc(sizeof(VOLRES));
855 memset(tvol, 0, sizeof(VOLRES));
856 tvol->vol_name = bstrdup(vol->vol_name);
857 tvol->dev = vol->dev;
858 nvol = (VOLRES *)temp_vol_list->binary_insert(tvol, my_compare);
860 tvol->dev = NULL; /* don't zap dev entry */
862 Pmsg0(000, "Logic error. Duplicating vol list hit duplicate.\n");
863 Jmsg(jcr, M_WARNING, 0, "Logic error. Duplicating vol list hit duplicate.\n");
868 /* Look through reserved volumes for one we can use */
869 Dmsg1(dbglvl, "jid=%u look for vol in vol list\n", (int)rctx.jcr->JobId);
870 foreach_dlist(vol, temp_vol_list) {
872 Dmsg2(dbglvl, "jid=%u vol=%s no dev\n", (int)rctx.jcr->JobId, vol->vol_name);
875 /* Check with Director if this Volume is OK */
876 bstrncpy(dcr->VolumeName, vol->vol_name, sizeof(dcr->VolumeName));
877 if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE)) {
881 Dmsg2(dbglvl, "jid=%u vol=%s OK for this job\n", (int)rctx.jcr->JobId, vol->vol_name);
882 foreach_alist(store, dirstore) {
885 foreach_alist(device_name, store->device) {
886 /* Found a device, try to use it */
887 rctx.device_name = device_name;
888 rctx.device = vol->dev->device;
890 if (vol->dev->is_autochanger()) {
891 Dmsg2(dbglvl, "jid=%u vol=%s is in changer\n", (int)rctx.jcr->JobId,
893 if (!is_vol_in_autochanger(rctx, vol)) {
896 } else if (strcmp(device_name, vol->dev->device->hdr.name) != 0) {
897 Dmsg3(dbglvl, "jid=%u device=%s not suitable want %s\n", (int)rctx.jcr->JobId,
898 vol->dev->device->hdr.name, device_name);
902 bstrncpy(rctx.VolumeName, vol->vol_name, sizeof(rctx.VolumeName));
903 rctx.have_volume = true;
904 /* Try reserving this device and volume */
905 Dmsg3(dbglvl, "jid=%u try vol=%s on device=%s\n", (int)rctx.jcr->JobId,
906 rctx.VolumeName, device_name);
907 stat = reserve_device(rctx);
908 if (stat == 1) { /* found available device */
909 Dmsg2(dbglvl, "jid=%u Suitable device found=%s\n", (int)rctx.jcr->JobId,
913 } else if (stat == 0) { /* device busy */
914 Dmsg2(dbglvl, "jid=%u Suitable device=%s, busy: not use\n",
915 (int)rctx.jcr->JobId, device_name);
917 /* otherwise error */
918 Dmsg1(dbglvl, "jid=%u No suitable device found.\n", (int)rctx.jcr->JobId);
920 rctx.have_volume = false;
929 } /* end for loop over reserved volumes */
932 save_vol_list = vol_list;
933 vol_list = temp_vol_list;
934 free_volume_list(); /* release temp_vol_list */
935 vol_list = save_vol_list;
936 Dmsg1(dbglvl, "jid=%u deleted temp vol list\n", (int)rctx.jcr->JobId);
940 Dmsg2(dbglvl, "jid=%u got vol %s from in-use vols list\n", (int)rctx.jcr->JobId,
946 * No reserved volume we can use, so now search for an available device.
948 * For each storage device that the user specified, we
949 * search and see if there is a resource for that device.
951 foreach_alist(store, dirstore) {
953 foreach_alist(device_name, store->device) {
955 rctx.device_name = device_name;
956 stat = search_res_for_device(rctx);
957 if (stat == 1) { /* found available device */
958 Dmsg2(dbglvl, "jid=%u available device found=%s\n", (int)rctx.jcr->JobId,
962 } else if (stat == 0) { /* device busy */
963 Dmsg2(dbglvl, "jid=%u Suitable device=%s, busy: not use\n",
964 (int)rctx.jcr->JobId, device_name);
966 /* otherwise error */
967 Dmsg1(dbglvl, "jid=%u No suitable device found.\n", (int)rctx.jcr->JobId);
978 * Search for a particular storage device with particular storage
979 * characteristics (MediaType).
981 int search_res_for_device(RCTX &rctx)
983 AUTOCHANGER *changer;
986 Dmsg2(dbglvl, "jid=%u search res for %s\n", (int)rctx.jcr->JobId, rctx.device_name);
987 /* Look through Autochangers first */
988 foreach_res(changer, R_AUTOCHANGER) {
989 Dmsg2(dbglvl, "jid=%u Try match changer res=%s\n", (int)rctx.jcr->JobId, changer->hdr.name);
990 /* Find resource, and make sure we were able to open it */
991 if (strcmp(rctx.device_name, changer->hdr.name) == 0) {
992 /* Try each device in this AutoChanger */
993 foreach_alist(rctx.device, changer->device) {
994 Dmsg2(dbglvl, "jid=%u Try changer device %s\n", (int)rctx.jcr->JobId,
995 rctx.device->hdr.name);
996 stat = reserve_device(rctx);
997 if (stat != 1) { /* try another device */
1001 if (rctx.store->append == SD_APPEND) {
1002 Dmsg3(dbglvl, "jid=%u Device %s reserved=%d for append.\n",
1003 (int)rctx.jcr->JobId, rctx.device->hdr.name,
1004 rctx.jcr->dcr->dev->reserved_device);
1006 Dmsg3(dbglvl, "jid=%u Device %s reserved=%d for read.\n",
1007 (int)rctx.jcr->JobId, rctx.device->hdr.name,
1008 rctx.jcr->read_dcr->dev->reserved_device);
1015 /* Now if requested look through regular devices */
1016 if (!rctx.autochanger_only) {
1017 foreach_res(rctx.device, R_DEVICE) {
1018 Dmsg2(dbglvl, "jid=%u Try match res=%s\n", (int)rctx.jcr->JobId, rctx.device->hdr.name);
1019 /* Find resource, and make sure we were able to open it */
1020 if (strcmp(rctx.device_name, rctx.device->hdr.name) == 0) {
1021 stat = reserve_device(rctx);
1022 if (stat != 1) { /* try another device */
1026 if (rctx.store->append == SD_APPEND) {
1027 Dmsg3(dbglvl, "jid=%u Device %s reserved=%d for append.\n",
1028 (int)rctx.jcr->JobId, rctx.device->hdr.name,
1029 rctx.jcr->dcr->dev->reserved_device);
1031 Dmsg3(dbglvl, "jid=%u Device %s reserved=%d for read.\n",
1032 (int)rctx.jcr->JobId, rctx.device->hdr.name,
1033 rctx.jcr->read_dcr->dev->reserved_device);
1039 return -1; /* nothing found */
1043 * Try to reserve a specific device.
1045 * Returns: 1 -- OK, have DCR
1049 static int reserve_device(RCTX &rctx)
1053 const int name_len = MAX_NAME_LENGTH;
1055 /* Make sure MediaType is OK */
1056 Dmsg3(dbglvl, "jid=%u chk MediaType device=%s request=%s\n",
1057 (int)rctx.jcr->JobId,
1058 rctx.device->media_type, rctx.store->media_type);
1059 if (strcmp(rctx.device->media_type, rctx.store->media_type) != 0) {
1063 /* Make sure device exists -- i.e. we can stat() it */
1064 if (!rctx.device->dev) {
1065 rctx.device->dev = init_dev(rctx.jcr, rctx.device);
1067 if (!rctx.device->dev) {
1068 if (rctx.device->changer_res) {
1069 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
1070 " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
1071 rctx.device->hdr.name, rctx.device_name);
1073 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
1074 " Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
1077 return -1; /* no use waiting */
1080 rctx.suitable_device = true;
1081 Dmsg2(dbglvl, "jid=%u try reserve %s\n", rctx.jcr->JobId, rctx.device->hdr.name);
1082 rctx.jcr->dcr = dcr = new_dcr(rctx.jcr, rctx.jcr->dcr, rctx.device->dev);
1084 BSOCK *dir = rctx.jcr->dir_bsock;
1085 dir->fsend(_("3926 Could not get dcr for device: %s\n"), rctx.device_name);
1086 Dmsg1(dbglvl, ">dird: %s", dir->msg);
1089 bstrncpy(dcr->pool_name, rctx.store->pool_name, name_len);
1090 bstrncpy(dcr->pool_type, rctx.store->pool_type, name_len);
1091 bstrncpy(dcr->media_type, rctx.store->media_type, name_len);
1092 bstrncpy(dcr->dev_name, rctx.device_name, name_len);
1093 if (rctx.store->append == SD_APPEND) {
1094 Dmsg3(dbglvl, "jid=%u have_vol=%d vol=%s\n", (int)rctx.jcr->JobId,
1095 rctx.have_volume, rctx.VolumeName);
1096 ok = reserve_device_for_append(dcr, rctx);
1101 rctx.jcr->dcr = dcr;
1102 Dmsg6(dbglvl, "jid=%u Reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
1103 (int)rctx.jcr->JobId,
1104 dcr->dev->reserved_device,
1105 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
1106 if (!rctx.have_volume) {
1107 dcr->any_volume = true;
1108 if (dir_find_next_appendable_volume(dcr)) {
1109 bstrncpy(rctx.VolumeName, dcr->VolumeName, sizeof(rctx.VolumeName));
1110 Dmsg2(dbglvl, "jid=%u looking for Volume=%s\n", (int)rctx.jcr->JobId, rctx.VolumeName);
1111 rctx.have_volume = true;
1113 Dmsg1(dbglvl, "jid=%u No next volume found\n", (int)rctx.jcr->JobId);
1114 rctx.have_volume = false;
1115 rctx.VolumeName[0] = 0;
1117 * If there is at least one volume that is valid and in use,
1118 * but we get here, check if we are running with prefers
1119 * non-mounted drives. In that case, we have selected a
1120 * non-used drive and our one and only volume is mounted
1121 * elsewhere, so we bail out and retry using that drive.
1123 if (dcr->volume_in_use && !rctx.PreferMountedVols) {
1124 rctx.PreferMountedVols = true;
1130 ok = reserve_device_for_read(dcr);
1132 rctx.jcr->read_dcr = dcr;
1133 Dmsg6(dbglvl, "jid=%u Read reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
1134 (int)rctx.jcr->JobId,
1135 dcr->dev->reserved_device,
1136 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
1142 if (rctx.notify_dir) {
1144 BSOCK *dir = rctx.jcr->dir_bsock;
1145 pm_strcpy(dev_name, rctx.device->hdr.name);
1146 bash_spaces(dev_name);
1147 ok = dir->fsend(OK_device, dev_name.c_str()); /* Return real device name */
1148 Dmsg2(dbglvl, "jid=%u >dird changer: %s", jid(), dir->msg);
1155 rctx.have_volume = false;
1157 Dmsg1(dbglvl, "jid=%u Not OK.\n", (int)rctx.jcr->JobId);
1162 * We "reserve" the drive by setting the ST_READ bit. No one else
1163 * should touch the drive until that is cleared.
1164 * This allows the DIR to "reserve" the device before actually
1167 static bool reserve_device_for_read(DCR *dcr)
1169 DEVICE *dev = dcr->dev;
1170 JCR *jcr = dcr->jcr;
1177 if (is_device_unmounted(dev)) {
1178 Dmsg2(dbglvl, "jid=%u Device %s is BLOCKED due to user unmount.\n",
1179 (int)jcr->JobId, dev->print_name());
1180 Mmsg(jcr->errmsg, _("3601 JobId=%u device %s is BLOCKED due to user unmount.\n"),
1181 jcr->JobId, dev->print_name());
1182 queue_reserve_message(jcr);
1186 if (dev->is_busy()) {
1187 Dmsg5(dbglvl, "jid=%u Device %s is busy ST_READ=%d num_writers=%d reserved=%d.\n",
1188 (int)jcr->JobId, dev->print_name(),
1189 dev->state & ST_READ?1:0, dev->num_writers, dev->reserved_device);
1190 Mmsg(jcr->errmsg, _("3602 JobId=%u device %s is busy (already reading/writing).\n"),
1191 jcr->JobId, dev->print_name());
1192 queue_reserve_message(jcr);
1196 dev->clear_append();
1199 dev->reserved_device++;
1200 Dmsg4(dbglvl, "jid=%u Inc reserve=%d dev=%s %p\n", (int)jcr->JobId,
1201 dev->reserved_device, dev->print_name(), dev);
1202 dcr->reserved_device = true;
1211 * We reserve the device for appending by incrementing the
1212 * reserved_device. We do virtually all the same work that
1213 * is done in acquire_device_for_append(), but we do
1214 * not attempt to mount the device. This routine allows
1215 * the DIR to reserve multiple devices before *really*
1216 * starting the job. It also permits the SD to refuse
1217 * certain devices (not up, ...).
1219 * Note, in reserving a device, if the device is for the
1220 * same pool and the same pool type, then it is acceptable.
1221 * The Media Type has already been checked. If we are
1222 * the first tor reserve the device, we put the pool
1223 * name and pool type in the device record.
1225 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
1227 JCR *jcr = dcr->jcr;
1228 DEVICE *dev = dcr->dev;
1235 /* If device is being read, we cannot write it */
1236 if (dev->can_read()) {
1237 Mmsg(jcr->errmsg, _("3603 JobId=%u device %s is busy reading.\n"),
1238 jcr->JobId, dev->print_name());
1239 Dmsg2(dbglvl, "jid=%u %s", jid(), jcr->errmsg);
1240 queue_reserve_message(jcr);
1244 /* If device is unmounted, we are out of luck */
1245 if (is_device_unmounted(dev)) {
1246 Mmsg(jcr->errmsg, _("3604 JobId=%u device %s is BLOCKED due to user unmount.\n"),
1247 jcr->JobId, dev->print_name());
1248 Dmsg2(dbglvl, "jid=%u %s", jid(), jcr->errmsg);
1249 queue_reserve_message(jcr);
1253 Dmsg2(dbglvl, "jid=%u reserve_append device is %s\n",
1254 (int)jcr->JobId, dev->print_name());
1256 /* Now do detailed tests ... */
1257 if (can_reserve_drive(dcr, rctx) != 1) {
1258 Dmsg1(dbglvl, "jid=%u can_reserve_drive!=1\n", (int)jcr->JobId);
1262 dev->reserved_device++;
1263 Dmsg4(dbglvl, "jid=%u Inc reserve=%d dev=%s %p\n", (int)jcr->JobId, dev->reserved_device,
1264 dev->print_name(), dev);
1265 dcr->reserved_device = true;
1274 * Returns: 1 if drive can be reserved
1275 * 0 if we should wait
1276 * -1 on error or impossibility
1278 static int can_reserve_drive(DCR *dcr, RCTX &rctx)
1280 DEVICE *dev = dcr->dev;
1281 JCR *jcr = dcr->jcr;
1283 Dmsg6(dbglvl, "jid=%u PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
1285 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
1286 rctx.autochanger_only, rctx.any_drive);
1288 /* setting any_drive overrides PreferMountedVols flag */
1289 if (!rctx.any_drive) {
1291 * When PreferMountedVols is set, we keep track of the
1292 * drive in use that has the least number of writers, then if
1293 * no unmounted drive is found, we try that drive. This
1294 * helps spread the load to the least used drives.
1296 if (rctx.try_low_use_drive && dev == rctx.low_use_drive) {
1297 Dmsg3(dbglvl, "jid=%u OK dev=%s == low_drive=%s.\n",
1298 jcr->JobId, dev->print_name(), rctx.low_use_drive->print_name());
1301 /* If he wants a free drive, but this one is busy, no go */
1302 if (!rctx.PreferMountedVols && dev->is_busy()) {
1303 /* Save least used drive */
1304 if ((dev->num_writers + dev->reserved_device) < rctx.num_writers) {
1305 rctx.num_writers = dev->num_writers + dev->reserved_device;
1306 rctx.low_use_drive = dev;
1307 Dmsg3(dbglvl, "jid=%u set low use drive=%s num_writers=%d\n",
1308 (int)jcr->JobId, dev->print_name(), rctx.num_writers);
1310 Dmsg2(dbglvl, "jid=%u not low use num_writers=%d\n",
1311 (int)jcr->JobId, dev->num_writers+dev->reserved_device);
1313 Dmsg1(dbglvl, "jid=%u failed: !prefMnt && busy.\n", jcr->JobId);
1314 Mmsg(jcr->errmsg, _("3605 JobId=%u wants free drive but device %s is busy.\n"),
1315 jcr->JobId, dev->print_name());
1316 queue_reserve_message(jcr);
1320 /* Check for prefer mounted volumes */
1321 if (rctx.PreferMountedVols && !dev->vol && dev->is_tape()) {
1322 Mmsg(jcr->errmsg, _("3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n"),
1323 jcr->JobId, dev->print_name());
1324 queue_reserve_message(jcr);
1325 Dmsg1(dbglvl, "jid=%u failed: want mounted -- no vol\n", (uint32_t)jcr->JobId);
1326 return 0; /* No volume mounted */
1329 /* Check for exact Volume name match */
1330 /* ***FIXME*** for Disk, we can accept any volume that goes with this
1333 if (rctx.exact_match && rctx.have_volume) {
1335 Dmsg6(dbglvl, "jid=%u PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
1337 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
1338 rctx.autochanger_only, rctx.any_drive);
1339 Dmsg5(dbglvl, "jid=%u have_vol=%d have=%s resvol=%s want=%s\n",
1340 (int)jcr->JobId, rctx.have_volume, dev->VolHdr.VolumeName,
1341 dev->vol?dev->vol->vol_name:"*none*", rctx.VolumeName);
1342 ok = strcmp(dev->VolHdr.VolumeName, rctx.VolumeName) == 0 ||
1343 (dev->vol && strcmp(dev->vol->vol_name, rctx.VolumeName) == 0);
1345 Mmsg(jcr->errmsg, _("3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n"),
1346 jcr->JobId, rctx.VolumeName, dev->VolHdr.VolumeName,
1348 queue_reserve_message(jcr);
1349 Dmsg4(dbglvl, "jid=%u not OK: dev have=%s resvol=%s want=%s\n",
1350 (int)jcr->JobId, dev->VolHdr.VolumeName,
1351 dev->vol?dev->vol->vol_name:"*none*", rctx.VolumeName);
1354 if (is_volume_in_use(dcr)) {
1355 return 0; /* fail if volume on another drive */
1360 /* Check for unused autochanger drive */
1361 if (rctx.autochanger_only && !dev->is_busy() &&
1362 dev->VolHdr.VolumeName[0] == 0) {
1363 /* Device is available but not yet reserved, reserve it for us */
1364 Dmsg2(dbglvl, "jid=%u OK Res Unused autochanger %s.\n",
1365 jcr->JobId, dev->print_name());
1366 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1367 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1368 return 1; /* reserve drive */
1372 * Handle the case that there are no writers
1374 if (dev->num_writers == 0) {
1375 /* Now check if there are any reservations on the drive */
1376 if (dev->reserved_device) {
1377 /* Now check if we want the same Pool and pool type */
1378 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1379 strcmp(dev->pool_type, dcr->pool_type) == 0) {
1380 /* OK, compatible device */
1381 Dmsg2(dbglvl, "jid=%u OK dev: %s num_writers=0, reserved, pool matches\n",
1382 jcr->JobId, dev->print_name());
1385 /* Drive Pool not suitable for us */
1386 Mmsg(jcr->errmsg, _(
1387 "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %s.\n"),
1388 jcr->JobId, dcr->pool_name, dev->pool_name,
1389 dev->reserved_device, dev->print_name());
1390 queue_reserve_message(jcr);
1391 Dmsg3(dbglvl, "jid=%u failed: busy num_writers=0, reserved, pool=%s wanted=%s\n",
1392 (int)jcr->JobId, dev->pool_name, dcr->pool_name);
1393 return 0; /* wait */
1395 } else if (dev->can_append()) {
1396 /* Device in append mode, check if changing pool */
1397 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1398 strcmp(dev->pool_type, dcr->pool_type) == 0) {
1399 Dmsg2(dbglvl, "jid=%u OK dev: %s num_writers=0, can_append, pool matches.\n",
1400 jcr->JobId, dev->print_name());
1401 /* OK, compatible device */
1404 /* Changing pool, unload old tape if any in drive */
1405 Dmsg1(dbglvl, "jid=%u OK dev: num_writers=0, not reserved, pool change, unload changer\n",
1407 unload_autochanger(dcr, 0);
1410 /* Device is available but not yet reserved, reserve it for us */
1411 Dmsg2(dbglvl, "jid=%u OK Dev avail reserved %s\n", jcr->JobId, dev->print_name());
1412 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1413 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1414 return 1; /* reserve drive */
1418 * Check if the device is in append mode with writers (i.e.
1419 * available if pool is the same).
1421 if (dev->can_append() || dev->num_writers > 0) {
1422 /* Yes, now check if we want the same Pool and pool type */
1423 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1424 strcmp(dev->pool_type, dcr->pool_type) == 0) {
1425 Dmsg2(dbglvl, "jid=%u OK dev: %s num_writers>=0, can_append, pool matches.\n",
1426 jcr->JobId, dev->print_name());
1427 /* OK, compatible device */
1430 /* Drive Pool not suitable for us */
1431 Mmsg(jcr->errmsg, _("3609 JobId=%u wants Pool=\"%s\" but has Pool=\"%s\" on drive %s.\n"),
1432 jcr->JobId, dcr->pool_name, dev->pool_name, dev->print_name());
1433 queue_reserve_message(jcr);
1434 Dmsg3(dbglvl, "jid=%u failed: busy num_writers>0, can_append, pool=%s wanted=%s\n",
1435 (int)jcr->JobId, dev->pool_name, dcr->pool_name);
1436 return 0; /* wait */
1439 Pmsg1(000, _("Logic error!!!! JobId=%u Should not get here.\n"), (int)jcr->JobId);
1440 Mmsg(jcr->errmsg, _("3910 JobId=%u Logic error!!!! drive %s Should not get here.\n"),
1441 jcr->JobId, dev->print_name());
1442 queue_reserve_message(jcr);
1443 Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
1444 return -1; /* error, should not get here */
1446 Mmsg(jcr->errmsg, _("3911 JobId=%u failed reserve drive %s.\n"),
1447 jcr->JobId, dev->print_name());
1448 queue_reserve_message(jcr);
1449 Dmsg2(dbglvl, "jid=%u failed: No reserve %s\n", jcr->JobId, dev->print_name());
1457 * Queue a reservation error or failure message for this jcr
1459 static void queue_reserve_message(JCR *jcr)
1467 msgs = jcr->reserve_msgs;
1472 * Look for duplicate message. If found, do
1475 for (i=msgs->size()-1; i >= 0; i--) {
1476 msg = (char *)msgs->get(i);
1480 /* Comparison based on 4 digit message number */
1481 if (strncmp(msg, jcr->errmsg, 4) == 0) {
1485 /* Message unique, so insert it */
1486 jcr->reserve_msgs->push(bstrdup(jcr->errmsg));
1493 * Send any reservation messages queued for this jcr
1495 void send_drive_reserve_messages(JCR *jcr, void sendit(const char *msg, int len, void *sarg), void *arg)
1502 msgs = jcr->reserve_msgs;
1503 if (!msgs || msgs->size() == 0) {
1506 for (i=msgs->size()-1; i >= 0; i--) {
1507 msg = (char *)msgs->get(i);
1509 sendit(" ", 3, arg);
1510 sendit(msg, strlen(msg), arg);
1521 * Pop and release any reservations messages
1523 static void pop_reserve_messages(JCR *jcr)
1529 msgs = jcr->reserve_msgs;
1533 while ((msg = (char *)msgs->pop())) {
1541 * Also called from acquire.c
1543 void release_reserve_messages(JCR *jcr)
1545 pop_reserve_messages(jcr);
1547 if (!jcr->reserve_msgs) {
1550 delete jcr->reserve_msgs;
1551 jcr->reserve_msgs = NULL;