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
267 * NULL volume busy on another drive
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.
283 debug_list_volumes("begin reserve_volume", debug_nolock);
285 * First, remove any old volume attached to this device as it
291 * Make sure we don't remove the current volume we are inserting
292 * because it was probably inserted by another job.
294 if (strcmp(vol->vol_name, VolumeName) == 0) {
295 goto get_out; /* Volume already on this device */
297 Dmsg3(100, "reserve_vol free vol=%s at %p JobId=%u\n", vol->vol_name,
298 vol->vol_name, (int)dcr->jcr->JobId);
299 debug_list_volumes("reserve_vol free", debug_nolock);
300 vol_list->remove(vol);
305 /* Create a new Volume entry */
306 nvol = new_vol_item(dcr, VolumeName);
309 * Now try to insert the new Volume
311 vol = (VOLRES *)vol_list->binary_insert(nvol, my_compare);
313 Dmsg2(100, "Found vol=%s dev-same=%d\n", vol->vol_name, dev==vol->dev);
315 * At this point, a Volume with this name already is in the list,
316 * so we simply release our new Volume entry. Note, this should
317 * only happen if we are moving the volume from one drive to another.
319 Dmsg3(100, "reserve_vol free-tmp vol=%s at %p JobId=%u\n", vol->vol_name,
320 vol->vol_name, (int)dcr->jcr->JobId);
322 * Clear dev pointer so that free_vol_item() doesn't
323 * take away our volume.
325 nvol->dev = NULL; /* don't zap dev entry */
328 /* Check if we are trying to use the Volume on a different drive */
329 if (dev != vol->dev) {
330 /* Caller wants to switch Volume to another device */
331 if (!vol->dev->is_busy()) {
332 /* OK to move it -- I'm not sure this will work */
333 Dmsg3(100, "==== Swap vol=%s from dev=%s to %s\n", VolumeName,
334 vol->dev->print_name(), dev->print_name());
335 vol->dev->vol = NULL; /* take vol from old drive */
336 vol->dev->VolHdr.VolumeName[0] = 0;
337 vol->dev = dev; /* point vol at new drive */
338 dev->vol = vol; /* point dev at vol */
339 dev->VolHdr.VolumeName[0] = 0;
341 Dmsg3(100, "Volume busy could not swap vol=%s from dev=%s to %s\n", VolumeName,
342 vol->dev->print_name(), dev->print_name());
343 vol = NULL; /* device busy */
350 debug_list_volumes("end new volume", debug_nolock);
356 * Search for a Volume name in the Volume list.
358 * Returns: VOLRES entry on success
359 * NULL if the Volume is not in the list
361 VOLRES *find_volume(const char *VolumeName)
364 /* Do not lock reservations here */
366 vol.vol_name = bstrdup(VolumeName);
367 fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare);
369 Dmsg2(100, "find_vol=%s found=%d\n", VolumeName, fvol!=NULL);
370 debug_list_volumes("find_volume", debug_nolock);
376 * Remove any reservation from a drive and tell the system
377 * that the volume is unused at least by us.
379 void unreserve_device(DCR *dcr)
381 DEVICE *dev = dcr->dev;
383 if (dcr->reserved_device) {
384 dcr->reserved_device = false;
385 dev->reserved_device--;
386 Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
387 dcr->reserved_device = false;
388 /* If we set read mode in reserving, remove it */
389 if (dev->can_read()) {
392 if (dev->num_writers < 0) {
393 Jmsg1(dcr->jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers);
394 dev->num_writers = 0;
403 * Free a Volume from the Volume list if it is no longer used
405 * Returns: true if the Volume found and removed from the list
406 * false if the Volume is not in the list or is in use
408 bool volume_unused(DCR *dcr)
410 DEVICE *dev = dcr->dev;
412 if (dev->vol == NULL) {
413 Dmsg1(100, " unreserve_volume: no vol on %s\n", dev->print_name());
414 debug_list_volumes("null return unreserve_volume", debug_lock);
418 if (dev->is_busy()) {
419 Dmsg1(100, "unreserve_volume: dev is busy %s\n", dev->print_name());
420 debug_list_volumes("dev busy return unreserve_volume", debug_lock);
424 return free_volume(dev);
428 * Unconditionally release the volume
430 bool free_volume(DEVICE *dev)
434 if (dev->vol == NULL) {
435 Dmsg1(100, "No vol on dev %s\n", dev->print_name());
441 Dmsg1(100, "free_volume %s\n", vol->vol_name);
442 vol_list->remove(vol);
443 Dmsg3(100, "free_volume %s at %p dev=%s\n", vol->vol_name, vol->vol_name,
446 debug_list_volumes("free_volume", debug_nolock);
452 /* Create the Volume list */
453 void create_volume_list()
455 VOLRES *dummy = NULL;
456 if (vol_list == NULL) {
457 vol_list = New(dlist(dummy, &dummy->link));
461 /* Release all Volumes from the list */
462 void free_volume_list()
469 for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
470 Dmsg2(100, "Unreleased Volume=%s dev=%p\n", vol->vol_name, vol->dev);
472 vol->vol_name = NULL;
479 bool is_volume_in_use(DCR *dcr)
481 VOLRES *vol = find_volume(dcr->VolumeName);
483 Dmsg1(100, "Vol=%s not in use.\n", dcr->VolumeName);
484 return false; /* vol not in list */
486 ASSERT(vol->dev != NULL);
488 if (dcr->dev == vol->dev) { /* same device OK */
489 Dmsg1(100, "Vol=%s on same dev.\n", dcr->VolumeName);
492 if (!vol->dev->is_busy()) {
493 Dmsg2(100, "Vol=%s dev=%s not busy.\n", dcr->VolumeName, vol->dev->print_name());
496 Dmsg2(100, "Vol=%s used by %s.\n", dcr->VolumeName, vol->dev->print_name());
502 * We get the following type of information:
504 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=1 copy=0 strip=0
508 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=0 copy=0 strip=0
512 static bool use_storage_cmd(JCR *jcr)
514 POOL_MEM store_name, dev_name, media_type, pool_name, pool_type;
515 BSOCK *dir = jcr->dir_bsock;
525 memset(&rctx, 0, sizeof(RCTX));
528 * If there are multiple devices, the director sends us
529 * use_device for each device that it wants to use.
531 dirstore = New(alist(10, not_owned_by_alist));
532 // Dmsg2(000, "dirstore=%p JobId=%u\n", dirstore, jcr->JobId);
533 msgs = jcr->reserve_msgs = New(alist(10, not_owned_by_alist));
535 Dmsg1(100, "<dird: %s", dir->msg);
536 ok = sscanf(dir->msg, use_storage, store_name.c_str(),
537 media_type.c_str(), pool_name.c_str(),
538 pool_type.c_str(), &append, &Copy, &Stripe) == 7;
543 jcr->write_store = dirstore;
545 jcr->read_store = dirstore;
547 rctx.append = append;
548 unbash_spaces(store_name);
549 unbash_spaces(media_type);
550 unbash_spaces(pool_name);
551 unbash_spaces(pool_type);
552 store = new DIRSTORE;
553 dirstore->append(store);
554 memset(store, 0, sizeof(DIRSTORE));
555 store->device = New(alist(10));
556 bstrncpy(store->name, store_name, sizeof(store->name));
557 bstrncpy(store->media_type, media_type, sizeof(store->media_type));
558 bstrncpy(store->pool_name, pool_name, sizeof(store->pool_name));
559 bstrncpy(store->pool_type, pool_type, sizeof(store->pool_type));
560 store->append = append;
562 /* Now get all devices */
563 while (dir->recv() >= 0) {
564 Dmsg1(100, "<dird device: %s", dir->msg);
565 ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
569 unbash_spaces(dev_name);
570 store->device->append(bstrdup(dev_name.c_str()));
572 } while (ok && dir->recv() >= 0);
575 /* This loop is debug code and can be removed */
576 /* ***FIXME**** remove after 1.38 release */
578 foreach_alist(store, dirstore) {
579 Dmsg5(110, "Storage=%s media_type=%s pool=%s pool_type=%s append=%d\n",
580 store->name, store->media_type, store->pool_name,
581 store->pool_type, store->append);
582 foreach_alist(device_name, store->device) {
583 Dmsg1(110, " Device=%s\n", device_name);
588 init_jcr_device_wait_timers(jcr);
590 * At this point, we have a list of all the Director's Storage
591 * resources indicated for this Job, which include Pool, PoolType,
592 * storage name, and Media type.
593 * Then for each of the Storage resources, we have a list of
594 * device names that were given.
596 * Wiffle through them and find one that can do the backup.
599 bool first = true; /* print wait message once */
601 rctx.notify_dir = true;
603 for ( ; !fail && !job_canceled(jcr); ) {
604 while ((msg = (char *)msgs->pop())) {
607 rctx.suitable_device = false;
608 rctx.have_volume = false;
609 rctx.VolumeName[0] = 0;
610 rctx.any_drive = false;
611 if (!jcr->PreferMountedVols) {
612 /* Look for unused drives in autochangers */
613 rctx.num_writers = 20000000; /* start with impossible number */
614 rctx.low_use_drive = NULL;
615 rctx.PreferMountedVols = false;
616 rctx.exact_match = false;
617 rctx.autochanger_only = true;
618 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
619 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
620 rctx.autochanger_only, rctx.any_drive);
621 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
624 /* Look through all drives possibly for low_use drive */
625 if (rctx.low_use_drive) {
626 rctx.try_low_use_drive = true;
627 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
630 rctx.try_low_use_drive = false;
632 rctx.autochanger_only = false;
633 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
634 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
635 rctx.autochanger_only, rctx.any_drive);
636 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
640 /* Look for an exact match all drives */
641 rctx.PreferMountedVols = true;
642 rctx.exact_match = true;
643 rctx.autochanger_only = false;
644 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
645 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
646 rctx.autochanger_only, rctx.any_drive);
647 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
650 /* Look for any mounted drive */
651 rctx.exact_match = false;
652 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
653 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
654 rctx.autochanger_only, rctx.any_drive);
655 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
659 rctx.any_drive = true;
660 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
661 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
662 rctx.autochanger_only, rctx.any_drive);
663 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
666 /* Keep reservations locked *except* during wait_for_device() */
667 unlock_reservations();
668 if (!rctx.suitable_device || !wait_for_device(jcr, first)) {
669 Dmsg0(100, "Fail. !suitable_device || !wait_for_device\n");
674 bnet_sig(dir, BNET_HEARTBEAT); /* Inform Dir that we are alive */
676 unlock_reservations();
679 * If we get here, there are no suitable devices available, which
680 * means nothing configured. If a device is suitable but busy
681 * with another Volume, we will not come here.
683 unbash_spaces(dir->msg);
684 pm_strcpy(jcr->errmsg, dir->msg);
685 Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
686 Jmsg(jcr, M_FATAL, 0, _("\n"
687 " Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"),
688 dev_name.c_str(), media_type.c_str());
689 bnet_fsend(dir, NO_device, dev_name.c_str());
691 Dmsg1(100, ">dird: %s", dir->msg);
694 unbash_spaces(dir->msg);
695 pm_strcpy(jcr->errmsg, dir->msg);
696 Jmsg(jcr, M_FATAL, 0, _("Failed command: %s\n"), jcr->errmsg);
697 bnet_fsend(dir, BAD_use, jcr->errmsg);
698 Dmsg1(100, ">dird: %s", dir->msg);
705 void release_msgs(JCR *jcr)
707 alist *msgs = jcr->reserve_msgs;
714 while ((msg = (char *)msgs->pop())) {
718 jcr->reserve_msgs = NULL;
719 unlock_reservations();
723 * Search for a device suitable for this job.
725 bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx)
733 dirstore = jcr->write_store;
735 dirstore = jcr->read_store;
738 * For each storage device that the user specified, we
739 * search and see if there is a resource for that device.
741 Dmsg4(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d\n",
742 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
743 rctx.autochanger_only);
745 foreach_alist(store, dirstore) {
747 foreach_alist(device_name, store->device) {
749 rctx.device_name = device_name;
750 stat = search_res_for_device(rctx);
751 if (stat == 1) { /* found available device */
752 Dmsg1(100, "Suitable device found=%s\n", device_name);
755 } else if (stat == 0) { /* device busy */
756 Dmsg1(110, "Suitable device=%s, busy: not use\n", device_name);
758 /* otherwise error */
759 Dmsg0(110, "No suitable device found.\n");
770 * Search for a particular storage device with particular storage
771 * characteristics (MediaType).
773 int search_res_for_device(RCTX &rctx)
775 AUTOCHANGER *changer;
776 BSOCK *dir = rctx.jcr->dir_bsock;
780 Dmsg1(110, "Search res for %s\n", rctx.device_name);
781 /* Look through Autochangers first */
782 foreach_res(changer, R_AUTOCHANGER) {
783 Dmsg1(150, "Try match changer res=%s\n", changer->hdr.name);
784 /* Find resource, and make sure we were able to open it */
785 if (fnmatch(rctx.device_name, changer->hdr.name, 0) == 0) {
786 /* Try each device in this AutoChanger */
787 foreach_alist(rctx.device, changer->device) {
788 Dmsg1(110, "Try changer device %s\n", rctx.device->hdr.name);
789 stat = reserve_device(rctx);
790 if (stat != 1) { /* try another device */
794 if (rctx.store->append == SD_APPEND) {
795 Dmsg2(100, "Device %s reserved=%d for append.\n", rctx.device->hdr.name,
796 rctx.jcr->dcr->dev->reserved_device);
798 Dmsg2(100, "Device %s reserved=%d for read.\n", rctx.device->hdr.name,
799 rctx.jcr->read_dcr->dev->reserved_device);
801 if (rctx.notify_dir) {
802 pm_strcpy(dev_name, rctx.device->hdr.name);
803 bash_spaces(dev_name);
804 ok = bnet_fsend(dir, OK_device, dev_name.c_str()); /* Return real device name */
805 Dmsg1(100, ">dird changer: %s", dir->msg);
814 /* Now if requested look through regular devices */
815 if (!rctx.autochanger_only) {
816 foreach_res(rctx.device, R_DEVICE) {
817 Dmsg1(150, "Try match res=%s\n", rctx.device->hdr.name);
818 /* Find resource, and make sure we were able to open it */
819 if (fnmatch(rctx.device_name, rctx.device->hdr.name, 0) == 0) {
820 stat = reserve_device(rctx);
824 if (rctx.notify_dir) {
825 bash_spaces(rctx.device_name);
826 ok = bnet_fsend(dir, OK_device, rctx.device_name);
827 Dmsg1(100, ">dird dev: %s", dir->msg);
835 return -1; /* nothing found */
839 * Try to reserve a specific device.
841 * Returns: 1 -- OK, have DCR
845 static int reserve_device(RCTX &rctx)
849 const int name_len = MAX_NAME_LENGTH;
851 /* Make sure MediaType is OK */
852 Dmsg2(110, "MediaType device=%s request=%s\n",
853 rctx.device->media_type, rctx.store->media_type);
854 if (strcmp(rctx.device->media_type, rctx.store->media_type) != 0) {
858 /* Make sure device exists -- i.e. we can stat() it */
859 if (!rctx.device->dev) {
860 rctx.device->dev = init_dev(rctx.jcr, rctx.device);
862 if (!rctx.device->dev) {
863 if (rctx.device->changer_res) {
864 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
865 " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
866 rctx.device->hdr.name, rctx.device_name);
868 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
869 " Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
872 return -1; /* no use waiting */
875 rctx.suitable_device = true;
876 Dmsg2(110, "Try reserve %s JobId=%u\n", rctx.device->hdr.name,
878 dcr = new_dcr(rctx.jcr, rctx.device->dev);
880 BSOCK *dir = rctx.jcr->dir_bsock;
881 bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), rctx.device_name);
882 Dmsg1(100, ">dird: %s", dir->msg);
885 bstrncpy(dcr->pool_name, rctx.store->pool_name, name_len);
886 bstrncpy(dcr->pool_type, rctx.store->pool_type, name_len);
887 bstrncpy(dcr->media_type, rctx.store->media_type, name_len);
888 bstrncpy(dcr->dev_name, rctx.device_name, name_len);
889 if (rctx.store->append == SD_APPEND) {
890 Dmsg2(100, "have_vol=%d vol=%s\n", rctx.have_volume, rctx.VolumeName);
891 if (!rctx.have_volume) {
892 dcr->any_volume = true;
893 if (dir_find_next_appendable_volume(dcr)) {
894 bstrncpy(rctx.VolumeName, dcr->VolumeName, sizeof(rctx.VolumeName));
895 Dmsg2(100, "JobId=%u looking for Volume=%s\n", (int)rctx.jcr->JobId, rctx.VolumeName);
896 rctx.have_volume = true;
898 Dmsg0(100, "No next volume found\n");
899 rctx.have_volume = false;
900 rctx.VolumeName[0] = 0;
903 ok = reserve_device_for_append(dcr, rctx);
906 Dmsg5(100, "Reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
907 dcr->dev->reserved_device,
908 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
911 ok = reserve_device_for_read(dcr);
913 rctx.jcr->read_dcr = dcr;
914 Dmsg5(100, "Read reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
915 dcr->dev->reserved_device,
916 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
920 rctx.have_volume = false;
922 Dmsg0(110, "Not OK.\n");
929 * We "reserve" the drive by setting the ST_READ bit. No one else
930 * should touch the drive until that is cleared.
931 * This allows the DIR to "reserve" the device before actually
934 static bool reserve_device_for_read(DCR *dcr)
936 DEVICE *dev = dcr->dev;
944 if (is_device_unmounted(dev)) {
945 Dmsg1(200, "Device %s is BLOCKED due to user unmount.\n", dev->print_name());
946 Mmsg(jcr->errmsg, _("3601 JobId=%u device %s is BLOCKED due to user unmount.\n"),
947 jcr->JobId, dev->print_name());
948 queue_reserve_message(jcr);
952 if (dev->is_busy()) {
953 Dmsg4(200, "Device %s is busy ST_READ=%d num_writers=%d reserved=%d.\n", dev->print_name(),
954 dev->state & ST_READ?1:0, dev->num_writers, dev->reserved_device);
955 Mmsg(jcr->errmsg, _("3602 JobId=%u device %s is busy (already reading/writing).\n"),
956 jcr->JobId, dev->print_name());
957 queue_reserve_message(jcr);
964 dev->reserved_device++;
965 Dmsg3(100, "Inc reserve=%d dev=%s %p\n", dev->reserved_device,
966 dev->print_name(), dev);
967 dcr->reserved_device = true;
976 * We reserve the device for appending by incrementing the
977 * reserved_device. We do virtually all the same work that
978 * is done in acquire_device_for_append(), but we do
979 * not attempt to mount the device. This routine allows
980 * the DIR to reserve multiple devices before *really*
981 * starting the job. It also permits the SD to refuse
982 * certain devices (not up, ...).
984 * Note, in reserving a device, if the device is for the
985 * same pool and the same pool type, then it is acceptable.
986 * The Media Type has already been checked. If we are
987 * the first tor reserve the device, we put the pool
988 * name and pool type in the device record.
990 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
993 DEVICE *dev = dcr->dev;
1000 /* If device is being read, we cannot write it */
1001 if (dev->can_read()) {
1002 Mmsg(jcr->errmsg, _("3603 JobId=%u device %s is busy reading.\n"),
1003 jcr->JobId, dev->print_name());
1004 Dmsg1(110, "%s", jcr->errmsg);
1005 queue_reserve_message(jcr);
1009 /* If device is unmounted, we are out of luck */
1010 if (is_device_unmounted(dev)) {
1011 Mmsg(jcr->errmsg, _("3604 JobId=%u device %s is BLOCKED due to user unmount.\n"),
1012 jcr->JobId, dev->print_name());
1013 Dmsg1(110, "%s", jcr->errmsg);
1014 queue_reserve_message(jcr);
1018 Dmsg1(110, "reserve_append device is %s\n", dev->is_tape()?"tape":"disk");
1020 /* Now do detailed tests ... */
1021 if (can_reserve_drive(dcr, rctx) != 1) {
1022 Dmsg0(110, "can_reserve_drive!=1\n");
1026 dev->reserved_device++;
1027 Dmsg3(100, "Inc reserve=%d dev=%s %p\n", dev->reserved_device,
1028 dev->print_name(), dev);
1029 dcr->reserved_device = true;
1038 * Returns: 1 if drive can be reserved
1039 * 0 if we should wait
1040 * -1 on error or impossibility
1042 static int can_reserve_drive(DCR *dcr, RCTX &rctx)
1044 DEVICE *dev = dcr->dev;
1045 JCR *jcr = dcr->jcr;
1047 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
1048 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
1049 rctx.autochanger_only, rctx.any_drive);
1051 /* setting any_drive overrides PreferMountedVols flag */
1052 if (!rctx.any_drive) {
1054 * When PreferMountedVols is set, we keep track of the
1055 * drive in use that has the least number of writers, then if
1056 * no unmounted drive is found, we try that drive. This
1057 * helps spread the load to the least used drives.
1059 if (rctx.try_low_use_drive && dev == rctx.low_use_drive) {
1060 Dmsg3(110, "OK dev=%s == low_drive=%s. JobId=%u\n",
1061 dev->print_name(), rctx.low_use_drive->print_name(), jcr->JobId);
1064 /* If he wants a free drive, but this one is busy, no go */
1065 if (!rctx.PreferMountedVols && dev->is_busy()) {
1066 /* Save least used drive */
1067 if ((dev->num_writers + dev->reserved_device) < rctx.num_writers) {
1068 rctx.num_writers = dev->num_writers + dev->reserved_device;
1069 rctx.low_use_drive = dev;
1070 Dmsg2(110, "set low use drive=%s num_writers=%d\n", dev->print_name(),
1073 Dmsg1(110, "not low use num_writers=%d\n", dev->num_writers+
1074 dev->reserved_device);
1076 Dmsg1(110, "failed: !prefMnt && busy. JobId=%u\n", jcr->JobId);
1077 Mmsg(jcr->errmsg, _("3605 JobId=%u wants free drive but device %s is busy.\n"),
1078 jcr->JobId, dev->print_name());
1079 queue_reserve_message(jcr);
1083 /* Check for prefer mounted volumes */
1084 if (rctx.PreferMountedVols && !dev->VolHdr.VolumeName[0] && dev->is_tape()) {
1085 Mmsg(jcr->errmsg, _("3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n"),
1086 jcr->JobId, dev->print_name());
1087 queue_reserve_message(jcr);
1088 Dmsg1(110, "failed: want mounted -- no vol JobId=%u\n", jcr->JobId);
1089 return 0; /* No volume mounted */
1092 /* Check for exact Volume name match */
1093 if (rctx.exact_match && rctx.have_volume &&
1094 strcmp(dev->VolHdr.VolumeName, rctx.VolumeName) != 0) {
1095 Mmsg(jcr->errmsg, _("3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n"),
1096 jcr->JobId, rctx.VolumeName, dev->VolHdr.VolumeName,
1098 queue_reserve_message(jcr);
1099 Dmsg2(110, "failed: Not exact match have=%s want=%s\n",
1100 dev->VolHdr.VolumeName, rctx.VolumeName);
1105 /* Check for unused autochanger drive */
1106 if (rctx.autochanger_only && dev->num_writers == 0 &&
1107 dev->VolHdr.VolumeName[0] == 0) {
1108 /* Device is available but not yet reserved, reserve it for us */
1109 Dmsg2(100, "OK Res Unused autochanger %s JobId=%u.\n",
1110 dev->print_name(), jcr->JobId);
1111 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1112 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1113 return 1; /* reserve drive */
1117 * Handle the case that there are no writers
1119 if (dev->num_writers == 0) {
1120 /* Now check if there are any reservations on the drive */
1121 if (dev->reserved_device) {
1122 /* Now check if we want the same Pool and pool type */
1123 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1124 strcmp(dev->pool_type, dcr->pool_type) == 0) {
1125 /* OK, compatible device */
1126 Dmsg2(100, "OK dev: %s num_writers=0, reserved, pool matches JobId=%u\n",
1127 dev->print_name(), jcr->JobId);
1130 /* Drive Pool not suitable for us */
1131 Mmsg(jcr->errmsg, _(
1132 "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %s.\n"),
1133 jcr->JobId, dcr->pool_name, dev->pool_name,
1134 dev->reserved_device, dev->print_name());
1135 queue_reserve_message(jcr);
1136 Dmsg2(110, "failed: busy num_writers=0, reserved, pool=%s wanted=%s\n",
1137 dev->pool_name, dcr->pool_name);
1138 return 0; /* wait */
1140 } else if (dev->can_append()) {
1141 /* Device in append mode, check if changing pool */
1142 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1143 strcmp(dev->pool_type, dcr->pool_type) == 0) {
1144 Dmsg2(100, "OK dev: %s num_writers=0, can_append, pool matches. JobId=%u\n",
1145 dev->print_name(), jcr->JobId);
1146 /* OK, compatible device */
1149 /* Changing pool, unload old tape if any in drive */
1150 Dmsg0(100, "OK dev: num_writers=0, not reserved, pool change, unload changer\n");
1151 unload_autochanger(dcr, 0);
1154 /* Device is available but not yet reserved, reserve it for us */
1155 Dmsg2(100, "OK Dev avail reserved %s JobId=%u\n", dev->print_name(),
1157 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1158 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1159 return 1; /* reserve drive */
1163 * Check if the device is in append mode with writers (i.e.
1164 * available if pool is the same).
1166 if (dev->can_append() || dev->num_writers > 0) {
1167 /* Yes, now check if we want the same Pool and pool type */
1168 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1169 strcmp(dev->pool_type, dcr->pool_type) == 0) {
1170 Dmsg2(100, "OK dev: %s num_writers>=0, can_append, pool matches. JobId=%u\n",
1171 dev->print_name(), jcr->JobId);
1172 /* OK, compatible device */
1175 /* Drive Pool not suitable for us */
1176 Mmsg(jcr->errmsg, _("3609 JobId=%u wants Pool=\"%s\" but has Pool=\"%s\" on drive %s.\n"),
1177 jcr->JobId, dcr->pool_name, dev->pool_name, dev->print_name());
1178 queue_reserve_message(jcr);
1179 Dmsg2(110, "failed: busy num_writers>0, can_append, pool=%s wanted=%s\n",
1180 dev->pool_name, dcr->pool_name);
1181 return 0; /* wait */
1184 Pmsg0(000, _("Logic error!!!! Should not get here.\n"));
1185 Mmsg(jcr->errmsg, _("3910 JobId=%u Logic error!!!! drive %s Should not get here.\n"),
1186 jcr->JobId, dev->print_name());
1187 queue_reserve_message(jcr);
1188 Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
1189 return -1; /* error, should not get here */
1191 Mmsg(jcr->errmsg, _("3911 JobId=%u failed reserve drive %s.\n"),
1192 jcr->JobId, dev->print_name());
1193 queue_reserve_message(jcr);
1194 Dmsg2(110, "failed: No reserve %s JobId=%u\n", dev->print_name(), jcr->JobId);
1199 * search_lock is already set on entering this routine
1201 static void queue_reserve_message(JCR *jcr)
1204 alist *msgs = jcr->reserve_msgs;
1211 * Look for duplicate message. If found, do
1214 for (i=msgs->size()-1; i >= 0; i--) {
1215 msg = (char *)msgs->get(i);
1219 /* Comparison based on 4 digit message number */
1220 if (strncmp(msg, jcr->errmsg, 4) == 0) {
1224 /* Message unique, so insert it */
1225 jcr->reserve_msgs->push(bstrdup(jcr->errmsg));
1229 * Send any reservation messages queued for this jcr
1231 void send_drive_reserve_messages(JCR *jcr, void sendit(const char *msg, int len, void *sarg), void *arg)
1237 lock_reservations();
1238 msgs = jcr->reserve_msgs;
1239 if (!msgs || msgs->size() == 0) {
1240 unlock_reservations();
1243 for (i=msgs->size()-1; i >= 0; i--) {
1244 msg = (char *)msgs->get(i);
1246 sendit(" ", 3, arg);
1247 sendit(msg, strlen(msg), arg);
1252 unlock_reservations();