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 int reservations_lock_count = 0;
101 /* This applies to a drive and to Volumes */
102 void _lock_reservations()
105 reservations_lock_count++;
106 if ((errstat=rwl_writelock(&reservation_lock)) != 0) {
108 Emsg2(M_ABORT, 0, "rwl_writelock failure. stat=%d: ERR=%s\n",
109 errstat, be.strerror(errstat));
113 void _unlock_reservations()
116 reservations_lock_count--;
117 if ((errstat=rwl_writeunlock(&reservation_lock)) != 0) {
119 Emsg2(M_ABORT, 0, "rwl_writeunlock failure. stat=%d: ERR=%s\n",
120 errstat, be.strerror(errstat));
125 * List Volumes -- this should be moved to status.c
132 static void debug_list_volumes(const char *imsg, bool do_lock)
135 POOL_MEM msg(PM_MESSAGE);
139 if (do_lock) P(vol_list_lock);
140 for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
142 Mmsg(msg, "List from %s: %s at %p on device %s\n", imsg,
143 vol->vol_name, vol->vol_name, vol->dev->print_name());
145 Mmsg(msg, "List from %s: %s at %p no dev\n", imsg, vol->vol_name, vol->vol_name);
147 Dmsg1(100, "%s", msg.c_str());
151 for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
152 if (vol->dev == dev) {
153 Dmsg0(000, "Two Volumes on same device.\n");
159 Dmsg2(100, "List from %s: %d volumes\n", imsg, count);
160 if (do_lock) V(vol_list_lock);
165 * List Volumes -- this should be moved to status.c
167 void list_volumes(void sendit(const char *msg, int len, void *sarg), void *arg)
170 POOL_MEM msg(PM_MESSAGE);
174 for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
176 len = Mmsg(msg, "%s on device %s\n", vol->vol_name, vol->dev->print_name());
177 sendit(msg.c_str(), len, arg);
179 len = Mmsg(msg, "%s no dev\n", vol->vol_name);
180 sendit(msg.c_str(), len, arg);
187 * Create a Volume item to put in the Volume list
188 * Ensure that the device points to it.
190 static VOLRES *new_vol_item(DCR *dcr, const char *VolumeName)
193 vol = (VOLRES *)malloc(sizeof(VOLRES));
194 memset(vol, 0, sizeof(VOLRES));
195 vol->vol_name = bstrdup(VolumeName);
197 Dmsg4(100, "New Vol=%s at %p dev=%s JobId=%u\n", VolumeName, vol->vol_name,
198 vol->dev->print_name(), (int)dcr->jcr->JobId);
202 static void free_vol_item(VOLRES *vol)
206 vol->dev->vol = NULL;
213 * Put a new Volume entry in the Volume list. This
214 * effectively reserves the volume so that it will
215 * not be mounted again.
217 * If the device has any current volume associated with it,
218 * and it is a different Volume, and the device is not busy,
219 * we release the old Volume item and insert the new one.
221 * It is assumed that the device is free and locked so that
222 * we can change the device structure.
224 * Some details of the Volume list handling:
226 * 1. The Volume list entry must be attached to the drive (rather than
227 * attached to a job as it currently is. I.e. the drive that "owns"
228 * the volume (reserved, in use, mounted)
229 * must point to the volume (still to be maintained in a list).
231 * 2. The Volume is entered in the list when a drive is reserved.
233 * 3. When a drive is in use, the device code must appropriately update the
234 * volume name as it changes (currently the list is static -- an entry is
235 * removed when the Volume is no longer reserved, in use or mounted).
236 * The new code must keep the same list entry as long as the drive
237 * has any volume associated with it but the volume name in the list
238 * must be updated when the drive has a different volume mounted.
240 * 4. A job that has reserved a volume, can un-reserve the volume, and if the
241 * volume is not mounted, and not reserved, and not in use, it will be
242 * removed from the list.
244 * 5. If a job wants to reserve a drive with a different Volume from the one on
245 * the drive, it can re-use the drive for the new Volume.
247 * 6. If a job wants a Volume that is in a different drive, it can either use the
248 * other drive or take the volume, only if the other drive is not in use or
251 * One nice aspect of this is that the reserve use count and the writer use count
252 * already exist and are correctly programmed and will need no changes -- use
253 * counts are always very tricky.
255 * The old code had a concept of "reserving" a Volume, but it needs to be changed
256 * to reserving and using a drive. A volume is must be attached to (owned by) a
257 * drive and can move from drive to drive or be unused given certain specific
258 * conditions of the drive. The key is that the drive must "own" the Volume.
259 * The old code has the job (dcr) owning the volume (more or less). The job is
260 * to change the insertion and removal of the volumes from the list to be based
261 * on the drive rather than the job. The new logic described above needs to be
262 * reviewed a couple more times for completeness and correctness. Then I can
266 * Return: VOLRES entry on success
269 VOLRES *reserve_volume(DCR *dcr, const char *VolumeName)
272 DEVICE *dev = dcr->dev;
276 Dmsg1(100, "reserve_volume %s\n", VolumeName);
278 * We lock the reservations system here to ensure
279 * when adding a new volume that no newly scheduled
280 * job can reserve it.
284 debug_list_volumes("begin reserve_volume", debug_nolock);
286 * First, remove any old volume attached to this device as it
292 * Make sure we don't remove the current volume we are inserting
293 * because it was probably inserted by another job.
295 if (strcmp(vol->vol_name, VolumeName) == 0) {
296 goto get_out; /* Volume already on this device */
298 Dmsg3(100, "reserve_vol free vol=%s at %p JobId=%u\n", vol->vol_name,
299 vol->vol_name, (int)dcr->jcr->JobId);
300 debug_list_volumes("reserve_vol free", debug_nolock);
301 vol_list->remove(vol);
306 /* Create a new Volume entry */
307 nvol = new_vol_item(dcr, VolumeName);
310 * Now try to insert the new Volume
312 vol = (VOLRES *)vol_list->binary_insert(nvol, my_compare);
314 Dmsg2(100, "Found vol=%s dev-same=%d\n", vol->vol_name, dev==vol->dev);
316 * At this point, a Volume with this name already is in the list,
317 * so we simply release our new Volume entry. Note, this should
318 * only happen if we are moving the volume from one drive to another.
320 Dmsg3(100, "reserve_vol free-tmp vol=%s at %p JobId=%u\n", vol->vol_name,
321 vol->vol_name, (int)dcr->jcr->JobId);
323 * Clear dev pointer so that free_vol_item() doesn't
324 * take away our volume.
326 nvol->dev = NULL; /* don't zap dev entry */
329 /* Check if we are trying to use the Volume on a different drive */
330 if (dev != vol->dev) {
331 /* Caller wants to switch Volume to another device */
332 if (!vol->dev->is_busy()) {
333 /* OK to move it -- I'm not sure this will work */
334 Dmsg3(100, "Swap vol=%s from dev=%s to %s\n", VolumeName,
335 dev->print_name(), dev->print_name());
336 vol->dev->vol = NULL; /* take vol from old drive */
337 vol->dev->VolHdr.VolumeName[0] = 0;
338 vol->dev = dev; /* point vol at new drive */
339 dev->vol = vol; /* point dev at vol */
340 dev->VolHdr.VolumeName[0] = 0;
342 vol = NULL; /* device busy */
343 Dmsg3(100, "Logic ERROR!!!! could not swap vol=%s from dev=%s to %s\n", VolumeName,
344 dev->print_name(), dcr->dev->print_name());
345 ASSERT(1); /* blow up!!! */
352 debug_list_volumes("end new volume", debug_nolock);
354 unlock_reservations();
359 * Search for a Volume name in the Volume list.
361 * Returns: VOLRES entry on success
362 * NULL if the Volume is not in the list
364 VOLRES *find_volume(const char *VolumeName)
367 /* Do not lock reservations here */
369 vol.vol_name = bstrdup(VolumeName);
370 fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare);
372 Dmsg2(100, "find_vol=%s found=%d\n", VolumeName, fvol!=NULL);
373 debug_list_volumes("find_volume", debug_nolock);
379 * Remove any reservation from a drive and tell the system
380 * that the volume is unused at least by us.
382 void unreserve_device(DCR *dcr)
384 DEVICE *dev = dcr->dev;
386 if (dcr->reserved_device) {
387 dcr->reserved_device = false;
388 dev->reserved_device--;
389 Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
390 dcr->reserved_device = false;
391 /* If we set read mode in reserving, remove it */
392 if (dev->can_read()) {
395 if (dev->num_writers < 0) {
396 Jmsg1(dcr->jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers);
397 dev->num_writers = 0;
406 * Free a Volume from the Volume list if it is no longer used
408 * Returns: true if the Volume found and removed from the list
409 * false if the Volume is not in the list or is in use
411 bool volume_unused(DCR *dcr)
413 DEVICE *dev = dcr->dev;
415 if (dev->vol == NULL) {
416 Dmsg1(100, " unreserve_volume: no vol on %s\n", dev->print_name());
417 debug_list_volumes("null return unreserve_volume", debug_lock);
421 if (dev->is_busy()) {
422 Dmsg1(100, "unreserve_volume: dev is busy %s\n", dev->print_name());
423 debug_list_volumes("dev busy return unreserve_volume", debug_lock);
427 return free_volume(dev);
431 * Unconditionally release the volume
433 bool free_volume(DEVICE *dev)
437 if (dev->vol == NULL) {
438 Dmsg1(100, "No vol on dev %s\n", dev->print_name());
444 Dmsg1(100, "free_volume %s\n", vol->vol_name);
445 vol_list->remove(vol);
446 Dmsg3(100, "free_volume %s at %p dev=%s\n", vol->vol_name, vol->vol_name,
449 debug_list_volumes("free_volume", debug_nolock);
455 /* Create the Volume list */
456 void create_volume_list()
458 VOLRES *dummy = NULL;
459 if (vol_list == NULL) {
460 vol_list = New(dlist(dummy, &dummy->link));
464 /* Release all Volumes from the list */
465 void free_volume_list()
472 for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
473 Dmsg2(100, "Unreleased Volume=%s dev=%p\n", vol->vol_name, vol->dev);
475 vol->vol_name = NULL;
482 bool is_volume_in_use(DCR *dcr)
484 VOLRES *vol = find_volume(dcr->VolumeName);
486 Dmsg1(100, "Vol=%s not in use.\n", dcr->VolumeName);
487 return false; /* vol not in list */
489 ASSERT(vol->dev != NULL);
491 if (dcr->dev == vol->dev) { /* same device OK */
492 Dmsg1(100, "Vol=%s on same dev.\n", dcr->VolumeName);
495 if (!vol->dev->is_busy()) {
496 Dmsg2(100, "Vol=%s dev=%s not busy.\n", dcr->VolumeName, vol->dev->print_name());
499 Dmsg2(100, "Vol=%s used by %s.\n", dcr->VolumeName, vol->dev->print_name());
505 * We get the following type of information:
507 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=1 copy=0 strip=0
511 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=0 copy=0 strip=0
515 static bool use_storage_cmd(JCR *jcr)
517 POOL_MEM store_name, dev_name, media_type, pool_name, pool_type;
518 BSOCK *dir = jcr->dir_bsock;
528 memset(&rctx, 0, sizeof(RCTX));
531 * If there are multiple devices, the director sends us
532 * use_device for each device that it wants to use.
534 dirstore = New(alist(10, not_owned_by_alist));
535 // Dmsg2(000, "dirstore=%p JobId=%u\n", dirstore, jcr->JobId);
536 msgs = jcr->reserve_msgs = New(alist(10, not_owned_by_alist));
538 Dmsg1(100, "<dird: %s", dir->msg);
539 ok = sscanf(dir->msg, use_storage, store_name.c_str(),
540 media_type.c_str(), pool_name.c_str(),
541 pool_type.c_str(), &append, &Copy, &Stripe) == 7;
546 jcr->write_store = dirstore;
548 jcr->read_store = dirstore;
550 rctx.append = append;
551 unbash_spaces(store_name);
552 unbash_spaces(media_type);
553 unbash_spaces(pool_name);
554 unbash_spaces(pool_type);
555 store = new DIRSTORE;
556 dirstore->append(store);
557 memset(store, 0, sizeof(DIRSTORE));
558 store->device = New(alist(10));
559 bstrncpy(store->name, store_name, sizeof(store->name));
560 bstrncpy(store->media_type, media_type, sizeof(store->media_type));
561 bstrncpy(store->pool_name, pool_name, sizeof(store->pool_name));
562 bstrncpy(store->pool_type, pool_type, sizeof(store->pool_type));
563 store->append = append;
565 /* Now get all devices */
566 while (dir->recv() >= 0) {
567 Dmsg1(100, "<dird device: %s", dir->msg);
568 ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
572 unbash_spaces(dev_name);
573 store->device->append(bstrdup(dev_name.c_str()));
575 } while (ok && dir->recv() >= 0);
578 /* This loop is debug code and can be removed */
579 /* ***FIXME**** remove after 1.38 release */
581 foreach_alist(store, dirstore) {
582 Dmsg5(110, "Storage=%s media_type=%s pool=%s pool_type=%s append=%d\n",
583 store->name, store->media_type, store->pool_name,
584 store->pool_type, store->append);
585 foreach_alist(device_name, store->device) {
586 Dmsg1(110, " Device=%s\n", device_name);
591 init_jcr_device_wait_timers(jcr);
593 * At this point, we have a list of all the Director's Storage
594 * resources indicated for this Job, which include Pool, PoolType,
595 * storage name, and Media type.
596 * Then for each of the Storage resources, we have a list of
597 * device names that were given.
599 * Wiffle through them and find one that can do the backup.
602 bool first = true; /* print wait message once */
604 rctx.notify_dir = true;
606 for ( ; !fail && !job_canceled(jcr); ) {
607 while ((msg = (char *)msgs->pop())) {
610 rctx.suitable_device = false;
611 rctx.have_volume = false;
612 rctx.VolumeName[0] = 0;
613 rctx.any_drive = false;
614 if (!jcr->PreferMountedVols) {
615 /* Look for unused drives in autochangers */
616 rctx.num_writers = 20000000; /* start with impossible number */
617 rctx.low_use_drive = NULL;
618 rctx.PreferMountedVols = false;
619 rctx.exact_match = false;
620 rctx.autochanger_only = true;
621 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
622 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
623 rctx.autochanger_only, rctx.any_drive);
624 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
627 /* Look through all drives possibly for low_use drive */
628 if (rctx.low_use_drive) {
629 rctx.try_low_use_drive = true;
630 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
633 rctx.try_low_use_drive = false;
635 rctx.autochanger_only = false;
636 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
637 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
638 rctx.autochanger_only, rctx.any_drive);
639 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
643 /* Look for an exact match all drives */
644 rctx.PreferMountedVols = true;
645 rctx.exact_match = true;
646 rctx.autochanger_only = false;
647 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
648 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
649 rctx.autochanger_only, rctx.any_drive);
650 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
653 /* Look for any mounted drive */
654 rctx.exact_match = false;
655 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
656 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
657 rctx.autochanger_only, rctx.any_drive);
658 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
662 rctx.any_drive = true;
663 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
664 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
665 rctx.autochanger_only, rctx.any_drive);
666 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
669 /* Keep reservations locked *except* during wait_for_device() */
670 unlock_reservations();
671 if (!rctx.suitable_device || !wait_for_device(jcr, first)) {
672 Dmsg0(100, "Fail. !suitable_device || !wait_for_device\n");
677 bnet_sig(dir, BNET_HEARTBEAT); /* Inform Dir that we are alive */
679 unlock_reservations();
682 * If we get here, there are no suitable devices available, which
683 * means nothing configured. If a device is suitable but busy
684 * with another Volume, we will not come here.
686 unbash_spaces(dir->msg);
687 pm_strcpy(jcr->errmsg, dir->msg);
688 Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
689 Jmsg(jcr, M_FATAL, 0, _("\n"
690 " Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"),
691 dev_name.c_str(), media_type.c_str());
692 bnet_fsend(dir, NO_device, dev_name.c_str());
694 Dmsg1(100, ">dird: %s", dir->msg);
697 unbash_spaces(dir->msg);
698 pm_strcpy(jcr->errmsg, dir->msg);
699 Jmsg(jcr, M_FATAL, 0, _("Failed command: %s\n"), jcr->errmsg);
700 bnet_fsend(dir, BAD_use, jcr->errmsg);
701 Dmsg1(100, ">dird: %s", dir->msg);
708 void release_msgs(JCR *jcr)
710 alist *msgs = jcr->reserve_msgs;
717 while ((msg = (char *)msgs->pop())) {
721 jcr->reserve_msgs = NULL;
722 unlock_reservations();
726 * Search for a device suitable for this job.
728 bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx)
736 dirstore = jcr->write_store;
738 dirstore = jcr->read_store;
741 * For each storage device that the user specified, we
742 * search and see if there is a resource for that device.
744 Dmsg4(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d\n",
745 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
746 rctx.autochanger_only);
748 foreach_alist(store, dirstore) {
750 foreach_alist(device_name, store->device) {
752 rctx.device_name = device_name;
753 stat = search_res_for_device(rctx);
754 if (stat == 1) { /* found available device */
755 Dmsg1(100, "Suitable device found=%s\n", device_name);
758 } else if (stat == 0) { /* device busy */
759 Dmsg1(110, "Suitable device=%s, busy: not use\n", device_name);
761 /* otherwise error */
762 Dmsg0(110, "No suitable device found.\n");
773 * Search for a particular storage device with particular storage
774 * characteristics (MediaType).
776 int search_res_for_device(RCTX &rctx)
778 AUTOCHANGER *changer;
779 BSOCK *dir = rctx.jcr->dir_bsock;
783 Dmsg1(110, "Search res for %s\n", rctx.device_name);
784 /* Look through Autochangers first */
785 foreach_res(changer, R_AUTOCHANGER) {
786 Dmsg1(150, "Try match changer res=%s\n", changer->hdr.name);
787 /* Find resource, and make sure we were able to open it */
788 if (fnmatch(rctx.device_name, changer->hdr.name, 0) == 0) {
789 /* Try each device in this AutoChanger */
790 foreach_alist(rctx.device, changer->device) {
791 Dmsg1(110, "Try changer device %s\n", rctx.device->hdr.name);
792 stat = reserve_device(rctx);
793 if (stat != 1) { /* try another device */
797 if (rctx.store->append == SD_APPEND) {
798 Dmsg2(100, "Device %s reserved=%d for append.\n", rctx.device->hdr.name,
799 rctx.jcr->dcr->dev->reserved_device);
801 Dmsg2(100, "Device %s reserved=%d for read.\n", rctx.device->hdr.name,
802 rctx.jcr->read_dcr->dev->reserved_device);
804 if (rctx.notify_dir) {
805 pm_strcpy(dev_name, rctx.device->hdr.name);
806 bash_spaces(dev_name);
807 ok = bnet_fsend(dir, OK_device, dev_name.c_str()); /* Return real device name */
808 Dmsg1(100, ">dird changer: %s", dir->msg);
817 /* Now if requested look through regular devices */
818 if (!rctx.autochanger_only) {
819 foreach_res(rctx.device, R_DEVICE) {
820 Dmsg1(150, "Try match res=%s\n", rctx.device->hdr.name);
821 /* Find resource, and make sure we were able to open it */
822 if (fnmatch(rctx.device_name, rctx.device->hdr.name, 0) == 0) {
823 stat = reserve_device(rctx);
827 if (rctx.notify_dir) {
828 bash_spaces(rctx.device_name);
829 ok = bnet_fsend(dir, OK_device, rctx.device_name);
830 Dmsg1(100, ">dird dev: %s", dir->msg);
838 return -1; /* nothing found */
842 * Try to reserve a specific device.
844 * Returns: 1 -- OK, have DCR
848 static int reserve_device(RCTX &rctx)
852 const int name_len = MAX_NAME_LENGTH;
854 /* Make sure MediaType is OK */
855 Dmsg2(110, "MediaType device=%s request=%s\n",
856 rctx.device->media_type, rctx.store->media_type);
857 if (strcmp(rctx.device->media_type, rctx.store->media_type) != 0) {
861 /* Make sure device exists -- i.e. we can stat() it */
862 if (!rctx.device->dev) {
863 rctx.device->dev = init_dev(rctx.jcr, rctx.device);
865 if (!rctx.device->dev) {
866 if (rctx.device->changer_res) {
867 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
868 " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
869 rctx.device->hdr.name, rctx.device_name);
871 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
872 " Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
875 return -1; /* no use waiting */
878 rctx.suitable_device = true;
879 Dmsg2(110, "Try reserve %s JobId=%u\n", rctx.device->hdr.name,
881 dcr = new_dcr(rctx.jcr, rctx.device->dev);
883 BSOCK *dir = rctx.jcr->dir_bsock;
884 bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), rctx.device_name);
885 Dmsg1(100, ">dird: %s", dir->msg);
888 bstrncpy(dcr->pool_name, rctx.store->pool_name, name_len);
889 bstrncpy(dcr->pool_type, rctx.store->pool_type, name_len);
890 bstrncpy(dcr->media_type, rctx.store->media_type, name_len);
891 bstrncpy(dcr->dev_name, rctx.device_name, name_len);
892 if (rctx.store->append == SD_APPEND) {
893 Dmsg2(100, "have_vol=%d vol=%s\n", rctx.have_volume, rctx.VolumeName);
894 if (!rctx.have_volume) {
895 dcr->any_volume = true;
896 if (dir_find_next_appendable_volume(dcr)) {
897 bstrncpy(rctx.VolumeName, dcr->VolumeName, sizeof(rctx.VolumeName));
898 Dmsg2(100, "JobId=%u looking for Volume=%s\n", (int)rctx.jcr->JobId, rctx.VolumeName);
899 rctx.have_volume = true;
901 Dmsg0(100, "No next volume found\n");
902 rctx.have_volume = false;
903 rctx.VolumeName[0] = 0;
906 ok = reserve_device_for_append(dcr, rctx);
909 Dmsg5(100, "Reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
910 dcr->dev->reserved_device,
911 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
914 ok = reserve_device_for_read(dcr);
916 rctx.jcr->read_dcr = dcr;
917 Dmsg5(100, "Read reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
918 dcr->dev->reserved_device,
919 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
923 rctx.have_volume = false;
925 Dmsg0(110, "Not OK.\n");
932 * We "reserve" the drive by setting the ST_READ bit. No one else
933 * should touch the drive until that is cleared.
934 * This allows the DIR to "reserve" the device before actually
937 static bool reserve_device_for_read(DCR *dcr)
939 DEVICE *dev = dcr->dev;
945 /* Get locks in correct order */
946 unlock_reservations();
950 if (is_device_unmounted(dev)) {
951 Dmsg1(200, "Device %s is BLOCKED due to user unmount.\n", dev->print_name());
952 Mmsg(jcr->errmsg, _("3601 JobId=%u device %s is BLOCKED due to user unmount.\n"),
953 jcr->JobId, dev->print_name());
954 queue_reserve_message(jcr);
958 if (dev->is_busy()) {
959 Dmsg4(200, "Device %s is busy ST_READ=%d num_writers=%d reserved=%d.\n", dev->print_name(),
960 dev->state & ST_READ?1:0, dev->num_writers, dev->reserved_device);
961 Mmsg(jcr->errmsg, _("3602 JobId=%u device %s is busy (already reading/writing).\n"),
962 jcr->JobId, dev->print_name());
963 queue_reserve_message(jcr);
970 dev->reserved_device++;
971 Dmsg3(100, "Inc reserve=%d dev=%s %p\n", dev->reserved_device,
972 dev->print_name(), dev);
973 dcr->reserved_device = true;
982 * We reserve the device for appending by incrementing the
983 * reserved_device. We do virtually all the same work that
984 * is done in acquire_device_for_append(), but we do
985 * not attempt to mount the device. This routine allows
986 * the DIR to reserve multiple devices before *really*
987 * starting the job. It also permits the SD to refuse
988 * certain devices (not up, ...).
990 * Note, in reserving a device, if the device is for the
991 * same pool and the same pool type, then it is acceptable.
992 * The Media Type has already been checked. If we are
993 * the first tor reserve the device, we put the pool
994 * name and pool type in the device record.
996 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
999 DEVICE *dev = dcr->dev;
1004 /* Get locks in correct order */
1005 unlock_reservations();
1007 lock_reservations();
1009 /* If device is being read, we cannot write it */
1010 if (dev->can_read()) {
1011 Mmsg(jcr->errmsg, _("3603 JobId=%u device %s is busy reading.\n"),
1012 jcr->JobId, dev->print_name());
1013 Dmsg1(110, "%s", jcr->errmsg);
1014 queue_reserve_message(jcr);
1018 /* If device is unmounted, we are out of luck */
1019 if (is_device_unmounted(dev)) {
1020 Mmsg(jcr->errmsg, _("3604 JobId=%u device %s is BLOCKED due to user unmount.\n"),
1021 jcr->JobId, dev->print_name());
1022 Dmsg1(110, "%s", jcr->errmsg);
1023 queue_reserve_message(jcr);
1027 Dmsg1(110, "reserve_append device is %s\n", dev->is_tape()?"tape":"disk");
1029 /* Now do detailed tests ... */
1030 if (can_reserve_drive(dcr, rctx) != 1) {
1031 Dmsg0(110, "can_reserve_drive!=1\n");
1035 dev->reserved_device++;
1036 Dmsg3(100, "Inc reserve=%d dev=%s %p\n", dev->reserved_device,
1037 dev->print_name(), dev);
1038 dcr->reserved_device = true;
1047 * Returns: 1 if drive can be reserved
1048 * 0 if we should wait
1049 * -1 on error or impossibility
1051 static int can_reserve_drive(DCR *dcr, RCTX &rctx)
1053 DEVICE *dev = dcr->dev;
1054 JCR *jcr = dcr->jcr;
1056 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
1057 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
1058 rctx.autochanger_only, rctx.any_drive);
1060 /* setting any_drive overrides PreferMountedVols flag */
1061 if (!rctx.any_drive) {
1063 * When PreferMountedVols is set, we keep track of the
1064 * drive in use that has the least number of writers, then if
1065 * no unmounted drive is found, we try that drive. This
1066 * helps spread the load to the least used drives.
1068 if (rctx.try_low_use_drive && dev == rctx.low_use_drive) {
1069 Dmsg3(110, "OK dev=%s == low_drive=%s. JobId=%u\n",
1070 dev->print_name(), rctx.low_use_drive->print_name(), jcr->JobId);
1073 /* If he wants a free drive, but this one is busy, no go */
1074 if (!rctx.PreferMountedVols && dev->is_busy()) {
1075 /* Save least used drive */
1076 if ((dev->num_writers + dev->reserved_device) < rctx.num_writers) {
1077 rctx.num_writers = dev->num_writers + dev->reserved_device;
1078 rctx.low_use_drive = dev;
1079 Dmsg2(110, "set low use drive=%s num_writers=%d\n", dev->print_name(),
1082 Dmsg1(110, "not low use num_writers=%d\n", dev->num_writers+
1083 dev->reserved_device);
1085 Dmsg1(110, "failed: !prefMnt && busy. JobId=%u\n", jcr->JobId);
1086 Mmsg(jcr->errmsg, _("3605 JobId=%u wants free drive but device %s is busy.\n"),
1087 jcr->JobId, dev->print_name());
1088 queue_reserve_message(jcr);
1092 /* Check for prefer mounted volumes */
1093 if (rctx.PreferMountedVols && !dev->VolHdr.VolumeName[0] && dev->is_tape()) {
1094 Mmsg(jcr->errmsg, _("3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n"),
1095 jcr->JobId, dev->print_name());
1096 queue_reserve_message(jcr);
1097 Dmsg1(110, "failed: want mounted -- no vol JobId=%u\n", jcr->JobId);
1098 return 0; /* No volume mounted */
1101 /* Check for exact Volume name match */
1102 if (rctx.exact_match && rctx.have_volume &&
1103 strcmp(dev->VolHdr.VolumeName, rctx.VolumeName) != 0) {
1104 Mmsg(jcr->errmsg, _("3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n"),
1105 jcr->JobId, rctx.VolumeName, dev->VolHdr.VolumeName,
1107 queue_reserve_message(jcr);
1108 Dmsg2(110, "failed: Not exact match have=%s want=%s\n",
1109 dev->VolHdr.VolumeName, rctx.VolumeName);
1114 /* Check for unused autochanger drive */
1115 if (rctx.autochanger_only && dev->num_writers == 0 &&
1116 dev->VolHdr.VolumeName[0] == 0) {
1117 /* Device is available but not yet reserved, reserve it for us */
1118 Dmsg2(100, "OK Res Unused autochanger %s JobId=%u.\n",
1119 dev->print_name(), jcr->JobId);
1120 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1121 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1122 return 1; /* reserve drive */
1126 * Handle the case that there are no writers
1128 if (dev->num_writers == 0) {
1129 /* Now check if there are any reservations on the drive */
1130 if (dev->reserved_device) {
1131 /* Now check if we want the same Pool and pool type */
1132 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1133 strcmp(dev->pool_type, dcr->pool_type) == 0) {
1134 /* OK, compatible device */
1135 Dmsg2(100, "OK dev: %s num_writers=0, reserved, pool matches JobId=%u\n",
1136 dev->print_name(), jcr->JobId);
1139 /* Drive Pool not suitable for us */
1140 Mmsg(jcr->errmsg, _(
1141 "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %s.\n"),
1142 jcr->JobId, dcr->pool_name, dev->pool_name,
1143 dev->reserved_device, dev->print_name());
1144 queue_reserve_message(jcr);
1145 Dmsg2(110, "failed: busy num_writers=0, reserved, pool=%s wanted=%s\n",
1146 dev->pool_name, dcr->pool_name);
1147 return 0; /* wait */
1149 } else if (dev->can_append()) {
1150 /* Device in append mode, check if changing pool */
1151 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1152 strcmp(dev->pool_type, dcr->pool_type) == 0) {
1153 Dmsg2(100, "OK dev: %s num_writers=0, can_append, pool matches. JobId=%u\n",
1154 dev->print_name(), jcr->JobId);
1155 /* OK, compatible device */
1158 /* Changing pool, unload old tape if any in drive */
1159 Dmsg0(100, "OK dev: num_writers=0, not reserved, pool change, unload changer\n");
1160 unload_autochanger(dcr, 0);
1163 /* Device is available but not yet reserved, reserve it for us */
1164 Dmsg2(100, "OK Dev avail reserved %s JobId=%u\n", dev->print_name(),
1166 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1167 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1168 return 1; /* reserve drive */
1172 * Check if the device is in append mode with writers (i.e.
1173 * available if pool is the same).
1175 if (dev->can_append() || dev->num_writers > 0) {
1176 /* Yes, now check if we want the same Pool and pool type */
1177 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1178 strcmp(dev->pool_type, dcr->pool_type) == 0) {
1179 Dmsg2(100, "OK dev: %s num_writers>=0, can_append, pool matches. JobId=%u\n",
1180 dev->print_name(), jcr->JobId);
1181 /* OK, compatible device */
1184 /* Drive Pool not suitable for us */
1185 Mmsg(jcr->errmsg, _("3609 JobId=%u wants Pool=\"%s\" but has Pool=\"%s\" on drive %s.\n"),
1186 jcr->JobId, dcr->pool_name, dev->pool_name, dev->print_name());
1187 queue_reserve_message(jcr);
1188 Dmsg2(110, "failed: busy num_writers>0, can_append, pool=%s wanted=%s\n",
1189 dev->pool_name, dcr->pool_name);
1190 return 0; /* wait */
1193 Pmsg0(000, _("Logic error!!!! Should not get here.\n"));
1194 Mmsg(jcr->errmsg, _("3910 JobId=%u Logic error!!!! drive %s Should not get here.\n"),
1195 jcr->JobId, dev->print_name());
1196 queue_reserve_message(jcr);
1197 Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
1198 return -1; /* error, should not get here */
1200 Mmsg(jcr->errmsg, _("3911 JobId=%u failed reserve drive %s.\n"),
1201 jcr->JobId, dev->print_name());
1202 queue_reserve_message(jcr);
1203 Dmsg2(110, "failed: No reserve %s JobId=%u\n", dev->print_name(), jcr->JobId);
1208 * search_lock is already set on entering this routine
1210 static void queue_reserve_message(JCR *jcr)
1213 alist *msgs = jcr->reserve_msgs;
1220 * Look for duplicate message. If found, do
1223 for (i=msgs->size()-1; i >= 0; i--) {
1224 msg = (char *)msgs->get(i);
1228 /* Comparison based on 4 digit message number */
1229 if (strncmp(msg, jcr->errmsg, 4) == 0) {
1233 /* Message unique, so insert it */
1234 jcr->reserve_msgs->push(bstrdup(jcr->errmsg));
1238 * Send any reservation messages queued for this jcr
1240 void send_drive_reserve_messages(JCR *jcr, void sendit(const char *msg, int len, void *sarg), void *arg)
1246 lock_reservations();
1247 msgs = jcr->reserve_msgs;
1248 if (!msgs || msgs->size() == 0) {
1249 unlock_reservations();
1252 for (i=msgs->size()-1; i >= 0; i--) {
1253 msg = (char *)msgs->get(i);
1255 sendit(" ", 3, arg);
1256 sendit(msg, strlen(msg), arg);
1261 unlock_reservations();