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 int retries = 0; /* wait for device retries */
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, retries)) {
669 Dmsg0(100, "Fail. !suitable_device || !wait_for_device\n");
673 bnet_sig(dir, BNET_HEARTBEAT); /* Inform Dir that we are alive */
675 unlock_reservations();
678 * If we get here, there are no suitable devices available, which
679 * means nothing configured. If a device is suitable but busy
680 * with another Volume, we will not come here.
682 unbash_spaces(dir->msg);
683 pm_strcpy(jcr->errmsg, dir->msg);
684 Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
685 Jmsg(jcr, M_FATAL, 0, _("\n"
686 " Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"),
687 dev_name.c_str(), media_type.c_str());
688 bnet_fsend(dir, NO_device, dev_name.c_str());
690 Dmsg1(100, ">dird: %s", dir->msg);
693 unbash_spaces(dir->msg);
694 pm_strcpy(jcr->errmsg, dir->msg);
695 Jmsg(jcr, M_FATAL, 0, _("Failed command: %s\n"), jcr->errmsg);
696 bnet_fsend(dir, BAD_use, jcr->errmsg);
697 Dmsg1(100, ">dird: %s", dir->msg);
704 void release_msgs(JCR *jcr)
706 alist *msgs = jcr->reserve_msgs;
713 while ((msg = (char *)msgs->pop())) {
717 jcr->reserve_msgs = NULL;
718 unlock_reservations();
722 * Search for a device suitable for this job.
724 bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx)
732 dirstore = jcr->write_store;
734 dirstore = jcr->read_store;
737 * For each storage device that the user specified, we
738 * search and see if there is a resource for that device.
740 Dmsg4(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d\n",
741 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
742 rctx.autochanger_only);
744 foreach_alist(store, dirstore) {
746 foreach_alist(device_name, store->device) {
748 rctx.device_name = device_name;
749 stat = search_res_for_device(rctx);
750 if (stat == 1) { /* found available device */
751 Dmsg1(100, "Suitable device found=%s\n", device_name);
754 } else if (stat == 0) { /* device busy */
755 Dmsg1(110, "Suitable device=%s, busy: not use\n", device_name);
757 /* otherwise error */
758 Dmsg0(110, "No suitable device found.\n");
769 * Search for a particular storage device with particular storage
770 * characteristics (MediaType).
772 int search_res_for_device(RCTX &rctx)
774 AUTOCHANGER *changer;
775 BSOCK *dir = rctx.jcr->dir_bsock;
779 Dmsg1(110, "Search res for %s\n", rctx.device_name);
780 /* Look through Autochangers first */
781 foreach_res(changer, R_AUTOCHANGER) {
782 Dmsg1(150, "Try match changer res=%s\n", changer->hdr.name);
783 /* Find resource, and make sure we were able to open it */
784 if (fnmatch(rctx.device_name, changer->hdr.name, 0) == 0) {
785 /* Try each device in this AutoChanger */
786 foreach_alist(rctx.device, changer->device) {
787 Dmsg1(110, "Try changer device %s\n", rctx.device->hdr.name);
788 stat = reserve_device(rctx);
789 if (stat != 1) { /* try another device */
793 if (rctx.store->append == SD_APPEND) {
794 Dmsg2(100, "Device %s reserved=%d for append.\n", rctx.device->hdr.name,
795 rctx.jcr->dcr->dev->reserved_device);
797 Dmsg2(100, "Device %s reserved=%d for read.\n", rctx.device->hdr.name,
798 rctx.jcr->read_dcr->dev->reserved_device);
800 if (rctx.notify_dir) {
801 pm_strcpy(dev_name, rctx.device->hdr.name);
802 bash_spaces(dev_name);
803 ok = bnet_fsend(dir, OK_device, dev_name.c_str()); /* Return real device name */
804 Dmsg1(100, ">dird changer: %s", dir->msg);
813 /* Now if requested look through regular devices */
814 if (!rctx.autochanger_only) {
815 foreach_res(rctx.device, R_DEVICE) {
816 Dmsg1(150, "Try match res=%s\n", rctx.device->hdr.name);
817 /* Find resource, and make sure we were able to open it */
818 if (fnmatch(rctx.device_name, rctx.device->hdr.name, 0) == 0) {
819 stat = reserve_device(rctx);
823 if (rctx.notify_dir) {
824 bash_spaces(rctx.device_name);
825 ok = bnet_fsend(dir, OK_device, rctx.device_name);
826 Dmsg1(100, ">dird dev: %s", dir->msg);
834 return -1; /* nothing found */
838 * Try to reserve a specific device.
840 * Returns: 1 -- OK, have DCR
844 static int reserve_device(RCTX &rctx)
848 const int name_len = MAX_NAME_LENGTH;
850 /* Make sure MediaType is OK */
851 Dmsg2(110, "MediaType device=%s request=%s\n",
852 rctx.device->media_type, rctx.store->media_type);
853 if (strcmp(rctx.device->media_type, rctx.store->media_type) != 0) {
857 /* Make sure device exists -- i.e. we can stat() it */
858 if (!rctx.device->dev) {
859 rctx.device->dev = init_dev(rctx.jcr, rctx.device);
861 if (!rctx.device->dev) {
862 if (rctx.device->changer_res) {
863 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
864 " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
865 rctx.device->hdr.name, rctx.device_name);
867 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
868 " Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
871 return -1; /* no use waiting */
874 rctx.suitable_device = true;
875 Dmsg2(110, "Try reserve %s JobId=%u\n", rctx.device->hdr.name,
877 dcr = new_dcr(rctx.jcr, rctx.device->dev);
879 BSOCK *dir = rctx.jcr->dir_bsock;
880 bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), rctx.device_name);
881 Dmsg1(100, ">dird: %s", dir->msg);
884 bstrncpy(dcr->pool_name, rctx.store->pool_name, name_len);
885 bstrncpy(dcr->pool_type, rctx.store->pool_type, name_len);
886 bstrncpy(dcr->media_type, rctx.store->media_type, name_len);
887 bstrncpy(dcr->dev_name, rctx.device_name, name_len);
888 if (rctx.store->append == SD_APPEND) {
889 Dmsg2(100, "have_vol=%d vol=%s\n", rctx.have_volume, rctx.VolumeName);
890 if (!rctx.have_volume) {
891 dcr->any_volume = true;
892 if (dir_find_next_appendable_volume(dcr)) {
893 bstrncpy(rctx.VolumeName, dcr->VolumeName, sizeof(rctx.VolumeName));
894 Dmsg2(100, "JobId=%u looking for Volume=%s\n", (int)rctx.jcr->JobId, rctx.VolumeName);
895 rctx.have_volume = true;
897 Dmsg0(100, "No next volume found\n");
898 rctx.have_volume = false;
899 rctx.VolumeName[0] = 0;
902 ok = reserve_device_for_append(dcr, rctx);
905 Dmsg5(100, "Reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
906 dcr->dev->reserved_device,
907 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
910 ok = reserve_device_for_read(dcr);
912 rctx.jcr->read_dcr = dcr;
913 Dmsg5(100, "Read reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
914 dcr->dev->reserved_device,
915 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
919 rctx.have_volume = false;
921 Dmsg0(110, "Not OK.\n");
928 * We "reserve" the drive by setting the ST_READ bit. No one else
929 * should touch the drive until that is cleared.
930 * This allows the DIR to "reserve" the device before actually
933 static bool reserve_device_for_read(DCR *dcr)
935 DEVICE *dev = dcr->dev;
943 if (is_device_unmounted(dev)) {
944 Dmsg1(200, "Device %s is BLOCKED due to user unmount.\n", dev->print_name());
945 Mmsg(jcr->errmsg, _("3601 JobId=%u device %s is BLOCKED due to user unmount.\n"),
946 jcr->JobId, dev->print_name());
947 queue_reserve_message(jcr);
951 if (dev->is_busy()) {
952 Dmsg4(200, "Device %s is busy ST_READ=%d num_writers=%d reserved=%d.\n", dev->print_name(),
953 dev->state & ST_READ?1:0, dev->num_writers, dev->reserved_device);
954 Mmsg(jcr->errmsg, _("3602 JobId=%u device %s is busy (already reading/writing).\n"),
955 jcr->JobId, dev->print_name());
956 queue_reserve_message(jcr);
963 dev->reserved_device++;
964 Dmsg3(100, "Inc reserve=%d dev=%s %p\n", dev->reserved_device,
965 dev->print_name(), dev);
966 dcr->reserved_device = true;
975 * We reserve the device for appending by incrementing the
976 * reserved_device. We do virtually all the same work that
977 * is done in acquire_device_for_append(), but we do
978 * not attempt to mount the device. This routine allows
979 * the DIR to reserve multiple devices before *really*
980 * starting the job. It also permits the SD to refuse
981 * certain devices (not up, ...).
983 * Note, in reserving a device, if the device is for the
984 * same pool and the same pool type, then it is acceptable.
985 * The Media Type has already been checked. If we are
986 * the first tor reserve the device, we put the pool
987 * name and pool type in the device record.
989 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
992 DEVICE *dev = dcr->dev;
999 /* If device is being read, we cannot write it */
1000 if (dev->can_read()) {
1001 Mmsg(jcr->errmsg, _("3603 JobId=%u device %s is busy reading.\n"),
1002 jcr->JobId, dev->print_name());
1003 Dmsg1(110, "%s", jcr->errmsg);
1004 queue_reserve_message(jcr);
1008 /* If device is unmounted, we are out of luck */
1009 if (is_device_unmounted(dev)) {
1010 Mmsg(jcr->errmsg, _("3604 JobId=%u device %s is BLOCKED due to user unmount.\n"),
1011 jcr->JobId, dev->print_name());
1012 Dmsg1(110, "%s", jcr->errmsg);
1013 queue_reserve_message(jcr);
1017 Dmsg1(110, "reserve_append device is %s\n", dev->is_tape()?"tape":"disk");
1019 /* Now do detailed tests ... */
1020 if (can_reserve_drive(dcr, rctx) != 1) {
1021 Dmsg0(110, "can_reserve_drive!=1\n");
1025 dev->reserved_device++;
1026 Dmsg3(100, "Inc reserve=%d dev=%s %p\n", dev->reserved_device,
1027 dev->print_name(), dev);
1028 dcr->reserved_device = true;
1037 * Returns: 1 if drive can be reserved
1038 * 0 if we should wait
1039 * -1 on error or impossibility
1041 static int can_reserve_drive(DCR *dcr, RCTX &rctx)
1043 DEVICE *dev = dcr->dev;
1044 JCR *jcr = dcr->jcr;
1046 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
1047 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
1048 rctx.autochanger_only, rctx.any_drive);
1050 /* setting any_drive overrides PreferMountedVols flag */
1051 if (!rctx.any_drive) {
1053 * When PreferMountedVols is set, we keep track of the
1054 * drive in use that has the least number of writers, then if
1055 * no unmounted drive is found, we try that drive. This
1056 * helps spread the load to the least used drives.
1058 if (rctx.try_low_use_drive && dev == rctx.low_use_drive) {
1059 Dmsg3(110, "OK dev=%s == low_drive=%s. JobId=%u\n",
1060 dev->print_name(), rctx.low_use_drive->print_name(), jcr->JobId);
1063 /* If he wants a free drive, but this one is busy, no go */
1064 if (!rctx.PreferMountedVols && dev->is_busy()) {
1065 /* Save least used drive */
1066 if ((dev->num_writers + dev->reserved_device) < rctx.num_writers) {
1067 rctx.num_writers = dev->num_writers + dev->reserved_device;
1068 rctx.low_use_drive = dev;
1069 Dmsg2(110, "set low use drive=%s num_writers=%d\n", dev->print_name(),
1072 Dmsg1(110, "not low use num_writers=%d\n", dev->num_writers+
1073 dev->reserved_device);
1075 Dmsg1(110, "failed: !prefMnt && busy. JobId=%u\n", jcr->JobId);
1076 Mmsg(jcr->errmsg, _("3605 JobId=%u wants free drive but device %s is busy.\n"),
1077 jcr->JobId, dev->print_name());
1078 queue_reserve_message(jcr);
1082 /* Check for prefer mounted volumes */
1083 if (rctx.PreferMountedVols && !dev->VolHdr.VolumeName[0] && dev->is_tape()) {
1084 Mmsg(jcr->errmsg, _("3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n"),
1085 jcr->JobId, dev->print_name());
1086 queue_reserve_message(jcr);
1087 Dmsg1(110, "failed: want mounted -- no vol JobId=%u\n", jcr->JobId);
1088 return 0; /* No volume mounted */
1091 /* Check for exact Volume name match */
1092 if (rctx.exact_match && rctx.have_volume &&
1093 strcmp(dev->VolHdr.VolumeName, rctx.VolumeName) != 0) {
1094 Mmsg(jcr->errmsg, _("3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n"),
1095 jcr->JobId, rctx.VolumeName, dev->VolHdr.VolumeName,
1097 queue_reserve_message(jcr);
1098 Dmsg2(110, "failed: Not exact match have=%s want=%s\n",
1099 dev->VolHdr.VolumeName, rctx.VolumeName);
1104 /* Check for unused autochanger drive */
1105 if (rctx.autochanger_only && dev->num_writers == 0 &&
1106 dev->VolHdr.VolumeName[0] == 0) {
1107 /* Device is available but not yet reserved, reserve it for us */
1108 Dmsg2(100, "OK Res Unused autochanger %s JobId=%u.\n",
1109 dev->print_name(), jcr->JobId);
1110 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1111 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1112 return 1; /* reserve drive */
1116 * Handle the case that there are no writers
1118 if (dev->num_writers == 0) {
1119 /* Now check if there are any reservations on the drive */
1120 if (dev->reserved_device) {
1121 /* Now check if we want the same Pool and pool type */
1122 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1123 strcmp(dev->pool_type, dcr->pool_type) == 0) {
1124 /* OK, compatible device */
1125 Dmsg2(100, "OK dev: %s num_writers=0, reserved, pool matches JobId=%u\n",
1126 dev->print_name(), jcr->JobId);
1129 /* Drive Pool not suitable for us */
1130 Mmsg(jcr->errmsg, _(
1131 "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %s.\n"),
1132 jcr->JobId, dcr->pool_name, dev->pool_name,
1133 dev->reserved_device, dev->print_name());
1134 queue_reserve_message(jcr);
1135 Dmsg2(110, "failed: busy num_writers=0, reserved, pool=%s wanted=%s\n",
1136 dev->pool_name, dcr->pool_name);
1137 return 0; /* wait */
1139 } else if (dev->can_append()) {
1140 /* Device in append mode, check if changing pool */
1141 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1142 strcmp(dev->pool_type, dcr->pool_type) == 0) {
1143 Dmsg2(100, "OK dev: %s num_writers=0, can_append, pool matches. JobId=%u\n",
1144 dev->print_name(), jcr->JobId);
1145 /* OK, compatible device */
1148 /* Changing pool, unload old tape if any in drive */
1149 Dmsg0(100, "OK dev: num_writers=0, not reserved, pool change, unload changer\n");
1150 unload_autochanger(dcr, 0);
1153 /* Device is available but not yet reserved, reserve it for us */
1154 Dmsg2(100, "OK Dev avail reserved %s JobId=%u\n", dev->print_name(),
1156 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1157 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1158 return 1; /* reserve drive */
1162 * Check if the device is in append mode with writers (i.e.
1163 * available if pool is the same).
1165 if (dev->can_append() || dev->num_writers > 0) {
1166 /* Yes, now check if we want the same Pool and pool type */
1167 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1168 strcmp(dev->pool_type, dcr->pool_type) == 0) {
1169 Dmsg2(100, "OK dev: %s num_writers>=0, can_append, pool matches. JobId=%u\n",
1170 dev->print_name(), jcr->JobId);
1171 /* OK, compatible device */
1174 /* Drive Pool not suitable for us */
1175 Mmsg(jcr->errmsg, _("3609 JobId=%u wants Pool=\"%s\" but has Pool=\"%s\" on drive %s.\n"),
1176 jcr->JobId, dcr->pool_name, dev->pool_name, dev->print_name());
1177 queue_reserve_message(jcr);
1178 Dmsg2(110, "failed: busy num_writers>0, can_append, pool=%s wanted=%s\n",
1179 dev->pool_name, dcr->pool_name);
1180 return 0; /* wait */
1183 Pmsg0(000, _("Logic error!!!! Should not get here.\n"));
1184 Mmsg(jcr->errmsg, _("3910 JobId=%u Logic error!!!! drive %s Should not get here.\n"),
1185 jcr->JobId, dev->print_name());
1186 queue_reserve_message(jcr);
1187 Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
1188 return -1; /* error, should not get here */
1190 Mmsg(jcr->errmsg, _("3911 JobId=%u failed reserve drive %s.\n"),
1191 jcr->JobId, dev->print_name());
1192 queue_reserve_message(jcr);
1193 Dmsg2(110, "failed: No reserve %s JobId=%u\n", dev->print_name(), jcr->JobId);
1198 * search_lock is already set on entering this routine
1200 static void queue_reserve_message(JCR *jcr)
1203 alist *msgs = jcr->reserve_msgs;
1210 * Look for duplicate message. If found, do
1213 for (i=msgs->size()-1; i >= 0; i--) {
1214 msg = (char *)msgs->get(i);
1218 /* Comparison based on 4 digit message number */
1219 if (strncmp(msg, jcr->errmsg, 4) == 0) {
1223 /* Message unique, so insert it */
1224 jcr->reserve_msgs->push(bstrdup(jcr->errmsg));
1228 * Send any reservation messages queued for this jcr
1230 void send_drive_reserve_messages(JCR *jcr, void sendit(const char *msg, int len, void *sarg), void *arg)
1236 lock_reservations();
1237 msgs = jcr->reserve_msgs;
1238 if (!msgs || msgs->size() == 0) {
1239 unlock_reservations();
1242 for (i=msgs->size()-1; i >= 0; i--) {
1243 msg = (char *)msgs->get(i);
1245 sendit(" ", 3, arg);
1246 sendit(msg, strlen(msg), arg);
1251 unlock_reservations();