diff --git a/WHATS_NEW b/WHATS_NEW index ff8da1d17..f0a764b89 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.104 - =================================== + Fix and improve logic for implicitely exclusive activations. Return success when LV cannot be activated because of volume_list filter. Return proper error state for remote exclusive activation. Fix missing lvmetad scan for PVs found on MD partitions. diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c index e59bd8e12..c1f6271e0 100644 --- a/lib/metadata/lv.c +++ b/lib/metadata/lv.c @@ -735,39 +735,62 @@ char *lv_host_dup(struct dm_pool *mem, const struct logical_volume *lv) return dm_pool_strdup(mem, lv->hostname ? : ""); } +static int _lv_is_exclusive(struct logical_volume *lv) +{ + /* Some devices require exlusivness */ + return seg_is_raid(first_seg(lv)) || + lv_is_origin(lv) || + lv_is_thin_type(lv); +} + int lv_active_change(struct cmd_context *cmd, struct logical_volume *lv, enum activation_change activate) { - if (activate == CHANGE_AN) { + switch (activate) { + case CHANGE_AN: +deactivate: log_verbose("Deactivating logical volume \"%s\"", lv->name); if (!deactivate_lv(cmd, lv)) return_0; - } else if ((activate == CHANGE_AE) || - seg_is_raid(first_seg(lv)) || - lv_is_origin(lv) || - lv_is_thin_type(lv)) { - if (activate == CHANGE_ALN) { - /* origin, thin or RAID - all others have _AE */ - /* other types of activation are implicitly exclusive */ - /* Note: the order of tests is mandatory */ - log_error("Cannot deactivate \"%s\" locally.", lv->name); - return 0; + break; + case CHANGE_ALN: + if (_lv_is_exclusive(lv)) { + if (!lv_is_active_locally(lv)) { + log_error("Cannot deactivate remotely exclusive device locally."); + return 0; + } + /* Unlock whole exclusive activation */ + goto deactivate; } - log_verbose("Activating logical volume \"%s\" exclusively.", - lv->name); - if (!activate_lv_excl(cmd, lv)) - return_0; - } else if (activate == CHANGE_ALN) { log_verbose("Deactivating logical volume \"%s\" locally.", lv->name); if (!deactivate_lv_local(cmd, lv)) return_0; - } else if ((activate == CHANGE_ALY) || (activate == CHANGE_AAY)) { - log_verbose("Activating logical volume \"%s\" locally.", + break; + case CHANGE_ALY: + case CHANGE_AAY: + if (_lv_is_exclusive(lv)) { + log_verbose("Activating logical volume \"%s\" exclusively locally.", + lv->name); + if (!activate_lv_excl_local(cmd, lv)) + return_0; + } else { + log_verbose("Activating logical volume \"%s\" locally.", + lv->name); + if (!activate_lv_local(cmd, lv)) + return_0; + } + break; + case CHANGE_AE: +exclusive: + log_verbose("Activating logical volume \"%s\" exclusively.", lv->name); - if (!activate_lv_local(cmd, lv)) + if (!activate_lv_excl(cmd, lv)) return_0; - } else { /* CHANGE_AY */ + break; + default: /* CHANGE_AY */ + if (_lv_is_exclusive(lv)) + goto exclusive; log_verbose("Activating logical volume \"%s\".", lv->name); if (!activate_lv(cmd, lv)) return_0; diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c index 020b365a1..4a224e4e8 100644 --- a/lib/metadata/lv_manip.c +++ b/lib/metadata/lv_manip.c @@ -2892,8 +2892,8 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah, continue; } - /* For clearing, simply activate exclusive locally */ - if (!activate_lv_excl_local(meta_lv->vg->cmd, meta_lv)) { + /* For clearing, simply activate locally */ + if (!activate_lv_local(meta_lv->vg->cmd, meta_lv)) { log_error("Failed to activate %s/%s for clearing", meta_lv->vg->name, meta_lv->name); return 0; @@ -6046,7 +6046,7 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, stack; goto revert_new_lv; } - if (!activate_lv_excl(cmd, lv)) { + if (!lv_active_change(cmd, lv, lp->activate)) { log_error("Failed to activate thin %s.", lv->name); goto deactivate_and_revert_new_lv; } @@ -6057,9 +6057,7 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, "exception store."); goto revert_new_lv; } - } else if ((lp->activate == CHANGE_AY && !activate_lv(cmd, lv)) || - (lp->activate == CHANGE_AE && !activate_lv_excl(cmd, lv)) || - (lp->activate == CHANGE_ALY && !activate_lv_local(cmd, lv))) { + } else if (!lv_active_change(cmd, lv, lp->activate)) { log_error("Failed to activate new LV."); if (lp->zero) goto deactivate_and_revert_new_lv;