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 plus additions
11 that are listed in the file LICENSE.
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 static dlist *vol_list = NULL;
43 static pthread_mutex_t vol_list_lock = PTHREAD_MUTEX_INITIALIZER;
45 /* Forward referenced functions */
46 static int can_reserve_drive(DCR *dcr, RCTX &rctx);
47 static int reserve_device(RCTX &rctx);
48 static bool reserve_device_for_read(DCR *dcr);
49 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx);
50 static bool use_storage_cmd(JCR *jcr);
51 static void queue_reserve_message(JCR *jcr);
53 /* Requests from the Director daemon */
54 static char use_storage[] = "use storage=%127s media_type=%127s "
55 "pool_name=%127s pool_type=%127s append=%d copy=%d stripe=%d\n";
56 static char use_device[] = "use device=%127s\n";
58 /* Responses sent to Director daemon */
59 static char OK_device[] = "3000 OK use device device=%s\n";
60 static char NO_device[] = "3924 Device \"%s\" not in SD Device resources.\n";
61 static char BAD_use[] = "3913 Bad use command: %s\n";
63 bool use_cmd(JCR *jcr)
66 * Get the device, media, and pool information
68 if (!use_storage_cmd(jcr)) {
69 set_jcr_job_status(jcr, JS_ErrorTerminated);
70 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
76 static int my_compare(void *item1, void *item2)
78 return strcmp(((VOLRES *)item1)->vol_name, ((VOLRES *)item2)->vol_name);
81 static brwlock_t reservation_lock;
83 void init_reservations_lock()
86 if ((errstat=rwl_init(&reservation_lock)) != 0) {
88 Emsg1(M_ABORT, 0, _("Unable to initialize reservation lock. ERR=%s\n"),
89 be.strerror(errstat));
94 void term_reservations_lock()
96 rwl_destroy(&reservation_lock);
99 /* This applies to a drive and to Volumes */
100 void lock_reservations()
103 if ((errstat=rwl_writelock(&reservation_lock)) != 0) {
105 Emsg2(M_ABORT, 0, "rwl_writelock failure. stat=%d: ERR=%s\n",
106 errstat, be.strerror(errstat));
110 void unlock_reservations()
113 if ((errstat=rwl_writeunlock(&reservation_lock)) != 0) {
115 Emsg2(M_ABORT, 0, "rwl_writeunlock failure. stat=%d: ERR=%s\n",
116 errstat, be.strerror(errstat));
122 * Put a new Volume entry in the Volume list. This
123 * effectively reserves the volume so that it will
124 * not be mounted again.
126 * Return: VOLRES entry on success
127 * NULL if the Volume is already in the list
129 VOLRES *new_volume(DCR *dcr, const char *VolumeName)
133 Dmsg1(400, "new_volume %s\n", VolumeName);
135 * We lock the reservations system here to ensure
136 * when adding a new volume that no newly scheduled
137 * job can reserve it.
142 * First, if this dcr already is attached to any device,
143 * remove any old volumes attached to this device as they
144 * are no longer used (there should at max be one).
148 foreach_dlist(vol, vol_list) {
149 if (vol && vol->dev == dcr->dev) {
150 vol_list->remove(vol);
152 * Make sure we don't remove the current volume we are inserting
153 * because it was probably inserted by another job.
155 if (vol->vol_name && strcmp(vol->vol_name, VolumeName) != 0) {
156 Dmsg1(100, "new_vol free vol=%s\n", vol->vol_name);
164 vol = (VOLRES *)malloc(sizeof(VOLRES));
165 memset(vol, 0, sizeof(VOLRES));
166 vol->vol_name = bstrdup(VolumeName);
169 Dmsg2(100, "New Vol=%s dev=%s\n", VolumeName, dcr->dev->print_name());
171 * Now try to insert the new Volume
173 nvol = (VOLRES *)vol_list->binary_insert(vol, my_compare);
175 Dmsg2(100, "Found vol=%s same dcr=%d\n", nvol->vol_name, dcr==nvol->dcr);
177 * At this point, a Volume with this name already is in the
178 * list, free our temp structure
184 DEVICE *dev = nvol->dev;
185 /* ***FIXME*** don't we need a mutex here? */
186 if (!dev->is_busy()) {
187 Dmsg3(100, "Swap vol=%s from dev=%s to %s\n", VolumeName,
188 dev->print_name(), dcr->dev->print_name());
189 nvol->dev = dcr->dev;
190 dev->VolHdr.VolumeName[0] = 0;
192 Dmsg3(100, "Logic ERROR!!!! could not swap vol=%s from dev=%s to %s\n", VolumeName,
193 dev->print_name(), dcr->dev->print_name());
198 unlock_reservations();
203 * Search for a Volume name in the Volume list.
205 * Returns: VOLRES entry on success
206 * NULL if the Volume is not in the list
208 VOLRES *find_volume(const char *VolumeName)
211 /* Do not lock reservations here */
213 vol.vol_name = bstrdup(VolumeName);
214 fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare);
217 Dmsg2(100, "find_vol=%s found=%d\n", VolumeName, fvol!=NULL);
222 * Free a Volume from the Volume list
224 * Returns: true if the Volume found and removed from the list
225 * false if the Volume is not in the list
227 bool free_volume(DEVICE *dev)
231 if (dev->VolHdr.VolumeName[0] == 0) {
237 Dmsg1(100, "free_volume: no vol on dev %s\n", dev->print_name());
239 * Our device has no VolumeName listed, but
240 * search the list for any Volume attached to
241 * this device and remove it.
243 foreach_dlist(fvol, vol_list) {
244 if (fvol && fvol->dev == dev) {
245 vol_list->remove(fvol);
246 if (fvol->vol_name) {
247 Dmsg2(100, "free_volume %s dev=%s\n", fvol->vol_name, dev->print_name());
248 free(fvol->vol_name);
257 Dmsg1(400, "free_volume %s\n", dev->VolHdr.VolumeName);
258 vol.vol_name = bstrdup(dev->VolHdr.VolumeName);
259 fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare);
261 vol_list->remove(fvol);
262 Dmsg2(100, "free_volume %s dev=%s\n", fvol->vol_name, dev->print_name());
263 free(fvol->vol_name);
267 // dev->VolHdr.VolumeName[0] = 0;
273 /* Free volume reserved by this dcr but not attached to a dev */
274 void free_unused_volume(DCR *dcr)
279 for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
281 * Releease this volume, but only if we inserted it (same dcr) and
282 * it is not attached to a device or the Volume in the device is
283 * different. Requiring a different name for the Volume in the
284 * device ensures that we don't free a volume in use.
286 if (vol->dcr == dcr && (vol->dev == NULL ||
287 strcmp(vol->vol_name, vol->dev->VolHdr.VolumeName) != 0)) {
288 vol_list->remove(vol);
289 Dmsg1(100, "free_unused_volume %s\n", vol->vol_name);
299 * List Volumes -- this should be moved to status.c
301 void list_volumes(void sendit(const char *msg, int len, void *sarg), void *arg)
307 msg = (char *)get_pool_memory(PM_MESSAGE);
310 for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
312 len = Mmsg(msg, "%s on device %s\n", vol->vol_name, vol->dev->print_name());
313 sendit(msg, len, arg);
315 len = Mmsg(msg, "%s\n", vol->vol_name);
316 sendit(msg, len, arg);
321 free_pool_memory(msg);
324 /* Create the Volume list */
325 void create_volume_list()
327 VOLRES *dummy = NULL;
328 if (vol_list == NULL) {
329 vol_list = New(dlist(dummy, &dummy->link));
333 /* Release all Volumes from the list */
334 void free_volume_list()
341 for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
342 Dmsg3(100, "Unreleased Volume=%s dcr=0x%x dev=0x%x\n", vol->vol_name,
350 bool is_volume_in_use(DCR *dcr)
352 VOLRES *vol = find_volume(dcr->VolumeName);
354 Dmsg1(100, "Vol=%s not in use.\n", dcr->VolumeName);
355 return false; /* vol not in list */
357 if (!vol->dev) { /* vol not attached to device */
358 Dmsg1(100, "Vol=%s has no dev.\n", dcr->VolumeName);
361 if (dcr->dev == vol->dev) { /* same device OK */
362 Dmsg1(100, "Vol=%s on same dev.\n", dcr->VolumeName);
365 if (!vol->dev->is_busy()) {
366 Dmsg2(100, "Vol=%s dev=%s not busy.\n", dcr->VolumeName, vol->dev->print_name());
369 Dmsg2(100, "Vol=%s used by %s.\n", dcr->VolumeName, vol->dev->print_name());
375 * We get the following type of information:
377 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=1 copy=0 strip=0
381 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=0 copy=0 strip=0
385 static bool use_storage_cmd(JCR *jcr)
387 POOL_MEM store_name, dev_name, media_type, pool_name, pool_type;
388 BSOCK *dir = jcr->dir_bsock;
398 memset(&rctx, 0, sizeof(RCTX));
401 * If there are multiple devices, the director sends us
402 * use_device for each device that it wants to use.
404 dirstore = New(alist(10, not_owned_by_alist));
405 // Dmsg2(000, "dirstore=%p JobId=%u\n", dirstore, jcr->JobId);
406 msgs = jcr->reserve_msgs = New(alist(10, not_owned_by_alist));
408 Dmsg1(100, "<dird: %s", dir->msg);
409 ok = sscanf(dir->msg, use_storage, store_name.c_str(),
410 media_type.c_str(), pool_name.c_str(),
411 pool_type.c_str(), &append, &Copy, &Stripe) == 7;
416 jcr->write_store = dirstore;
418 jcr->read_store = dirstore;
420 rctx.append = append;
421 unbash_spaces(store_name);
422 unbash_spaces(media_type);
423 unbash_spaces(pool_name);
424 unbash_spaces(pool_type);
425 store = new DIRSTORE;
426 dirstore->append(store);
427 memset(store, 0, sizeof(DIRSTORE));
428 store->device = New(alist(10));
429 bstrncpy(store->name, store_name, sizeof(store->name));
430 bstrncpy(store->media_type, media_type, sizeof(store->media_type));
431 bstrncpy(store->pool_name, pool_name, sizeof(store->pool_name));
432 bstrncpy(store->pool_type, pool_type, sizeof(store->pool_type));
433 store->append = append;
435 /* Now get all devices */
436 while (dir->recv() >= 0) {
437 Dmsg1(100, "<dird device: %s", dir->msg);
438 ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
442 unbash_spaces(dev_name);
443 store->device->append(bstrdup(dev_name.c_str()));
445 } while (ok && dir->recv() >= 0);
448 /* This loop is debug code and can be removed */
449 /* ***FIXME**** remove after 1.38 release */
451 foreach_alist(store, dirstore) {
452 Dmsg5(110, "Storage=%s media_type=%s pool=%s pool_type=%s append=%d\n",
453 store->name, store->media_type, store->pool_name,
454 store->pool_type, store->append);
455 foreach_alist(device_name, store->device) {
456 Dmsg1(110, " Device=%s\n", device_name);
461 init_jcr_device_wait_timers(jcr);
463 * At this point, we have a list of all the Director's Storage
464 * resources indicated for this Job, which include Pool, PoolType,
465 * storage name, and Media type.
466 * Then for each of the Storage resources, we have a list of
467 * device names that were given.
469 * Wiffle through them and find one that can do the backup.
472 bool first = true; /* print wait message once */
474 rctx.notify_dir = true;
476 for ( ; !fail && !job_canceled(jcr); ) {
477 while ((msg = (char *)msgs->pop())) {
480 rctx.suitable_device = false;
481 rctx.have_volume = false;
482 rctx.any_drive = false;
483 if (!jcr->PreferMountedVols) {
484 /* Look for unused drives in autochangers */
485 rctx.num_writers = 20000000; /* start with impossible number */
486 rctx.low_use_drive = NULL;
487 rctx.PreferMountedVols = false;
488 rctx.exact_match = false;
489 rctx.autochanger_only = true;
490 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
491 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
492 rctx.autochanger_only, rctx.any_drive);
493 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
496 /* Look through all drives possibly for low_use drive */
497 if (rctx.low_use_drive) {
498 rctx.try_low_use_drive = true;
499 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
502 rctx.try_low_use_drive = false;
504 rctx.autochanger_only = false;
505 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
506 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
507 rctx.autochanger_only, rctx.any_drive);
508 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
512 /* Look for an exact match all drives */
513 rctx.PreferMountedVols = true;
514 rctx.exact_match = true;
515 rctx.autochanger_only = false;
516 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
517 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
518 rctx.autochanger_only, rctx.any_drive);
519 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
522 /* Look for any mounted drive */
523 rctx.exact_match = false;
524 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
525 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
526 rctx.autochanger_only, rctx.any_drive);
527 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
531 rctx.any_drive = true;
532 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
533 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
534 rctx.autochanger_only, rctx.any_drive);
535 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
538 /* Keep reservations locked *except* during wait_for_device() */
539 unlock_reservations();
540 if (!rctx.suitable_device || !wait_for_device(jcr, first)) {
541 Dmsg0(100, "Fail. !suitable_device || !wait_for_device\n");
546 bnet_sig(dir, BNET_HEARTBEAT); /* Inform Dir that we are alive */
548 unlock_reservations();
551 * If we get here, there are no suitable devices available, which
552 * means nothing configured. If a device is suitable but busy
553 * with another Volume, we will not come here.
555 unbash_spaces(dir->msg);
556 pm_strcpy(jcr->errmsg, dir->msg);
557 Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
558 Jmsg(jcr, M_FATAL, 0, _("\n"
559 " Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"),
560 dev_name.c_str(), media_type.c_str());
561 bnet_fsend(dir, NO_device, dev_name.c_str());
563 Dmsg1(100, ">dird: %s", dir->msg);
566 unbash_spaces(dir->msg);
567 pm_strcpy(jcr->errmsg, dir->msg);
568 Jmsg(jcr, M_FATAL, 0, _("Failed command: %s\n"), jcr->errmsg);
569 bnet_fsend(dir, BAD_use, jcr->errmsg);
570 Dmsg1(100, ">dird: %s", dir->msg);
577 void release_msgs(JCR *jcr)
579 alist *msgs = jcr->reserve_msgs;
586 while ((msg = (char *)msgs->pop())) {
590 jcr->reserve_msgs = NULL;
591 unlock_reservations();
595 * Search for a device suitable for this job.
597 bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx)
605 dirstore = jcr->write_store;
607 dirstore = jcr->read_store;
610 * For each storage device that the user specified, we
611 * search and see if there is a resource for that device.
613 Dmsg4(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d\n",
614 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
615 rctx.autochanger_only);
617 foreach_alist(store, dirstore) {
619 foreach_alist(device_name, store->device) {
621 rctx.device_name = device_name;
622 stat = search_res_for_device(rctx);
623 if (stat == 1) { /* found available device */
624 Dmsg1(100, "Suitable device found=%s\n", device_name);
627 } else if (stat == 0) { /* device busy */
628 Dmsg1(110, "Suitable device found=%s, not used: busy\n", device_name);
630 /* otherwise error */
631 Dmsg0(110, "No suitable device found.\n");
642 * Search for a particular storage device with particular storage
643 * characteristics (MediaType).
645 int search_res_for_device(RCTX &rctx)
647 AUTOCHANGER *changer;
648 BSOCK *dir = rctx.jcr->dir_bsock;
652 Dmsg1(110, "Search res for %s\n", rctx.device_name);
653 /* Look through Autochangers first */
654 foreach_res(changer, R_AUTOCHANGER) {
655 Dmsg1(150, "Try match changer res=%s\n", changer->hdr.name);
656 /* Find resource, and make sure we were able to open it */
657 if (fnmatch(rctx.device_name, changer->hdr.name, 0) == 0) {
658 /* Try each device in this AutoChanger */
659 foreach_alist(rctx.device, changer->device) {
660 Dmsg1(110, "Try changer device %s\n", rctx.device->hdr.name);
661 stat = reserve_device(rctx);
662 if (stat != 1) { /* try another device */
666 if (rctx.store->append == SD_APPEND) {
667 Dmsg2(100, "Device %s reserved=%d for append.\n", rctx.device->hdr.name,
668 rctx.jcr->dcr->dev->reserved_device);
670 Dmsg2(100, "Device %s reserved=%d for read.\n", rctx.device->hdr.name,
671 rctx.jcr->read_dcr->dev->reserved_device);
673 if (rctx.notify_dir) {
674 pm_strcpy(dev_name, rctx.device->hdr.name);
675 bash_spaces(dev_name);
676 ok = bnet_fsend(dir, OK_device, dev_name.c_str()); /* Return real device name */
677 Dmsg1(100, ">dird changer: %s", dir->msg);
686 /* Now if requested look through regular devices */
687 if (!rctx.autochanger_only) {
688 foreach_res(rctx.device, R_DEVICE) {
689 Dmsg1(150, "Try match res=%s\n", rctx.device->hdr.name);
690 /* Find resource, and make sure we were able to open it */
691 if (fnmatch(rctx.device_name, rctx.device->hdr.name, 0) == 0) {
692 stat = reserve_device(rctx);
696 if (rctx.notify_dir) {
697 bash_spaces(rctx.device_name);
698 ok = bnet_fsend(dir, OK_device, rctx.device_name);
699 Dmsg1(100, ">dird dev: %s", dir->msg);
707 return -1; /* nothing found */
711 * Try to reserve a specific device.
713 * Returns: 1 -- OK, have DCR
717 static int reserve_device(RCTX &rctx)
721 const int name_len = MAX_NAME_LENGTH;
723 /* Make sure MediaType is OK */
724 Dmsg2(110, "MediaType device=%s request=%s\n",
725 rctx.device->media_type, rctx.store->media_type);
726 if (strcmp(rctx.device->media_type, rctx.store->media_type) != 0) {
730 /* Make sure device exists -- i.e. we can stat() it */
731 if (!rctx.device->dev) {
732 rctx.device->dev = init_dev(rctx.jcr, rctx.device);
734 if (!rctx.device->dev) {
735 if (rctx.device->changer_res) {
736 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
737 " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
738 rctx.device->hdr.name, rctx.device_name);
740 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
741 " Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
744 return -1; /* no use waiting */
747 rctx.suitable_device = true;
748 Dmsg2(110, "Try reserve %s JobId=%u\n", rctx.device->hdr.name,
750 dcr = new_dcr(rctx.jcr, rctx.device->dev);
752 BSOCK *dir = rctx.jcr->dir_bsock;
753 bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), rctx.device_name);
754 Dmsg1(100, ">dird: %s", dir->msg);
757 bstrncpy(dcr->pool_name, rctx.store->pool_name, name_len);
758 bstrncpy(dcr->pool_type, rctx.store->pool_type, name_len);
759 bstrncpy(dcr->media_type, rctx.store->media_type, name_len);
760 bstrncpy(dcr->dev_name, rctx.device_name, name_len);
761 if (rctx.store->append == SD_APPEND) {
762 if (rctx.exact_match && !rctx.have_volume) {
763 dcr->any_volume = true;
764 if (dir_find_next_appendable_volume(dcr)) {
765 bstrncpy(rctx.VolumeName, dcr->VolumeName, sizeof(rctx.VolumeName));
766 Dmsg2(100, "JobId=%u looking for Volume=%s\n", rctx.jcr->JobId, rctx.VolumeName);
767 rctx.have_volume = true;
769 Dmsg0(100, "No next volume found\n");
770 rctx.VolumeName[0] = 0;
773 ok = reserve_device_for_append(dcr, rctx);
776 Dmsg5(100, "Reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
777 dcr->dev->reserved_device,
778 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
781 ok = reserve_device_for_read(dcr);
783 rctx.jcr->read_dcr = dcr;
784 Dmsg5(100, "Read reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
785 dcr->dev->reserved_device,
786 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
791 Dmsg0(110, "Not OK.\n");
798 * We "reserve" the drive by setting the ST_READ bit. No one else
799 * should touch the drive until that is cleared.
800 * This allows the DIR to "reserve" the device before actually
803 static bool reserve_device_for_read(DCR *dcr)
805 DEVICE *dev = dcr->dev;
811 /* Get locks in correct order */
812 unlock_reservations();
816 if (is_device_unmounted(dev)) {
817 Dmsg1(200, "Device %s is BLOCKED due to user unmount.\n", dev->print_name());
818 Mmsg(jcr->errmsg, _("3601 JobId=%u device %s is BLOCKED due to user unmount.\n"),
819 jcr->JobId, dev->print_name());
820 queue_reserve_message(jcr);
824 if (dev->is_busy()) {
825 Dmsg4(200, "Device %s is busy ST_READ=%d num_writers=%d reserved=%d.\n", dev->print_name(),
826 dev->state & ST_READ?1:0, dev->num_writers, dev->reserved_device);
827 Mmsg(jcr->errmsg, _("3602 JobId=%u device %s is busy (already reading/writing).\n"),
828 jcr->JobId, dev->print_name());
829 queue_reserve_message(jcr);
836 dev->reserved_device++;
837 Dmsg3(100, "Inc reserve=%d dev=%s %p\n", dev->reserved_device,
838 dev->print_name(), dev);
839 dcr->reserved_device = true;
848 * We reserve the device for appending by incrementing the
849 * reserved_device. We do virtually all the same work that
850 * is done in acquire_device_for_append(), but we do
851 * not attempt to mount the device. This routine allows
852 * the DIR to reserve multiple devices before *really*
853 * starting the job. It also permits the SD to refuse
854 * certain devices (not up, ...).
856 * Note, in reserving a device, if the device is for the
857 * same pool and the same pool type, then it is acceptable.
858 * The Media Type has already been checked. If we are
859 * the first tor reserve the device, we put the pool
860 * name and pool type in the device record.
862 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
865 DEVICE *dev = dcr->dev;
870 /* Get locks in correct order */
871 unlock_reservations();
875 /* If device is being read, we cannot write it */
876 if (dev->can_read()) {
877 Mmsg(jcr->errmsg, _("3603 JobId=%u device %s is busy reading.\n"),
878 jcr->JobId, dev->print_name());
879 Dmsg1(110, "%s", jcr->errmsg);
880 queue_reserve_message(jcr);
884 /* If device is unmounted, we are out of luck */
885 if (is_device_unmounted(dev)) {
886 Mmsg(jcr->errmsg, _("3604 JobId=%u device %s is BLOCKED due to user unmount.\n"),
887 jcr->JobId, dev->print_name());
888 Dmsg1(110, "%s", jcr->errmsg);
889 queue_reserve_message(jcr);
893 Dmsg1(110, "reserve_append device is %s\n", dev->is_tape()?"tape":"disk");
895 /* Now do detailed tests ... */
896 if (can_reserve_drive(dcr, rctx) != 1) {
897 Dmsg0(110, "can_reserve_drive!=1\n");
901 dev->reserved_device++;
902 Dmsg3(100, "Inc reserve=%d dev=%s %p\n", dev->reserved_device,
903 dev->print_name(), dev);
904 dcr->reserved_device = true;
913 * Returns: 1 if drive can be reserved
914 * 0 if we should wait
915 * -1 on error or impossibility
917 static int can_reserve_drive(DCR *dcr, RCTX &rctx)
919 DEVICE *dev = dcr->dev;
922 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
923 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
924 rctx.autochanger_only, rctx.any_drive);
926 /* setting any_drive overrides PreferMountedVols flag */
927 if (!rctx.any_drive) {
929 * When PreferMountedVols is set, we keep track of the
930 * drive in use that has the least number of writers, then if
931 * no unmounted drive is found, we try that drive. This
932 * helps spread the load to the least used drives.
934 if (rctx.try_low_use_drive && dev == rctx.low_use_drive) {
935 Dmsg3(110, "OK dev=%s == low_drive=%s. JobId=%u\n",
936 dev->print_name(), rctx.low_use_drive->print_name(), jcr->JobId);
939 /* If he wants a free drive, but this one is busy, no go */
940 if (!rctx.PreferMountedVols && dev->is_busy()) {
941 /* Save least used drive */
942 if ((dev->num_writers + dev->reserved_device) < rctx.num_writers) {
943 rctx.num_writers = dev->num_writers + dev->reserved_device;
944 rctx.low_use_drive = dev;
945 Dmsg2(110, "set low use drive=%s num_writers=%d\n", dev->print_name(),
948 Dmsg1(110, "not low use num_writers=%d\n", dev->num_writers+
949 dev->reserved_device);
951 Dmsg1(110, "failed: !prefMnt && busy. JobId=%u\n", jcr->JobId);
952 Mmsg(jcr->errmsg, _("3605 JobId=%u wants free drive but device %s is busy.\n"),
953 jcr->JobId, dev->print_name());
954 queue_reserve_message(jcr);
958 /* Check for prefer mounted volumes */
959 if (rctx.PreferMountedVols && !dev->VolHdr.VolumeName[0] && dev->is_tape()) {
960 Mmsg(jcr->errmsg, _("3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n"),
961 jcr->JobId, dev->print_name());
962 queue_reserve_message(jcr);
963 Dmsg1(110, "failed: want mounted -- no vol JobId=%u\n", jcr->JobId);
964 return 0; /* No volume mounted */
967 /* Check for exact Volume name match */
968 if (rctx.exact_match && rctx.have_volume &&
969 strcmp(dev->VolHdr.VolumeName, rctx.VolumeName) != 0) {
970 Mmsg(jcr->errmsg, _("3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n"),
971 jcr->JobId, rctx.VolumeName, dev->VolHdr.VolumeName,
973 queue_reserve_message(jcr);
974 Dmsg2(110, "failed: Not exact match have=%s want=%s\n",
975 dev->VolHdr.VolumeName, rctx.VolumeName);
980 /* Check for unused autochanger drive */
981 if (rctx.autochanger_only && dev->num_writers == 0 &&
982 dev->VolHdr.VolumeName[0] == 0) {
983 /* Device is available but not yet reserved, reserve it for us */
984 Dmsg2(100, "OK Res Unused autochanger %s JobId=%u.\n",
985 dev->print_name(), jcr->JobId);
986 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
987 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
988 return 1; /* reserve drive */
992 * Handle the case that there are no writers
994 if (dev->num_writers == 0) {
995 /* Now check if there are any reservations on the drive */
996 if (dev->reserved_device) {
997 /* Now check if we want the same Pool and pool type */
998 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
999 strcmp(dev->pool_type, dcr->pool_type) == 0) {
1000 /* OK, compatible device */
1001 Dmsg2(100, "OK dev: %s num_writers=0, reserved, pool matches JobId=%u\n",
1002 dev->print_name(), jcr->JobId);
1005 /* Drive Pool not suitable for us */
1006 Mmsg(jcr->errmsg, _(
1007 "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %s.\n"),
1008 jcr->JobId, dcr->pool_name, dev->pool_name,
1009 dev->reserved_device, dev->print_name());
1010 queue_reserve_message(jcr);
1011 Dmsg2(110, "failed: busy num_writers=0, reserved, pool=%s wanted=%s\n",
1012 dev->pool_name, dcr->pool_name);
1013 return 0; /* wait */
1015 } else if (dev->can_append()) {
1016 /* Device in append mode, check if changing pool */
1017 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1018 strcmp(dev->pool_type, dcr->pool_type) == 0) {
1019 Dmsg2(100, "OK dev: %s num_writers=0, can_append, pool matches. JobId=%u\n",
1020 dev->print_name(), jcr->JobId);
1021 /* OK, compatible device */
1024 /* Changing pool, unload old tape if any in drive */
1025 Dmsg0(100, "OK dev: num_writers=0, not reserved, pool change, unload changer\n");
1026 unload_autochanger(dcr, 0);
1029 /* Device is available but not yet reserved, reserve it for us */
1030 Dmsg2(100, "OK Dev avail reserved %s JobId=%u\n", dev->print_name(),
1032 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1033 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1034 return 1; /* reserve drive */
1038 * Check if the device is in append mode with writers (i.e.
1039 * available if pool is the same).
1041 if (dev->can_append() || dev->num_writers > 0) {
1042 /* Yes, now check if we want the same Pool and pool type */
1043 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1044 strcmp(dev->pool_type, dcr->pool_type) == 0) {
1045 Dmsg2(100, "OK dev: %s num_writers>=0, can_append, pool matches. JobId=%u\n",
1046 dev->print_name(), jcr->JobId);
1047 /* OK, compatible device */
1050 /* Drive Pool not suitable for us */
1051 Mmsg(jcr->errmsg, _("3609 JobId=%u wants Pool=\"%s\" but has Pool=\"%s\" on drive %s.\n"),
1052 jcr->JobId, dcr->pool_name, dev->pool_name, dev->print_name());
1053 queue_reserve_message(jcr);
1054 Dmsg2(110, "failed: busy num_writers>0, can_append, pool=%s wanted=%s\n",
1055 dev->pool_name, dcr->pool_name);
1056 return 0; /* wait */
1059 Pmsg0(000, _("Logic error!!!! Should not get here.\n"));
1060 Mmsg(jcr->errmsg, _("3910 JobId=%u Logic error!!!! drive %s Should not get here.\n"),
1061 jcr->JobId, dev->print_name());
1062 queue_reserve_message(jcr);
1063 Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
1064 return -1; /* error, should not get here */
1066 Mmsg(jcr->errmsg, _("3911 JobId=%u failed reserve drive %s.\n"),
1067 jcr->JobId, dev->print_name());
1068 queue_reserve_message(jcr);
1069 Dmsg2(110, "failed: No reserve %s JobId=%u\n", dev->print_name(), jcr->JobId);
1074 * search_lock is already set on entering this routine
1076 static void queue_reserve_message(JCR *jcr)
1079 alist *msgs = jcr->reserve_msgs;
1086 * Look for duplicate message. If found, do
1089 for (i=msgs->size()-1; i >= 0; i--) {
1090 msg = (char *)msgs->get(i);
1094 /* Comparison based on 4 digit message number */
1095 if (strncmp(msg, jcr->errmsg, 4) == 0) {
1099 /* Message unique, so insert it */
1100 jcr->reserve_msgs->push(bstrdup(jcr->errmsg));
1104 * Send any reservation messages queued for this jcr
1106 void send_drive_reserve_messages(JCR *jcr, void sendit(const char *msg, int len, void *sarg), void *arg)
1112 lock_reservations();
1113 msgs = jcr->reserve_msgs;
1114 if (!msgs || msgs->size() == 0) {
1115 unlock_reservations();
1118 for (i=msgs->size()-1; i >= 0; i--) {
1119 msg = (char *)msgs->get(i);
1121 sendit(" ", 3, arg);
1122 sendit(msg, strlen(msg), arg);
1127 unlock_reservations();