X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fstored%2Freserve.c;h=280abd01b60ddd20150ece3ae8e29fd6151600bd;hb=cfc2aa18dbf9afb34902a14473152f388836538d;hp=f2c81f4f31b8d679a35c16503d020e7a6633e938;hpb=9bdee7bbe252559fb486b0bb71ab3db8097911bd;p=bacula%2Fbacula diff --git a/bacula/src/stored/reserve.c b/bacula/src/stored/reserve.c index f2c81f4f31..280abd01b6 100644 --- a/bacula/src/stored/reserve.c +++ b/bacula/src/stored/reserve.c @@ -53,7 +53,7 @@ static bool reserve_device_for_append(DCR *dcr, RCTX &rctx); static bool use_storage_cmd(JCR *jcr); static void queue_reserve_message(JCR *jcr); static void pop_reserve_messages(JCR *jcr); -void switch_device(DCR *dcr, DEVICE *dev); +//void switch_device(DCR *dcr, DEVICE *dev); /* Requests from the Director daemon */ static char use_storage[] = "use storage=%127s media_type=%127s " @@ -170,7 +170,7 @@ enum { debug_nolock = false }; -static void debug_list_volumes(const char *imsg) +void debug_list_volumes(const char *imsg) { VOLRES *vol; POOL_MEM msg(PM_MESSAGE); @@ -178,26 +178,15 @@ static void debug_list_volumes(const char *imsg) lock_volumes(); foreach_dlist(vol, vol_list) { if (vol->dev) { - Mmsg(msg, "List %s: %s reserved=%d on device %s\n", imsg, - vol->vol_name, vol->is_reserved(), vol->dev->print_name()); + Mmsg(msg, "List %s: %s in_use=%d on device %s\n", imsg, + vol->vol_name, vol->is_in_use(), vol->dev->print_name()); } else { - Mmsg(msg, "List %s: %s reserved=%d no dev\n", imsg, vol->vol_name, - vol->is_reserved()); + Mmsg(msg, "List %s: %s in_use=%d no dev\n", imsg, vol->vol_name, + vol->is_in_use()); } Dmsg1(dbglvl, "%s", msg.c_str()); } -#ifdef xxx - DEVICE *dev = NULL; - foreach_dlist(vol, vol_list) { - if (vol->dev == dev) { - Dmsg0(dbglvl, "Two Volumes on same device.\n"); - ASSERT(0); - dev = vol->dev; - } - } -#endif - unlock_volumes(); } @@ -217,13 +206,13 @@ void list_volumes(void sendit(const char *msg, int len, void *sarg), void *arg) if (dev) { len = Mmsg(msg, "%s on device %s\n", vol->vol_name, dev->print_name()); sendit(msg.c_str(), len, arg); - len = Mmsg(msg, " Reader=%d writers=%d devres=%d volres=%d\n", - dev->can_read()?1:0, dev->num_writers, dev->reserved_device, - vol->is_reserved()); + len = Mmsg(msg, " Reader=%d writers=%d devres=%d volinuse=%d\n", + dev->can_read()?1:0, dev->num_writers, dev->num_reserved(), + vol->is_in_use()); sendit(msg.c_str(), len, arg); } else { - len = Mmsg(msg, "%s no device. volres= %d\n", vol->vol_name, - vol->is_reserved()); + len = Mmsg(msg, "%s no device. volinuse= %d\n", vol->vol_name, + vol->is_in_use()); sendit(msg.c_str(), len, arg); } } @@ -260,7 +249,6 @@ static void free_vol_item(VOLRES *vol) } } - /* * Put a new Volume entry in the Volume list. This * effectively reserves the volume so that it will @@ -277,7 +265,7 @@ static void free_vol_item(VOLRES *vol) * * 1. The Volume list entry must be attached to the drive (rather than * attached to a job as it currently is. I.e. the drive that "owns" - * the volume (reserved, in use, mounted) + * the volume (in use, mounted) * must point to the volume (still to be maintained in a list). * * 2. The Volume is entered in the list when a drive is reserved. @@ -337,8 +325,8 @@ VOLRES *reserve_volume(DCR *dcr, const char *VolumeName) */ if (dev->vol) { vol = dev->vol; - Dmsg4(dbglvl, "Vol attached=%s, newvol=%s volres=%d on %s\n", - vol->vol_name, VolumeName, vol->is_reserved(), dev->print_name()); + Dmsg4(dbglvl, "Vol attached=%s, newvol=%s volinuse=%d on %s\n", + vol->vol_name, VolumeName, vol->is_in_use(), dev->print_name()); /* * Make sure we don't remove the current volume we are inserting * because it was probably inserted by another job, or it @@ -347,19 +335,20 @@ VOLRES *reserve_volume(DCR *dcr, const char *VolumeName) if (strcmp(vol->vol_name, VolumeName) == 0) { Dmsg2(dbglvl, "=== set reserved vol=%s dev=%s\n", VolumeName, vol->dev->print_name()); - vol->set_reserved(); /* retake vol if released previously */ + vol->set_in_use(); /* retake vol if released previously */ dcr->reserved_volume = true; /* reserved volume */ goto get_out; /* Volume already on this device */ } else { /* Don't release a volume if it was reserved by someone other than us */ - if (vol->is_reserved() && !dcr->reserved_volume) { + if (vol->is_in_use() && !dcr->reserved_volume) { Dmsg1(dbglvl, "Cannot free vol=%s. It is reserved.\n", vol->vol_name); vol = NULL; /* vol in use */ goto get_out; } Dmsg2(dbglvl, "reserve_vol free vol=%s at %p\n", vol->vol_name, vol->vol_name); free_volume(dev); - dcr->unload_device = true; /* have to unload current volume */ +// volume_unused(dcr); + dev->set_unload(); /* have to unload current volume */ debug_list_volumes("reserve_vol free"); } } @@ -387,18 +376,35 @@ VOLRES *reserve_volume(DCR *dcr, const char *VolumeName) nvol->dev = NULL; /* don't zap dev entry */ free_vol_item(nvol); - /* Check if we are trying to use the Volume on a different drive */ + /* + * Check if we are trying to use the Volume on a different drive + * dev is our device + * vol->dev is where the Volume we want is + */ if (dev != vol->dev) { /* Caller wants to switch Volume to another device */ if (!vol->dev->is_busy() && !vol->is_swapping()) { - vol->set_swapping(); - dcr->swap_dev = vol->dev; /* remember to get this vol */ + int32_t slot; Dmsg3(dbglvl, "==== Swap vol=%s from dev=%s to %s\n", VolumeName, vol->dev->print_name(), dev->print_name()); + free_volume(dev); /* free any volume attached to our drive */ +// volume_unused(dcr); + dev->set_unload(); /* Unload any volume that is on our drive */ + dcr->dev = vol->dev; /* temp point to other dev */ + slot = get_autochanger_loaded_slot(dcr); /* get slot on other drive */ + dcr->dev = dev; /* restore dev */ + vol->set_slot(slot); /* save slot */ + vol->dev->set_unload(); /* unload the other drive */ + vol->set_swapping(); /* swap from other drive */ + dev->swap_dev = vol->dev; /* remember to get this vol */ + dev->set_load(); /* then reload on our drive */ + vol->dev->vol = NULL; /* remove volume from other drive */ + vol->dev = dev; /* point the Volume at our drive */ + dev->vol = vol; /* point our drive at the Volume */ } else { Dmsg3(dbglvl, "==== Swap not possible Vol busy vol=%s from dev=%s to %s\n", VolumeName, vol->dev->print_name(), dev->print_name()); - vol = NULL; /* device busy */ + vol = NULL; /* device busy */ goto get_out; } } else { @@ -410,10 +416,11 @@ VOLRES *reserve_volume(DCR *dcr, const char *VolumeName) get_out: if (vol) { - Dmsg2(dbglvl, "=== set reserved. vol=%s dev=%s\n", vol->vol_name, + Dmsg2(dbglvl, "=== set in_use. vol=%s dev=%s\n", vol->vol_name, vol->dev->print_name()); - vol->set_reserved(); + vol->set_in_use(); dcr->reserved_volume = true; + bstrncpy(dcr->VolumeName, vol->vol_name, sizeof(dcr->VolumeName)); } debug_list_volumes("end new volume"); unlock_volumes(); @@ -424,6 +431,7 @@ get_out: * Switch from current device to given device * (not yet used) */ +#ifdef xxx void switch_device(DCR *dcr, DEVICE *dev) { DCR save_dcr; @@ -443,11 +451,11 @@ void switch_device(DCR *dcr, DEVICE *dev) bstrncpy(dcr->pool_type, save_dcr.pool_type, sizeof(dcr->pool_type)); bstrncpy(dcr->dev_name, dev->dev_name, sizeof(dcr->dev_name)); - dev->reserved_device++; - dcr->reserved_device = true; +// dcr->set_reserved(); dev->dunlock(); } +#endif /* * Search for a Volume name in the Volume list. @@ -455,43 +463,56 @@ void switch_device(DCR *dcr, DEVICE *dev) * Returns: VOLRES entry on success * NULL if the Volume is not in the list */ -VOLRES *find_volume(DCR *dcr) +VOLRES *find_volume(const char *VolumeName) { VOLRES vol, *fvol; /* Do not lock reservations here */ lock_volumes(); - vol.vol_name = bstrdup(dcr->VolumeName); + vol.vol_name = bstrdup(VolumeName); fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare); free(vol.vol_name); - Dmsg2(dbglvl, "find_vol=%s found=%d\n", dcr->VolumeName, fvol!=NULL); + Dmsg2(dbglvl, "find_vol=%s found=%d\n", VolumeName, fvol!=NULL); debug_list_volumes("find_volume"); unlock_volumes(); return fvol; } +void DCR::set_reserved() +{ + m_reserved = true; + Dmsg2(dbglvl, "Inc reserve=%d dev=%s\n", dev->num_reserved(), dev->print_name()); + dev->inc_reserved(); +} + +void DCR::clear_reserved() +{ + if (m_reserved) { + m_reserved = false; + dev->dec_reserved(); + Dmsg2(dbglvl, "Dec reserve=%d dev=%s\n", dev->num_reserved(), dev->print_name()); + } +} + /* * Remove any reservation from a drive and tell the system * that the volume is unused at least by us. */ -void unreserve_device(DCR *dcr) +void DCR::unreserve_device() { - DEVICE *dev = dcr->dev; lock_volumes(); - if (dcr->reserved_device) { - dcr->reserved_device = false; - dcr->reserved_volume = false; - dev->reserved_device--; - Dmsg2(dbglvl, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name()); + if (is_reserved()) { + clear_reserved(); + reserved_volume = false; /* If we set read mode in reserving, remove it */ if (dev->can_read()) { dev->clear_read(); } if (dev->num_writers < 0) { - Jmsg1(dcr->jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers); + Jmsg1(jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers); dev->num_writers = 0; } - if (dev->reserved_device == 0 && dev->num_writers == 0) { - volume_unused(dcr); + if (dev->num_reserved() == 0 && dev->num_writers == 0) { + volume_unused(this); } } unlock_volumes(); @@ -530,7 +551,7 @@ bool volume_unused(DCR *dcr) } #endif #ifdef xxx - if (dev->num_writers > 0 || dev->reserved_device > 0) { + if (dev->num_writers > 0 || dev->num_reserved() > 0) { ASSERT(0); } #endif @@ -541,11 +562,9 @@ bool volume_unused(DCR *dcr) * explicitly read in this drive. This allows the SD to remember * where the tapes are or last were. */ - Dmsg3(dbglvl, "=== mark not reserved vol=%s num_writers=%d dev_reserved=%d\n", - dev->vol->vol_name, dev->num_writers, dev->reserved_device); - dev->vol->clear_reserved(); - Dmsg2(dbglvl, "=== set not reserved. Vol=%s dev=%s\n", dev->vol->vol_name, - dev->print_name()); + Dmsg4(dbglvl, "=== set not reserved vol=%s num_writers=%d dev_reserved=%d dev=%s\n", + dev->vol->vol_name, dev->num_writers, dev->num_reserved(), dev->print_name()); + dev->vol->clear_in_use(); if (dev->is_tape() || dev->is_autochanger()) { return true; } else { @@ -570,11 +589,14 @@ bool free_volume(DEVICE *dev) } lock_volumes(); vol = dev->vol; - dev->vol = NULL; - vol_list->remove(vol); - Dmsg2(dbglvl, "=== free_volume %s dev=%s\n", vol->vol_name, dev->print_name()); - free_vol_item(vol); - debug_list_volumes("free_volume"); + /* Don't free a volume while it is being swapped */ + if (!vol->is_swapping()) { + dev->vol = NULL; + vol_list->remove(vol); + Dmsg2(dbglvl, "=== remove volume %s dev=%s\n", vol->vol_name, dev->print_name()); + free_vol_item(vol); + debug_list_volumes("free_volume"); + } unlock_volumes(); return true; } @@ -611,34 +633,35 @@ void free_volume_list() unlock_volumes(); } -bool is_volume_in_use(DCR *dcr) +bool DCR::can_i_use_volume() { - bool rtn = false; + bool rtn = true; VOLRES *vol; lock_volumes(); - vol = find_volume(dcr); + vol = find_volume(VolumeName); if (!vol) { - Dmsg1(dbglvl, "Vol=%s not in use.\n", dcr->VolumeName); + Dmsg1(dbglvl, "Vol=%s not in use.\n", VolumeName); goto get_out; /* vol not in list */ } ASSERT(vol->dev != NULL); - if (dcr->dev == vol->dev) { /* same device OK */ - Dmsg1(dbglvl, "Vol=%s on same dev.\n", dcr->VolumeName); + if (dev == vol->dev) { /* same device OK */ + Dmsg1(dbglvl, "Vol=%s on same dev.\n", VolumeName); goto get_out; } else { - Dmsg3(dbglvl, "Vol=%s on %s we have %s\n", dcr->VolumeName, - vol->dev->print_name(), dcr->dev->print_name()); + Dmsg3(dbglvl, "Vol=%s on %s we have %s\n", VolumeName, + vol->dev->print_name(), dev->print_name()); } + /* ***FIXME*** check this ... */ if (!vol->dev->is_busy()) { - Dmsg2(dbglvl, "Vol=%s dev=%s not busy.\n", dcr->VolumeName, vol->dev->print_name()); + Dmsg2(dbglvl, "Vol=%s dev=%s not busy.\n", VolumeName, vol->dev->print_name()); goto get_out; } else { - Dmsg2(dbglvl, "Vol=%s dev=%s busy.\n", dcr->VolumeName, vol->dev->print_name()); + Dmsg2(dbglvl, "Vol=%s dev=%s busy.\n", VolumeName, vol->dev->print_name()); } - Dmsg2(dbglvl, "Vol=%s in use by %s.\n", dcr->VolumeName, vol->dev->print_name()); - rtn = true; + Dmsg2(dbglvl, "Vol=%s in use by %s.\n", VolumeName, vol->dev->print_name()); + rtn = false; get_out: unlock_volumes(); @@ -771,9 +794,6 @@ static bool use_storage_cmd(JCR *jcr) rctx.PreferMountedVols = false; rctx.exact_match = false; rctx.autochanger_only = true; - Dmsg5(dbglvl, "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); if ((ok = find_suitable_device_for_job(jcr, rctx))) { break; } @@ -786,9 +806,6 @@ static bool use_storage_cmd(JCR *jcr) rctx.try_low_use_drive = false; } rctx.autochanger_only = false; - Dmsg5(dbglvl, "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); if ((ok = find_suitable_device_for_job(jcr, rctx))) { break; } @@ -801,25 +818,16 @@ static bool use_storage_cmd(JCR *jcr) rctx.PreferMountedVols = true; rctx.exact_match = true; rctx.autochanger_only = false; - Dmsg5(dbglvl, "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); if ((ok = find_suitable_device_for_job(jcr, rctx))) { break; } /* Look for any mounted drive */ rctx.exact_match = false; - Dmsg5(dbglvl, "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); if ((ok = find_suitable_device_for_job(jcr, rctx))) { break; } /* Try any drive */ rctx.any_drive = true; - Dmsg5(dbglvl, "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); if ((ok = find_suitable_device_for_job(jcr, rctx))) { break; } @@ -912,9 +920,9 @@ bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx) } else { dirstore = jcr->read_store; } - Dmsg4(dbglvl, "PrefMnt=%d exact=%d suitable=%d chgronly=%d\n", - rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device, - rctx.autochanger_only); + Dmsg5(dbglvl, "Start find_suit_dev 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); /* * If the appropriate conditions of this if are met, namely that @@ -1025,10 +1033,10 @@ bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx) Dmsg0(dbglvl, "deleted temp vol list\n"); Dmsg0(dbglvl, "unlock volumes\n"); unlock_volumes(); - debug_list_volumes("=== After free temp table\n"); + debug_list_volumes("after free temp table"); } if (ok) { - Dmsg1(dbglvl, "Usable dev found. Vol=%s from in-use vols list\n", rctx.VolumeName); + Dmsg1(dbglvl, "OK dev found. Vol=%s from in-use vols list\n", rctx.VolumeName); return true; } @@ -1060,7 +1068,9 @@ bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx) } } if (ok) { - Dmsg1(dbglvl, "Usable dev found. Vol=%s\n", rctx.VolumeName); + Dmsg1(dbglvl, "OK dev found. Vol=%s\n", rctx.VolumeName); + } else { + Dmsg0(dbglvl, "Leave find_suit_dev: no dev found.\n"); } return ok; } @@ -1090,10 +1100,10 @@ int search_res_for_device(RCTX &rctx) /* Debug code */ if (rctx.store->append == SD_APPEND) { Dmsg2(dbglvl, "Device %s reserved=%d for append.\n", - rctx.device->hdr.name, rctx.jcr->dcr->dev->reserved_device); + rctx.device->hdr.name, rctx.jcr->dcr->dev->num_reserved()); } else { Dmsg2(dbglvl, "Device %s reserved=%d for read.\n", - rctx.device->hdr.name, rctx.jcr->read_dcr->dev->reserved_device); + rctx.device->hdr.name, rctx.jcr->read_dcr->dev->num_reserved()); } return stat; } @@ -1113,10 +1123,10 @@ int search_res_for_device(RCTX &rctx) /* Debug code */ if (rctx.store->append == SD_APPEND) { Dmsg2(dbglvl, "Device %s reserved=%d for append.\n", - rctx.device->hdr.name, rctx.jcr->dcr->dev->reserved_device); + rctx.device->hdr.name, rctx.jcr->dcr->dev->num_reserved()); } else { Dmsg2(dbglvl, "Device %s reserved=%d for read.\n", - rctx.device->hdr.name, rctx.jcr->read_dcr->dev->reserved_device); + rctx.device->hdr.name, rctx.jcr->read_dcr->dev->num_reserved()); } return stat; } @@ -1184,7 +1194,7 @@ static int reserve_device(RCTX &rctx) rctx.jcr->dcr = dcr; Dmsg5(dbglvl, "Reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n", - dcr->dev->reserved_device, + dcr->dev->num_reserved(), dcr->dev_name, dcr->media_type, dcr->pool_name, ok); Dmsg3(dbglvl, "Vol=%s num_writers=%d, have_vol=%d\n", rctx.VolumeName, dcr->dev->num_writers, rctx.have_volume); @@ -1214,10 +1224,10 @@ static int reserve_device(RCTX &rctx) * non-used drive and our one and only volume is mounted * elsewhere, so we bail out and retry using that drive. */ - if (dcr->volume_in_use && !rctx.PreferMountedVols) { + if (dcr->found_in_use() && !rctx.PreferMountedVols) { rctx.PreferMountedVols = true; if (dcr->VolumeName[0]) { - unreserve_device(dcr); + dcr->unreserve_device(); } goto bail_out; } @@ -1234,7 +1244,7 @@ static int reserve_device(RCTX &rctx) */ if (dcr->dev->num_writers != 0) { if (dcr->VolumeName[0]) { - unreserve_device(dcr); + dcr->unreserve_device(); } goto bail_out; } @@ -1245,7 +1255,7 @@ static int reserve_device(RCTX &rctx) if (ok) { rctx.jcr->read_dcr = dcr; Dmsg5(dbglvl, "Read reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n", - dcr->dev->reserved_device, + dcr->dev->num_reserved(), dcr->dev_name, dcr->media_type, dcr->pool_name, ok); } } @@ -1299,7 +1309,7 @@ static bool reserve_device_for_read(DCR *dcr) if (dev->is_busy()) { Dmsg4(dbglvl, "Device %s is busy ST_READ=%d num_writers=%d reserved=%d.\n", dev->print_name(), - dev->state & ST_READ?1:0, dev->num_writers, dev->reserved_device); + dev->state & ST_READ?1:0, dev->num_writers, dev->num_reserved()); Mmsg(jcr->errmsg, _("3602 JobId=%u device %s is busy (already reading/writing).\n"), jcr->JobId, dev->print_name()); queue_reserve_message(jcr); @@ -1309,9 +1319,7 @@ static bool reserve_device_for_read(DCR *dcr) dev->clear_append(); dev->set_read(); ok = true; - dev->reserved_device++; - Dmsg3(dbglvl, "Inc reserve=%d dev=%s %p\n", dev->reserved_device, dev->print_name(), dev); - dcr->reserved_device = true; + dcr->set_reserved(); bail_out: dev->dunlock(); @@ -1320,8 +1328,8 @@ bail_out: /* - * We reserve the device for appending by incrementing the - * reserved_device. We do virtually all the same work that + * We reserve the device for appending by incrementing + * num_reserved(). We do virtually all the same work that * is done in acquire_device_for_append(), but we do * not attempt to mount the device. This routine allows * the DIR to reserve multiple devices before *really* @@ -1370,10 +1378,7 @@ static bool reserve_device_for_append(DCR *dcr, RCTX &rctx) goto bail_out; } - dev->reserved_device++; - Dmsg3(dbglvl, "Inc reserve=%d dev=%s %p\n", dev->reserved_device, - dev->print_name(), dev); - dcr->reserved_device = true; + dcr->set_reserved(); ok = true; bail_out: @@ -1397,7 +1402,7 @@ static int is_pool_ok(DCR *dcr) Mmsg(jcr->errmsg, _( "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %s.\n"), (uint32_t)jcr->JobId, dcr->pool_name, dev->pool_name, - dev->reserved_device, dev->print_name()); + dev->num_reserved(), dev->print_name()); queue_reserve_message(jcr); Dmsg2(dbglvl, "failed: busy num_writers=0, reserved, pool=%s wanted=%s\n", dev->pool_name, dcr->pool_name); @@ -1410,12 +1415,16 @@ static bool is_max_jobs_ok(DCR *dcr) DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; - Dmsg4(dbglvl, "MaxJobs=%d Jobs=%d reserves=%d Vol=%s\n", + Dmsg5(dbglvl, "MaxJobs=%d Jobs=%d reserves=%d Status=%s Vol=%s\n", dcr->VolCatInfo.VolCatMaxJobs, - dcr->VolCatInfo.VolCatJobs, dev->reserved_device, + dcr->VolCatInfo.VolCatJobs, dev->num_reserved(), + dcr->VolCatInfo.VolCatStatus, dcr->VolumeName); + if (strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0) { + return true; + } if (dcr->VolCatInfo.VolCatMaxJobs > 0 && dcr->VolCatInfo.VolCatMaxJobs <= - (dcr->VolCatInfo.VolCatJobs + dev->reserved_device)) { + (dcr->VolCatInfo.VolCatJobs + dev->num_reserved())) { /* Max Job Vols depassed or already reserved */ Mmsg(jcr->errmsg, _("3610 JobId=%u Volume max jobs exceeded on drive %s.\n"), (uint32_t)jcr->JobId, dev->print_name()); @@ -1461,13 +1470,13 @@ static int can_reserve_drive(DCR *dcr, RCTX &rctx) /* 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; + if ((dev->num_writers + dev->num_reserved()) < rctx.num_writers) { + rctx.num_writers = dev->num_writers + dev->num_reserved(); rctx.low_use_drive = dev; Dmsg2(dbglvl, "set low use drive=%s num_writers=%d\n", dev->print_name(), rctx.num_writers); } else { - Dmsg1(dbglvl, "not low use num_writers=%d\n", dev->num_writers+dev->reserved_device); + Dmsg1(dbglvl, "not low use num_writers=%d\n", dev->num_writers+dev->num_reserved()); } Dmsg0(dbglvl, "failed: !prefMnt && busy.\n"); Mmsg(jcr->errmsg, _("3605 JobId=%u wants free drive but device %s is busy.\n"), @@ -1508,7 +1517,7 @@ static int can_reserve_drive(DCR *dcr, RCTX &rctx) dev->VolHdr.VolumeName, dev->vol?dev->vol->vol_name:"*none*", rctx.VolumeName); return 0; } - if (is_volume_in_use(dcr)) { + if (!dcr->can_i_use_volume()) { return 0; /* fail if volume on another drive */ } } @@ -1529,7 +1538,7 @@ static int can_reserve_drive(DCR *dcr, RCTX &rctx) */ if (dev->num_writers == 0) { /* Now check if there are any reservations on the drive */ - if (dev->reserved_device) { + if (dev->num_reserved()) { return is_pool_ok(dcr); } else if (dev->can_append()) { if (is_pool_ok(dcr)) { @@ -1537,7 +1546,8 @@ static int can_reserve_drive(DCR *dcr, RCTX &rctx) } else { /* Changing pool, unload old tape if any in drive */ Dmsg0(dbglvl, "OK dev: num_writers=0, not reserved, pool change, unload changer\n"); - unload_autochanger(dcr, 0); + /* ***FIXME*** use set_unload() */ + unload_autochanger(dcr, -1); } } /* Device is available but not yet reserved, reserve it for us */