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.
}
/*
- * 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
int vg_set_clustered(struct volume_group *vg, int clustered)
{
struct lv_list *lvl;
- struct logical_volume *lv;
+ int fail = 0;
+
+ 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;
+ }
- 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 (fail) {
+ log_print_unless_silent("Conversion is supported only for "
+ "locally exclusive volumes.");
return 0;
}
}
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
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 "-"
struct volume_group *vg,
void *handle __attribute__((unused)))
{
+ int ret = ECMD_PROCESSED;
unsigned i;
+ struct lv_list *lvl;
static const struct {
int arg;
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)) {
if (!_vgchange_background_polling(cmd, vg))
return_ECMD_FAILED;
- return ECMD_PROCESSED;
+ return ret;
}
int vgchange(struct cmd_context *cmd, int argc, char **argv)