1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

activation: improve activation

This patch fixes mostly cluster behavior but also updates
non-cluster reaction where calls like   'lvchange -aln'
lead to incorrect errors for some segment types.

Fix the implicit activation rules where some segment types could
be activated only in exclusive mode in cluster.
lvm2 command was not preserver 'local' property and incorrectly
converted local activations in to plain exclusive, so the local
activation could have activate volumes exclusively, but remotely.
This commit is contained in:
Zdenek Kabelac 2013-11-01 10:31:31 +01:00
parent c3e674ad30
commit 9f6209b878
3 changed files with 48 additions and 26 deletions

View File

@ -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.

View File

@ -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);
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;
}
log_verbose("Activating logical volume \"%s\" exclusively.",
lv->name);
if (!activate_lv_excl(cmd, lv))
return_0;
} else if (activate == CHANGE_ALN) {
/* Unlock whole exclusive activation */
goto deactivate;
}
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)) {
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;
} else { /* CHANGE_AY */
}
break;
case CHANGE_AE:
exclusive:
log_verbose("Activating logical volume \"%s\" exclusively.",
lv->name);
if (!activate_lv_excl(cmd, lv))
return_0;
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;

View File

@ -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;