2 * Drive reservation functions for Storage Daemon
6 * Split from job.c and acquire.c June 2005
12 Copyright (C) 2000-2005 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.
30 * Use Device command from Director
31 * He tells is what Device Name to use, the Media Type,
32 * the Pool Name, and the Pool Type.
34 * Ensure that the device exists and is opened, then store
35 * the media and pool info in the JCR. This class is used
36 * only temporarily in this file.
42 char name[MAX_NAME_LENGTH];
43 char media_type[MAX_NAME_LENGTH];
44 char pool_name[MAX_NAME_LENGTH];
45 char pool_type[MAX_NAME_LENGTH];
56 bool PreferMountedVols;
60 bool available_autochanger;
61 char VolumeName[MAX_NAME_LENGTH];
64 static dlist *vol_list = NULL;
65 static pthread_mutex_t vol_list_lock = PTHREAD_MUTEX_INITIALIZER;
66 static pthread_mutex_t search_lock = PTHREAD_MUTEX_INITIALIZER;
68 /* Forward referenced functions */
69 static int can_reserve_drive(DCR *dcr, RCTX &rctx);
70 static int search_res_for_device(RCTX &rctx);
71 static int reserve_device(RCTX &rctx);
72 static bool reserve_device_for_read(DCR *dcr);
73 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx);
74 static bool use_storage_cmd(JCR *jcr);
75 bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx);
77 /* Requests from the Director daemon */
78 static char use_storage[] = "use storage=%127s media_type=%127s "
79 "pool_name=%127s pool_type=%127s append=%d copy=%d stripe=%d\n";
80 static char use_device[] = "use device=%127s\n";
82 /* Responses sent to Director daemon */
83 static char OK_device[] = "3000 OK use device device=%s\n";
84 static char NO_device[] = "3924 Device \"%s\" not in SD Device resources.\n";
85 static char BAD_use[] = "3913 Bad use command: %s\n";
87 bool use_cmd(JCR *jcr)
90 * Get the device, media, and pool information
92 if (!use_storage_cmd(jcr)) {
93 set_jcr_job_status(jcr, JS_ErrorTerminated);
94 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
100 static int my_compare(void *item1, void *item2)
102 return strcmp(((VOLRES *)item1)->vol_name, ((VOLRES *)item2)->vol_name);
107 * Put a new Volume entry in the Volume list. This
108 * effectively reserves the volume so that it will
109 * not be mounted again.
111 * Return: VOLRES entry on success
112 * NULL if the Volume is already in the list
114 VOLRES *new_volume(DCR *dcr, const char *VolumeName)
118 Dmsg1(400, "new_volume %s\n", VolumeName);
122 foreach_dlist(vol, vol_list) {
123 if (vol && vol->dev == dcr->dev) {
124 vol_list->remove(vol);
133 vol = (VOLRES *)malloc(sizeof(VOLRES));
134 memset(vol, 0, sizeof(VOLRES));
135 vol->vol_name = bstrdup(VolumeName);
138 nvol = (VOLRES *)vol_list->binary_insert(vol, my_compare);
144 nvol->dev = dcr->dev;
152 * Search for a Volume name in the Volume list.
154 * Returns: VOLRES entry on success
155 * NULL if the Volume is not in the list
157 VOLRES *find_volume(const char *VolumeName)
161 vol.vol_name = bstrdup(VolumeName);
162 fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare);
169 * Free a Volume from the Volume list
171 * Returns: true if the Volume found and removed from the list
172 * false if the Volume is not in the list
174 bool free_volume(DEVICE *dev)
179 if (dev->VolHdr.VolumeName[0] == 0) {
181 * Our device has no VolumeName listed, but
182 * search the list for any Volume attached to
183 * this device and remove it.
185 foreach_dlist(fvol, vol_list) {
186 if (fvol && fvol->dev == dev) {
187 vol_list->remove(fvol);
188 if (fvol->vol_name) {
189 free(fvol->vol_name);
197 Dmsg1(400, "free_volume %s\n", dev->VolHdr.VolumeName);
198 vol.vol_name = bstrdup(dev->VolHdr.VolumeName);
199 fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare);
201 vol_list->remove(fvol);
202 free(fvol->vol_name);
206 dev->VolHdr.VolumeName[0] = 0;
212 /* Free volume reserved by this dcr but not attached to a dev */
213 void free_unused_volume(DCR *dcr)
217 for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
218 if (vol->dcr == dcr && (vol->dev == NULL ||
219 strcmp(vol->vol_name, vol->dev->VolHdr.VolumeName) != 0)) {
220 vol_list->remove(vol);
230 * List Volumes -- this should be moved to status.c
232 void list_volumes(BSOCK *user)
235 for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
237 bnet_fsend(user, "%s on device %s\n", vol->vol_name, vol->dev->print_name());
239 bnet_fsend(user, "%s\n", vol->vol_name);
244 /* Create the Volume list */
245 void create_volume_list()
247 VOLRES *dummy = NULL;
248 if (vol_list == NULL) {
249 vol_list = New(dlist(dummy, &dummy->link));
253 /* Release all Volumes from the list */
254 void free_volume_list()
260 for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
261 Dmsg3(000, "Unreleased Volume=%s dcr=0x%x dev=0x%x\n", vol->vol_name,
268 bool is_volume_in_use(DCR *dcr)
270 VOLRES *vol = find_volume(dcr->VolumeName);
272 return false; /* vol not in list */
274 if (!vol->dev) { /* vol not attached to device */
277 if (dcr->dev == vol->dev) { /* same device OK */
280 if (!vol->dev->is_busy()) {
287 static bool use_storage_cmd(JCR *jcr)
289 POOL_MEM store_name, dev_name, media_type, pool_name, pool_type;
290 BSOCK *dir = jcr->dir_bsock;
300 memset(&rctx, 0, sizeof(RCTX));
303 * If there are multiple devices, the director sends us
304 * use_device for each device that it wants to use.
306 jcr->dirstore = New(alist(10, not_owned_by_alist));
308 Dmsg1(100, "<dird: %s", dir->msg);
309 ok = sscanf(dir->msg, use_storage, store_name.c_str(),
310 media_type.c_str(), pool_name.c_str(),
311 pool_type.c_str(), &append, &Copy, &Stripe) == 7;
315 unbash_spaces(store_name);
316 unbash_spaces(media_type);
317 unbash_spaces(pool_name);
318 unbash_spaces(pool_type);
319 store = new DIRSTORE;
320 jcr->dirstore->append(store);
321 memset(store, 0, sizeof(DIRSTORE));
322 store->device = New(alist(10));
323 bstrncpy(store->name, store_name, sizeof(store->name));
324 bstrncpy(store->media_type, media_type, sizeof(store->media_type));
325 bstrncpy(store->pool_name, pool_name, sizeof(store->pool_name));
326 bstrncpy(store->pool_type, pool_type, sizeof(store->pool_type));
327 store->append = append;
329 /* Now get all devices */
330 while (bnet_recv(dir) >= 0) {
331 Dmsg1(100, "<dird device: %s", dir->msg);
332 ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
336 unbash_spaces(dev_name);
337 store->device->append(bstrdup(dev_name.c_str()));
339 } while (ok && bnet_recv(dir) >= 0);
342 /* This loop is debug code and can be removed */
343 /* ***FIXME**** remove after 1.38 release */
345 foreach_alist(store, jcr->dirstore) {
346 Dmsg4(100, "Storage=%s media_type=%s pool=%s pool_type=%s\n",
347 store->name, store->media_type, store->pool_name,
349 foreach_alist(device_name, store->device) {
350 Dmsg1(100, " Device=%s\n", device_name);
356 * At this point, we have a list of all the Director's Storage
357 * resources indicated for this Job, which include Pool, PoolType,
358 * storage name, and Media type.
359 * Then for each of the Storage resources, we have a list of
360 * device names that were given.
362 * Wiffle through them and find one that can do the backup.
367 * First look for an exact match of Volume name as the
368 * tape may already be mounted.
370 rctx.do_not_wait = true;
371 rctx.exact_match = true;
372 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
375 rctx.exact_match = false;
377 /* Now search if an unused autochanger slot is available */
378 rctx.available_autochanger = true;
379 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
382 rctx.available_autochanger = false;
386 * Make up to two passes. The first with PreferMountedVols possibly
387 * set to true. In that case, we look only for an available
388 * drive with something mounted. If that fails, then we
389 * do a second pass with PerferMountedVols set false.
391 rctx.PreferMountedVols = jcr->PreferMountedVols;
392 if (!rctx.PreferMountedVols) {
393 rctx.do_not_wait = false;
395 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
398 if (rctx.PreferMountedVols) {
399 rctx.PreferMountedVols = false;
400 rctx.do_not_wait = false;
401 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
405 #else /* NEW SEARCH ALGORITHM */
406 rctx.do_not_wait = true;
407 if (!jcr->PreferMountedVols) {
408 /* Look for unused drives in autochangers */
409 rctx.PreferMountedVols = false;
410 rctx.exact_match = false;
411 rctx.available_autochanger = true;
412 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
415 /* Look through all drives */
416 rctx.available_autochanger = false;
417 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
421 /* Look for an exact match all drives */
422 rctx.PreferMountedVols = true;
423 rctx.exact_match = true;
424 rctx.available_autochanger = false;
425 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
428 /* Look for any mounted drive */
429 rctx.exact_match = false;
430 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
433 /* Wait for any drive anywhere */
434 rctx.PreferMountedVols = false;
435 rctx.exact_match = false;
436 rctx.do_not_wait = false;
437 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
442 unbash_spaces(dir->msg);
443 pm_strcpy(jcr->errmsg, dir->msg);
444 Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
446 Jmsg(jcr, M_FATAL, 0, _("\n"
447 " Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"),
448 dev_name.c_str(), media_type.c_str());
449 bnet_fsend(dir, NO_device, dev_name.c_str());
451 for (error=(char*)rctx->errors.first(); error;
452 error=(char*)rctx->errors.next()) {
453 Jmsg(jcr, M_INFO, 0, "%s", error);
456 Dmsg1(100, ">dird: %s", dir->msg);
458 unbash_spaces(dir->msg);
459 pm_strcpy(jcr->errmsg, dir->msg);
461 Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
463 bnet_fsend(dir, BAD_use, jcr->errmsg);
464 Dmsg1(100, ">dird: %s", dir->msg);
468 foreach_alist(store, jcr->dirstore) {
469 delete store->device;
472 delete jcr->dirstore;
474 for (error=(char*)rctx->errors.first(); error;
475 error=(char*)rctx->errors.next()) {
484 * Search for a device suitable for this job.
486 bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx)
493 Dmsg4(100, "PrefMnt=%d exact=%d no_wait=%d availchgr=%d\n",
494 rctx.PreferMountedVols, rctx.exact_match, rctx.do_not_wait,
495 rctx.available_autochanger);
496 init_jcr_device_wait_timers(jcr);
498 int can_wait = false;
501 foreach_alist(store, jcr->dirstore) {
503 foreach_alist(device_name, store->device) {
505 rctx.device_name = device_name;
506 stat = search_res_for_device(rctx);
507 if (stat == 1) { /* found available device */
510 } else if (stat == 0) { /* device busy */
513 /* otherwise error */
514 // rctx->errors.push(bstrdup(jcr->errmsg));
522 * We did not find a suitable device, so
523 * if there is some device for which we can wait, then
524 * wait and try again until the wait time expires
526 if (rctx.do_not_wait || !can_wait || !wait_for_device(jcr, first)) {
529 first = false; /* first wait complete */
532 for (error=(char*)rctx->errors.first(); error;
533 error=(char*)rctx->errors.next()) {
542 * Search for a particular storage device with particular storage
543 * characteristics (MediaType).
545 static int search_res_for_device(RCTX &rctx)
547 AUTOCHANGER *changer;
548 BSOCK *dir = rctx.jcr->dir_bsock;
552 Dmsg1(100, "Search res for %s\n", rctx.device_name);
553 if (!rctx.available_autochanger) {
554 foreach_res(rctx.device, R_DEVICE) {
555 Dmsg1(100, "Try res=%s\n", rctx.device->hdr.name);
556 /* Find resource, and make sure we were able to open it */
557 if (fnmatch(rctx.device_name, rctx.device->hdr.name, 0) == 0) {
558 stat = reserve_device(rctx);
562 Dmsg1(220, "Got: %s", dir->msg);
563 bash_spaces(rctx.device_name);
564 ok = bnet_fsend(dir, OK_device, rctx.device_name);
565 Dmsg1(100, ">dird dev: %s", dir->msg);
570 foreach_res(changer, R_AUTOCHANGER) {
571 Dmsg1(100, "Try changer res=%s\n", changer->hdr.name);
572 /* Find resource, and make sure we were able to open it */
573 if (fnmatch(rctx.device_name, changer->hdr.name, 0) == 0) {
574 /* Try each device in this AutoChanger */
575 foreach_alist(rctx.device, changer->device) {
576 Dmsg1(100, "Try changer device %s\n", rctx.device->hdr.name);
577 stat = reserve_device(rctx);
578 if (stat != 1) { /* try another device */
582 if (rctx.store->append == SD_APPEND) {
583 Dmsg2(100, "Device %s reserved=%d.\n", rctx.device_name,
584 rctx.jcr->dcr->dev->reserved_device);
586 Dmsg2(100, "Device %s reserved=%d.\n", rctx.device_name,
587 rctx.jcr->read_dcr->dev->reserved_device);
589 pm_strcpy(dev_name, rctx.device->hdr.name);
590 bash_spaces(dev_name);
591 ok = bnet_fsend(dir, OK_device, dev_name.c_str()); /* Return real device name */
592 Dmsg1(100, ">dird changer: %s", dir->msg);
597 return 0; /* nothing found */
601 * Try to reserve a specific device.
603 * Returns: 1 -- OK, have DCR
607 static int reserve_device(RCTX &rctx)
611 const int name_len = MAX_NAME_LENGTH;
613 /* Make sure MediaType is OK */
614 if (strcmp(rctx.device->media_type, rctx.store->media_type) != 0) {
618 if (!rctx.device->dev) {
619 rctx.device->dev = init_dev(rctx.jcr, rctx.device);
621 if (!rctx.device->dev) {
622 if (rctx.device->changer_res) {
623 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
624 " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
625 rctx.device->hdr.name, rctx.device_name);
627 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
628 " Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
631 return -1; /* no use waiting */
633 Dmsg2(100, "Try reserve %s jobid=%d\n", rctx.device->hdr.name,
635 dcr = new_dcr(rctx.jcr, rctx.device->dev);
637 BSOCK *dir = rctx.jcr->dir_bsock;
638 bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), rctx.device_name);
639 Dmsg1(100, ">dird: %s", dir->msg);
642 bstrncpy(dcr->pool_name, rctx.store->pool_name, name_len);
643 bstrncpy(dcr->pool_type, rctx.store->pool_type, name_len);
644 bstrncpy(dcr->media_type, rctx.store->media_type, name_len);
645 bstrncpy(dcr->dev_name, rctx.device_name, name_len);
646 if (rctx.store->append == SD_APPEND) {
647 if (rctx.exact_match && !rctx.have_volume) {
648 dcr->any_volume = true;
649 if (dir_find_next_appendable_volume(dcr)) {
650 Dmsg1(100, "Looking for Volume=%s\n", dcr->VolumeName);
651 bstrncpy(rctx.VolumeName, dcr->VolumeName, sizeof(rctx.VolumeName));
652 rctx.have_volume = true;
654 Dmsg0(100, "No next volume found\n");
655 rctx.VolumeName[0] = 0;
658 ok = reserve_device_for_append(dcr, rctx);
661 Dmsg5(100, "Reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
662 dcr->dev->reserved_device,
663 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
666 ok = reserve_device_for_read(dcr);
668 rctx.jcr->read_dcr = dcr;
669 Dmsg5(100, "Read reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
670 dcr->dev->reserved_device,
671 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
676 Dmsg0(100, "Not OK.\n");
683 * We "reserve" the drive by setting the ST_READ bit. No one else
684 * should touch the drive until that is cleared.
685 * This allows the DIR to "reserve" the device before actually
688 static bool reserve_device_for_read(DCR *dcr)
690 DEVICE *dev = dcr->dev;
698 if (is_device_unmounted(dev)) {
699 Dmsg1(200, "Device %s is BLOCKED due to user unmount.\n", dev->print_name());
700 Mmsg(jcr->errmsg, _("Device %s is BLOCKED due to user unmount.\n"),
705 if (dev->is_busy()) {
706 Dmsg4(200, "Device %s is busy ST_READ=%d num_writers=%d reserved=%d.\n", dev->print_name(),
707 dev->state & ST_READ?1:0, dev->num_writers, dev->reserved_device);
708 Mmsg1(jcr->errmsg, _("Device %s is busy.\n"),
724 * We reserve the device for appending by incrementing the
725 * reserved_device. We do virtually all the same work that
726 * is done in acquire_device_for_append(), but we do
727 * not attempt to mount the device. This routine allows
728 * the DIR to reserve multiple devices before *really*
729 * starting the job. It also permits the SD to refuse
730 * certain devices (not up, ...).
732 * Note, in reserving a device, if the device is for the
733 * same pool and the same pool type, then it is acceptable.
734 * The Media Type has already been checked. If we are
735 * the first tor reserve the device, we put the pool
736 * name and pool type in the device record.
738 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
741 DEVICE *dev = dcr->dev;
748 if (dev->can_read()) {
749 Mmsg1(jcr->errmsg, _("Device %s is busy reading.\n"), dev->print_name());
750 Dmsg1(100, "%s", jcr->errmsg);
754 if (is_device_unmounted(dev)) {
755 Mmsg(jcr->errmsg, _("Device %s is BLOCKED due to user unmount.\n"), dev->print_name());
756 Dmsg1(100, "%s", jcr->errmsg);
760 Dmsg1(100, "reserve_append device is %s\n", dev->is_tape()?"tape":"disk");
762 if (can_reserve_drive(dcr, rctx) != 1) {
763 Dmsg0(100, "can_reserve_drive!=1\n");
767 dev->reserved_device++;
768 Dmsg3(100, "Inc reserve=%d dev=%s %p\n", dev->reserved_device,
769 dev->print_name(), dev);
770 dcr->reserved_device = true;
779 * Returns: 1 if drive can be reserved
780 * 0 if we should wait
783 static int can_reserve_drive(DCR *dcr, RCTX &rctx)
785 DEVICE *dev = dcr->dev;
788 /* If he wants a free drive, but this one is busy, no go */
789 if (!rctx.PreferMountedVols && dev->is_busy()) {
790 Dmsg1(100, "!prefMnt && busy. JobId=%d\n", jcr->JobId);
793 Dmsg3(100, "can_reserve_drive: prefmnt=%d busy=%d res=%d\n", rctx.PreferMountedVols,
794 dev->is_busy(), dev->reserved_device);
796 /* Check for prefer mounted volumes */
797 if (rctx.PreferMountedVols && !dev->VolHdr.VolumeName[0] && dev->is_tape()) {
798 Dmsg1(100, "failed: want mounted -- no vol JobId=%d\n", jcr->JobId);
799 return 0; /* No volume mounted */
802 /* Check for exact Volume name match */
803 if (rctx.exact_match && rctx.have_volume &&
804 strcmp(dev->VolHdr.VolumeName, rctx.VolumeName) != 0) {
805 Dmsg2(100, "failed: Not exact match have=%s want=%s\n",
806 dev->VolHdr.VolumeName, rctx.VolumeName);
810 /* Check for unused autochanger drive */
811 if (rctx.available_autochanger && dev->num_writers == 0 &&
812 dev->VolHdr.VolumeName[0] == 0) {
813 /* Device is available but not yet reserved, reserve it for us */
814 Dmsg2(100, "OK Res Unused autochanger %s JobId=%d.\n",
815 dev->print_name(), jcr->JobId);
816 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
817 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
818 return 1; /* reserve drive */
822 * Handle the case that there are no writers
824 if (dev->num_writers == 0) {
825 /* Now check if there are any reservations on the drive */
826 if (dev->reserved_device) {
827 /* Now check if we want the same Pool and pool type */
828 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
829 strcmp(dev->pool_type, dcr->pool_type) == 0) {
830 /* OK, compatible device */
831 Dmsg2(100, "OK got dev: %s num_writers=0, reserved, pool matches JobId=%d\n",
832 dev->print_name(), jcr->JobId);
835 /* Drive not suitable for us */
836 Dmsg2(100, "failed: busy num_writers=0, reserved, pool=%s wanted=%s\n",
837 dev->pool_name, dcr->pool_name);
840 } else if (dev->can_append()) {
841 /* Device in append mode, check if changing pool */
842 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
843 strcmp(dev->pool_type, dcr->pool_type) == 0) {
844 Dmsg2(100, "OK got dev: %s num_writers=0, can_append, pool matches. JobId=%d\n",
845 dev->print_name(), jcr->JobId);
846 /* OK, compatible device */
849 /* Changing pool, unload old tape if any in drive */
850 Dmsg0(100, "got dev: num_writers=0, not reserved, pool change, unload changer\n");
851 unload_autochanger(dcr, 0);
854 /* Device is available but not yet reserved, reserve it for us */
855 Dmsg2(100, "OK Dev avail reserved %s JobId=%d\n", dev->print_name(),
857 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
858 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
859 return 1; /* reserve drive */
863 * Check if the device is in append mode with writers (i.e.
864 * available if pool is the same).
866 if (dev->can_append() || dev->num_writers > 0) {
867 /* Yes, now check if we want the same Pool and pool type */
868 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
869 strcmp(dev->pool_type, dcr->pool_type) == 0) {
870 Dmsg2(100, "OK got dev: %s num_writers>=0, can_append, pool matches. JobId=%d\n",
871 dev->print_name(), jcr->JobId);
872 /* OK, compatible device */
875 /* Drive not suitable for us */
876 Dmsg2(100, "failed: busy num_writers>0, can_append, pool=%s wanted=%s\n",
877 dev->pool_name, dcr->pool_name);
881 Pmsg0(000, _("Logic error!!!! Should not get here.\n"));
882 Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
883 return -1; /* error, should not get here */
885 Dmsg2(100, "failed: No reserve %s JobId=%d\n", dev->print_name(), jcr->JobId);