2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2009 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 and included
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 Kern Sibbald.
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 const int dbglvl = 150;
44 static brwlock_t reservation_lock;
46 /* Forward referenced functions */
47 static int can_reserve_drive(DCR *dcr, RCTX &rctx);
48 static int reserve_device(RCTX &rctx);
49 static bool reserve_device_for_read(DCR *dcr);
50 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx);
51 static bool use_storage_cmd(JCR *jcr);
52 static void queue_reserve_message(JCR *jcr);
53 static void pop_reserve_messages(JCR *jcr);
54 //void switch_device(DCR *dcr, DEVICE *dev);
56 /* Requests from the Director daemon */
57 static char use_storage[] = "use storage=%127s media_type=%127s "
58 "pool_name=%127s pool_type=%127s append=%d copy=%d stripe=%d\n";
59 static char use_device[] = "use device=%127s\n";
61 /* Responses sent to Director daemon */
62 static char OK_device[] = "3000 OK use device device=%s\n";
63 static char NO_device[] = "3924 Device \"%s\" not in SD Device resources.\n";
64 static char BAD_use[] = "3913 Bad use command: %s\n";
66 bool use_cmd(JCR *jcr)
69 * Get the device, media, and pool information
71 if (!use_storage_cmd(jcr)) {
72 set_jcr_job_status(jcr, JS_ErrorTerminated);
73 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
80 * This allows a given thread to recursively call lock_reservations.
81 * It must, of course, call unlock_... the same number of times.
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.bstrerror(errstat));
95 void term_reservations_lock()
97 rwl_destroy(&reservation_lock);
101 int reservations_lock_count = 0;
103 /* This applies to a drive and to Volumes */
104 void _lock_reservations(const char *file, int line)
107 reservations_lock_count++;
108 if ((errstat=rwl_writelock_p(&reservation_lock, file, line)) != 0) {
110 Emsg2(M_ABORT, 0, "rwl_writelock failure. stat=%d: ERR=%s\n",
111 errstat, be.bstrerror(errstat));
115 void _unlock_reservations()
118 reservations_lock_count--;
119 if ((errstat=rwl_writeunlock(&reservation_lock)) != 0) {
121 Emsg2(M_ABORT, 0, "rwl_writeunlock failure. stat=%d: ERR=%s\n",
122 errstat, be.bstrerror(errstat));
126 void DCR::set_reserved()
129 Dmsg2(dbglvl, "Inc reserve=%d dev=%s\n", dev->num_reserved(), dev->print_name());
133 void DCR::clear_reserved()
138 Dmsg2(dbglvl, "Dec reserve=%d dev=%s\n", dev->num_reserved(), dev->print_name());
143 * Remove any reservation from a drive and tell the system
144 * that the volume is unused at least by us.
146 void DCR::unreserve_device()
152 reserved_volume = false;
153 /* If we set read mode in reserving, remove it */
154 if (dev->can_read()) {
157 if (dev->num_writers < 0) {
158 Jmsg1(jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers);
159 dev->num_writers = 0;
161 if (dev->num_reserved() == 0 && dev->num_writers == 0) {
170 * We get the following type of information:
172 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=1 copy=0 strip=0
176 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=0 copy=0 strip=0
180 static bool use_storage_cmd(JCR *jcr)
182 POOL_MEM store_name, dev_name, media_type, pool_name, pool_type;
183 BSOCK *dir = jcr->dir_bsock;
191 memset(&rctx, 0, sizeof(RCTX));
194 * If there are multiple devices, the director sends us
195 * use_device for each device that it wants to use.
197 dirstore = New(alist(10, not_owned_by_alist));
198 jcr->reserve_msgs = New(alist(10, not_owned_by_alist));
200 Dmsg1(dbglvl, "<dird: %s", dir->msg);
201 ok = sscanf(dir->msg, use_storage, store_name.c_str(),
202 media_type.c_str(), pool_name.c_str(),
203 pool_type.c_str(), &append, &Copy, &Stripe) == 7;
208 jcr->write_store = dirstore;
210 jcr->read_store = dirstore;
212 rctx.append = append;
213 unbash_spaces(store_name);
214 unbash_spaces(media_type);
215 unbash_spaces(pool_name);
216 unbash_spaces(pool_type);
217 store = new DIRSTORE;
218 dirstore->append(store);
219 memset(store, 0, sizeof(DIRSTORE));
220 store->device = New(alist(10));
221 bstrncpy(store->name, store_name, sizeof(store->name));
222 bstrncpy(store->media_type, media_type, sizeof(store->media_type));
223 bstrncpy(store->pool_name, pool_name, sizeof(store->pool_name));
224 bstrncpy(store->pool_type, pool_type, sizeof(store->pool_type));
225 store->append = append;
227 /* Now get all devices */
228 while (dir->recv() >= 0) {
229 Dmsg1(dbglvl, "<dird device: %s", dir->msg);
230 ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
234 unbash_spaces(dev_name);
235 store->device->append(bstrdup(dev_name.c_str()));
237 } while (ok && dir->recv() >= 0);
239 /* Developer debug code */
241 if (debug_level >= dbglvl) {
242 foreach_alist(store, dirstore) {
243 Dmsg5(dbglvl, "Storage=%s media_type=%s pool=%s pool_type=%s append=%d\n",
244 store->name, store->media_type, store->pool_name,
245 store->pool_type, store->append);
246 foreach_alist(device_name, store->device) {
247 Dmsg1(dbglvl, " Device=%s\n", device_name);
252 init_jcr_device_wait_timers(jcr);
253 jcr->dcr = new_dcr(jcr, NULL, NULL); /* get a dcr */
255 BSOCK *dir = jcr->dir_bsock;
256 dir->fsend(_("3939 Could not get dcr\n"));
257 Dmsg1(dbglvl, ">dird: %s", dir->msg);
261 * At this point, we have a list of all the Director's Storage
262 * resources indicated for this Job, which include Pool, PoolType,
263 * storage name, and Media type.
264 * Then for each of the Storage resources, we have a list of
265 * device names that were given.
267 * Wiffle through them and find one that can do the backup.
270 int wait_for_device_retries = 0;
273 rctx.notify_dir = true;
276 for ( ; !fail && !job_canceled(jcr); ) {
277 pop_reserve_messages(jcr);
278 rctx.suitable_device = false;
279 rctx.have_volume = false;
280 rctx.VolumeName[0] = 0;
281 rctx.any_drive = false;
282 if (!jcr->PreferMountedVols) {
284 * Here we try to find a drive that is not used.
285 * This will maximize the use of available drives.
288 rctx.num_writers = 20000000; /* start with impossible number */
289 rctx.low_use_drive = NULL;
290 rctx.PreferMountedVols = false;
291 rctx.exact_match = false;
292 rctx.autochanger_only = true;
293 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
296 /* Look through all drives possibly for low_use drive */
297 if (rctx.low_use_drive) {
298 rctx.try_low_use_drive = true;
299 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
302 rctx.try_low_use_drive = false;
304 rctx.autochanger_only = false;
305 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
310 * Now we look for a drive that may or may not be in
313 /* Look for an exact Volume match all drives */
314 rctx.PreferMountedVols = true;
315 rctx.exact_match = true;
316 rctx.autochanger_only = false;
317 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
320 /* Look for any mounted drive */
321 rctx.exact_match = false;
322 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
326 rctx.any_drive = true;
327 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
330 /* Keep reservations locked *except* during wait_for_device() */
331 unlock_reservations();
333 * The idea of looping on repeat a few times it to ensure
334 * that if there is some subtle timing problem between two
335 * jobs, we will simply try again, and most likely succeed.
336 * This can happen if one job reserves a drive or finishes using
337 * a drive at the same time a second job wants it.
339 if (repeat++ > 1) { /* try algorithm 3 times */
340 bmicrosleep(30, 0); /* wait a bit */
341 Dmsg0(dbglvl, "repeat reserve algorithm\n");
342 } else if (!rctx.suitable_device || !wait_for_device(jcr, wait_for_device_retries)) {
343 Dmsg0(dbglvl, "Fail. !suitable_device || !wait_for_device\n");
347 dir->signal(BNET_HEARTBEAT); /* Inform Dir that we are alive */
349 unlock_reservations();
352 * If we get here, there are no suitable devices available, which
353 * means nothing configured. If a device is suitable but busy
354 * with another Volume, we will not come here.
356 unbash_spaces(dir->msg);
357 pm_strcpy(jcr->errmsg, dir->msg);
358 Jmsg(jcr, M_FATAL, 0, _("Device reservation failed for JobId=%d: %s\n"),
359 jcr->JobId, jcr->errmsg);
360 dir->fsend(NO_device, dev_name.c_str());
362 Dmsg1(dbglvl, ">dird: %s", dir->msg);
365 unbash_spaces(dir->msg);
366 pm_strcpy(jcr->errmsg, dir->msg);
367 Jmsg(jcr, M_FATAL, 0, _("Failed command: %s\n"), jcr->errmsg);
368 dir->fsend(BAD_use, jcr->errmsg);
369 Dmsg1(dbglvl, ">dird: %s", dir->msg);
372 release_reserve_messages(jcr);
378 * Walk through the autochanger resources and check if
379 * the volume is in one of them.
381 * Returns: true if volume is in device
384 static bool is_vol_in_autochanger(RCTX &rctx, VOLRES *vol)
386 AUTOCHANGER *changer = vol->dev->device->changer_res;
388 /* Find resource, and make sure we were able to open it */
389 if (strcmp(rctx.device_name, changer->hdr.name) == 0) {
390 Dmsg1(dbglvl, "Found changer device %s\n", vol->dev->device->hdr.name);
393 Dmsg1(dbglvl, "Incorrect changer device %s\n", changer->hdr.name);
398 * Search for a device suitable for this job.
399 * Note, this routine sets sets rctx.suitable_device if any
400 * device exists within the SD. The device may not be actually
402 * It also returns if it finds a useable device.
404 bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx)
413 dirstore = jcr->write_store;
415 dirstore = jcr->read_store;
417 Dmsg5(dbglvl, "Start find_suit_dev PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
418 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
419 rctx.autochanger_only, rctx.any_drive);
422 * If the appropriate conditions of this if are met, namely that
423 * we are appending and the user wants mounted drive (or we
424 * force try a mounted drive because they are all busy), we
425 * start by looking at all the Volumes in the volume list.
427 if (!is_vol_list_empty() && rctx.append && rctx.PreferMountedVols) {
428 dlist *temp_vol_list;
430 temp_vol_list = dup_vol_list(jcr);
432 /* Look through reserved volumes for one we can use */
433 Dmsg0(dbglvl, "look for vol in vol list\n");
434 foreach_dlist(vol, temp_vol_list) {
436 Dmsg1(dbglvl, "vol=%s no dev\n", vol->vol_name);
439 /* Check with Director if this Volume is OK */
440 bstrncpy(dcr->VolumeName, vol->vol_name, sizeof(dcr->VolumeName));
441 if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE)) {
445 Dmsg1(dbglvl, "vol=%s OK for this job\n", vol->vol_name);
446 foreach_alist(store, dirstore) {
449 foreach_alist(device_name, store->device) {
450 /* Found a device, try to use it */
451 rctx.device_name = device_name;
452 rctx.device = vol->dev->device;
454 if (vol->dev->is_autochanger()) {
455 Dmsg1(dbglvl, "vol=%s is in changer\n", vol->vol_name);
456 if (!is_vol_in_autochanger(rctx, vol)) {
459 } else if (strcmp(device_name, vol->dev->device->hdr.name) != 0) {
460 Dmsg2(dbglvl, "device=%s not suitable want %s\n",
461 vol->dev->device->hdr.name, device_name);
465 bstrncpy(rctx.VolumeName, vol->vol_name, sizeof(rctx.VolumeName));
466 rctx.have_volume = true;
467 /* Try reserving this device and volume */
468 Dmsg2(dbglvl, "try vol=%s on device=%s\n", rctx.VolumeName, device_name);
469 stat = reserve_device(rctx);
470 if (stat == 1) { /* found available device */
471 Dmsg1(dbglvl, "Suitable device found=%s\n", device_name);
474 } else if (stat == 0) { /* device busy */
475 Dmsg1(dbglvl, "Suitable device=%s, busy: not use\n", device_name);
477 /* otherwise error */
478 Dmsg0(dbglvl, "No suitable device found.\n");
480 rctx.have_volume = false;
481 rctx.VolumeName[0] = 0;
490 } /* end for loop over reserved volumes */
492 Dmsg0(dbglvl, "lock volumes\n");
493 free_temp_vol_list(temp_vol_list);
496 Dmsg1(dbglvl, "OK dev found. Vol=%s from in-use vols list\n", rctx.VolumeName);
501 * No reserved volume we can use, so now search for an available device.
503 * For each storage device that the user specified, we
504 * search and see if there is a resource for that device.
506 foreach_alist(store, dirstore) {
508 foreach_alist(device_name, store->device) {
510 rctx.device_name = device_name;
511 stat = search_res_for_device(rctx);
512 if (stat == 1) { /* found available device */
513 Dmsg1(dbglvl, "available device found=%s\n", device_name);
516 } else if (stat == 0) { /* device busy */
517 Dmsg1(dbglvl, "No usable device=%s, busy: not use\n", device_name);
519 /* otherwise error */
520 Dmsg0(dbglvl, "No usable device found.\n");
528 Dmsg1(dbglvl, "OK dev found. Vol=%s\n", rctx.VolumeName);
530 Dmsg0(dbglvl, "Leave find_suit_dev: no dev found.\n");
536 * Search for a particular storage device with particular storage
537 * characteristics (MediaType).
539 int search_res_for_device(RCTX &rctx)
541 AUTOCHANGER *changer;
544 Dmsg1(dbglvl, "search res for %s\n", rctx.device_name);
545 /* Look through Autochangers first */
546 foreach_res(changer, R_AUTOCHANGER) {
547 Dmsg1(dbglvl, "Try match changer res=%s\n", changer->hdr.name);
548 /* Find resource, and make sure we were able to open it */
549 if (strcmp(rctx.device_name, changer->hdr.name) == 0) {
550 /* Try each device in this AutoChanger */
551 foreach_alist(rctx.device, changer->device) {
552 Dmsg1(dbglvl, "Try changer device %s\n", rctx.device->hdr.name);
553 if (!rctx.device->autoselect) {
554 Dmsg1(100, "Device %s not autoselect skipped.\n",
555 rctx.device->hdr.name);
556 continue; /* device is not available */
558 stat = reserve_device(rctx);
559 if (stat != 1) { /* try another device */
563 if (rctx.store->append == SD_APPEND) {
564 Dmsg2(dbglvl, "Device %s reserved=%d for append.\n",
565 rctx.device->hdr.name, rctx.jcr->dcr->dev->num_reserved());
567 Dmsg2(dbglvl, "Device %s reserved=%d for read.\n",
568 rctx.device->hdr.name, rctx.jcr->read_dcr->dev->num_reserved());
575 /* Now if requested look through regular devices */
576 if (!rctx.autochanger_only) {
577 foreach_res(rctx.device, R_DEVICE) {
578 Dmsg1(dbglvl, "Try match res=%s\n", rctx.device->hdr.name);
579 /* Find resource, and make sure we were able to open it */
580 if (strcmp(rctx.device_name, rctx.device->hdr.name) == 0) {
581 stat = reserve_device(rctx);
582 if (stat != 1) { /* try another device */
586 if (rctx.store->append == SD_APPEND) {
587 Dmsg2(dbglvl, "Device %s reserved=%d for append.\n",
588 rctx.device->hdr.name, rctx.jcr->dcr->dev->num_reserved());
590 Dmsg2(dbglvl, "Device %s reserved=%d for read.\n",
591 rctx.device->hdr.name, rctx.jcr->read_dcr->dev->num_reserved());
597 return -1; /* nothing found */
601 * Try to reserve a specific device.
603 * Returns: 1 -- OK, have DCR
607 static int reserve_device(RCTX &rctx)
611 const int name_len = MAX_NAME_LENGTH;
613 /* Make sure MediaType is OK */
614 Dmsg2(dbglvl, "chk MediaType device=%s request=%s\n",
615 rctx.device->media_type, rctx.store->media_type);
616 if (strcmp(rctx.device->media_type, rctx.store->media_type) != 0) {
620 /* Make sure device exists -- i.e. we can stat() it */
621 if (!rctx.device->dev) {
622 rctx.device->dev = init_dev(rctx.jcr, rctx.device);
624 if (!rctx.device->dev) {
625 if (rctx.device->changer_res) {
626 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
627 " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
628 rctx.device->hdr.name, rctx.device_name);
630 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
631 " Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
634 return -1; /* no use waiting */
637 rctx.suitable_device = true;
638 Dmsg1(dbglvl, "try reserve %s\n", rctx.device->hdr.name);
639 if (rctx.store->append) {
640 dcr = new_dcr(rctx.jcr, rctx.jcr->dcr, rctx.device->dev);
642 dcr = new_dcr(rctx.jcr, rctx.jcr->read_dcr, rctx.device->dev);
645 BSOCK *dir = rctx.jcr->dir_bsock;
646 dir->fsend(_("3926 Could not get dcr for device: %s\n"), rctx.device_name);
647 Dmsg1(dbglvl, ">dird: %s", dir->msg);
650 bstrncpy(dcr->pool_name, rctx.store->pool_name, name_len);
651 bstrncpy(dcr->pool_type, rctx.store->pool_type, name_len);
652 bstrncpy(dcr->media_type, rctx.store->media_type, name_len);
653 bstrncpy(dcr->dev_name, rctx.device_name, name_len);
654 if (rctx.store->append == SD_APPEND) {
655 Dmsg2(dbglvl, "call reserve for append: have_vol=%d vol=%s\n", rctx.have_volume, rctx.VolumeName);
656 ok = reserve_device_for_append(dcr, rctx);
662 Dmsg5(dbglvl, "Reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
663 dcr->dev->num_reserved(),
664 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
665 Dmsg3(dbglvl, "Vol=%s num_writers=%d, have_vol=%d\n",
666 rctx.VolumeName, dcr->dev->num_writers, rctx.have_volume);
667 if (rctx.have_volume) {
668 Dmsg0(dbglvl, "Call reserve_volume\n");
669 if (reserve_volume(dcr, rctx.VolumeName)) {
670 Dmsg1(dbglvl, "Reserved vol=%s\n", rctx.VolumeName);
672 Dmsg1(dbglvl, "Could not reserve vol=%s\n", rctx.VolumeName);
676 dcr->any_volume = true;
677 Dmsg0(dbglvl, "no vol, call find_next_appendable_vol.\n");
678 if (dir_find_next_appendable_volume(dcr)) {
679 bstrncpy(rctx.VolumeName, dcr->VolumeName, sizeof(rctx.VolumeName));
680 rctx.have_volume = true;
681 Dmsg1(dbglvl, "looking for Volume=%s\n", rctx.VolumeName);
683 Dmsg0(dbglvl, "No next volume found\n");
684 rctx.have_volume = false;
685 rctx.VolumeName[0] = 0;
687 * If there is at least one volume that is valid and in use,
688 * but we get here, check if we are running with prefers
689 * non-mounted drives. In that case, we have selected a
690 * non-used drive and our one and only volume is mounted
691 * elsewhere, so we bail out and retry using that drive.
693 if (dcr->found_in_use() && !rctx.PreferMountedVols) {
694 rctx.PreferMountedVols = true;
695 if (dcr->VolumeName[0]) {
696 dcr->unreserve_device();
701 * Note. Under some circumstances, the Director can hand us
702 * a Volume name that is not the same as the one on the current
703 * drive, and in that case, the call above to find the next
704 * volume will fail because in attempting to reserve the Volume
705 * the code will realize that we already have a tape mounted,
706 * and it will fail. This *should* only happen if there are
707 * writers, thus the following test. In that case, we simply
708 * bail out, and continue waiting, rather than plunging on
709 * and hoping that the operator can resolve the problem.
711 if (dcr->dev->num_writers != 0) {
712 if (dcr->VolumeName[0]) {
713 dcr->unreserve_device();
720 ok = reserve_device_for_read(dcr);
722 rctx.jcr->read_dcr = dcr;
723 Dmsg5(dbglvl, "Read reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
724 dcr->dev->num_reserved(),
725 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
732 if (rctx.notify_dir) {
734 BSOCK *dir = rctx.jcr->dir_bsock;
735 pm_strcpy(dev_name, rctx.device->hdr.name);
736 bash_spaces(dev_name);
737 ok = dir->fsend(OK_device, dev_name.c_str()); /* Return real device name */
738 Dmsg1(dbglvl, ">dird: %s", dir->msg);
745 rctx.have_volume = false;
746 rctx.VolumeName[0] = 0;
747 Dmsg0(dbglvl, "Not OK.\n");
752 * We "reserve" the drive by setting the ST_READ bit. No one else
753 * should touch the drive until that is cleared.
754 * This allows the DIR to "reserve" the device before actually
757 static bool reserve_device_for_read(DCR *dcr)
759 DEVICE *dev = dcr->dev;
764 if (job_canceled(jcr)) {
770 if (dev->is_device_unmounted()) {
771 Dmsg1(dbglvl, "Device %s is BLOCKED due to user unmount.\n", dev->print_name());
772 Mmsg(jcr->errmsg, _("3601 JobId=%u device %s is BLOCKED due to user unmount.\n"),
773 jcr->JobId, dev->print_name());
774 queue_reserve_message(jcr);
778 if (dev->is_busy()) {
779 Dmsg4(dbglvl, "Device %s is busy ST_READ=%d num_writers=%d reserved=%d.\n",
781 dev->state & ST_READ?1:0, dev->num_writers, dev->num_reserved());
782 Mmsg(jcr->errmsg, _("3602 JobId=%u device %s is busy (already reading/writing).\n"),
783 jcr->JobId, dev->print_name());
784 queue_reserve_message(jcr);
800 * We reserve the device for appending by incrementing
801 * num_reserved(). We do virtually all the same work that
802 * is done in acquire_device_for_append(), but we do
803 * not attempt to mount the device. This routine allows
804 * the DIR to reserve multiple devices before *really*
805 * starting the job. It also permits the SD to refuse
806 * certain devices (not up, ...).
808 * Note, in reserving a device, if the device is for the
809 * same pool and the same pool type, then it is acceptable.
810 * The Media Type has already been checked. If we are
811 * the first tor reserve the device, we put the pool
812 * name and pool type in the device record.
814 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
817 DEVICE *dev = dcr->dev;
821 if (job_canceled(jcr)) {
827 /* If device is being read, we cannot write it */
828 if (dev->can_read()) {
829 Mmsg(jcr->errmsg, _("3603 JobId=%u device %s is busy reading.\n"),
830 jcr->JobId, dev->print_name());
831 Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
832 queue_reserve_message(jcr);
836 /* If device is unmounted, we are out of luck */
837 if (dev->is_device_unmounted()) {
838 Mmsg(jcr->errmsg, _("3604 JobId=%u device %s is BLOCKED due to user unmount.\n"),
839 jcr->JobId, dev->print_name());
840 Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
841 queue_reserve_message(jcr);
845 Dmsg1(dbglvl, "reserve_append device is %s\n", dev->print_name());
847 /* Now do detailed tests ... */
848 if (can_reserve_drive(dcr, rctx) != 1) {
849 Dmsg0(dbglvl, "can_reserve_drive!=1\n");
861 static int is_pool_ok(DCR *dcr)
863 DEVICE *dev = dcr->dev;
866 /* Now check if we want the same Pool and pool type */
867 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
868 strcmp(dev->pool_type, dcr->pool_type) == 0) {
869 /* OK, compatible device */
870 Dmsg1(dbglvl, "OK dev: %s num_writers=0, reserved, pool matches\n", dev->print_name());
873 /* Drive Pool not suitable for us */
875 "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %s.\n"),
876 (uint32_t)jcr->JobId, dcr->pool_name, dev->pool_name,
877 dev->num_reserved(), dev->print_name());
878 Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
879 queue_reserve_message(jcr);
884 static bool is_max_jobs_ok(DCR *dcr)
886 DEVICE *dev = dcr->dev;
889 Dmsg5(dbglvl, "MaxJobs=%d Jobs=%d reserves=%d Status=%s Vol=%s\n",
890 dcr->VolCatInfo.VolCatMaxJobs,
891 dcr->VolCatInfo.VolCatJobs, dev->num_reserved(),
892 dcr->VolCatInfo.VolCatStatus,
894 /* Limit max concurrent jobs on this drive */
895 if (dev->max_concurrent_jobs > 0 && dev->max_concurrent_jobs <=
896 (uint32_t)(dev->num_writers + dev->num_reserved())) {
897 /* Max Concurrent Jobs depassed or already reserved */
898 Mmsg(jcr->errmsg, _("3609 JobId=%u Max concurrent jobs exceeded on drive %s.\n"),
899 (uint32_t)jcr->JobId, dev->print_name());
900 Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
901 queue_reserve_message(jcr);
904 if (strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0) {
907 if (dcr->VolCatInfo.VolCatMaxJobs > 0 && dcr->VolCatInfo.VolCatMaxJobs <=
908 (dcr->VolCatInfo.VolCatJobs + dev->num_reserved())) {
909 /* Max Job Vols depassed or already reserved */
910 Mmsg(jcr->errmsg, _("3610 JobId=%u Volume max jobs exceeded on drive %s.\n"),
911 (uint32_t)jcr->JobId, dev->print_name());
912 Dmsg1(dbglvl, "reserve dev failed: %s", jcr->errmsg);
913 queue_reserve_message(jcr);
914 return false; /* wait */
920 * Returns: 1 if drive can be reserved
921 * 0 if we should wait
922 * -1 on error or impossibility
924 static int can_reserve_drive(DCR *dcr, RCTX &rctx)
926 DEVICE *dev = dcr->dev;
929 Dmsg5(dbglvl, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
930 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
931 rctx.autochanger_only, rctx.any_drive);
933 /* Check for max jobs on this Volume */
934 if (!is_max_jobs_ok(dcr)) {
938 /* setting any_drive overrides PreferMountedVols flag */
939 if (!rctx.any_drive) {
941 * When PreferMountedVols is set, we keep track of the
942 * drive in use that has the least number of writers, then if
943 * no unmounted drive is found, we try that drive. This
944 * helps spread the load to the least used drives.
946 if (rctx.try_low_use_drive && dev == rctx.low_use_drive) {
947 Dmsg2(dbglvl, "OK dev=%s == low_drive=%s.\n",
948 dev->print_name(), rctx.low_use_drive->print_name());
951 /* If he wants a free drive, but this one is busy, no go */
952 if (!rctx.PreferMountedVols && dev->is_busy()) {
953 /* Save least used drive */
954 if ((dev->num_writers + dev->num_reserved()) < rctx.num_writers) {
955 rctx.num_writers = dev->num_writers + dev->num_reserved();
956 rctx.low_use_drive = dev;
957 Dmsg2(dbglvl, "set low use drive=%s num_writers=%d\n",
958 dev->print_name(), rctx.num_writers);
960 Dmsg1(dbglvl, "not low use num_writers=%d\n", dev->num_writers+dev->num_reserved());
962 Mmsg(jcr->errmsg, _("3605 JobId=%u wants free drive but device %s is busy.\n"),
963 jcr->JobId, dev->print_name());
964 Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
965 queue_reserve_message(jcr);
969 /* Check for prefer mounted volumes */
970 if (rctx.PreferMountedVols && !dev->vol && dev->is_tape()) {
971 Mmsg(jcr->errmsg, _("3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n"),
972 jcr->JobId, dev->print_name());
973 Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
974 queue_reserve_message(jcr);
975 return 0; /* No volume mounted */
978 /* Check for exact Volume name match */
979 /* ***FIXME*** for Disk, we can accept any volume that goes with this
982 if (rctx.exact_match && rctx.have_volume) {
984 Dmsg5(dbglvl, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
985 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
986 rctx.autochanger_only, rctx.any_drive);
987 Dmsg4(dbglvl, "have_vol=%d have=%s resvol=%s want=%s\n",
988 rctx.have_volume, dev->VolHdr.VolumeName,
989 dev->vol?dev->vol->vol_name:"*none*", rctx.VolumeName);
990 ok = strcmp(dev->VolHdr.VolumeName, rctx.VolumeName) == 0 ||
991 (dev->vol && strcmp(dev->vol->vol_name, rctx.VolumeName) == 0);
993 Mmsg(jcr->errmsg, _("3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n"),
994 jcr->JobId, rctx.VolumeName, dev->VolHdr.VolumeName,
996 queue_reserve_message(jcr);
997 Dmsg3(dbglvl, "not OK: dev have=%s resvol=%s want=%s\n",
998 dev->VolHdr.VolumeName, dev->vol?dev->vol->vol_name:"*none*", rctx.VolumeName);
1001 if (!dcr->can_i_use_volume()) {
1002 return 0; /* fail if volume on another drive */
1007 /* Check for unused autochanger drive */
1008 if (rctx.autochanger_only && !dev->is_busy() &&
1009 dev->VolHdr.VolumeName[0] == 0) {
1010 /* Device is available but not yet reserved, reserve it for us */
1011 Dmsg1(dbglvl, "OK Res Unused autochanger %s.\n", dev->print_name());
1012 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1013 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1014 return 1; /* reserve drive */
1018 * Handle the case that there are no writers
1020 if (dev->num_writers == 0) {
1021 /* Now check if there are any reservations on the drive */
1022 if (dev->num_reserved()) {
1023 return is_pool_ok(dcr);
1024 } else if (dev->can_append()) {
1025 if (is_pool_ok(dcr)) {
1028 /* Changing pool, unload old tape if any in drive */
1029 Dmsg0(dbglvl, "OK dev: num_writers=0, not reserved, pool change, unload changer\n");
1030 /* ***FIXME*** use set_unload() */
1031 unload_autochanger(dcr, -1);
1034 /* Device is available but not yet reserved, reserve it for us */
1035 Dmsg1(dbglvl, "OK Dev avail reserved %s\n", dev->print_name());
1036 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1037 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1038 return 1; /* reserve drive */
1042 * Check if the device is in append mode with writers (i.e.
1043 * available if pool is the same).
1045 if (dev->can_append() || dev->num_writers > 0) {
1046 return is_pool_ok(dcr);
1048 Pmsg1(000, _("Logic error!!!! JobId=%u Should not get here.\n"), (int)jcr->JobId);
1049 Mmsg(jcr->errmsg, _("3910 JobId=%u Logic error!!!! drive %s Should not get here.\n"),
1050 jcr->JobId, dev->print_name());
1051 queue_reserve_message(jcr);
1052 Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
1053 return -1; /* error, should not get here */
1055 Mmsg(jcr->errmsg, _("3911 JobId=%u failed reserve drive %s.\n"),
1056 jcr->JobId, dev->print_name());
1057 queue_reserve_message(jcr);
1058 Dmsg1(dbglvl, "Failed: No reserve %s\n", dev->print_name());
1066 * Queue a reservation error or failure message for this jcr
1068 static void queue_reserve_message(JCR *jcr)
1076 msgs = jcr->reserve_msgs;
1081 * Look for duplicate message. If found, do
1084 for (i=msgs->size()-1; i >= 0; i--) {
1085 msg = (char *)msgs->get(i);
1089 /* Comparison based on 4 digit message number */
1090 if (strncmp(msg, jcr->errmsg, 4) == 0) {
1094 /* Message unique, so insert it */
1095 jcr->reserve_msgs->push(bstrdup(jcr->errmsg));
1102 * Send any reservation messages queued for this jcr
1104 void send_drive_reserve_messages(JCR *jcr, void sendit(const char *msg, int len, void *sarg), void *arg)
1111 msgs = jcr->reserve_msgs;
1112 if (!msgs || msgs->size() == 0) {
1115 for (i=msgs->size()-1; i >= 0; i--) {
1116 msg = (char *)msgs->get(i);
1118 sendit(" ", 3, arg);
1119 sendit(msg, strlen(msg), arg);
1130 * Pop and release any reservations messages
1132 static void pop_reserve_messages(JCR *jcr)
1138 msgs = jcr->reserve_msgs;
1142 while ((msg = (char *)msgs->pop())) {
1150 * Also called from acquire.c
1152 void release_reserve_messages(JCR *jcr)
1154 pop_reserve_messages(jcr);
1156 if (!jcr->reserve_msgs) {
1159 delete jcr->reserve_msgs;
1160 jcr->reserve_msgs = NULL;