2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2015 Kern Sibbald
5 Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
7 The original author of Bacula is Kern Sibbald, with contributions
8 from many others, a complete list can be found in the file AUTHORS.
10 You may use this file and others of this release according to the
11 license defined in the LICENSE file, which includes the Affero General
12 Public License, v3.0 ("AGPLv3") and some additional permissions and
13 terms pursuant to its AGPLv3 Section 7.
15 This notice must be preserved when any source code is
16 conveyed and/or propagated.
18 Bacula(R) is a registered trademark of Kern Sibbald.
21 * Drive reservation functions for Storage Daemon
23 * Written by Kern Sibbald, MM
25 * Split from job.c and acquire.c June 2005
32 const int dbglvl = 150;
34 static brwlock_t reservation_lock;
35 int reservations_lock_count = 0;
37 /* Forward referenced functions */
38 static int can_reserve_drive(DCR *dcr, RCTX &rctx);
39 static bool is_vol_in_autochanger(RCTX &rctx, VOLRES *vol);
40 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx);
41 static bool reserve_device_for_read(DCR *dcr);
42 static bool use_device_cmd(JCR *jcr);
43 static int reserve_device(RCTX &rctx);
44 static void pop_reserve_messages(JCR *jcr);
45 static void queue_reserve_message(JCR *jcr);
46 //void switch_device(DCR *dcr, DEVICE *dev);
48 /* Requests from the Director daemon */
49 static char use_storage[] = "use storage=%127s media_type=%127s "
50 "pool_name=%127s pool_type=%127s append=%d copy=%d stripe=%d\n";
51 static char use_device[] = "use device=%127s\n";
53 /* Responses sent to Director daemon */
54 static char OK_device[] = "3000 OK use device device=%s\n";
55 static char NO_device[] = "3924 Device \"%s\" not in SD Device"
56 " resources or no matching Media Type.\n";
57 static char BAD_use[] = "3913 Bad use command: %s\n";
60 * This allows a given thread to recursively call lock_reservations.
61 * It must, of course, call unlock_... the same number of times.
63 void init_reservations_lock()
66 if ((errstat=rwl_init(&reservation_lock)) != 0) {
68 Emsg1(M_ABORT, 0, _("Unable to initialize reservation lock. ERR=%s\n"),
69 be.bstrerror(errstat));
76 /* This applies to a drive and to Volumes */
77 void _lock_reservations(const char *file, int line)
80 reservations_lock_count++;
81 if ((errstat=rwl_writelock_p(&reservation_lock, file, line)) != 0) {
83 Emsg2(M_ABORT, 0, "rwl_writelock failure. stat=%d: ERR=%s\n",
84 errstat, be.bstrerror(errstat));
88 void _unlock_reservations()
91 reservations_lock_count--;
92 if ((errstat=rwl_writeunlock(&reservation_lock)) != 0) {
94 Emsg2(M_ABORT, 0, "rwl_writeunlock failure. stat=%d: ERR=%s\n",
95 errstat, be.bstrerror(errstat));
99 void term_reservations_lock()
101 rwl_destroy(&reservation_lock);
102 term_vol_list_lock();
105 void DCR::clear_reserved()
110 Dmsg2(dbglvl, "Dec reserve=%d dev=%s\n", dev->num_reserved(), dev->print_name());
114 void DCR::set_reserved_for_append()
117 dev->set_append_reserve();
118 Dmsg2(dbglvl, "Inc reserve=%d dev=%s\n", dev->num_reserved(), dev->print_name());
122 void DCR::set_reserved_for_read()
125 dev->set_read_reserve();
126 Dmsg2(dbglvl, "Inc reserve=%d dev=%s\n", dev->num_reserved(), dev->print_name());
131 * Remove any reservation from a drive and tell the system
132 * that the volume is unused at least by us.
134 void DCR::unreserve_device(bool locked)
141 reserved_volume = false;
142 /* If we set read mode in reserving, remove it */
143 if (dev->can_read()) {
144 remove_read_volume(jcr, this->VolumeName);
147 if (dev->num_writers < 0) {
148 Jmsg1(jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers);
149 dev->num_writers = 0;
151 if (dev->num_reserved() == 0 && dev->num_writers == 0) {
152 generate_plugin_event(jcr, bsdEventDeviceClose, this);
161 bool use_cmd(JCR *jcr)
164 * Get the device, media, and pool information
166 if (!use_device_cmd(jcr)) {
167 jcr->setJobStatus(JS_ErrorTerminated);
168 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
175 * We get the following type of information:
177 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=1 copy=0 strip=0
181 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=0 copy=0 strip=0
185 static bool use_device_cmd(JCR *jcr)
187 POOL_MEM store_name, dev_name, media_type, pool_name, pool_type;
188 BSOCK *dir = jcr->dir_bsock;
191 int32_t Copy, Stripe;
196 memset(&rctx, 0, sizeof(RCTX));
199 * If there are multiple devices, the director sends us
200 * use_device for each device that it wants to use.
202 dirstore = New(alist(10, not_owned_by_alist));
203 jcr->reserve_msgs = New(alist(10, not_owned_by_alist));
205 Dmsg1(dbglvl, "<dird: %s", dir->msg);
206 ok = sscanf(dir->msg, use_storage, store_name.c_str(),
207 media_type.c_str(), pool_name.c_str(),
208 pool_type.c_str(), &append, &Copy, &Stripe) == 7;
213 jcr->write_store = dirstore;
215 jcr->read_store = dirstore;
217 rctx.append = append;
218 unbash_spaces(store_name);
219 unbash_spaces(media_type);
220 unbash_spaces(pool_name);
221 unbash_spaces(pool_type);
222 store = new DIRSTORE;
223 dirstore->append(store);
224 memset(store, 0, sizeof(DIRSTORE));
225 store->device = New(alist(10));
226 bstrncpy(store->name, store_name, sizeof(store->name));
227 bstrncpy(store->media_type, media_type, sizeof(store->media_type));
228 bstrncpy(store->pool_name, pool_name, sizeof(store->pool_name));
229 bstrncpy(store->pool_type, pool_type, sizeof(store->pool_type));
230 store->append = append;
232 /* Now get all devices */
233 while (dir->recv() >= 0) {
234 Dmsg1(dbglvl, "<dird device: %s", dir->msg);
235 ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
239 unbash_spaces(dev_name);
240 store->device->append(bstrdup(dev_name.c_str()));
242 } while (ok && dir->recv() >= 0);
245 /* Developers debug code */
247 if (debug_level >= dbglvl) {
248 foreach_alist(store, dirstore) {
249 Dmsg5(dbglvl, "Storage=%s media_type=%s pool=%s pool_type=%s append=%d\n",
250 store->name, store->media_type, store->pool_name,
251 store->pool_type, store->append);
252 foreach_alist(device_name, store->device) {
253 Dmsg1(dbglvl, " Device=%s\n", device_name);
259 init_jcr_device_wait_timers(jcr);
260 jcr->dcr = new_dcr(jcr, NULL, NULL, !rctx.append); /* get a dcr */
262 BSOCK *dir = jcr->dir_bsock;
263 dir->fsend(_("3939 Could not get dcr\n"));
264 Dmsg1(dbglvl, ">dird: %s", dir->msg);
268 * At this point, we have a list of all the Director's Storage
269 * resources indicated for this Job, which include Pool, PoolType,
270 * storage name, and Media type.
271 * Then for each of the Storage resources, we have a list of
272 * device names that were given.
274 * Wiffle through them and find one that can do the backup.
277 int wait_for_device_retries = 0;
280 rctx.notify_dir = true;
282 /* Put new dcr in proper location */
284 rctx.jcr->dcr = jcr->dcr;
286 rctx.jcr->read_dcr = jcr->dcr;
289 for ( ; !fail && !job_canceled(jcr); ) {
290 pop_reserve_messages(jcr);
291 rctx.suitable_device = false;
292 rctx.have_volume = false;
293 rctx.VolumeName[0] = 0;
294 rctx.any_drive = false;
295 if (!jcr->PreferMountedVols) {
297 * Here we try to find a drive that is not used.
298 * This will maximize the use of available drives.
301 rctx.num_writers = 20000000; /* start with impossible number */
302 rctx.low_use_drive = NULL;
303 rctx.PreferMountedVols = false;
304 rctx.exact_match = false;
305 rctx.autochanger_only = true;
306 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
309 /* Look through all drives possibly for low_use drive */
310 if (rctx.low_use_drive) {
311 rctx.try_low_use_drive = true;
312 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
315 rctx.try_low_use_drive = false;
317 rctx.autochanger_only = false;
318 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
323 * Now we look for a drive that may or may not be in
326 /* Look for an exact Volume match all drives */
327 rctx.PreferMountedVols = true;
328 rctx.exact_match = true;
329 rctx.autochanger_only = false;
330 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
333 /* Look for any mounted drive */
334 rctx.exact_match = false;
335 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
339 rctx.any_drive = true;
340 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
343 /* Keep reservations locked *except* during wait_for_device() */
344 unlock_reservations();
346 * The idea of looping on repeat a few times it to ensure
347 * that if there is some subtle timing problem between two
348 * jobs, we will simply try again, and most likely succeed.
349 * This can happen if one job reserves a drive or finishes using
350 * a drive at the same time a second job wants it.
352 if (repeat++ > 1) { /* try algorithm 3 times */
353 bmicrosleep(30, 0); /* wait a bit */
354 Dmsg1(100, "repeat reserve algorithm JobId=%d\n", jcr->JobId);
355 } else if (!rctx.suitable_device || !wait_for_any_device(jcr, wait_for_device_retries)) {
356 Dmsg0(100, "Fail. !suitable_device || !wait_for_device\n");
360 dir->signal(BNET_HEARTBEAT); /* Inform Dir that we are alive */
362 unlock_reservations();
366 * If we get here, there are no suitable devices available, which
367 * means nothing configured. If a device is suitable but busy
368 * with another Volume, we will not come here.
370 unbash_spaces(dir->msg);
371 pm_strcpy(jcr->errmsg, dir->msg);
372 Jmsg(jcr, M_FATAL, 0, _("Device reservation failed for JobId=%d: %s\n"),
373 jcr->JobId, jcr->errmsg);
374 dir->fsend(NO_device, dev_name.c_str());
376 Dmsg1(dbglvl, ">dird: %s", dir->msg);
379 unbash_spaces(dir->msg);
380 pm_strcpy(jcr->errmsg, dir->msg);
381 Jmsg(jcr, M_FATAL, 0, _("Failed command: %s\n"), jcr->errmsg);
382 dir->fsend(BAD_use, jcr->errmsg);
383 Dmsg1(dbglvl, ">dird: %s", dir->msg);
386 release_reserve_messages(jcr);
391 * Search for a device suitable for this job.
392 * Note, this routine sets sets rctx.suitable_device if any
393 * device exists within the SD. The device may not be actually
395 * It also returns if it finds a useable device.
397 bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx)
406 dirstore = jcr->write_store;
408 dirstore = jcr->read_store;
410 Dmsg5(dbglvl, "Start find_suit_dev PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
411 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
412 rctx.autochanger_only, rctx.any_drive);
415 * If the appropriate conditions of this if are met, namely that
416 * we are appending and the user wants mounted drive (or we
417 * force try a mounted drive because they are all busy), we
418 * start by looking at all the Volumes in the volume list.
420 if (!is_vol_list_empty() && rctx.append && rctx.PreferMountedVols) {
421 dlist *temp_vol_list;
423 temp_vol_list = dup_vol_list(jcr);
425 /* Look through reserved volumes for one we can use */
426 Dmsg0(dbglvl, "look for vol in vol list\n");
427 foreach_dlist(vol, temp_vol_list) {
429 Dmsg1(dbglvl, "vol=%s no dev\n", vol->vol_name);
432 /* Check with Director if this Volume is OK */
433 bstrncpy(dcr->VolumeName, vol->vol_name, sizeof(dcr->VolumeName));
434 if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE)) {
438 Dmsg1(dbglvl, "vol=%s OK for this job\n", vol->vol_name);
439 foreach_alist(store, dirstore) {
442 foreach_alist(device_name, store->device) {
443 /* Found a device, try to use it */
444 rctx.device_name = device_name;
445 rctx.device = vol->dev->device;
447 if (vol->dev->read_only) {
450 if (vol->dev->is_autochanger()) {
451 Dmsg1(dbglvl, "vol=%s is in changer\n", vol->vol_name);
452 if (!is_vol_in_autochanger(rctx, vol) || !vol->dev->autoselect ||
453 !vol->dev->enabled) {
456 } else if (strcmp(device_name, vol->dev->device->hdr.name) != 0) {
457 Dmsg2(dbglvl, "device=%s not suitable want %s\n",
458 vol->dev->device->hdr.name, device_name);
462 bstrncpy(rctx.VolumeName, vol->vol_name, sizeof(rctx.VolumeName));
463 rctx.have_volume = true;
464 /* Try reserving this device and volume */
465 Dmsg2(dbglvl, "try vol=%s on device=%s\n", rctx.VolumeName, device_name);
466 stat = reserve_device(rctx);
467 if (stat == 1) { /* found available device */
468 Dmsg1(dbglvl, "Suitable device found=%s\n", device_name);
471 } else if (stat == 0) { /* device busy */
472 Dmsg1(dbglvl, "Suitable device=%s, busy: not use\n", device_name);
474 /* otherwise error */
475 Dmsg0(dbglvl, "No suitable device found.\n");
477 rctx.have_volume = false;
478 rctx.VolumeName[0] = 0;
487 } /* end for loop over reserved volumes */
489 Dmsg0(dbglvl, "lock volumes\n");
490 free_temp_vol_list(temp_vol_list);
493 Dmsg1(dbglvl, "OK dev found. Vol=%s from in-use vols list\n", rctx.VolumeName);
498 * No reserved volume we can use, so now search for an available device.
500 * For each storage device that the user specified, we
501 * search and see if there is a resource for that device.
503 foreach_alist(store, dirstore) {
505 foreach_alist(device_name, store->device) {
507 rctx.device_name = device_name;
508 stat = search_res_for_device(rctx);
509 if (stat == 1) { /* found available device */
510 Dmsg1(dbglvl, "available device found=%s\n", device_name);
513 } else if (stat == 0) { /* device busy */
514 Dmsg1(dbglvl, "No usable device=%s, busy: not use\n", device_name);
516 /* otherwise error */
517 Dmsg0(dbglvl, "No usable device found.\n");
525 Dmsg1(dbglvl, "OK dev found. Vol=%s\n", rctx.VolumeName);
527 Dmsg0(dbglvl, "Leave find_suit_dev: no dev found.\n");
533 * Search for a particular storage device with particular storage
534 * characteristics (MediaType).
536 int search_res_for_device(RCTX &rctx)
538 AUTOCHANGER *changer;
541 Dmsg1(dbglvl, "search res for %s\n", rctx.device_name);
542 /* Look through Autochangers first */
543 foreach_res(changer, R_AUTOCHANGER) {
544 Dmsg1(dbglvl, "Try match changer res=%s\n", changer->hdr.name);
545 /* Find resource, and make sure we were able to open it */
546 if (strcmp(rctx.device_name, changer->hdr.name) == 0) {
547 /* Try each device in this AutoChanger */
548 foreach_alist(rctx.device, changer->device) {
549 Dmsg1(dbglvl, "Try changer device %s\n", rctx.device->hdr.name);
550 if (rctx.store->append && rctx.device->read_only) {
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) {
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) {
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 * Walk through the autochanger resources and check if
602 * the volume is in one of them.
604 * Returns: true if volume is in device
607 static bool is_vol_in_autochanger(RCTX &rctx, VOLRES *vol)
609 AUTOCHANGER *changer = vol->dev->device->changer_res;
615 /* Find resource, and make sure we were able to open it */
616 if (strcmp(rctx.device_name, changer->hdr.name) == 0) {
617 Dmsg1(dbglvl, "Found changer device %s\n", vol->dev->device->hdr.name);
620 Dmsg1(dbglvl, "Incorrect changer device %s\n", changer->hdr.name);
626 * Try to reserve a specific device.
628 * Returns: 1 -- OK, have DCR
632 static int reserve_device(RCTX &rctx)
636 const int name_len = MAX_NAME_LENGTH;
638 /* Make sure MediaType is OK */
639 Dmsg2(dbglvl, "chk MediaType device=%s request=%s\n",
640 rctx.device->media_type, rctx.store->media_type);
641 if (strcmp(rctx.device->media_type, rctx.store->media_type) != 0) {
645 /* Make sure device exists -- i.e. we can stat() it */
646 if (!rctx.device->dev) {
647 rctx.device->dev = init_dev(rctx.jcr, rctx.device);
649 if (!rctx.device->dev) {
650 if (rctx.device->changer_res) {
651 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
652 " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
653 rctx.device->hdr.name, rctx.device_name);
655 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
656 " Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
659 return -1; /* no use waiting */
660 } else if (!rctx.device->dev->enabled) {
661 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
662 " Device \"%s\" requested by DIR is disabled.\n"),
664 return -1; /* no use waiting */
667 rctx.suitable_device = true;
668 Dmsg1(dbglvl, "try reserve %s\n", rctx.device->hdr.name);
669 if (rctx.store->append) {
670 dcr = new_dcr(rctx.jcr, rctx.jcr->dcr, rctx.device->dev, SD_APPEND);
672 dcr = new_dcr(rctx.jcr, rctx.jcr->read_dcr, rctx.device->dev, SD_READ);
675 BSOCK *dir = rctx.jcr->dir_bsock;
676 dir->fsend(_("3926 Could not get dcr for device: %s\n"), rctx.device_name);
677 Dmsg1(dbglvl, ">dird: %s", dir->msg);
680 bstrncpy(dcr->pool_name, rctx.store->pool_name, name_len);
681 bstrncpy(dcr->pool_type, rctx.store->pool_type, name_len);
682 bstrncpy(dcr->media_type, rctx.store->media_type, name_len);
683 bstrncpy(dcr->dev_name, rctx.device_name, name_len);
684 if (rctx.store->append) {
685 Dmsg2(dbglvl, "call reserve for append: have_vol=%d vol=%s\n", rctx.have_volume, rctx.VolumeName);
686 ok = reserve_device_for_append(dcr, rctx);
692 Dmsg5(dbglvl, "Reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
693 dcr->dev->num_reserved(),
694 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
695 Dmsg3(dbglvl, "Vol=%s num_writers=%d, have_vol=%d\n",
696 rctx.VolumeName, dcr->dev->num_writers, rctx.have_volume);
697 if (rctx.have_volume) {
698 Dmsg0(dbglvl, "Call reserve_volume for append.\n");
699 if (reserve_volume(dcr, rctx.VolumeName)) {
700 Dmsg1(dbglvl, "Reserved vol=%s\n", rctx.VolumeName);
702 Dmsg1(dbglvl, "Could not reserve vol=%s\n", rctx.VolumeName);
706 dcr->any_volume = true;
707 Dmsg0(dbglvl, "no vol, call find_next_appendable_vol.\n");
708 if (dir_find_next_appendable_volume(dcr)) {
709 bstrncpy(rctx.VolumeName, dcr->VolumeName, sizeof(rctx.VolumeName));
710 rctx.have_volume = true;
711 Dmsg1(dbglvl, "looking for Volume=%s\n", rctx.VolumeName);
713 dcr->dev->clear_wait();
714 Dmsg0(dbglvl, "No next volume found\n");
715 rctx.have_volume = false;
716 rctx.VolumeName[0] = 0;
718 * If there is at least one volume that is valid and in use,
719 * but we get here, check if we are running with prefers
720 * non-mounted drives. In that case, we have selected a
721 * non-used drive and our one and only volume is mounted
722 * elsewhere, so we bail out and retry using that drive.
724 if (dcr->found_in_use() && !rctx.PreferMountedVols) {
725 rctx.PreferMountedVols = true;
726 if (dcr->VolumeName[0]) {
727 dcr->unreserve_device(false);
732 * Note. Under some circumstances, the Director can hand us
733 * a Volume name that is not the same as the one on the current
734 * drive, and in that case, the call above to find the next
735 * volume will fail because in attempting to reserve the Volume
736 * the code will realize that we already have a tape mounted,
737 * and it will fail. This *should* only happen if there are
738 * writers, thus the following test. In that case, we simply
739 * bail out, and continue waiting, rather than plunging on
740 * and hoping that the operator can resolve the problem.
742 if (dcr->dev->num_writers != 0) {
743 if (dcr->VolumeName[0]) {
744 dcr->unreserve_device(false);
751 ok = reserve_device_for_read(dcr);
753 rctx.jcr->read_dcr = dcr;
754 Dmsg5(dbglvl, "Read reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
755 dcr->dev->num_reserved(),
756 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
763 if (rctx.notify_dir) {
765 BSOCK *dir = rctx.jcr->dir_bsock;
766 pm_strcpy(dev_name, rctx.device->hdr.name);
767 bash_spaces(dev_name);
768 ok = dir->fsend(OK_device, dev_name.c_str()); /* Return real device name */
769 Dmsg1(dbglvl, ">dird: %s", dir->msg);
771 dcr->unreserve_device(false);
779 rctx.have_volume = false;
780 rctx.VolumeName[0] = 0;
781 Dmsg0(dbglvl, "Not OK.\n");
787 * We reserve the device for appending by incrementing
788 * num_reserved(). We do virtually all the same work that
789 * is done in acquire_device_for_append(), but we do
790 * not attempt to mount the device. This routine allows
791 * the DIR to reserve multiple devices before *really*
792 * starting the job. It also permits the SD to refuse
793 * certain devices (not up, ...).
795 * Note, in reserving a device, if the device is for the
796 * same pool and the same pool type, then it is acceptable.
797 * The Media Type has already been checked. If we are
798 * the first tor reserve the device, we put the pool
799 * name and pool type in the device record.
801 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
804 DEVICE *dev = dcr->dev;
807 ASSERT2(dcr, "No dcr in reserve_device_for_append!");
808 if (job_canceled(jcr)) {
814 /* If device is being read or reserved for read, we cannot write it */
815 if (dev->can_read() || dev->is_reserved_for_read()) {
816 Mmsg(jcr->errmsg, _("3603 JobId=%u %s device %s is busy reading.\n"),
817 jcr->JobId, dev->print_type(), dev->print_name());
818 queue_reserve_message(jcr);
819 Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
823 /* If device is unmounted, we are out of luck */
824 if (dev->is_device_unmounted()) {
825 Mmsg(jcr->errmsg, _("3604 JobId=%u %s device %s is BLOCKED due to user unmount.\n"),
826 jcr->JobId, dev->print_type(), dev->print_name());
827 queue_reserve_message(jcr);
828 Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
832 Dmsg2(dbglvl, "reserve_append %s device is %s\n", dev->print_type(), dev->print_name());
834 /* Now do detailed tests ... */
835 if (can_reserve_drive(dcr, rctx) != 1) {
836 Dmsg0(dbglvl, "can_reserve_drive!=1\n");
840 /* Note: on failure this returns jcr->errmsg properly edited */
841 if (generate_plugin_event(jcr, bsdEventDeviceTryOpen, dcr) != bRC_OK) {
842 queue_reserve_message(jcr);
845 dcr->set_reserved_for_append();
854 * We "reserve" the drive by setting the ST_READ bit. No one else
855 * should touch the drive until that is cleared.
856 * This allows the DIR to "reserve" the device before actually
859 static bool reserve_device_for_read(DCR *dcr)
861 DEVICE *dev = dcr->dev;
865 ASSERT2(dcr, "No dcr in reserve_device_for_read!");
866 if (job_canceled(jcr)) {
872 if (dev->is_device_unmounted()) {
873 Mmsg(jcr->errmsg, _("3601 JobId=%u %s device %s is BLOCKED due to user unmount.\n"),
874 jcr->JobId, dev->print_type(), dev->print_name());
875 queue_reserve_message(jcr);
876 Dmsg1(dbglvl, "Device %s is BLOCKED due to user unmount.\n", dev->print_name());
880 if (dev->is_busy()) {
881 Mmsg(jcr->errmsg, _("3602 JobId=%u %s device %s is busy (already reading/writing)."
882 " read=%d, writers=%d reserved=%d\n"),
883 jcr->JobId, dev->print_type(), dev->print_name(),
884 dev->state & ST_READ?1:0, dev->num_writers, dev->num_reserved());
885 queue_reserve_message(jcr);
886 Dmsg4(dbglvl, "Device %s is busy ST_READ=%d num_writers=%d reserved=%d.\n",
888 dev->state & ST_READ?1:0, dev->num_writers, dev->num_reserved());
892 /* Note: on failure this returns jcr->errmsg properly edited */
893 if (generate_plugin_event(jcr, bsdEventDeviceTryOpen, dcr) != bRC_OK) {
894 queue_reserve_message(jcr);
898 dcr->set_reserved_for_read();
906 static bool is_max_jobs_ok(DCR *dcr)
908 DEVICE *dev = dcr->dev;
911 Dmsg5(dbglvl, "MaxJobs=%d Jobs=%d reserves=%d Status=%s Vol=%s\n",
912 dcr->VolCatInfo.VolCatMaxJobs,
913 dcr->VolCatInfo.VolCatJobs, dev->num_reserved(),
914 dcr->VolCatInfo.VolCatStatus,
916 /* Limit max concurrent jobs on this drive */
917 if (dev->max_concurrent_jobs > 0 && dev->max_concurrent_jobs <=
918 (uint32_t)(dev->num_writers + dev->num_reserved())) {
919 /* Max Concurrent Jobs depassed or already reserved */
920 Mmsg(jcr->errmsg, _("3609 JobId=%u Max concurrent jobs=%d exceeded on %s device %s.\n"),
921 (uint32_t)jcr->JobId, dev->max_concurrent_jobs,
922 dev->print_type(), dev->print_name());
923 queue_reserve_message(jcr);
924 Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
927 if (strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0) {
931 if (dcr->VolCatInfo.VolCatMaxJobs > 0 && dcr->VolCatInfo.VolCatMaxJobs <=
932 (dcr->VolCatInfo.VolCatJobs + dev->num_reserved())) {
933 /* Max Job Vols depassed or already reserved */
934 Mmsg(jcr->errmsg, _("3611 JobId=%u Volume max jobs=%d exceeded on %s device %s.\n"),
935 (uint32_t)jcr->JobId, dcr->VolCatInfo.VolCatMaxJobs,
936 dev->print_type(), dev->print_name());
937 queue_reserve_message(jcr);
938 Dmsg1(dbglvl, "reserve dev failed: %s", jcr->errmsg);
939 return false; /* wait */
945 static int is_pool_ok(DCR *dcr)
947 DEVICE *dev = dcr->dev;
950 /* Now check if we want the same Pool and pool type */
951 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
952 strcmp(dev->pool_type, dcr->pool_type) == 0) {
953 /* OK, compatible device */
954 Dmsg1(dbglvl, "OK dev: %s num_writers=0, reserved, pool matches\n", dev->print_name());
957 /* Drive Pool not suitable for us */
959 "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on %s device %s.\n"),
960 (uint32_t)jcr->JobId, dcr->pool_name, dev->pool_name,
961 dev->num_reserved(), dev->print_type(), dev->print_name());
962 Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
963 queue_reserve_message(jcr);
969 * Returns: 1 if drive can be reserved
970 * 0 if we should wait
971 * -1 on error or impossibility
973 static int can_reserve_drive(DCR *dcr, RCTX &rctx)
975 DEVICE *dev = dcr->dev;
978 Dmsg5(dbglvl, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
979 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
980 rctx.autochanger_only, rctx.any_drive);
982 /* Check for max jobs on this Volume */
983 if (!is_max_jobs_ok(dcr)) {
987 /* setting any_drive overrides PreferMountedVols flag */
988 if (!rctx.any_drive) {
990 * When PreferMountedVols is set, we keep track of the
991 * drive in use that has the least number of writers, then if
992 * no unmounted drive is found, we try that drive. This
993 * helps spread the load to the least used drives.
995 if (rctx.try_low_use_drive && dev == rctx.low_use_drive) {
996 Dmsg2(dbglvl, "OK dev=%s == low_drive=%s.\n",
997 dev->print_name(), rctx.low_use_drive->print_name());
1000 /* If he wants a free drive, but this one is busy, no go */
1001 if (!rctx.PreferMountedVols && dev->is_busy()) {
1002 /* Save least used drive */
1003 if ((dev->num_writers + dev->num_reserved()) < rctx.num_writers) {
1004 rctx.num_writers = dev->num_writers + dev->num_reserved();
1005 rctx.low_use_drive = dev;
1006 Dmsg2(dbglvl, "set low use drive=%s num_writers=%d\n",
1007 dev->print_name(), rctx.num_writers);
1009 Dmsg1(dbglvl, "not low use num_writers=%d\n", dev->num_writers+dev->num_reserved());
1011 Mmsg(jcr->errmsg, _("3605 JobId=%u wants free drive but %s device %s is busy.\n"),
1012 jcr->JobId, dev->print_type(), dev->print_name());
1013 queue_reserve_message(jcr);
1014 Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
1018 /* Check for prefer mounted volumes */
1019 if (rctx.PreferMountedVols && !dev->vol && dev->is_tape()) {
1020 Mmsg(jcr->errmsg, _("3606 JobId=%u prefers mounted drives, but %s device %s has no Volume.\n"),
1021 jcr->JobId, dev->print_type(), dev->print_name());
1022 queue_reserve_message(jcr);
1023 Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
1024 return 0; /* No volume mounted */
1027 /* Check for exact Volume name match */
1028 /* ***FIXME*** for Disk, we can accept any volume that goes with this
1031 if (rctx.exact_match && rctx.have_volume) {
1033 Dmsg5(dbglvl, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
1034 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
1035 rctx.autochanger_only, rctx.any_drive);
1036 Dmsg4(dbglvl, "have_vol=%d have=%s resvol=%s want=%s\n",
1037 rctx.have_volume, dev->VolHdr.VolumeName,
1038 dev->vol?dev->vol->vol_name:"*none*", rctx.VolumeName);
1039 ok = strcmp(dev->VolHdr.VolumeName, rctx.VolumeName) == 0 ||
1040 (dev->vol && strcmp(dev->vol->vol_name, rctx.VolumeName) == 0);
1042 Mmsg(jcr->errmsg, _("3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on %s device %s.\n"),
1043 jcr->JobId, rctx.VolumeName, dev->VolHdr.VolumeName,
1044 dev->print_type(), dev->print_name());
1045 queue_reserve_message(jcr);
1046 Dmsg3(dbglvl, "not OK: dev have=%s resvol=%s want=%s\n",
1047 dev->VolHdr.VolumeName, dev->vol?dev->vol->vol_name:"*none*", rctx.VolumeName);
1050 if (!dcr->can_i_use_volume()) {
1051 return 0; /* fail if volume on another drive */
1056 /* Check for unused autochanger drive */
1057 if (rctx.autochanger_only && !dev->is_busy() &&
1058 dev->VolHdr.VolumeName[0] == 0) {
1059 /* Device is available but not yet reserved, reserve it for us */
1060 Dmsg1(dbglvl, "OK Res Unused autochanger %s.\n", dev->print_name());
1061 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1062 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1063 return 1; /* reserve drive */
1067 * Handle the case that there are no writers
1069 if (dev->num_writers == 0) {
1070 /* Now check if there are any reservations on the drive */
1071 if (dev->num_reserved()) {
1072 return is_pool_ok(dcr);
1073 } else if (dev->can_append()) {
1074 if (is_pool_ok(dcr)) {
1077 /* Changing pool, unload old tape if any in drive */
1078 Dmsg0(dbglvl, "OK dev: num_writers=0, not reserved, pool change, unload changer\n");
1079 /* ***FIXME*** use set_unload() */
1080 unload_autochanger(dcr, -1);
1083 /* Device is available but not yet reserved, reserve it for us */
1084 Dmsg1(dbglvl, "OK Dev avail reserved %s\n", dev->print_name());
1085 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1086 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1087 return 1; /* reserve drive */
1091 * Check if the device is in append mode with writers (i.e.
1092 * available if pool is the same).
1094 if (dev->can_append() || dev->num_writers > 0) {
1095 return is_pool_ok(dcr);
1097 Pmsg1(000, _("Logic error!!!! JobId=%u Should not get here.\n"), (int)jcr->JobId);
1098 Mmsg(jcr->errmsg, _("3910 JobId=%u Logic error!!!! %s device %s Should not get here.\n"),
1099 jcr->JobId, dev->print_type(), dev->print_name());
1100 queue_reserve_message(jcr);
1101 Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
1102 return -1; /* error, should not get here */
1104 Mmsg(jcr->errmsg, _("3911 JobId=%u failed reserve %s device %s.\n"),
1105 jcr->JobId, dev->print_type(), dev->print_name());
1106 queue_reserve_message(jcr);
1107 Dmsg1(dbglvl, "Failed: No reserve %s\n", dev->print_name());
1113 * Queue a reservation error or failure message for this jcr
1115 static void queue_reserve_message(JCR *jcr)
1123 msgs = jcr->reserve_msgs;
1128 * Look for duplicate message. If found, do
1131 for (i=msgs->size()-1; i >= 0; i--) {
1132 msg = (char *)msgs->get(i);
1136 /* Comparison based on 4 digit message number */
1137 if (strncmp(msg, jcr->errmsg, 4) == 0) {
1141 /* Message unique, so insert it */
1142 jcr->reserve_msgs->push(bstrdup(jcr->errmsg));
1149 * Send any reservation messages queued for this jcr
1151 void send_drive_reserve_messages(JCR *jcr, void sendit(const char *msg, int len, void *sarg), void *arg)
1158 msgs = jcr->reserve_msgs;
1159 if (!msgs || msgs->size() == 0) {
1162 for (i=msgs->size()-1; i >= 0; i--) {
1163 msg = (char *)msgs->get(i);
1165 sendit(" ", 3, arg);
1166 sendit(msg, strlen(msg), arg);
1177 * Pop and release any reservations messages
1179 static void pop_reserve_messages(JCR *jcr)
1185 msgs = jcr->reserve_msgs;
1189 while ((msg = (char *)msgs->pop())) {
1197 * Also called from acquire.c
1199 void release_reserve_messages(JCR *jcr)
1201 pop_reserve_messages(jcr);
1203 if (!jcr->reserve_msgs) {
1206 delete jcr->reserve_msgs;
1207 jcr->reserve_msgs = NULL;