mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
vgchange: support clustered conversion for active lv
If we want to support conversion of VG to clustered type, we currently need to relock active LV to get proper DLM lock. So add extra loop after change of VG clustered attribute to exlusively activate all active top level LVs. When doing change -cy -> -cn we should validate LVs are not active on other cluster nodes - we could be sure about this only when with local exclusive activation - for other types we require user to deactivate volumes first. As a workaround for this limitation there is always locking_type = 0 which amongs other skip the detection of active LVs. FIXME: clvmd should handle looks for cluster locking type all the time.
This commit is contained in:
parent
f90bc22ca5
commit
98414ca7dd
@ -1,7 +1,7 @@
|
||||
Version 2.02.112 -
|
||||
=====================================
|
||||
Fix inablility to specify cachemode when 'lvconvert'ing to cache-pool.
|
||||
Disable vgchange of clustered attribute with any active LV in VG.
|
||||
Grab cluster lock for active LVs when setting clustered attribute.
|
||||
Use va_copy to properly pass va_list through functions.
|
||||
Add function to detect rotational devices.
|
||||
Review internal checks for mirror/raid/pvmove volumes.
|
||||
|
@ -520,7 +520,8 @@ int vg_set_alloc_policy(struct volume_group *vg, alloc_policy_t alloc)
|
||||
}
|
||||
|
||||
/*
|
||||
* We do not currently support switching the cluster attribute
|
||||
* Switching the cluster attribute make the active volume
|
||||
* exclusively activate
|
||||
* with any active logical volumes.
|
||||
*
|
||||
* FIXME: resolve logic with reacquiring proper top-level LV locks
|
||||
@ -529,14 +530,32 @@ int vg_set_alloc_policy(struct volume_group *vg, alloc_policy_t alloc)
|
||||
int vg_set_clustered(struct volume_group *vg, int clustered)
|
||||
{
|
||||
struct lv_list *lvl;
|
||||
struct logical_volume *lv;
|
||||
int fail = 0;
|
||||
|
||||
dm_list_iterate_items(lvl, &vg->lvs) {
|
||||
/* For COW, check lock for origin */
|
||||
lv = lv_is_cow(lvl->lv) ? origin_from_cow(lvl->lv) : lvl->lv;
|
||||
if (lv_is_active(lv)) {
|
||||
log_error("Can't change cluster attribute with active "
|
||||
"oogical volume %s.", display_lvname(lv));
|
||||
if (vg_is_clustered(vg) &&
|
||||
locking_is_clustered() &&
|
||||
locking_supports_remote_queries() &&
|
||||
!clustered) {
|
||||
/*
|
||||
* If the volume is locally active but not exclusively
|
||||
* we cannot determine when other nodes also use
|
||||
* locally active (CR lock), so refuse conversion.
|
||||
*/
|
||||
dm_list_iterate_items(lvl, &vg->lvs)
|
||||
if ((lv_lock_holder(lvl->lv) == lvl->lv) &&
|
||||
lv_is_active(lvl->lv) &&
|
||||
!lv_is_active_exclusive_locally(lvl->lv)) {
|
||||
/* Show all non-local-exclusively active LVs
|
||||
* this includes i.e. clustered mirrors */
|
||||
log_error("Can't change cluster attribute with "
|
||||
"active logical volume %s.",
|
||||
display_lvname(lvl->lv));
|
||||
fail = 1;
|
||||
}
|
||||
|
||||
if (fail) {
|
||||
log_print_unless_silent("Conversion is supported only for "
|
||||
"locally exclusive volumes.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -89,27 +89,28 @@ fail vgchange -cy |& tee out
|
||||
grep "y/n" out
|
||||
check vg_attr_bit cluster $vg "-"
|
||||
|
||||
lvcreate -l1 $vg
|
||||
lvcreate -l1 -n $lv1 $vg
|
||||
|
||||
# check on cluster
|
||||
# either skipped as clustered (non-cluster), or already clustered (on cluster)
|
||||
if test -e LOCAL_CLVMD ; then
|
||||
# can't switch with active LV
|
||||
not vgchange -cy $vg
|
||||
lvchange -an $vg
|
||||
# can switch with active LV
|
||||
vgchange -cy $vg
|
||||
fail vgchange -cy $vg
|
||||
# check volume is active locally exclusively
|
||||
check lv_field $vg/$lv1 lv_active "local exclusive"
|
||||
check vg_attr_bit cluster $vg "c"
|
||||
# check we do not support conversion of just locally active LVs
|
||||
lvchange -an $vg
|
||||
lvchange -ay $vg
|
||||
not vgchange -cn $vg
|
||||
lvchange -an $vg
|
||||
lvchange -aey $vg
|
||||
vgchange -cn $vg
|
||||
else
|
||||
# no clvmd is running
|
||||
fail vgchange -cy $vg
|
||||
# can't switch with active LV
|
||||
not vgchange --yes -cy $vg
|
||||
lvchange -an $vg
|
||||
vgchange --yes -cy $vg
|
||||
fail vgchange --yes -cy $vg
|
||||
fail vgs $vg |& tee out
|
||||
@ -117,7 +118,7 @@ else
|
||||
vgs --ignoreskippedcluster $vg |& tee out
|
||||
not grep "Skipping clustered volume group" out
|
||||
# reset back to non-clustered VG with disabled locking
|
||||
vgchange -cn --config 'global{locking_type=0}' $vg
|
||||
vgchange -cn $vg --config 'global{locking_type=0}' $vg
|
||||
fi
|
||||
check vg_attr_bit cluster $vg "-"
|
||||
|
||||
|
@ -479,7 +479,9 @@ static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
|
||||
struct volume_group *vg,
|
||||
void *handle __attribute__((unused)))
|
||||
{
|
||||
int ret = ECMD_PROCESSED;
|
||||
unsigned i;
|
||||
struct lv_list *lvl;
|
||||
|
||||
static const struct {
|
||||
int arg;
|
||||
@ -534,6 +536,31 @@ static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
|
||||
backup(vg);
|
||||
|
||||
log_print_unless_silent("Volume group \"%s\" successfully changed", vg->name);
|
||||
|
||||
/* FIXME: fix clvmd bug and take DLM lock for non clustered VGs. */
|
||||
if (arg_is_set(cmd, clustered_ARG) &&
|
||||
vg_is_clustered(vg) && /* just switched to clustered */
|
||||
locking_is_clustered() &&
|
||||
locking_supports_remote_queries())
|
||||
dm_list_iterate_items(lvl, &vg->lvs) {
|
||||
if ((lv_lock_holder(lvl->lv) != lvl->lv) ||
|
||||
!lv_is_active(lvl->lv))
|
||||
continue;
|
||||
|
||||
if (!activate_lv_excl_local(cmd, lvl->lv) ||
|
||||
!lv_is_active_exclusive_locally(lvl->lv)) {
|
||||
log_error("Can't reactive logical volume %s, "
|
||||
"please fix manually.",
|
||||
display_lvname(lvl->lv));
|
||||
ret = ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (lv_is_mirror(lvl->lv))
|
||||
/* Give hint for clustered mirroring */
|
||||
log_print_unless_silent("For clustered mirroring of %s "
|
||||
"deactivation and activation is needed.",
|
||||
display_lvname(lvl->lv));
|
||||
}
|
||||
}
|
||||
|
||||
if (arg_count(cmd, activate_ARG)) {
|
||||
@ -561,7 +588,7 @@ static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
|
||||
if (!_vgchange_background_polling(cmd, vg))
|
||||
return_ECMD_FAILED;
|
||||
|
||||
return ECMD_PROCESSED;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vgchange(struct cmd_context *cmd, int argc, char **argv)
|
||||
|
Loading…
Reference in New Issue
Block a user