2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2016 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
20 * Drive reservation functions for Storage Daemon
22 * Written by Kern Sibbald, MM
24 * Split from job.c and acquire.c June 2005
31 const int dbglvl = 150;
33 static brwlock_t reservation_lock;
34 int reservations_lock_count = 0;
36 /* Forward referenced functions */
37 static int can_reserve_drive(DCR *dcr, RCTX &rctx);
38 static bool is_vol_in_autochanger(RCTX &rctx, VOLRES *vol);
39 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx);
40 static bool reserve_device_for_read(DCR *dcr);
41 static bool use_device_cmd(JCR *jcr);
42 static int reserve_device(RCTX &rctx);
43 static void pop_reserve_messages(JCR *jcr);
44 static void queue_reserve_message(JCR *jcr);
45 //void switch_device(DCR *dcr, DEVICE *dev);
47 /* Requests from the Director daemon */
48 static char use_storage[] = "use storage=%127s media_type=%127s "
49 "pool_name=%127s pool_type=%127s append=%d copy=%d stripe=%d\n";
50 static char use_device[] = "use device=%127s\n";
52 /* Responses sent to Director daemon */
53 static char OK_device[] = "3000 OK use device device=%s\n";
54 static char NO_device[] = "3924 Device \"%s\" not in SD Device"
55 " resources or no matching Media Type.\n";
56 static char BAD_use[] = "3913 Bad use command: %s\n";
59 * This allows a given thread to recursively call lock_reservations.
60 * It must, of course, call unlock_... the same number of times.
62 void init_reservations_lock()
65 if ((errstat=rwl_init(&reservation_lock)) != 0) {
67 Emsg1(M_ABORT, 0, _("Unable to initialize reservation lock. ERR=%s\n"),
68 be.bstrerror(errstat));
75 /* This applies to a drive and to Volumes */
76 void _lock_reservations(const char *file, int line)
79 reservations_lock_count++;
80 if ((errstat=rwl_writelock_p(&reservation_lock, file, line)) != 0) {
82 Emsg2(M_ABORT, 0, "rwl_writelock failure. stat=%d: ERR=%s\n",
83 errstat, be.bstrerror(errstat));
87 void _unlock_reservations()
90 reservations_lock_count--;
91 if ((errstat=rwl_writeunlock(&reservation_lock)) != 0) {
93 Emsg2(M_ABORT, 0, "rwl_writeunlock failure. stat=%d: ERR=%s\n",
94 errstat, be.bstrerror(errstat));
98 void term_reservations_lock()
100 rwl_destroy(&reservation_lock);
101 term_vol_list_lock();
104 void DCR::clear_reserved()
109 Dmsg2(dbglvl, "Dec reserve=%d dev=%s\n", dev->num_reserved(), dev->print_name());
113 void DCR::set_reserved_for_append()
116 dev->set_append_reserve();
117 Dmsg2(dbglvl, "Inc reserve=%d dev=%s\n", dev->num_reserved(), dev->print_name());
121 void DCR::set_reserved_for_read()
124 dev->set_read_reserve();
125 Dmsg2(dbglvl, "Inc reserve=%d dev=%s\n", dev->num_reserved(), dev->print_name());
130 * Remove any reservation from a drive and tell the system
131 * that the volume is unused at least by us.
133 void DCR::unreserve_device(bool locked)
140 reserved_volume = false;
141 /* If we set read mode in reserving, remove it */
142 if (dev->can_read()) {
143 remove_read_volume(jcr, this->VolumeName);
146 if (dev->num_writers < 0) {
147 Jmsg1(jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers);
148 dev->num_writers = 0;
150 if (dev->num_reserved() == 0 && dev->num_writers == 0) {
151 generate_plugin_event(jcr, bsdEventDeviceClose, this);
160 bool use_cmd(JCR *jcr)
163 * Get the device, media, and pool information
165 if (!use_device_cmd(jcr)) {
166 jcr->setJobStatus(JS_ErrorTerminated);
167 memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
174 * We get the following type of information:
176 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=1 copy=0 strip=0
180 * use storage=xxx media_type=yyy pool_name=xxx pool_type=yyy append=0 copy=0 strip=0
184 static bool use_device_cmd(JCR *jcr)
186 POOL_MEM store_name, dev_name, media_type, pool_name, pool_type;
187 BSOCK *dir = jcr->dir_bsock;
190 int32_t Copy, Stripe;
195 memset(&rctx, 0, sizeof(RCTX));
198 * If there are multiple devices, the director sends us
199 * use_device for each device that it wants to use.
201 dirstore = New(alist(10, not_owned_by_alist));
202 jcr->reserve_msgs = New(alist(10, not_owned_by_alist));
204 Dmsg1(dbglvl, "<dird: %s", dir->msg);
205 ok = sscanf(dir->msg, use_storage, store_name.c_str(),
206 media_type.c_str(), pool_name.c_str(),
207 pool_type.c_str(), &append, &Copy, &Stripe) == 7;
212 jcr->write_store = dirstore;
214 jcr->read_store = dirstore;
216 rctx.append = append;
217 unbash_spaces(store_name);
218 unbash_spaces(media_type);
219 unbash_spaces(pool_name);
220 unbash_spaces(pool_type);
221 store = new DIRSTORE;
222 dirstore->append(store);
223 memset(store, 0, sizeof(DIRSTORE));
224 store->device = New(alist(10));
225 bstrncpy(store->name, store_name, sizeof(store->name));
226 bstrncpy(store->media_type, media_type, sizeof(store->media_type));
227 bstrncpy(store->pool_name, pool_name, sizeof(store->pool_name));
228 bstrncpy(store->pool_type, pool_type, sizeof(store->pool_type));
229 store->append = append;
231 /* Now get all devices */
232 while (dir->recv() >= 0) {
233 Dmsg1(dbglvl, "<dird device: %s", dir->msg);
234 ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
238 unbash_spaces(dev_name);
239 store->device->append(bstrdup(dev_name.c_str()));
241 } while (ok && dir->recv() >= 0);
244 /* Developers debug code */
246 if (debug_level >= dbglvl) {
247 foreach_alist(store, dirstore) {
248 Dmsg5(dbglvl, "Storage=%s media_type=%s pool=%s pool_type=%s append=%d\n",
249 store->name, store->media_type, store->pool_name,
250 store->pool_type, store->append);
251 foreach_alist(device_name, store->device) {
252 Dmsg1(dbglvl, " Device=%s\n", device_name);
258 init_jcr_device_wait_timers(jcr);
259 jcr->dcr = new_dcr(jcr, NULL, NULL, !rctx.append); /* get a dcr */
261 BSOCK *dir = jcr->dir_bsock;
262 dir->fsend(_("3939 Could not get dcr\n"));
263 Dmsg1(dbglvl, ">dird: %s", dir->msg);
267 * At this point, we have a list of all the Director's Storage
268 * resources indicated for this Job, which include Pool, PoolType,
269 * storage name, and Media type.
270 * Then for each of the Storage resources, we have a list of
271 * device names that were given.
273 * Wiffle through them and find one that can do the backup.
276 int wait_for_device_retries = 0;
279 rctx.notify_dir = true;
281 /* Put new dcr in proper location */
283 rctx.jcr->dcr = jcr->dcr;
285 rctx.jcr->read_dcr = jcr->dcr;
288 for ( ; !fail && !job_canceled(jcr); ) {
289 pop_reserve_messages(jcr);
290 rctx.suitable_device = false;
291 rctx.have_volume = false;
292 rctx.VolumeName[0] = 0;
293 rctx.any_drive = false;
294 if (!jcr->PreferMountedVols) {
296 * Here we try to find a drive that is not used.
297 * This will maximize the use of available drives.
300 rctx.num_writers = 20000000; /* start with impossible number */
301 rctx.low_use_drive = NULL;
302 rctx.PreferMountedVols = false;
303 rctx.exact_match = false;
304 rctx.autochanger_only = true;
305 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
308 /* Look through all drives possibly for low_use drive */
309 if (rctx.low_use_drive) {
310 rctx.try_low_use_drive = true;
311 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
314 rctx.try_low_use_drive = false;
316 rctx.autochanger_only = false;
317 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
322 * Now we look for a drive that may or may not be in
325 /* Look for an exact Volume match all drives */
326 rctx.PreferMountedVols = true;
327 rctx.exact_match = true;
328 rctx.autochanger_only = false;
329 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
332 /* Look for any mounted drive */
333 rctx.exact_match = false;
334 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
338 rctx.any_drive = true;
339 if ((ok = find_suitable_device_for_job(jcr, rctx))) {
342 /* Keep reservations locked *except* during wait_for_device() */
343 unlock_reservations();
345 * The idea of looping on repeat a few times it to ensure
346 * that if there is some subtle timing problem between two
347 * jobs, we will simply try again, and most likely succeed.
348 * This can happen if one job reserves a drive or finishes using
349 * a drive at the same time a second job wants it.
351 if (repeat++ > 1) { /* try algorithm 3 times */
352 bmicrosleep(30, 0); /* wait a bit */
353 Dmsg1(100, "repeat reserve algorithm JobId=%d\n", jcr->JobId);
354 } else if (!rctx.suitable_device || !wait_for_any_device(jcr, wait_for_device_retries)) {
355 Dmsg0(100, "Fail. !suitable_device || !wait_for_device\n");
359 dir->signal(BNET_HEARTBEAT); /* Inform Dir that we are alive */
361 unlock_reservations();
365 * If we get here, there are no suitable devices available, which
366 * means nothing configured. If a device is suitable but busy
367 * with another Volume, we will not come here.
369 unbash_spaces(dir->msg);
370 pm_strcpy(jcr->errmsg, dir->msg);
371 Jmsg(jcr, M_FATAL, 0, _("Device reservation failed for JobId=%d: %s\n"),
372 jcr->JobId, jcr->errmsg);
373 dir->fsend(NO_device, dev_name.c_str());
375 Dmsg1(dbglvl, ">dird: %s", dir->msg);
378 unbash_spaces(dir->msg);
379 pm_strcpy(jcr->errmsg, dir->msg);
380 Jmsg(jcr, M_FATAL, 0, _("Failed command: %s\n"), jcr->errmsg);
381 dir->fsend(BAD_use, jcr->errmsg);
382 Dmsg1(dbglvl, ">dird: %s", dir->msg);
385 release_reserve_messages(jcr);
390 * Search for a device suitable for this job.
391 * Note, this routine sets sets rctx.suitable_device if any
392 * device exists within the SD. The device may not be actually
394 * It also returns if it finds a useable device.
396 bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx)
405 dirstore = jcr->write_store;
407 dirstore = jcr->read_store;
409 Dmsg5(dbglvl, "Start find_suit_dev PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
410 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
411 rctx.autochanger_only, rctx.any_drive);
414 * If the appropriate conditions of this if are met, namely that
415 * we are appending and the user wants mounted drive (or we
416 * force try a mounted drive because they are all busy), we
417 * start by looking at all the Volumes in the volume list.
419 if (!is_vol_list_empty() && rctx.append && rctx.PreferMountedVols) {
420 dlist *temp_vol_list;
422 temp_vol_list = dup_vol_list(jcr);
424 /* Look through reserved volumes for one we can use */
425 Dmsg0(dbglvl, "look for vol in vol list\n");
426 foreach_dlist(vol, temp_vol_list) {
428 Dmsg1(dbglvl, "vol=%s no dev\n", vol->vol_name);
431 /* Check with Director if this Volume is OK */
432 bstrncpy(dcr->VolumeName, vol->vol_name, sizeof(dcr->VolumeName));
433 if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE)) {
437 Dmsg1(dbglvl, "vol=%s OK for this job\n", vol->vol_name);
438 foreach_alist(store, dirstore) {
441 foreach_alist(device_name, store->device) {
442 /* Found a device, try to use it */
443 rctx.device_name = device_name;
444 rctx.device = vol->dev->device;
446 if (vol->dev->read_only) {
449 if (vol->dev->is_autochanger()) {
450 Dmsg1(dbglvl, "vol=%s is in changer\n", vol->vol_name);
451 if (!is_vol_in_autochanger(rctx, vol) || !vol->dev->autoselect ||
452 !vol->dev->enabled) {
455 } else if (strcmp(device_name, vol->dev->device->hdr.name) != 0) {
456 Dmsg2(dbglvl, "device=%s not suitable want %s\n",
457 vol->dev->device->hdr.name, device_name);
461 bstrncpy(rctx.VolumeName, vol->vol_name, sizeof(rctx.VolumeName));
462 rctx.have_volume = true;
463 /* Try reserving this device and volume */
464 Dmsg2(dbglvl, "try vol=%s on device=%s\n", rctx.VolumeName, device_name);
465 stat = reserve_device(rctx);
466 if (stat == 1) { /* found available device */
467 Dmsg1(dbglvl, "Suitable device found=%s\n", device_name);
470 } else if (stat == 0) { /* device busy */
471 Dmsg1(dbglvl, "Suitable device=%s, busy: not use\n", device_name);
473 /* otherwise error */
474 Dmsg0(dbglvl, "No suitable device found.\n");
476 rctx.have_volume = false;
477 rctx.VolumeName[0] = 0;
486 } /* end for loop over reserved volumes */
488 Dmsg0(dbglvl, "lock volumes\n");
489 free_temp_vol_list(temp_vol_list);
492 Dmsg1(dbglvl, "OK dev found. Vol=%s from in-use vols list\n", rctx.VolumeName);
497 * No reserved volume we can use, so now search for an available device.
499 * For each storage device that the user specified, we
500 * search and see if there is a resource for that device.
502 foreach_alist(store, dirstore) {
504 foreach_alist(device_name, store->device) {
506 rctx.device_name = device_name;
507 stat = search_res_for_device(rctx);
508 if (stat == 1) { /* found available device */
509 Dmsg1(dbglvl, "available device found=%s\n", device_name);
512 } else if (stat == 0) { /* device busy */
513 Dmsg1(dbglvl, "No usable device=%s, busy: not use\n", device_name);
515 /* otherwise error */
516 Dmsg0(dbglvl, "No usable device found.\n");
524 Dmsg1(dbglvl, "OK dev found. Vol=%s\n", rctx.VolumeName);
526 Dmsg0(dbglvl, "Leave find_suit_dev: no dev found.\n");
532 * Search for a particular storage device with particular storage
533 * characteristics (MediaType).
535 int search_res_for_device(RCTX &rctx)
537 AUTOCHANGER *changer;
540 Dmsg1(dbglvl, "search res for %s\n", rctx.device_name);
541 /* Look through Autochangers first */
542 foreach_res(changer, R_AUTOCHANGER) {
543 Dmsg1(dbglvl, "Try match changer res=%s\n", changer->hdr.name);
544 /* Find resource, and make sure we were able to open it */
545 if (strcmp(rctx.device_name, changer->hdr.name) == 0) {
546 /* Try each device in this AutoChanger */
547 foreach_alist(rctx.device, changer->device) {
548 Dmsg1(dbglvl, "Try changer device %s\n", rctx.device->hdr.name);
549 if (rctx.store->append && rctx.device->read_only) {
552 if (!rctx.device->autoselect) {
553 Dmsg1(100, "Device %s not autoselect skipped.\n",
554 rctx.device->hdr.name);
555 continue; /* device is not available */
557 stat = reserve_device(rctx);
558 if (stat != 1) { /* try another device */
562 if (rctx.store->append) {
563 Dmsg2(dbglvl, "Device %s reserved=%d for append.\n",
564 rctx.device->hdr.name, rctx.jcr->dcr->dev->num_reserved());
566 Dmsg2(dbglvl, "Device %s reserved=%d for read.\n",
567 rctx.device->hdr.name, rctx.jcr->read_dcr->dev->num_reserved());
574 /* Now if requested look through regular devices */
575 if (!rctx.autochanger_only) {
576 foreach_res(rctx.device, R_DEVICE) {
577 Dmsg1(dbglvl, "Try match res=%s\n", rctx.device->hdr.name);
578 /* Find resource, and make sure we were able to open it */
579 if (strcmp(rctx.device_name, rctx.device->hdr.name) == 0) {
580 stat = reserve_device(rctx);
581 if (stat != 1) { /* try another device */
585 if (rctx.store->append) {
586 Dmsg2(dbglvl, "Device %s reserved=%d for append.\n",
587 rctx.device->hdr.name, rctx.jcr->dcr->dev->num_reserved());
589 Dmsg2(dbglvl, "Device %s reserved=%d for read.\n",
590 rctx.device->hdr.name, rctx.jcr->read_dcr->dev->num_reserved());
596 return -1; /* nothing found */
600 * Walk through the autochanger resources and check if
601 * the volume is in one of them.
603 * Returns: true if volume is in device
606 static bool is_vol_in_autochanger(RCTX &rctx, VOLRES *vol)
608 AUTOCHANGER *changer = vol->dev->device->changer_res;
614 /* Find resource, and make sure we were able to open it */
615 if (strcmp(rctx.device_name, changer->hdr.name) == 0) {
616 Dmsg1(dbglvl, "Found changer device %s\n", vol->dev->device->hdr.name);
619 Dmsg1(dbglvl, "Incorrect changer device %s\n", changer->hdr.name);
625 * Try to reserve a specific device.
627 * Returns: 1 -- OK, have DCR
631 static int reserve_device(RCTX &rctx)
635 const int name_len = MAX_NAME_LENGTH;
637 /* Make sure MediaType is OK */
638 Dmsg2(dbglvl, "chk MediaType device=%s request=%s\n",
639 rctx.device->media_type, rctx.store->media_type);
640 if (strcmp(rctx.device->media_type, rctx.store->media_type) != 0) {
644 /* Make sure device exists -- i.e. we can stat() it */
645 if (!rctx.device->dev) {
646 rctx.device->dev = init_dev(rctx.jcr, rctx.device);
648 if (!rctx.device->dev) {
649 if (rctx.device->changer_res) {
650 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
651 " Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
652 rctx.device->hdr.name, rctx.device_name);
654 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
655 " Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
658 return -1; /* no use waiting */
659 } else if (!rctx.device->dev->enabled) {
660 Jmsg(rctx.jcr, M_WARNING, 0, _("\n"
661 " Device \"%s\" requested by DIR is disabled.\n"),
663 return -1; /* no use waiting */
666 rctx.suitable_device = true;
667 Dmsg1(dbglvl, "try reserve %s\n", rctx.device->hdr.name);
668 if (rctx.store->append) {
669 dcr = new_dcr(rctx.jcr, rctx.jcr->dcr, rctx.device->dev, SD_APPEND);
671 dcr = new_dcr(rctx.jcr, rctx.jcr->read_dcr, rctx.device->dev, SD_READ);
674 BSOCK *dir = rctx.jcr->dir_bsock;
675 dir->fsend(_("3926 Could not get dcr for device: %s\n"), rctx.device_name);
676 Dmsg1(dbglvl, ">dird: %s", dir->msg);
679 bstrncpy(dcr->pool_name, rctx.store->pool_name, name_len);
680 bstrncpy(dcr->pool_type, rctx.store->pool_type, name_len);
681 bstrncpy(dcr->media_type, rctx.store->media_type, name_len);
682 bstrncpy(dcr->dev_name, rctx.device_name, name_len);
683 if (rctx.store->append) {
684 Dmsg2(dbglvl, "call reserve for append: have_vol=%d vol=%s\n", rctx.have_volume, rctx.VolumeName);
685 ok = reserve_device_for_append(dcr, rctx);
691 Dmsg5(dbglvl, "Reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
692 dcr->dev->num_reserved(),
693 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
694 Dmsg3(dbglvl, "Vol=%s num_writers=%d, have_vol=%d\n",
695 rctx.VolumeName, dcr->dev->num_writers, rctx.have_volume);
696 if (rctx.have_volume) {
697 Dmsg0(dbglvl, "Call reserve_volume for append.\n");
698 if (reserve_volume(dcr, rctx.VolumeName)) {
699 Dmsg1(dbglvl, "Reserved vol=%s\n", rctx.VolumeName);
701 Dmsg1(dbglvl, "Could not reserve vol=%s\n", rctx.VolumeName);
705 dcr->any_volume = true;
706 Dmsg0(dbglvl, "no vol, call find_next_appendable_vol.\n");
707 if (dir_find_next_appendable_volume(dcr)) {
708 bstrncpy(rctx.VolumeName, dcr->VolumeName, sizeof(rctx.VolumeName));
709 rctx.have_volume = true;
710 Dmsg1(dbglvl, "looking for Volume=%s\n", rctx.VolumeName);
712 dcr->dev->clear_wait();
713 Dmsg0(dbglvl, "No next volume found\n");
714 rctx.have_volume = false;
715 rctx.VolumeName[0] = 0;
717 * If there is at least one volume that is valid and in use,
718 * but we get here, check if we are running with prefers
719 * non-mounted drives. In that case, we have selected a
720 * non-used drive and our one and only volume is mounted
721 * elsewhere, so we bail out and retry using that drive.
723 if (dcr->found_in_use() && !rctx.PreferMountedVols) {
724 rctx.PreferMountedVols = true;
725 if (dcr->VolumeName[0]) {
726 dcr->unreserve_device(false);
731 * Note. Under some circumstances, the Director can hand us
732 * a Volume name that is not the same as the one on the current
733 * drive, and in that case, the call above to find the next
734 * volume will fail because in attempting to reserve the Volume
735 * the code will realize that we already have a tape mounted,
736 * and it will fail. This *should* only happen if there are
737 * writers, thus the following test. In that case, we simply
738 * bail out, and continue waiting, rather than plunging on
739 * and hoping that the operator can resolve the problem.
741 if (dcr->dev->num_writers != 0) {
742 if (dcr->VolumeName[0]) {
743 dcr->unreserve_device(false);
750 ok = reserve_device_for_read(dcr);
752 rctx.jcr->read_dcr = dcr;
753 Dmsg5(dbglvl, "Read reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
754 dcr->dev->num_reserved(),
755 dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
762 if (rctx.notify_dir) {
764 BSOCK *dir = rctx.jcr->dir_bsock;
765 pm_strcpy(dev_name, rctx.device->hdr.name);
766 bash_spaces(dev_name);
767 ok = dir->fsend(OK_device, dev_name.c_str()); /* Return real device name */
768 Dmsg1(dbglvl, ">dird: %s", dir->msg);
770 dcr->unreserve_device(false);
778 rctx.have_volume = false;
779 rctx.VolumeName[0] = 0;
780 Dmsg0(dbglvl, "Not OK.\n");
786 * We reserve the device for appending by incrementing
787 * num_reserved(). We do virtually all the same work that
788 * is done in acquire_device_for_append(), but we do
789 * not attempt to mount the device. This routine allows
790 * the DIR to reserve multiple devices before *really*
791 * starting the job. It also permits the SD to refuse
792 * certain devices (not up, ...).
794 * Note, in reserving a device, if the device is for the
795 * same pool and the same pool type, then it is acceptable.
796 * The Media Type has already been checked. If we are
797 * the first tor reserve the device, we put the pool
798 * name and pool type in the device record.
800 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
803 DEVICE *dev = dcr->dev;
806 ASSERT2(dcr, "No dcr in reserve_device_for_append!");
807 if (job_canceled(jcr)) {
813 /* If device is being read or reserved for read, we cannot write it */
814 if (dev->can_read() || dev->is_reserved_for_read()) {
815 Mmsg(jcr->errmsg, _("3603 JobId=%u %s device %s is busy reading.\n"),
816 jcr->JobId, dev->print_type(), dev->print_name());
817 queue_reserve_message(jcr);
818 Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
822 /* If device is unmounted, we are out of luck */
823 if (dev->is_device_unmounted()) {
824 Mmsg(jcr->errmsg, _("3604 JobId=%u %s device %s is BLOCKED due to user unmount.\n"),
825 jcr->JobId, dev->print_type(), dev->print_name());
826 queue_reserve_message(jcr);
827 Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
831 Dmsg2(dbglvl, "reserve_append %s device is %s\n", dev->print_type(), dev->print_name());
833 /* Now do detailed tests ... */
834 if (can_reserve_drive(dcr, rctx) != 1) {
835 Dmsg0(dbglvl, "can_reserve_drive!=1\n");
839 /* Note: on failure this returns jcr->errmsg properly edited */
840 if (generate_plugin_event(jcr, bsdEventDeviceTryOpen, dcr) != bRC_OK) {
841 queue_reserve_message(jcr);
844 dcr->set_reserved_for_append();
853 * We "reserve" the drive by setting the ST_READ bit. No one else
854 * should touch the drive until that is cleared.
855 * This allows the DIR to "reserve" the device before actually
858 static bool reserve_device_for_read(DCR *dcr)
860 DEVICE *dev = dcr->dev;
864 ASSERT2(dcr, "No dcr in reserve_device_for_read!");
865 if (job_canceled(jcr)) {
871 if (dev->is_device_unmounted()) {
872 Mmsg(jcr->errmsg, _("3601 JobId=%u %s device %s is BLOCKED due to user unmount.\n"),
873 jcr->JobId, dev->print_type(), dev->print_name());
874 queue_reserve_message(jcr);
875 Dmsg1(dbglvl, "Device %s is BLOCKED due to user unmount.\n", dev->print_name());
879 if (dev->is_busy()) {
880 Mmsg(jcr->errmsg, _("3602 JobId=%u %s device %s is busy (already reading/writing)."
881 " read=%d, writers=%d reserved=%d\n"),
882 jcr->JobId, dev->print_type(), dev->print_name(),
883 dev->state & ST_READ?1:0, dev->num_writers, dev->num_reserved());
884 queue_reserve_message(jcr);
885 Dmsg4(dbglvl, "Device %s is busy ST_READ=%d num_writers=%d reserved=%d.\n",
887 dev->state & ST_READ?1:0, dev->num_writers, dev->num_reserved());
891 /* Note: on failure this returns jcr->errmsg properly edited */
892 if (generate_plugin_event(jcr, bsdEventDeviceTryOpen, dcr) != bRC_OK) {
893 queue_reserve_message(jcr);
897 dcr->set_reserved_for_read();
905 static bool is_max_jobs_ok(DCR *dcr)
907 DEVICE *dev = dcr->dev;
910 Dmsg5(dbglvl, "MaxJobs=%d Jobs=%d reserves=%d Status=%s Vol=%s\n",
911 dcr->VolCatInfo.VolCatMaxJobs,
912 dcr->VolCatInfo.VolCatJobs, dev->num_reserved(),
913 dcr->VolCatInfo.VolCatStatus,
915 /* Limit max concurrent jobs on this drive */
916 if (dev->max_concurrent_jobs > 0 && dev->max_concurrent_jobs <=
917 (uint32_t)(dev->num_writers + dev->num_reserved())) {
918 /* Max Concurrent Jobs depassed or already reserved */
919 Mmsg(jcr->errmsg, _("3609 JobId=%u Max concurrent jobs=%d exceeded on %s device %s.\n"),
920 (uint32_t)jcr->JobId, dev->max_concurrent_jobs,
921 dev->print_type(), dev->print_name());
922 queue_reserve_message(jcr);
923 Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
926 if (strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0) {
930 if (dcr->VolCatInfo.VolCatMaxJobs > 0 && dcr->VolCatInfo.VolCatMaxJobs <=
931 (dcr->VolCatInfo.VolCatJobs + dev->num_reserved())) {
932 /* Max Job Vols depassed or already reserved */
933 Mmsg(jcr->errmsg, _("3611 JobId=%u Volume max jobs=%d exceeded on %s device %s.\n"),
934 (uint32_t)jcr->JobId, dcr->VolCatInfo.VolCatMaxJobs,
935 dev->print_type(), dev->print_name());
936 queue_reserve_message(jcr);
937 Dmsg1(dbglvl, "reserve dev failed: %s", jcr->errmsg);
938 return false; /* wait */
944 static int is_pool_ok(DCR *dcr)
946 DEVICE *dev = dcr->dev;
949 /* Now check if we want the same Pool and pool type */
950 if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
951 strcmp(dev->pool_type, dcr->pool_type) == 0) {
952 /* OK, compatible device */
953 Dmsg1(dbglvl, "OK dev: %s num_writers=0, reserved, pool matches\n", dev->print_name());
956 /* Drive Pool not suitable for us */
958 "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on %s device %s.\n"),
959 (uint32_t)jcr->JobId, dcr->pool_name, dev->pool_name,
960 dev->num_reserved(), dev->print_type(), dev->print_name());
961 Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
962 queue_reserve_message(jcr);
968 * Returns: 1 if drive can be reserved
969 * 0 if we should wait
970 * -1 on error or impossibility
972 static int can_reserve_drive(DCR *dcr, RCTX &rctx)
974 DEVICE *dev = dcr->dev;
977 Dmsg5(dbglvl, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
978 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
979 rctx.autochanger_only, rctx.any_drive);
981 /* Check for max jobs on this Volume */
982 if (!is_max_jobs_ok(dcr)) {
986 /* setting any_drive overrides PreferMountedVols flag */
987 if (!rctx.any_drive) {
989 * When PreferMountedVols is set, we keep track of the
990 * drive in use that has the least number of writers, then if
991 * no unmounted drive is found, we try that drive. This
992 * helps spread the load to the least used drives.
994 if (rctx.try_low_use_drive && dev == rctx.low_use_drive) {
995 Dmsg2(dbglvl, "OK dev=%s == low_drive=%s.\n",
996 dev->print_name(), rctx.low_use_drive->print_name());
999 /* If he wants a free drive, but this one is busy, no go */
1000 if (!rctx.PreferMountedVols && dev->is_busy()) {
1001 /* Save least used drive */
1002 if ((dev->num_writers + dev->num_reserved()) < rctx.num_writers) {
1003 rctx.num_writers = dev->num_writers + dev->num_reserved();
1004 rctx.low_use_drive = dev;
1005 Dmsg2(dbglvl, "set low use drive=%s num_writers=%d\n",
1006 dev->print_name(), rctx.num_writers);
1008 Dmsg1(dbglvl, "not low use num_writers=%d\n", dev->num_writers+dev->num_reserved());
1010 Mmsg(jcr->errmsg, _("3605 JobId=%u wants free drive but %s device %s is busy.\n"),
1011 jcr->JobId, dev->print_type(), dev->print_name());
1012 queue_reserve_message(jcr);
1013 Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
1017 /* Check for prefer mounted volumes */
1018 if (rctx.PreferMountedVols && !dev->vol && dev->is_tape()) {
1019 Mmsg(jcr->errmsg, _("3606 JobId=%u prefers mounted drives, but %s device %s has no Volume.\n"),
1020 jcr->JobId, dev->print_type(), dev->print_name());
1021 queue_reserve_message(jcr);
1022 Dmsg1(dbglvl, "Failed: %s", jcr->errmsg);
1023 return 0; /* No volume mounted */
1026 /* Check for exact Volume name match */
1027 /* ***FIXME*** for Disk, we can accept any volume that goes with this
1030 if (rctx.exact_match && rctx.have_volume) {
1032 Dmsg5(dbglvl, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
1033 rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
1034 rctx.autochanger_only, rctx.any_drive);
1035 Dmsg4(dbglvl, "have_vol=%d have=%s resvol=%s want=%s\n",
1036 rctx.have_volume, dev->VolHdr.VolumeName,
1037 dev->vol?dev->vol->vol_name:"*none*", rctx.VolumeName);
1038 ok = strcmp(dev->VolHdr.VolumeName, rctx.VolumeName) == 0 ||
1039 (dev->vol && strcmp(dev->vol->vol_name, rctx.VolumeName) == 0);
1041 Mmsg(jcr->errmsg, _("3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on %s device %s.\n"),
1042 jcr->JobId, rctx.VolumeName, dev->VolHdr.VolumeName,
1043 dev->print_type(), dev->print_name());
1044 queue_reserve_message(jcr);
1045 Dmsg3(dbglvl, "not OK: dev have=%s resvol=%s want=%s\n",
1046 dev->VolHdr.VolumeName, dev->vol?dev->vol->vol_name:"*none*", rctx.VolumeName);
1049 if (!dcr->can_i_use_volume()) {
1050 return 0; /* fail if volume on another drive */
1055 /* Check for unused autochanger drive */
1056 if (rctx.autochanger_only && !dev->is_busy() &&
1057 dev->VolHdr.VolumeName[0] == 0) {
1058 /* Device is available but not yet reserved, reserve it for us */
1059 Dmsg1(dbglvl, "OK Res Unused autochanger %s.\n", dev->print_name());
1060 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1061 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1062 return 1; /* reserve drive */
1066 * Handle the case that there are no writers
1068 if (dev->num_writers == 0) {
1069 /* Now check if there are any reservations on the drive */
1070 if (dev->num_reserved()) {
1071 return is_pool_ok(dcr);
1072 } else if (dev->can_append()) {
1073 if (is_pool_ok(dcr)) {
1076 /* Changing pool, unload old tape if any in drive */
1077 Dmsg0(dbglvl, "OK dev: num_writers=0, not reserved, pool change, unload changer\n");
1078 /* ***FIXME*** use set_unload() */
1079 unload_autochanger(dcr, -1);
1082 /* Device is available but not yet reserved, reserve it for us */
1083 Dmsg1(dbglvl, "OK Dev avail reserved %s\n", dev->print_name());
1084 bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
1085 bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
1086 return 1; /* reserve drive */
1090 * Check if the device is in append mode with writers (i.e.
1091 * available if pool is the same).
1093 if (dev->can_append() || dev->num_writers > 0) {
1094 return is_pool_ok(dcr);
1096 Pmsg1(000, _("Logic error!!!! JobId=%u Should not get here.\n"), (int)jcr->JobId);
1097 Mmsg(jcr->errmsg, _("3910 JobId=%u Logic error!!!! %s device %s Should not get here.\n"),
1098 jcr->JobId, dev->print_type(), dev->print_name());
1099 queue_reserve_message(jcr);
1100 Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
1101 return -1; /* error, should not get here */
1103 Mmsg(jcr->errmsg, _("3911 JobId=%u failed reserve %s device %s.\n"),
1104 jcr->JobId, dev->print_type(), dev->print_name());
1105 queue_reserve_message(jcr);
1106 Dmsg1(dbglvl, "Failed: No reserve %s\n", dev->print_name());
1112 * Queue a reservation error or failure message for this jcr
1114 static void queue_reserve_message(JCR *jcr)
1122 msgs = jcr->reserve_msgs;
1127 * Look for duplicate message. If found, do
1130 for (i=msgs->size()-1; i >= 0; i--) {
1131 msg = (char *)msgs->get(i);
1135 /* Comparison based on 4 digit message number */
1136 if (strncmp(msg, jcr->errmsg, 4) == 0) {
1140 /* Message unique, so insert it */
1141 jcr->reserve_msgs->push(bstrdup(jcr->errmsg));
1148 * Send any reservation messages queued for this jcr
1150 void send_drive_reserve_messages(JCR *jcr, void sendit(const char *msg, int len, void *sarg), void *arg)
1157 msgs = jcr->reserve_msgs;
1158 if (!msgs || msgs->size() == 0) {
1161 for (i=msgs->size()-1; i >= 0; i--) {
1162 msg = (char *)msgs->get(i);
1164 sendit(" ", 3, arg);
1165 sendit(msg, strlen(msg), arg);
1176 * Pop and release any reservations messages
1178 static void pop_reserve_messages(JCR *jcr)
1184 msgs = jcr->reserve_msgs;
1188 while ((msg = (char *)msgs->pop())) {
1196 * Also called from acquire.c
1198 void release_reserve_messages(JCR *jcr)
1200 pop_reserve_messages(jcr);
1202 if (!jcr->reserve_msgs) {
1205 delete jcr->reserve_msgs;
1206 jcr->reserve_msgs = NULL;