+ Dmsg5(110, "PrefMnt=%d exact=%d suitable=%d chgronly=%d any=%d\n",
+ rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
+ rctx.autochanger_only, rctx.any_drive);
+
+ /* setting any_drive overrides PreferMountedVols flag */
+ if (!rctx.any_drive) {
+ /*
+ * When PreferMountedVols is set, we keep track of the
+ * drive in use that has the least number of writers, then if
+ * no unmounted drive is found, we try that drive. This
+ * helps spread the load to the least used drives.
+ */
+ if (rctx.try_low_use_drive && dev == rctx.low_use_drive) {
+ Dmsg3(110, "OK dev=%s == low_drive=%s. JobId=%u\n",
+ dev->print_name(), rctx.low_use_drive->print_name(), jcr->JobId);
+ return 1;
+ }
+ /* If he wants a free drive, but this one is busy, no go */
+ if (!rctx.PreferMountedVols && dev->is_busy()) {
+ /* Save least used drive */
+ if ((dev->num_writers + dev->reserved_device) < rctx.num_writers) {
+ rctx.num_writers = dev->num_writers + dev->reserved_device;
+ rctx.low_use_drive = dev;
+ Dmsg2(110, "set low use drive=%s num_writers=%d\n", dev->print_name(),
+ rctx.num_writers);
+ } else {
+ Dmsg1(110, "not low use num_writers=%d\n", dev->num_writers+
+ dev->reserved_device);
+ }
+ Dmsg1(110, "failed: !prefMnt && busy. JobId=%u\n", jcr->JobId);
+ Mmsg(jcr->errmsg, _("3605 JobId=%u wants free drive but device %s is busy.\n"),
+ jcr->JobId, dev->print_name());
+ queue_reserve_message(jcr);
+ return 0;
+ }
+
+ /* Check for prefer mounted volumes */
+ if (rctx.PreferMountedVols && !dev->VolHdr.VolumeName[0] && dev->is_tape()) {
+ Mmsg(jcr->errmsg, _("3606 JobId=%u prefers mounted drives, but drive %s has no Volume.\n"),
+ jcr->JobId, dev->print_name());
+ queue_reserve_message(jcr);
+ Dmsg1(110, "failed: want mounted -- no vol JobId=%u\n", jcr->JobId);
+ return 0; /* No volume mounted */
+ }
+
+ /* Check for exact Volume name match */
+ if (rctx.exact_match && rctx.have_volume &&
+ strcmp(dev->VolHdr.VolumeName, rctx.VolumeName) != 0) {
+ Mmsg(jcr->errmsg, _("3607 JobId=%u wants Vol=\"%s\" drive has Vol=\"%s\" on drive %s.\n"),
+ jcr->JobId, rctx.VolumeName, dev->VolHdr.VolumeName,
+ dev->print_name());
+ queue_reserve_message(jcr);
+ Dmsg2(110, "failed: Not exact match have=%s want=%s\n",
+ dev->VolHdr.VolumeName, rctx.VolumeName);
+ return 0;
+ }
+ }
+
+ /* Check for unused autochanger drive */
+ if (rctx.autochanger_only && dev->num_writers == 0 &&
+ dev->VolHdr.VolumeName[0] == 0) {
+ /* Device is available but not yet reserved, reserve it for us */
+ Dmsg2(100, "OK Res Unused autochanger %s JobId=%u.\n",
+ dev->print_name(), jcr->JobId);
+ bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
+ bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
+ return 1; /* reserve drive */