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)
210 * Put a new Volume entry in the Volume list. This
211 * effectively reserves the volume so that it will
212 * not be mounted again.
214 * If the device has any current volume associated with it,
215 * and it is a different Volume, and the device is not busy,
216 * we release the old Volume item and insert the new one.
218 * It is assumed that the device is free and locked so that
219 * we can change the device structure.
221 * Some details of the Volume list handling:
223 * 1. The Volume list entry must be attached to the drive (rather than
224 * attached to a job as it currently is. I.e. the drive that "owns"
225 * the volume (reserved, in use, mounted)
226 * must point to the volume (still to be maintained in a list).
228 * 2. The Volume is entered in the list when a drive is reserved.
230 * 3. When a drive is in use, the device code must appropriately update the
231 * volume name as it changes (currently the list is static -- an entry is
232 * removed when the Volume is no longer reserved, in use or mounted).
233 * The new code must keep the same list entry as long as the drive
234 * has any volume associated with it but the volume name in the list
235 * must be updated when the drive has a different volume mounted.
237 * 4. A job that has reserved a volume, can un-reserve the volume, and if the
238 * volume is not mounted, and not reserved, and not in use, it will be
239 * removed from the list.
241 * 5. If a job wants to reserve a drive with a different Volume from the one on
242 * the drive, it can re-use the drive for the new Volume.
244 * 6. If a job wants a Volume that is in a different drive, it can either use the
245 * other drive or take the volume, only if the other drive is not in use or
248 * One nice aspect of this is that the reserve use count and the writer use count
249 * already exist and are correctly programmed and will need no changes -- use
250 * counts are always very tricky.
252 * The old code had a concept of "reserving" a Volume, but it needs to be changed
253 * to reserving and using a drive. A volume is must be attached to (owned by) a
254 * drive and can move from drive to drive or be unused given certain specific
255 * conditions of the drive. The key is that the drive must "own" the Volume.
256 * The old code has the job (dcr) owning the volume (more or less). The job is
257 * to change the insertion and removal of the volumes from the list to be based
258 * on the drive rather than the job. The new logic described above needs to be
259 * reviewed a couple more times for completeness and correctness. Then I can
263 * Return: VOLRES entry on success
266 VOLRES *reserve_volume(DCR *dcr, const char *VolumeName)
269 DEVICE *dev = dcr->dev;
273 Dmsg1(100, "reserve_volume %s\n", VolumeName);
275 * We lock the reservations system here to ensure
276 * when adding a new volume that no newly scheduled
277 * job can reserve it.
281 debug_list_volumes("begin reserve_volume", debug_nolock);
283 * First, remove any old volume attached to this device as it
289 * Make sure we don't remove the current volume we are inserting
290 * because it was probably inserted by another job.
292 if (strcmp(vol->vol_name, VolumeName) == 0) {
293 goto get_out; /* Volume already on this device */
295 Dmsg3(100, "reserve_vol free vol=%s at %p JobId=%u\n", vol->vol_name,
296 vol->vol_name, (int)dcr->jcr->JobId);
297 debug_list_volumes("reserve_vol free", debug_nolock);
298 vol_list->remove(vol);
303 /* Create a new Volume entry */
304 nvol = new_vol_item(dcr, VolumeName);
307 * Now try to insert the new Volume
309 vol = (VOLRES *)vol_list->binary_insert(nvol, my_compare);
311 Dmsg2(100, "Found vol=%s dev-same=%d\n", vol->vol_name, dev==vol->dev);
313 * At this point, a Volume with this name already is in the list,
314 * so we simply release our new Volume entry. Note, this should
315 * only happen if we are moving the volume from one drive to another.
317 Dmsg3(100, "reserve_vol free-tmp vol=%s at %p JobId=%u\n", vol->vol_name,
318 vol->vol_name, (int)dcr->jcr->JobId);
321 /* Check if we are trying to use the Volume on a different drive */
322 if (dev != vol->dev) {
323 /* Caller wants to switch Volume to another device */
324 if (!dev->is_busy()) {
326 Dmsg3(100, "Swap vol=%s from dev=%s to %s\n", VolumeName,
327 dev->print_name(), dev->print_name());
329 dev->VolHdr.VolumeName[0] = 0;
331 vol = NULL; /* device busy */
332 Dmsg3(100, "Logic ERROR!!!! could not swap vol=%s from dev=%s to %s\n", VolumeName,
333 dev->print_name(), dcr->dev->print_name());
334 ASSERT(1); /* blow up!!! */
341 debug_list_volumes("end new volume", debug_nolock);
343 unlock_reservations();
348 * Search for a Volume name in the Volume list.
350 * Returns: VOLRES entry on success
351 * NULL if the Volume is not in the list
353 VOLRES *find_volume(const char *VolumeName)
356 /* Do not lock reservations here */
358 vol.vol_name = bstrdup(VolumeName);
359 fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare);
361 Dmsg2(100, "find_vol=%s found=%d\n", VolumeName, fvol!=NULL);
362 debug_list_volumes("find_volume", debug_nolock);
368 * Remove any reservation from a drive and tell the system
369 * that the volume is unused at least by us.
371 void unreserve_device(DCR *dcr)
373 DEVICE *dev = dcr->dev;
375 if (dcr->reserved_device) {
376 dcr->reserved_device = false;
377 dev->reserved_device--;
378 Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
379 dcr->reserved_device = false;
380 /* If we set read mode in reserving, remove it */
381 if (dev->can_read()) {
384 if (dev->num_writers < 0) {
385 Jmsg1(dcr->jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers);
386 dev->num_writers = 0;
395 * Free a Volume from the Volume list if it is no longer used
397 * Returns: true if the Volume found and removed from the list
398 * false if the Volume is not in the list or is in use
400 bool volume_unused(DCR *dcr)
402 DEVICE *dev = dcr->dev;
404 if (dev->vol == NULL) {
405 Dmsg1(100, " unreserve_volume: no vol on %s\n", dev->print_name());
406 debug_list_volumes("null return unreserve_volume", debug_lock);
410 if (dev->is_busy()) {
411 Dmsg1(100, "unreserve_volume: dev is busy %s\n", dev->print_name());
412 debug_list_volumes("dev busy return unreserve_volume", debug_lock);
416 return free_volume(dev);
420 * Unconditionally release the volume
422 bool free_volume(DEVICE *dev)
426 if (dev->vol == NULL) {
427 Dmsg1(100, "No vol on dev %s\n", dev->print_name());
433 Dmsg1(100, "free_volume %s\n", vol->vol_name);
434 vol_list->remove(vol);
435 Dmsg3(100, "free_volume %s at %p dev=%s\n", vol->vol_name, vol->vol_name,
438 debug_list_volumes("free_volume", debug_nolock);
444 /* Create the Volume list */
445 void create_volume_list()
447 VOLRES *dummy = NULL;
448 if (vol_list == NULL) {
449 vol_list = New(dlist(dummy, &dummy->link));
453 /* Release all Volumes from the list */
454 void free_volume_list()
461 for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
462 Dmsg2(100, "Unreleased Volume=%s dev=%p\n", vol->vol_name, vol->dev);
464 vol->vol_name = NULL;
471 bool is_volume_in_use(DCR *dcr)
473 VOLRES *vol = find_volume(dcr->VolumeName);
475 Dmsg1(100, "Vol=%s not in use.\n", dcr->VolumeName);
476 return false; /* vol not in list */
478 ASSERT(vol->dev != NULL);
480 if (dcr->dev == vol->dev) { /* same device OK */
481 Dmsg1(100, "Vol=%s on same dev.\n", dcr->VolumeName);
484 if (!vol->dev->is_busy()) {
485 Dmsg2(100, "Vol=%s dev=%s not busy.\n", dcr->VolumeName, vol->dev->print_name());
488 Dmsg2(100, "Vol=%s used by %s.\n", dcr->VolumeName, vol->dev->print_name());
494 * We get the following type of information:
496 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=1 copy=0 strip=0
500 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=0 copy=0 strip=0
504 static bool use_storage_cmd(JCR *jcr)
506 POOL_MEM store_name, dev_name, media_type, pool_name, pool_type;
507 BSOCK *dir = jcr->dir_bsock;
517 memset(&rctx, 0, sizeof(RCTX));
520 * If there are multiple devices, the director sends us
521 * use_device for each device that it wants to use.
523 dirstore = New(alist(10, not_owned_by_alist));
524 // Dmsg2(000, "dirstore=%p JobId=%u\n", dirstore, jcr->JobId);
525 msgs = jcr->reserve_msgs = New(alist(10, not_owned_by_alist));
527 Dmsg1(100, "<dird: %s", dir->msg);
528 ok = sscanf(dir->msg, use_storage, store_name.c_str(),
529 media_type.c_str(), pool_name.c_str(),
530 pool_type.c_str(), &append, &Copy, &Stripe) == 7;
535 jcr->write_store = dirstore;
537 jcr->read_store = dirstore;
539 rctx.append = append;
540 unbash_spaces(store_name);
541 unbash_spaces(media_type);
542 unbash_spaces(pool_name);
543 unbash_spaces(pool_type);
544 store = new DIRSTORE;
545 dirstore->append(store);
546 memset(store, 0, sizeof(DIRSTORE));
547 store->device = New(alist(10));
548 bstrncpy(store->name, store_name, sizeof(store->name));
549 bstrncpy(store->media_type, media_type, sizeof(store->media_type));
550 bstrncpy(store->pool_name, pool_name, sizeof(store->pool_name));
551 bstrncpy(store->pool_type, pool_type, sizeof(store->pool_type));
552 store->append = append;
554 /* Now get all devices */
555 while (dir->recv() >= 0) {
556 Dmsg1(100, "<dird device: %s", dir->msg);
557 ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
561 unbash_spaces(dev_name);
562 store->device->append(bstrdup(dev_name.c_str()));
564 } while (ok && dir->recv() >= 0);
567 /* This loop is debug code and can be removed */
568 /* ***FIXME**** remove after 1.38 release */
570 foreach_alist(store, dirstore) {
571 Dmsg5(110, "Storage=%s media_type=%s pool=%s pool_type=%s append=%d\n",
572 store->name, store->media_type, store->pool_name,
573 store->pool_type, store->append);
574 foreach_alist(device_name, store->device) {
575 Dmsg1(110, " Device=%s\n", device_name);
580 init_jcr_device_wait_timers(jcr);
582 * At this point, we have a list of all the Director's Storage
583 * resources indicated for this Job, which include Pool, PoolType,
584 * storage name, and Media type.
585 * Then for each of the Storage resources, we have a list of
586 * device names that were given.
588 * Wiffle through them and find one that can do the backup.
591 bool first = true; /* print wait message once */
593 rctx.notify_dir = true;
595 for ( ; !fail && !job_canceled(jcr); ) {
596 while ((msg = (char *)msgs->pop())) {
599 rctx.suitable_device = false;
600 rctx.have_volume = false;
601 rctx.VolumeName[0] = 0;
602 rctx.any_drive = false;
603 if (!jcr->PreferMountedVols) {
604 /* Look for unused drives in autochangers */
605 rctx.num_writers = 20000000; /* start with impossible number */
606 rctx.low_use_drive = NULL;
607 rctx.PreferMountedVols = false;
608 rctx.exact_match = false;
609 rctx.autochanger_only = true;
610 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
611 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
612 rctx.autochanger_only, rctx.any_drive);
613 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
616 /* Look through all drives possibly for low_use drive */
617 if (rctx.low_use_drive) {
618 rctx.try_low_use_drive = true;
619 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
622 rctx.try_low_use_drive = false;
624 rctx.autochanger_only = false;
625 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
626 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
627 rctx.autochanger_only, rctx.any_drive);
628 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
632 /* Look for an exact match all drives */
633 rctx.PreferMountedVols = true;
634 rctx.exact_match = true;
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))) {
642 /* Look for any mounted drive */
643 rctx.exact_match = 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))) {
651 rctx.any_drive = true;
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))) {
658 /* Keep reservations locked *except* during wait_for_device() */
659 unlock_reservations();
660 if (!rctx.suitable_device || !wait_for_device(jcr, first)) {
661 Dmsg0(100, "Fail. !suitable_device || !wait_for_device\n");
666 bnet_sig(dir, BNET_HEARTBEAT); /* Inform Dir that we are alive */
668 unlock_reservations();
671 * If we get here, there are no suitable devices available, which
672 * means nothing configured. If a device is suitable but busy
673 * with another Volume, we will not come here.
675 unbash_spaces(dir->msg);
676 pm_strcpy(jcr->errmsg, dir->msg);
677 Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
678 Jmsg(jcr, M_FATAL, 0, _("\n"
679 " Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"),
680 dev_name.c_str(), media_type.c_str());
681 bnet_fsend(dir, NO_device, dev_name.c_str());
683 Dmsg1(100, ">dird: %s", dir->msg);
686 unbash_spaces(dir->msg);
687 pm_strcpy(jcr->errmsg, dir->msg);
688 Jmsg(jcr, M_FATAL, 0, _("Failed command: %s\n"), jcr->errmsg);
689 bnet_fsend(dir, BAD_use, jcr->errmsg);
690 Dmsg1(100, ">dird: %s", dir->msg);
697 void release_msgs(JCR *jcr)
699 alist *msgs = jcr->reserve_msgs;
706 while ((msg = (char *)msgs->pop())) {
710 jcr->reserve_msgs = NULL;
711 unlock_reservations();
715 * Search for a device suitable for this job.
717 bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx)
725 dirstore = jcr->write_store;
727 dirstore = jcr->read_store;
730 * For each storage device that the user specified, we
731 * search and see if there is a resource for that device.
733 Dmsg4(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d\n",
734 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
735 rctx.autochanger_only);
737 foreach_alist(store, dirstore) {
739 foreach_alist(device_name, store->device) {
741 rctx.device_name = device_name;
742 stat = search_res_for_device(rctx);
743 if (stat == 1) { /* found available device */
744 Dmsg1(100, "Suitable device found=%s\n", device_name);
747 } else if (stat == 0) { /* device busy */
748 Dmsg1(110, "Suitable device=%s, busy: not use\n", device_name);
750 /* otherwise error */
751 Dmsg0(110, "No suitable device found.\n");
762 * Search for a particular storage device with particular storage
763 * characteristics (MediaType).
765 int search_res_for_device(RCTX &rctx)
767 AUTOCHANGER *changer;
768 BSOCK *dir = rctx.jcr->dir_bsock;
772 Dmsg1(110, "Search res for %s\n", rctx.device_name);
773 /* Look through Autochangers first */
774 foreach_res(changer, R_AUTOCHANGER) {
775 Dmsg1(150, "Try match changer res=%s\n", changer->hdr.name);
776 /* Find resource, and make sure we were able to open it */
777 if (fnmatch(rctx.device_name, changer->hdr.name, 0) == 0) {
778 /* Try each device in this AutoChanger */
779 foreach_alist(rctx.device, changer->device) {
780 Dmsg1(110, "Try changer device %s\n", rctx.device->hdr.name);
781 stat = reserve_device(rctx);
782 if (stat != 1) { /* try another device */
786 if (rctx.store->append == SD_APPEND) {
787 Dmsg2(100, "Device %s reserved=%d for append.\n", rctx.device->hdr.name,
788 rctx.jcr->dcr->dev->reserved_device);
790 Dmsg2(100, "Device %s reserved=%d for read.\n", rctx.device->hdr.name,
791 rctx.jcr->read_dcr->dev->reserved_device);
793 if (rctx.notify_dir) {
794 pm_strcpy(dev_name, rctx.device->hdr.name);
795 bash_spaces(dev_name);
796 ok = bnet_fsend(dir, OK_device, dev_name.c_str()); /* Return real device name */
797 Dmsg1(100, ">dird changer: %s", dir->msg);
806 /* Now if requested look through regular devices */
807 if (!rctx.autochanger_only) {
808 foreach_res(rctx.device, R_DEVICE) {
809 Dmsg1(150, "Try match res=%s\n", rctx.device->hdr.name);
810 /* Find resource, and make sure we were able to open it */
811 if (fnmatch(rctx.device_name, rctx.device->hdr.name, 0) == 0) {
812 stat = reserve_device(rctx);
816 if (rctx.notify_dir) {
817 bash_spaces(rctx.device_name);
818 ok = bnet_fsend(dir, OK_device, rctx.device_name);
819 Dmsg1(100, ">dird dev: %s", dir->msg);
827 return -1; /* nothing found */
831 * Try to reserve a specific device.
833 * Returns: 1 -- OK, have DCR
837 static int reserve_device(RCTX &rctx)
841 const int name_len = MAX_NAME_LENGTH;
843 /* Make sure MediaType is OK */
844 Dmsg2(110, "MediaType device=%s request=%s\n",
845 rctx.device->media_type, rctx.store->media_type);
846 if (strcmp(rctx.device->media_type, rctx.store->media_type) != 0) {
850 /* Make sure device exists -- i.e. we can stat() it */
851 if (!rctx.device->dev) {
852 rctx.device->dev = init_dev(rctx.jcr, rctx.device);
854 if (!rctx.device->dev) {
855 if (rctx.device->changer_res) {
856 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
857 " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
858 rctx.device->hdr.name, rctx.device_name);
860 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
861 " Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
864 return -1; /* no use waiting */
867 rctx.suitable_device = true;
868 Dmsg2(110, "Try reserve %s JobId=%u\n", rctx.device->hdr.name,
870 dcr = new_dcr(rctx.jcr, rctx.device->dev);
872 BSOCK *dir = rctx.jcr->dir_bsock;
873 bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), rctx.device_name);
874 Dmsg1(100, ">dird: %s", dir->msg);
877 bstrncpy(dcr->pool_name, rctx.store->pool_name, name_len);
878 bstrncpy(dcr->pool_type, rctx.store->pool_type, name_len);
879 bstrncpy(dcr->media_type, rctx.store->media_type, name_len);
880 bstrncpy(dcr->dev_name, rctx.device_name, name_len);
881 if (rctx.store->append == SD_APPEND) {
882 Dmsg2(100, "have_vol=%d vol=%s\n", rctx.have_volume, rctx.VolumeName);
883 if (!rctx.have_volume) {
884 dcr->any_volume = true;
885 if (dir_find_next_appendable_volume(dcr)) {
886 bstrncpy(rctx.VolumeName, dcr->VolumeName, sizeof(rctx.VolumeName));
887 Dmsg2(100, "JobId=%u looking for Volume=%s\n", (int)rctx.jcr->JobId, rctx.VolumeName);
888 rctx.have_volume = true;
890 Dmsg0(100, "No next volume found\n");
891 rctx.have_volume = false;
892 rctx.VolumeName[0] = 0;
895 ok = reserve_device_for_append(dcr, rctx);
898 Dmsg5(100, "Reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
899 dcr->dev->reserved_device,
900 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
903 ok = reserve_device_for_read(dcr);
905 rctx.jcr->read_dcr = dcr;
906 Dmsg5(100, "Read 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);
912 rctx.have_volume = false;
914 Dmsg0(110, "Not OK.\n");
921 * We "reserve" the drive by setting the ST_READ bit. No one else
922 * should touch the drive until that is cleared.
923 * This allows the DIR to "reserve" the device before actually
926 static bool reserve_device_for_read(DCR *dcr)
928 DEVICE *dev = dcr->dev;
934 /* Get locks in correct order */
935 unlock_reservations();
939 if (is_device_unmounted(dev)) {
940 Dmsg1(200, "Device %s is BLOCKED due to user unmount.\n", dev->print_name());
941 Mmsg(jcr->errmsg, _("3601 JobId=%u device %s is BLOCKED due to user unmount.\n"),
942 jcr->JobId, dev->print_name());
943 queue_reserve_message(jcr);
947 if (dev->is_busy()) {
948 Dmsg4(200, "Device %s is busy ST_READ=%d num_writers=%d reserved=%d.\n", dev->print_name(),
949 dev->state & ST_READ?1:0, dev->num_writers, dev->reserved_device);
950 Mmsg(jcr->errmsg, _("3602 JobId=%u device %s is busy (already reading/writing).\n"),
951 jcr->JobId, dev->print_name());
952 queue_reserve_message(jcr);
959 dev->reserved_device++;
960 Dmsg3(100, "Inc reserve=%d dev=%s %p\n", dev->reserved_device,
961 dev->print_name(), dev);
962 dcr->reserved_device = true;
971 * We reserve the device for appending by incrementing the
972 * reserved_device. We do virtually all the same work that
973 * is done in acquire_device_for_append(), but we do
974 * not attempt to mount the device. This routine allows
975 * the DIR to reserve multiple devices before *really*
976 * starting the job. It also permits the SD to refuse
977 * certain devices (not up, ...).
979 * Note, in reserving a device, if the device is for the
980 * same pool and the same pool type, then it is acceptable.
981 * The Media Type has already been checked. If we are
982 * the first tor reserve the device, we put the pool
983 * name and pool type in the device record.
985 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
988 DEVICE *dev = dcr->dev;
993 /* Get locks in correct order */
994 unlock_reservations();
998 /* If device is being read, we cannot write it */
999 if (dev->can_read()) {
1000 Mmsg(jcr->errmsg, _("3603 JobId=%u device %s is busy reading.\n"),
1001 jcr->JobId, dev->print_name());
1002 Dmsg1(110, "%s", jcr->errmsg);
1003 queue_reserve_message(jcr);
1007 /* If device is unmounted, we are out of luck */
1008 if (is_device_unmounted(dev)) {
1009 Mmsg(jcr->errmsg, _("3604 JobId=%u device %s is BLOCKED due to user unmount.\n"),
1010 jcr->JobId, dev->print_name());
1011 Dmsg1(110, "%s", jcr->errmsg);
1012 queue_reserve_message(jcr);
1016 Dmsg1(110, "reserve_append device is %s\n", dev->is_tape()?"tape":"disk");
1018 /* Now do detailed tests ... */
1019 if (can_reserve_drive(dcr, rctx) != 1) {
1020 Dmsg0(110, "can_reserve_drive!=1\n");
1024 dev->reserved_device++;
1025 Dmsg3(100, "Inc reserve=%d dev=%s %p\n", dev->reserved_device,
1026 dev->print_name(), dev);
1027 dcr->reserved_device = true;
1036 * Returns: 1 if drive can be reserved
1037 * 0 if we should wait
1038 * -1 on error or impossibility
1040 static int can_reserve_drive(DCR *dcr, RCTX &rctx)
1042 DEVICE *dev = dcr->dev;
1043 JCR *jcr = dcr->jcr;
1045 Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
1046 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
1047 rctx.autochanger_only, rctx.any_drive);
1049 /* setting any_drive overrides PreferMountedVols flag */
1050 if (!rctx.any_drive) {
1052 * When PreferMountedVols is set, we keep track of the
1053 * drive in use that has the least number of writers, then if
1054 * no unmounted drive is found, we try that drive. This
1055 * helps spread the load to the least used drives.
1057 if (rctx.try_low_use_drive && dev == rctx.low_use_drive) {
1058 Dmsg3(110, "OK dev=%s == low_drive=%s. JobId=%u\n",
1059 dev->print_name(), rctx.low_use_drive->print_name(), jcr->JobId);
1062 /* If he wants a free drive, but this one is busy, no go */
1063 if (!rctx.PreferMountedVols && dev->is_busy()) {
1064 /* Save least used drive */
1065 if ((dev->num_writers + dev->reserved_device) < rctx.num_writers) {
1066 rctx.num_writers = dev->num_writers + dev->reserved_device;
1067 rctx.low_use_drive = dev;
1068 Dmsg2(110, "set low use drive=%s num_writers=%d\n", dev->print_name(),
1071 Dmsg1(110, "not low use num_writers=%d\n", dev->num_writers+
1072 dev->reserved_device);
1074 Dmsg1(110, "failed: !prefMnt && busy. JobId=%u\n", jcr->JobId);
1075 Mmsg(jcr->errmsg, _("3605 JobId=%u wants free drive but device %s is busy.\n"),
1076 jcr->JobId, dev->print_name());
1077 queue_reserve_message(jcr);
1081 /* Check for prefer mounted volumes */
1082 if (rctx.PreferMountedVols && !dev->VolHdr.VolumeName[0] && dev->is_tape()) {
1083 Mmsg(jcr->errmsg, _("3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n"),
1084 jcr->JobId, dev->print_name());
1085 queue_reserve_message(jcr);
1086 Dmsg1(110, "failed: want mounted -- no vol JobId=%u\n", jcr->JobId);
1087 return 0; /* No volume mounted */
1090 /* Check for exact Volume name match */
1091 if (rctx.exact_match && rctx.have_volume &&
1092 strcmp(dev->VolHdr.VolumeName, rctx.VolumeName) != 0) {
1093 Mmsg(jcr->errmsg, _("3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n"),
1094 jcr->JobId, rctx.VolumeName, dev->VolHdr.VolumeName,
1096 queue_reserve_message(jcr);
1097 Dmsg2(110, "failed: Not exact match have=%s want=%s\n",
1098 dev->VolHdr.VolumeName, rctx.VolumeName);
1103 /* Check for unused autochanger drive */
1104 if (rctx.autochanger_only && dev->num_writers == 0 &&
1105 dev->VolHdr.VolumeName[0] == 0) {
1106 /* Device is available but not yet reserved, reserve it for us */
1107 Dmsg2(100, "OK Res Unused autochanger %s JobId=%u.\n",
1108 dev->print_name(), jcr->JobId);
1109 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1110 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1111 return 1; /* reserve drive */
1115 * Handle the case that there are no writers
1117 if (dev->num_writers == 0) {
1118 /* Now check if there are any reservations on the drive */
1119 if (dev->reserved_device) {
1120 /* Now check if we want the same Pool and pool type */
1121 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1122 strcmp(dev->pool_type, dcr->pool_type) == 0) {
1123 /* OK, compatible device */
1124 Dmsg2(100, "OK dev: %s num_writers=0, reserved, pool matches JobId=%u\n",
1125 dev->print_name(), jcr->JobId);
1128 /* Drive Pool not suitable for us */
1129 Mmsg(jcr->errmsg, _(
1130 "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %s.\n"),
1131 jcr->JobId, dcr->pool_name, dev->pool_name,
1132 dev->reserved_device, dev->print_name());
1133 queue_reserve_message(jcr);
1134 Dmsg2(110, "failed: busy num_writers=0, reserved, pool=%s wanted=%s\n",
1135 dev->pool_name, dcr->pool_name);
1136 return 0; /* wait */
1138 } else if (dev->can_append()) {
1139 /* Device in append mode, check if changing pool */
1140 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1141 strcmp(dev->pool_type, dcr->pool_type) == 0) {
1142 Dmsg2(100, "OK dev: %s num_writers=0, can_append, pool matches. JobId=%u\n",
1143 dev->print_name(), jcr->JobId);
1144 /* OK, compatible device */
1147 /* Changing pool, unload old tape if any in drive */
1148 Dmsg0(100, "OK dev: num_writers=0, not reserved, pool change, unload changer\n");
1149 unload_autochanger(dcr, 0);
1152 /* Device is available but not yet reserved, reserve it for us */
1153 Dmsg2(100, "OK Dev avail reserved %s JobId=%u\n", dev->print_name(),
1155 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1156 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1157 return 1; /* reserve drive */
1161 * Check if the device is in append mode with writers (i.e.
1162 * available if pool is the same).
1164 if (dev->can_append() || dev->num_writers > 0) {
1165 /* Yes, now check if we want the same Pool and pool type */
1166 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
1167 strcmp(dev->pool_type, dcr->pool_type) == 0) {
1168 Dmsg2(100, "OK dev: %s num_writers>=0, can_append, pool matches. JobId=%u\n",
1169 dev->print_name(), jcr->JobId);
1170 /* OK, compatible device */
1173 /* Drive Pool not suitable for us */
1174 Mmsg(jcr->errmsg, _("3609 JobId=%u wants Pool=\"%s\" but has Pool=\"%s\" on drive %s.\n"),
1175 jcr->JobId, dcr->pool_name, dev->pool_name, dev->print_name());
1176 queue_reserve_message(jcr);
1177 Dmsg2(110, "failed: busy num_writers>0, can_append, pool=%s wanted=%s\n",
1178 dev->pool_name, dcr->pool_name);
1179 return 0; /* wait */
1182 Pmsg0(000, _("Logic error!!!! Should not get here.\n"));
1183 Mmsg(jcr->errmsg, _("3910 JobId=%u Logic error!!!! drive %s Should not get here.\n"),
1184 jcr->JobId, dev->print_name());
1185 queue_reserve_message(jcr);
1186 Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
1187 return -1; /* error, should not get here */
1189 Mmsg(jcr->errmsg, _("3911 JobId=%u failed reserve drive %s.\n"),
1190 jcr->JobId, dev->print_name());
1191 queue_reserve_message(jcr);
1192 Dmsg2(110, "failed: No reserve %s JobId=%u\n", dev->print_name(), jcr->JobId);
1197 * search_lock is already set on entering this routine
1199 static void queue_reserve_message(JCR *jcr)
1202 alist *msgs = jcr->reserve_msgs;
1209 * Look for duplicate message. If found, do
1212 for (i=msgs->size()-1; i >= 0; i--) {
1213 msg = (char *)msgs->get(i);
1217 /* Comparison based on 4 digit message number */
1218 if (strncmp(msg, jcr->errmsg, 4) == 0) {
1222 /* Message unique, so insert it */
1223 jcr->reserve_msgs->push(bstrdup(jcr->errmsg));
1227 * Send any reservation messages queued for this jcr
1229 void send_drive_reserve_messages(JCR *jcr, void sendit(const char *msg, int len, void *sarg), void *arg)
1235 lock_reservations();
1236 msgs = jcr->reserve_msgs;
1237 if (!msgs || msgs->size() == 0) {
1238 unlock_reservations();
1241 for (i=msgs->size()-1; i >= 0; i--) {
1242 msg = (char *)msgs->get(i);
1244 sendit(" ", 3, arg);
1245 sendit(msg, strlen(msg), arg);
1250 unlock_reservations();