master - RAID: Make RAID single-machine-exclusive capable in a cluster
by Jonathan Brassow
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=2691f1d7641827...
Commit: 2691f1d764182722195cda80be1f511e968480aa
Parent: 8d1d83504dcf9c86ad42d34d3bd0b201d7bab8f6
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Tue Sep 10 16:33:22 2013 -0500
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Tue Sep 10 16:33:22 2013 -0500
RAID: Make RAID single-machine-exclusive capable in a cluster
Creation, deletion, [de]activation, repair, conversion, scrubbing
and changing operations are all now available for RAID LVs in a
cluster - provided that they are activated exclusively.
The code has been changed to ensure that no LV or sub-LV activation
is attempted cluster-wide. This includes the often overlooked
operations of activating metadata areas for the brief time it takes
to clear them. Additionally, some 'resume_lv' operations were
replaced with 'activate_lv_excl_local' when sub-LVs were promoted
to top-level LVs for removal, clearing or extraction. This was
necessary because it forces the appropriate renaming actions the
occur via resume in the single-machine case, but won't happen in
a cluster due to the necessity of acquiring a lock first.
The *raid* tests have been updated to allow testing in a cluster.
For the most part, this meant creating devices with '-aey' if they
were to be converted to RAID. (RAID requires the converting LV to
be EX because it is a condition of activation for the RAID LV in
a cluster.)
---
WHATS_NEW | 1 +
lib/metadata/lv.c | 12 +++++--
lib/metadata/lv_manip.c | 29 +++++++----------
lib/metadata/raid_manip.c | 58 +++++++++++++++++++++++-----------
lib/metadata/vg.c | 11 ------
test/lib/aux.sh | 3 --
test/shell/lvchange-raid.sh | 6 ++--
test/shell/lvconvert-raid.sh | 29 ++++++++++++-----
test/shell/lvconvert-raid10.sh | 4 +-
test/shell/lvcreate-large-raid.sh | 3 +-
test/shell/lvcreate-large-raid10.sh | 1 -
tools/lvchange.c | 41 ++++++++++++++++++++-----
tools/lvconvert.c | 9 +++--
13 files changed, 124 insertions(+), 83 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index b1060af..b14daf5 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.101 -
===================================
+ Make RAID capable of single-machine exclusive operations in a cluster.
Drop calculation of read ahead for deactivated volume.
Check for exactly one lv segment in validation of thin pools and volumes.
Fix dmeventd unmonitoring of thin pools.
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index db71cf0..e3fda18 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -737,24 +737,28 @@ int lv_active_change(struct cmd_context *cmd, struct logical_volume *lv,
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 or thin, all others have _AE */
+ /* 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;
}
- log_verbose("Activating logical volume \"%s\" exclusively.", lv->name);
+ 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);
+ 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.", lv->name);
+ log_verbose("Activating logical volume \"%s\" locally.",
+ lv->name);
if (!activate_lv_local(cmd, lv))
return_0;
} else { /* CHANGE_AY */
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 1cccd8c..d12b34e 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -2881,7 +2881,8 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah,
continue;
}
- if (!activate_lv(meta_lv->vg->cmd, meta_lv)) {
+ /* For clearing, simply activate exclusive locally */
+ if (!activate_lv_excl_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;
@@ -5504,7 +5505,8 @@ int lv_activation_skip(struct logical_volume *lv, activation_change_t activate,
* If lp->activate is AY*, activate it.
* If lp->activate was AN* and the pool was originally inactive, deactivate it.
*/
-static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, struct lvcreate_params *lp,
+static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
+ struct lvcreate_params *lp,
const char *new_lv_name)
{
struct cmd_context *cmd = vg->cmd;
@@ -5527,21 +5529,6 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, struct l
return NULL;
}
- if (vg_is_clustered(vg) && segtype_is_raid(lp->segtype)) {
- /*
- * FIXME:
- * We could allow a RAID LV to be created as long as it
- * is activated exclusively. Any subsequent activations
- * would have to be enforced as exclusive also.
- *
- * For now, we disallow the existence of RAID LVs in a
- * cluster VG
- */
- log_error("Unable to create a %s logical volume in a cluster.",
- lp->segtype->name);
- return NULL;
- }
-
if ((segtype_is_mirrored(lp->segtype) ||
segtype_is_raid(lp->segtype) || segtype_is_thin(lp->segtype)) &&
!(vg->fid->fmt->features & FMT_SEGMENTS)) {
@@ -5843,6 +5830,14 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, struct l
} else if (seg_is_raid(lp)) {
first_seg(lv)->min_recovery_rate = lp->min_recovery_rate;
first_seg(lv)->max_recovery_rate = lp->max_recovery_rate;
+ if (vg_is_clustered(lv->vg) &&
+ is_change_activating(lp->activate) &&
+ (lp->activate != CHANGE_AE)) {
+ log_debug_activation("Creating RAID logical volume in a"
+ " cluster: setting activation"
+ " mode to EX");
+ lp->activate = CHANGE_AE;
+ }
}
/* FIXME Log allocation and attachment should have happened inside lv_extend. */
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index d13750d..147b478 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -174,7 +174,7 @@ static int _clear_lv(struct logical_volume *lv)
if (test_mode())
return 1;
- if (!was_active && !activate_lv(lv->vg->cmd, lv)) {
+ if (!was_active && !activate_lv_excl_local(lv->vg->cmd, lv)) {
log_error("Failed to activate %s for clearing",
lv->name);
return 0;
@@ -962,12 +962,12 @@ static int _raid_remove_images(struct logical_volume *lv,
}
/*
- * We resume the extracted sub-LVs first so they are renamed
+ * We activate the extracted sub-LVs first so they are renamed
* and won't conflict with the remaining (possibly shifted)
* sub-LVs.
*/
dm_list_iterate_items(lvl, &removal_list) {
- if (!resume_lv(lv->vg->cmd, lvl->lv)) {
+ if (!activate_lv_excl_local(lv->vg->cmd, lvl->lv)) {
log_error("Failed to resume extracted LVs");
return 0;
}
@@ -1023,6 +1023,16 @@ int lv_raid_change_image_count(struct logical_volume *lv,
return 1;
}
+ /*
+ * LV must be either in-active or exclusively active
+ */
+ if (lv_is_active(lv) && vg_is_clustered(lv->vg) &&
+ !lv_is_active_exclusive_locally(lv)) {
+ log_error("%s/%s must be active exclusive locally to"
+ " perform this operation.", lv->vg->name, lv->name);
+ return 0;
+ }
+
if (old_count > new_count)
return _raid_remove_images(lv, new_count, pvs);
@@ -1125,15 +1135,15 @@ int lv_raid_split(struct logical_volume *lv, const char *split_name,
}
/*
- * First resume the newly split LV and LVs on the removal list.
+ * First activate the newly split LV and LVs on the removal list.
* This is necessary so that there are no name collisions due to
* the original RAID LV having possibly had sub-LVs that have been
* shifted and renamed.
*/
- if (!resume_lv(cmd, lvl->lv))
+ if (!activate_lv_excl_local(cmd, lvl->lv))
return_0;
dm_list_iterate_items(lvl, &removal_list)
- if (!resume_lv(cmd, lvl->lv))
+ if (!activate_lv_excl_local(cmd, lvl->lv))
return_0;
if (!resume_lv(lv->vg->cmd, lv)) {
@@ -1470,6 +1480,12 @@ int lv_raid_reshape(struct logical_volume *lv,
return 0;
}
+ if (vg_is_clustered(lv->vg) && !lv_is_active_exclusive_locally(lv)) {
+ log_error("%s/%s must be active exclusive locally to"
+ " perform this operation.", lv->vg->name, lv->name);
+ return 0;
+ }
+
if (!strcmp(seg->segtype->name, "mirror") &&
(!strcmp(new_segtype->name, "raid1")))
return _convert_mirror_to_raid1(lv, new_segtype);
@@ -1493,21 +1509,23 @@ int lv_raid_replace(struct logical_volume *lv,
struct dm_list *allocate_pvs)
{
uint32_t s, sd, match_count = 0;
- struct dm_list old_meta_lvs, old_data_lvs;
+ struct dm_list old_lvs;
struct dm_list new_meta_lvs, new_data_lvs;
struct lv_segment *raid_seg = first_seg(lv);
struct lv_list *lvl;
char *tmp_names[raid_seg->area_count * 2];
- dm_list_init(&old_meta_lvs);
- dm_list_init(&old_data_lvs);
+ dm_list_init(&old_lvs);
dm_list_init(&new_meta_lvs);
dm_list_init(&new_data_lvs);
- if (!lv_is_active_locally(lv)) {
+ if (lv->status & PARTIAL_LV)
+ lv->vg->cmd->partial_activation = 1;
+
+ if (!lv_is_active_exclusive_locally(lv)) {
log_error("%s/%s must be active %sto perform this operation.",
lv->vg->name, lv->name,
- vg_is_clustered(lv->vg) ? "locally " : "");
+ vg_is_clustered(lv->vg) ? "exclusive locally " : "");
return 0;
}
@@ -1612,13 +1630,21 @@ try_again:
*/
if (!_raid_extract_images(lv, raid_seg->area_count - match_count,
remove_pvs, 0,
- &old_meta_lvs, &old_data_lvs)) {
+ &old_lvs, &old_lvs)) {
log_error("Failed to remove the specified images from %s/%s",
lv->vg->name, lv->name);
return 0;
}
/*
+ * Now that they are extracted and visible, make the system aware
+ * of their new names.
+ */
+ dm_list_iterate_items(lvl, &old_lvs)
+ if (!activate_lv_excl_local(lv->vg->cmd, lvl->lv))
+ return_0;
+
+ /*
* Skip metadata operation normally done to clear the metadata sub-LVs.
*
* The LV_REBUILD flag is set on the new sub-LVs,
@@ -1696,13 +1722,7 @@ try_again:
return 0;
}
- dm_list_iterate_items(lvl, &old_meta_lvs) {
- if (!deactivate_lv(lv->vg->cmd, lvl->lv))
- return_0;
- if (!lv_remove(lvl->lv))
- return_0;
- }
- dm_list_iterate_items(lvl, &old_data_lvs) {
+ dm_list_iterate_items(lvl, &old_lvs) {
if (!deactivate_lv(lv->vg->cmd, lvl->lv))
return_0;
if (!lv_remove(lvl->lv))
diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c
index 22099e2..476292e 100644
--- a/lib/metadata/vg.c
+++ b/lib/metadata/vg.c
@@ -524,17 +524,6 @@ int vg_set_clustered(struct volume_group *vg, int clustered)
* on active mirrors, snapshots or RAID logical volumes.
*/
dm_list_iterate_items(lvl, &vg->lvs) {
- /*
- * FIXME:
- * We could allow exclusive activation of RAID LVs, but
- * for now we disallow them in a cluster VG at all.
- */
- if (lv_is_raid_type(lvl->lv)) {
- log_error("RAID logical volumes are not allowed "
- "in a cluster volume group.");
- return 0;
- }
-
if (lv_is_active(lvl->lv) &&
(lv_is_mirrored(lvl->lv) || lv_is_raid_type(lvl->lv))) {
log_error("%s logical volumes must be inactive "
diff --git a/test/lib/aux.sh b/test/lib/aux.sh
index 5ff0b0c..e07397d 100644
--- a/test/lib/aux.sh
+++ b/test/lib/aux.sh
@@ -640,9 +640,6 @@ wait_for_sync() {
# i.e. dm_target_at_least dm-thin-pool 1 0
target_at_least()
{
- # Raid target does not work in cluster
- test -e LOCAL_CLVMD -a "$1" = "dm-raid" && return 1
-
case "$1" in
dm-*) modprobe "$1" || true ;;
esac
diff --git a/test/shell/lvchange-raid.sh b/test/shell/lvchange-raid.sh
index 38b9c4c..babe726 100644
--- a/test/shell/lvchange-raid.sh
+++ b/test/shell/lvchange-raid.sh
@@ -289,7 +289,7 @@ run_checks() {
# Hey, specifying devices for thin allocation doesn't work
# lvconvert --thinpool $1/$2 "$dev6"
- lvcreate -L 2M -n ${2}_meta $1 "$dev6"
+ lvcreate -aey -L 2M -n ${2}_meta $1 "$dev6"
lvconvert --thinpool $1/$2 --poolmetadata ${2}_meta
lvcreate -T $1/$2 -V 1 -n thinlv
THIN_POSTFIX="_tdata"
@@ -303,7 +303,7 @@ run_checks() {
printf "#\n#\n# run_checks: RAID as thinpool metadata\n#\n#\n"
lvrename $1/$2 ${2}_meta
- lvcreate -L 2M -n $2 $1 "$dev6"
+ lvcreate -aey -L 2M -n $2 $1 "$dev6"
lvconvert --thinpool $1/$2 --poolmetadata ${2}_meta
lvcreate -T $1/$2 -V 1 -n thinlv
THIN_POSTFIX="_tmeta"
@@ -314,7 +314,7 @@ run_checks() {
run_recovery_rate_check $1 $2
elif [ 'snapshot' == $3 ]; then
printf "#\n#\n# run_checks: RAID under snapshot\n#\n#\n"
- lvcreate -s $1/$2 -l 4 -n snap "$dev6"
+ lvcreate -aey -s $1/$2 -l 4 -n snap "$dev6"
run_writemostly_check $1 $2
run_syncaction_check $1 $2
diff --git a/test/shell/lvconvert-raid.sh b/test/shell/lvconvert-raid.sh
index 8693cf3..4c08386 100644
--- a/test/shell/lvconvert-raid.sh
+++ b/test/shell/lvconvert-raid.sh
@@ -11,8 +11,6 @@
. lib/test
-test -e LOCAL_CLVMD && skip
-
get_image_pvs() {
local d
local images
@@ -24,7 +22,10 @@ get_image_pvs() {
########################################################
# MAIN
########################################################
-aux target_at_least dm-raid 1 2 0 || skip
+if ! aux target_at_least dm-raid 1 2 0; then
+ dmsetup targets | grep raid
+ skip
+fi
# 9 PVs needed for RAID10 testing (3-stripes/2-mirror - replacing 3 devs)
aux prepare_pvs 9 80
@@ -57,17 +58,17 @@ for i in 1 2 3; do
# Shouldn't be able to create with just 1 image
not lvcreate --type raid1 -m 0 -l 2 -n $lv1 $vg
- lvcreate -l 2 -n $lv1 $vg
+ lvcreate -aey -l 2 -n $lv1 $vg
else
lvcreate --type raid1 -m $(($i - 1)) -l 2 -n $lv1 $vg
aux wait_for_sync $vg $lv1
fi
if $under_snap; then
- lvcreate -s $vg/$lv1 -n snap -l 2
+ lvcreate -aey -s $vg/$lv1 -n snap -l 2
fi
- lvconvert -m $((j - 1)) $vg/$lv1
+ lvconvert -m $((j - 1)) $vg/$lv1
# FIXME: ensure no residual devices
@@ -138,7 +139,7 @@ lvremove -ff $vg
###########################################
# Linear to RAID1 conversion ("raid1" default segtype)
###########################################
-lvcreate -l 2 -n $lv1 $vg
+lvcreate -aey -l 2 -n $lv1 $vg
lvconvert -m 1 $vg/$lv1 \
--config 'global { mirror_segtype_default = "raid1" }'
lvs --noheadings -o attr $vg/$lv1 | grep '^r*'
@@ -147,17 +148,27 @@ lvremove -ff $vg
###########################################
# Linear to RAID1 conversion (override "mirror" default segtype)
###########################################
-lvcreate -l 2 -n $lv1 $vg
+lvcreate -aey -l 2 -n $lv1 $vg
lvconvert --type raid1 -m 1 $vg/$lv1 \
--config 'global { mirror_segtype_default = "mirror" }'
lvs --noheadings -o attr $vg/$lv1 | grep '^r*'
lvremove -ff $vg
###########################################
+# Must not be able to convert non-EX LVs in a cluster
+###########################################
+if [ -e LOCAL_CLVMD ]; then
+ lvcreate -l 2 -n $lv1 $vg
+ not lvconvert --type raid1 -m 1 $vg/$lv1 \
+ --config 'global { mirror_segtype_default = "mirror" }'
+ lvremove -ff $vg
+fi
+
+###########################################
# Mirror to RAID1 conversion
###########################################
for i in 1 2 3 ; do
- lvcreate --type mirror -m $i -l 2 -n $lv1 $vg
+ lvcreate -aey --type mirror -m $i -l 2 -n $lv1 $vg
aux wait_for_sync $vg $lv1
lvconvert --type raid1 $vg/$lv1
lvremove -ff $vg
diff --git a/test/shell/lvconvert-raid10.sh b/test/shell/lvconvert-raid10.sh
index b2d4afd..4b3ceb4 100644
--- a/test/shell/lvconvert-raid10.sh
+++ b/test/shell/lvconvert-raid10.sh
@@ -11,8 +11,6 @@
. lib/test
-test -e LOCAL_CLVMD && skip
-
get_image_pvs() {
local d
local images
@@ -56,3 +54,5 @@ for i in 0 1; do
$vg/$lv1
aux wait_for_sync $vg $lv1
done
+
+lvremove -ff $vg
diff --git a/test/shell/lvcreate-large-raid.sh b/test/shell/lvcreate-large-raid.sh
index c0b40db..a91da05 100644
--- a/test/shell/lvcreate-large-raid.sh
+++ b/test/shell/lvcreate-large-raid.sh
@@ -13,7 +13,6 @@
. lib/test
-test -e LOCAL_CLVMD && skip
aux target_at_least dm-raid 1 1 0 || skip
aux prepare_vg 5
@@ -51,7 +50,7 @@ done
#
# Convert large linear to RAID1 (belong in different test script?)
#
-lvcreate -L 200T -n $lv1 $vg1
+lvcreate -aey -L 200T -n $lv1 $vg1
# Need to deactivate or the up-convert will start sync'ing
lvchange -an $vg1/$lv1
lvconvert --type raid1 -m 1 $vg1/$lv1
diff --git a/test/shell/lvcreate-large-raid10.sh b/test/shell/lvcreate-large-raid10.sh
index 50dd23a..d971d74 100644
--- a/test/shell/lvcreate-large-raid10.sh
+++ b/test/shell/lvcreate-large-raid10.sh
@@ -13,7 +13,6 @@
. lib/test
-test -e LOCAL_CLVMD && skip
aux target_at_least dm-raid 1 3 0 || skip
aux prepare_vg 5
diff --git a/tools/lvchange.c b/tools/lvchange.c
index 34e230c..1d4f0a5 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -301,6 +301,20 @@ static int lvchange_refresh(struct cmd_context *cmd, struct logical_volume *lv)
return lv_refresh(cmd, lv);
}
+static int _reactivate_lv(struct logical_volume *lv,
+ int active, int exclusive)
+{
+ struct cmd_context *cmd = lv->vg->cmd;
+
+ if (!active)
+ return 1;
+
+ if (exclusive)
+ return activate_lv_excl_local(cmd, lv);
+
+ return activate_lv(cmd, lv);
+}
+
/*
* lvchange_resync
* @cmd
@@ -311,6 +325,7 @@ static int lvchange_refresh(struct cmd_context *cmd, struct logical_volume *lv)
static int lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
{
int active = 0;
+ int exclusive = 0;
int monitored;
struct lvinfo info;
struct lv_segment *seg = first_seg(lv);
@@ -356,9 +371,17 @@ static int lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
return_0;
active = 1;
+ if (lv_is_active_exclusive_locally(lv))
+ exclusive = 1;
}
}
+ if (seg_is_raid(seg) && active && !exclusive) {
+ log_error("RAID logical volume %s/%s cannot be active remotely.",
+ lv->vg->name, lv->name);
+ return 0;
+ }
+
/* Activate exclusively to ensure no nodes still have LV active */
monitored = dmeventd_monitor_mode();
if (monitored != DMEVENTD_MONITOR_IGNORE)
@@ -403,7 +426,7 @@ static int lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
}
}
- if (active && !activate_lv(cmd, lv)) {
+ if (!_reactivate_lv(lv, active, exclusive)) {
log_error("Failed to reactivate %s to resynchronize "
"mirror", lv->name);
return 0;
@@ -429,7 +452,7 @@ static int lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
log_error("Failed to write intermediate VG metadata.");
if (!attach_metadata_devices(seg, &device_list))
stack;
- if (active && !activate_lv(cmd, lv))
+ if (!_reactivate_lv(lv, active, exclusive))
stack;
return 0;
}
@@ -438,7 +461,7 @@ static int lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
log_error("Failed to commit intermediate VG metadata.");
if (!attach_metadata_devices(seg, &device_list))
stack;
- if (active && !activate_lv(cmd, lv))
+ if (!_reactivate_lv(lv, active, exclusive))
stack;
return 0;
}
@@ -446,9 +469,10 @@ static int lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
backup(lv->vg);
dm_list_iterate_items(lvl, &device_list) {
- if (!activate_lv(cmd, lvl->lv)) {
- log_error("Unable to activate %s for mirror log resync",
- lvl->lv->name);
+ if (!activate_lv_excl_local(cmd, lvl->lv)) {
+ log_error("Unable to activate %s for %s clearing",
+ lvl->lv->name, (seg_is_raid(seg)) ?
+ "metadata area" : "mirror log");
return 0;
}
@@ -486,8 +510,9 @@ static int lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
return 0;
}
- if (active && !activate_lv(cmd, lv)) {
- log_error("Failed to reactivate %s after resync", lv->name);
+ if (!_reactivate_lv(lv, active, exclusive)) {
+ log_error("Failed to reactivate %s after resync",
+ lv->name);
return 0;
}
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 94ba8c8..13002e3 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -1754,10 +1754,11 @@ static int lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *lp
return lv_raid_replace(lv, lp->replace_pvh, lp->pvh);
if (arg_count(cmd, repair_ARG)) {
- if (!lv_is_active_locally(lv)) {
- log_error("%s/%s must be active %sto perform"
- "this operation.", lv->vg->name, lv->name,
- vg_is_clustered(lv->vg) ? "locally " : "");
+ if (!lv_is_active_exclusive_locally(lv)) {
+ log_error("%s/%s must be active %sto perform this"
+ " operation.", lv->vg->name, lv->name,
+ vg_is_clustered(lv->vg) ?
+ "exclusive locally " : "");
return 0;
}
10 years, 8 months
master - udev: fix pvscan --cache -aay to trigger on relevant events
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=8d1d83504dcf9c...
Commit: 8d1d83504dcf9c86ad42d34d3bd0b201d7bab8f6
Parent: 9ba40da7ae908fb36cb9927cde60a1a45cacce80
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Sep 10 15:49:05 2013 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue Sep 10 16:27:58 2013 +0200
udev: fix pvscan --cache -aay to trigger on relevant events
This patch fixes the way the special devices are handled
(special in this context means that they're not usable
after the usual ADD event like other generic devices):
- DM and MD devices are pvscanned only when they are just set up.
This is the first CHANGE event that makes the device usable
(the DM_UDEV_PRIMARY_SOURCE_FLAG is set for DM and the
md/array_state sysfs attribute is present for MD).
Whether the device is activated is remembered via
DM_ACTIVATED (for DM) and LVM_MD_PV_ACTIVATED (for MD)
udev environment variable. This is then used to decide
whether we should fire the pvscan on ADD event to
support coldplugging. For any (artificial) ADD event
generated during coldplug, the device must be already
set up properly to fire the pvscan on it.
- Similar for loop devices. For loop devices, only CHANGE
events are relevant (so there's a CHANGE after the loop
device is set up as well as detached). Whether the loop
has just been activated is detected via loop/backing_file
sysfs attribute presence. The activation state is remembered
via LVM_LOOP_PV_ACTIVATED udev environment variable.
- Do not pvscan multipath device components (underlying paths).
- Do not pvscan RAID device components.
- Also, set LVM_SCANNED="1" udev environment variable for
debug purposes (it's visible in the lvmdump -u that takes
the current udev database). This variable is set once
the pvscan is triggered.
The table below summarises when the pvscan is triggered
(marked with X, X* means fire only if the special dev is properly set up):
| real ADD | real CHANGE | artificial ADD | artificial CHANGE | remove
=============================================================================
DM | | X | X* | | X
MD | | X | X* | |
loop | | X | X* | |
other | X | | X | | X
---
udev/10-dm.rules.in | 20 +++++-------
udev/13-dm-disk.rules.in | 4 --
udev/69-dm-lvm-metad.rules.in | 66 +++++++++++++++++++++++++++++++++++-----
3 files changed, 65 insertions(+), 25 deletions(-)
diff --git a/udev/10-dm.rules.in b/udev/10-dm.rules.in
index 3a157d5..f495103 100644
--- a/udev/10-dm.rules.in
+++ b/udev/10-dm.rules.in
@@ -45,14 +45,13 @@ ENV{DISK_RO}=="1", GOTO="dm_disable"
# in libdevmapper so we need to detect this and try to behave correctly.
# For such spurious events, regenerate all flags from current udev database content
# (this information would normally be inaccessible for spurious ADD and CHANGE events).
-ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", ENV{DM_ACTIVATION}="1", GOTO="dm_flags_done"
+ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", ENV{DM_ACTIVATED}="1", GOTO="dm_flags_done"
IMPORT{db}="DM_UDEV_DISABLE_DM_RULES_FLAG"
IMPORT{db}="DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG"
IMPORT{db}="DM_UDEV_DISABLE_DISK_RULES_FLAG"
IMPORT{db}="DM_UDEV_DISABLE_OTHER_RULES_FLAG"
IMPORT{db}="DM_UDEV_LOW_PRIORITY_FLAG"
IMPORT{db}="DM_UDEV_DISABLE_LIBRARY_FALLBACK_FLAG"
-IMPORT{db}="DM_UDEV_PRIMARY_SOURCE_FLAG"
IMPORT{db}="DM_UDEV_FLAG7"
IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG0"
IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG1"
@@ -63,6 +62,7 @@ IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG5"
IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG6"
IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG7"
IMPORT{db}="DM_UDEV_RULES_VSN"
+IMPORT{db}="DM_ACTIVATED"
LABEL="dm_flags_done"
# Normally, we operate on "change" events. But when coldplugging, there's an
@@ -77,28 +77,24 @@ LABEL="dm_flags_done"
# before (e.g. in initrd). If udev is used in initrd, we require the udev init
# script to not remove the existing udev database so we can reuse the information
# stored at the time of device activation in the initrd.
-# The DM_ACTIVATION variable tells when any device stacked above should be
-# (re)activated as well.
-ACTION!="add", GOTO="dm_no_coldplug"
-ENV{DM_UDEV_RULES_VSN}!="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="dm_disable"
-ENV{DM_ACTIVATION}="1"
-LABEL="dm_no_coldplug"
+# The DM_ACTIVATED variable indicates that the device has already been activated.
+ACTION=="add", ENV{DM_UDEV_RULES_VSN}!="1", ENV{DM_ACTIVATED}!="1", GOTO="dm_disable"
# Putting it together, following table is used to recognize genuine and spurious events.
# N.B. Spurious events are generated based on use of the WATCH udev
# rule or by triggering an event manually by "udevadm trigger" call
# or by "echo <event_name> > /sys/block/dm-X/uevent".
#
-# EVENT DM_UDEV_PRIMARY_SOURCE_FLAG DM_ACTIVATION
-# ======================================================================
+# EVENT DM_UDEV_PRIMARY_SOURCE_FLAG DM_ACTIVATED
+# ====================================================================
# add event (genuine) 0 0
# change event (genuine) 1 1
# add event (spurious)
# |_ dev still not active 0 0
-# \_ dev already active 1 1
+# \_ dev already active 0 1
# change event (spurious)
# |_ dev still not active 0 0
-# \_ dev already active 1 0
+# \_ dev already active 0 1
# "dm" sysfs subdirectory is available in newer versions of DM
# only (kernels >= 2.6.29). We have to check for its existence
diff --git a/udev/13-dm-disk.rules.in b/udev/13-dm-disk.rules.in
index f8e4ac6..1920260 100644
--- a/udev/13-dm-disk.rules.in
+++ b/udev/13-dm-disk.rules.in
@@ -17,10 +17,6 @@ ENV{DM_UDEV_DISABLE_DISK_RULES_FLAG}=="1", GOTO="dm_end"
SYMLINK+="disk/by-id/dm-name-$env{DM_NAME}"
ENV{DM_UUID}=="?*", SYMLINK+="disk/by-id/dm-uuid-$env{DM_UUID}"
-# Save previously detected dev type.
-IMPORT{db}="ID_FS_TYPE"
-ENV{ID_FS_TYPE}=="?*", ENV{DM_ID_FS_TYPE_OLD}="$env{ID_FS_TYPE}", ENV{ID_FS_TYPE}=""
-
ENV{DM_SUSPENDED}=="1", GOTO="dm_end"
(BLKID_RULE)
diff --git a/udev/69-dm-lvm-metad.rules.in b/udev/69-dm-lvm-metad.rules.in
index aa787e3..f2d2f1b 100644
--- a/udev/69-dm-lvm-metad.rules.in
+++ b/udev/69-dm-lvm-metad.rules.in
@@ -17,23 +17,71 @@
SUBSYSTEM!="block", GOTO="lvm_end"
(LVM_EXEC_RULE)
-# If the PV label got lost, inform lvmetad about it.
-ENV{DM_ID_FS_TYPE_OLD}=="LVM2_member|LVM1_member", ENV{ID_FS_TYPE}!="LVM2_member|LVM1_member", GOTO="lvm_scan"
+# If the PV label got lost, inform lvmetad immediately.
+# Detect the lost PV label by comparing previous ID_FS_TYPE value with current one.
+ENV{.ID_FS_TYPE_NEW}="$env{ID_FS_TYPE}"
+IMPORT{db}="ID_FS_TYPE"
+ENV{ID_FS_TYPE}=="LVM2_member|LVM1_member", ENV{.ID_FS_TYPE_NEW}!="LVM2_member|LVM1_member", ENV{LVM_PV_GONE}="1"
+ENV{ID_FS_TYPE}="$env{.ID_FS_TYPE_NEW}"
+ENV{LVM_PV_GONE}=="1", GOTO="lvm_scan"
# Only process devices already marked as a PV - this requires blkid to be called before.
ENV{ID_FS_TYPE}!="LVM2_member|LVM1_member", GOTO="lvm_end"
+# Inform lvmetad about any PV that is gone.
ACTION=="remove", GOTO="lvm_scan"
-ACTION=="change", KERNEL=="md[0-9]*|loop[0-9]*", GOTO="lvm_scan"
-# If the PV is not a dm device, scan only after device addition (ADD event)
-KERNEL!="dm-[0-9]*", ACTION!="add", GOTO="lvm_end"
+# If the PV is a special device listed below, scan only if the device is
+# properly activated. These devices are not usable after an ADD event,
+# but they require an extra setup and they are ready after a CHANGE event.
+# Also support coldplugging with ADD event but only if the device is already
+# properly activated.
-# If the PV is a dm device, scan only after proper mapping activation (CHANGE event + DM_ACTIVATION=1)
-# or after a coldplug (event retrigger) with "add" event (ADD event + DM_ACTIVATION=1)
-KERNEL=="dm-[0-9]*", ENV{DM_ACTIVATION}!="1", GOTO="lvm_end"
+# DM device:
+KERNEL!="dm-[0-9]*", GOTO="next"
+ACTION=="add", ENV{DM_ACTIVATED}=="1", GOTO="lvm_scan"
+ACTION=="change", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", GOTO="lvm_scan"
+GOTO="lvm_end"
+
+# MD device:
+LABEL="next"
+KERNEL!="md[0-9]*", GOTO="next"
+IMPORT{db}="LVM_MD_PV_ACTIVATED"
+ACTION=="add", ENV{LVM_MD_PV_ACTIVATED}=="1", GOTO="lvm_scan"
+ACTION=="change", ENV{LVM_MD_PV_ACTIVATED}!="1", TEST=="md/array_state", ENV{LVM_MD_PV_ACTIVATED}="1", GOTO="lvm_scan"
+GOTO="lvm_end"
+
+# Loop device:
+LABEL="next"
+KERNEL!="loop[0-9]*", GOTO="next"
+ACTION=="add", ENV{LVM_LOOP_PV_ACTIVATED}=="1", GOTO="lvm_scan"
+ACTION=="change", ENV{LVM_LOOP_PV_ACTIVATED}!="1", TEST=="loop/backing_file", ENV{LVM_LOOP_PV_ACTIVATED}="1", GOTO="lvm_scan"
+GOTO="lvm_end"
+
+# If the PV is not a special device listed above, scan only after device addition (ADD event)
+LABEL="next"
+ACTION!="add", GOTO="lvm_end"
LABEL="lvm_scan"
-RUN+="(LVM_EXEC)/lvm pvscan --background --cache --activate ay --major $major --minor $minor"
+
+# The table below summarises the situations in which we reach the LABEL="lvm_scan".
+# Marked by X, X* means only if the special dev is properly set up.
+# The artificial ADD is supported for coldplugging. We avoid running the pvscan
+# on artificial CHANGE so there's no unexpected autoactivation when WATCH rule fires.
+# N.B. MD and loop never actually reaches lvm_scan on REMOVE as the PV label is gone
+# within a CHANGE event (these are caught by the "LVM_PV_GONE" rule at the beginning).
+#
+# | real ADD | real CHANGE | artificial ADD | artificial CHANGE | REMOVE
+# =============================================================================
+# DM | | X | X* | | X
+# MD | | X | X* | |
+# loop | | X | X* | |
+# other | X | | X | | X
+
+# Skip device that is a multipath or RAID component
+ENV{DM_MULTIPATH_DEVICE_PATH}=="1", GOTO="lvm_end"
+ENV{ID_FS_TYPE}=="*_raid_member", GOTO="lvm_end"
+
+RUN+="(LVM_EXEC)/lvm pvscan --background --cache --activate ay --major $major --minor $minor", ENV{LVM_SCANNED}="1"
LABEL="lvm_end"
10 years, 8 months
master - udev: DM_ID_FS_TYPE should be ID_FS_TYPE when comparing with old value
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=9ba40da7ae908f...
Commit: 9ba40da7ae908fb36cb9927cde60a1a45cacce80
Parent: ca514351536c2dd8929944bb6b01a64587cb0a46
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Tue Sep 10 12:38:18 2013 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Tue Sep 10 12:39:23 2013 +0200
udev: DM_ID_FS_TYPE should be ID_FS_TYPE when comparing with old value
---
udev/69-dm-lvm-metad.rules.in | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/udev/69-dm-lvm-metad.rules.in b/udev/69-dm-lvm-metad.rules.in
index b4be582..aa787e3 100644
--- a/udev/69-dm-lvm-metad.rules.in
+++ b/udev/69-dm-lvm-metad.rules.in
@@ -18,7 +18,7 @@ SUBSYSTEM!="block", GOTO="lvm_end"
(LVM_EXEC_RULE)
# If the PV label got lost, inform lvmetad about it.
-ENV{DM_ID_FS_TYPE_OLD}=="LVM2_member|LVM1_member", ENV{DM_ID_FS_TYPE}!="LVM2_member|LVM1_member", GOTO="lvm_scan"
+ENV{DM_ID_FS_TYPE_OLD}=="LVM2_member|LVM1_member", ENV{ID_FS_TYPE}!="LVM2_member|LVM1_member", GOTO="lvm_scan"
# Only process devices already marked as a PV - this requires blkid to be called before.
ENV{ID_FS_TYPE}!="LVM2_member|LVM1_member", GOTO="lvm_end"
10 years, 8 months
master - Misc/RAID: Enable resume_lv to handle some renaming conflicts.
by Jonathan Brassow
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ca514351536c2d...
Commit: ca514351536c2dd8929944bb6b01a64587cb0a46
Parent: 9f2fc2471cd39effccd549d73c2fc9c0e6419f94
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Mon Sep 9 15:07:28 2013 -0500
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Mon Sep 9 15:07:28 2013 -0500
Misc/RAID: Enable resume_lv to handle some renaming conflicts.
When images and their associated metadata are removed from a RAID1 LV,
the remaining sub-LVs are "shifted" down to fill the gaps. For
example, if there is a 3-way mirror:
[0][1][2]
and we remove device#0, the devices will be shifted down
[1][2]
and renamed.
[0][1]
This can create a problem for resume_lv (specifically,
dm_tree_activate_children) during the renaming process though. This
is because it will attempt to rename the higher indexed sub-LVs first
and find that it cannot because there are currently other sub-LVs with
that name. The solution is to check for a conflicting name before
attempting to rename. If a conflict is found and that conflicting
sub-LV is also in the process of renaming, we can defer the current
rename until the conflicting sub-LV has renamed and cleared the
conflict.
Now that resume_lv can handle these types of rename conflicts, we can
remove the workaround in RAID that was attempting to resume a RAID1
LV from the bottom-up in order to force a proper rename in assending
order before attempting a resume on the top-level LV. This "hack"
only worked for single machine use-cases of LVM. Clearing this up
paves the way for exclusive activation of RAID LVs in a cluster.
---
lib/metadata/raid_manip.c | 42 +--------------------------------
libdm/libdm-deptree.c | 55 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 57 insertions(+), 40 deletions(-)
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index 47c2788..d13750d 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -59,24 +59,6 @@ uint32_t lv_raid_image_count(const struct logical_volume *lv)
return seg->area_count;
}
-/*
- * Resume sub-LVs first, then top-level LV
- */
-static int _bottom_up_resume(struct logical_volume *lv)
-{
- uint32_t s;
- struct lv_segment *seg = first_seg(lv);
-
- if (seg_is_raid(seg) && (seg->area_count > 1)) {
- for (s = 0; s < seg->area_count; s++)
- if (!resume_lv(lv->vg->cmd, seg_lv(seg, s)) ||
- !resume_lv(lv->vg->cmd, seg_metalv(seg, s)))
- return_0;
- }
-
- return resume_lv(lv->vg->cmd, lv);
-}
-
static int _activate_sublv_preserving_excl(struct logical_volume *top_lv,
struct logical_volume *sub_lv)
{
@@ -991,17 +973,7 @@ static int _raid_remove_images(struct logical_volume *lv,
}
}
- /*
- * Resume the remaining LVs
- * We must start by resuming the sub-LVs first (which would
- * otherwise be handled automatically) because the shifting
- * of positions could otherwise cause name collisions. For
- * example, if position 0 of a 3-way array is removed, position
- * 1 and 2 must be shifted and renamed 0 and 1. If position 2
- * tries to rename first, it will collide with the existing
- * position 1.
- */
- if (!_bottom_up_resume(lv)) {
+ if (!resume_lv(lv->vg->cmd, lv)) {
log_error("Failed to resume %s/%s after committing changes",
lv->vg->name, lv->name);
return 0;
@@ -1164,17 +1136,7 @@ int lv_raid_split(struct logical_volume *lv, const char *split_name,
if (!resume_lv(cmd, lvl->lv))
return_0;
- /*
- * Resume the remaining LVs
- * We must start by resuming the sub-LVs first (which would
- * otherwise be handled automatically) because the shifting
- * of positions could otherwise cause name collisions. For
- * example, if position 0 of a 3-way array is split, position
- * 1 and 2 must be shifted and renamed 0 and 1. If position 2
- * tries to rename first, it will collide with the existing
- * position 1.
- */
- if (!_bottom_up_resume(lv)) {
+ if (!resume_lv(lv->vg->cmd, lv)) {
log_error("Failed to resume %s/%s after committing changes",
lv->vg->name, lv->name);
return 0;
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
index 57f00f6..752a44b 100644
--- a/libdm/libdm-deptree.c
+++ b/libdm/libdm-deptree.c
@@ -1702,11 +1702,58 @@ int dm_tree_suspend_children(struct dm_tree_node *dnode,
return r;
}
+/*
+ * _rename_conflict_exists
+ * @dnode
+ * @node
+ * @resolvable
+ *
+ * Check if there is a rename conflict with existing peers in
+ * this tree. 'resolvable' is set if the conflicting node will
+ * also be undergoing a rename. (Allowing that node to rename
+ * first would clear the conflict.)
+ *
+ * Returns: 1 if conflict, 0 otherwise
+ */
+static int _rename_conflict_exists(struct dm_tree_node *parent,
+ struct dm_tree_node *node,
+ int *resolvable)
+{
+ void *handle = NULL;
+ const char *name = dm_tree_node_get_name(node);
+ const char *sibling_name;
+ struct dm_tree_node *sibling;
+
+ *resolvable = 0;
+
+ if (!name)
+ return_0;
+
+ while ((sibling = dm_tree_next_child(&handle, parent, 0))) {
+ if (sibling == node)
+ continue;
+
+ if (!(sibling_name = dm_tree_node_get_name(sibling))) {
+ stack;
+ continue;
+ }
+
+ if (!strcmp(node->props.new_name, sibling_name)) {
+ if (sibling->props.new_name)
+ *resolvable = 1;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
int dm_tree_activate_children(struct dm_tree_node *dnode,
const char *uuid_prefix,
size_t uuid_prefix_len)
{
int r = 1;
+ int resolvable_name_conflict, awaiting_peer_rename = 0;
void *handle = NULL;
struct dm_tree_node *child = dnode;
struct dm_info newinfo;
@@ -1732,6 +1779,7 @@ int dm_tree_activate_children(struct dm_tree_node *dnode,
handle = NULL;
for (priority = 0; priority < 3; priority++) {
+ awaiting_peer_rename = 0;
while ((child = dm_tree_next_child(&handle, dnode, 0))) {
if (priority != child->activation_priority)
continue;
@@ -1751,6 +1799,11 @@ int dm_tree_activate_children(struct dm_tree_node *dnode,
/* Rename? */
if (child->props.new_name) {
+ if (_rename_conflict_exists(dnode, child, &resolvable_name_conflict) &&
+ resolvable_name_conflict) {
+ awaiting_peer_rename++;
+ continue;
+ }
if (!_rename_node(name, child->props.new_name, child->info.major,
child->info.minor, &child->dtree->cookie,
child->udev_flags)) {
@@ -1779,6 +1832,8 @@ int dm_tree_activate_children(struct dm_tree_node *dnode,
/* Update cached info */
child->info = newinfo;
}
+ if (awaiting_peer_rename)
+ priority--; /* redo priority level */
}
/*
10 years, 8 months
master - udev: also inform lvmetad about lost LVM1 PV label
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=9f2fc2471cd39e...
Commit: 9f2fc2471cd39effccd549d73c2fc9c0e6419f94
Parent: d89b514e06eb3431052d3dee4758103bf5f08963
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Sep 9 13:47:25 2013 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Sep 9 13:48:27 2013 +0200
udev: also inform lvmetad about lost LVM1 PV label
Addendum to 4d3b5724e0b51782000a45027de00e0fed1c9833
which covered only LVM2 PV labels.
---
udev/69-dm-lvm-metad.rules.in | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/udev/69-dm-lvm-metad.rules.in b/udev/69-dm-lvm-metad.rules.in
index 6162e26..b4be582 100644
--- a/udev/69-dm-lvm-metad.rules.in
+++ b/udev/69-dm-lvm-metad.rules.in
@@ -18,7 +18,7 @@ SUBSYSTEM!="block", GOTO="lvm_end"
(LVM_EXEC_RULE)
# If the PV label got lost, inform lvmetad about it.
-ENV{DM_ID_FS_TYPE_OLD}=="LVM2_member", ENV{DM_ID_FS_TYPE}!="LVM2_member", GOTO="lvm_scan"
+ENV{DM_ID_FS_TYPE_OLD}=="LVM2_member|LVM1_member", ENV{DM_ID_FS_TYPE}!="LVM2_member|LVM1_member", GOTO="lvm_scan"
# Only process devices already marked as a PV - this requires blkid to be called before.
ENV{ID_FS_TYPE}!="LVM2_member|LVM1_member", GOTO="lvm_end"
10 years, 8 months
master - cleanup: drop within comment gcc warning
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d89b514e06eb34...
Commit: d89b514e06eb3431052d3dee4758103bf5f08963
Parent: ac2de55d69605d058bbc7622638331549a0ba5c8
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Sep 9 12:15:48 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Sep 9 12:17:11 2013 +0200
cleanup: drop within comment gcc warning
toollib.c:69:24: warning: "/*" within comment
---
tools/toollib.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tools/toollib.c b/tools/toollib.c
index 5868ac0..bccebb6 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -66,7 +66,7 @@ int become_daemon(struct cmd_context *cmd, int skip_lvm)
strerror(errno));
/* Set this to avoid discarding output from background process */
-/* #define DEBUG_CHILD /* */
+/* #define DEBUG_CHILD */
#ifndef DEBUG_CHILD
if ((null_fd = open(devnull, O_RDWR)) == -1) {
10 years, 8 months
master - test: timeout when no write happens since last written line
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ac2de55d69605d...
Commit: ac2de55d69605d058bbc7622638331549a0ba5c8
Parent: f5832d8c49bfe96d0162d1b59125a169117c52b2
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Sep 9 12:14:00 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Sep 9 12:17:11 2013 +0200
test: timeout when no write happens since last written line
Change current test abort after 3 minutes, to abort after 3 minutes
without written output line.
---
test/lib/harness.c | 17 ++++++++++-------
1 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/test/lib/harness.c b/test/lib/harness.c
index 53814dc..415093d 100644
--- a/test/lib/harness.c
+++ b/test/lib/harness.c
@@ -365,8 +365,9 @@ static void run(int i, char *f) {
char outpath[PATH_MAX];
char *c = outpath + strlen(results) + 1;
struct timeval selectwait;
- fd_set master_set, copy_set;
+ fd_set set;
int runaway = 0;
+ int no_write = 0;
snprintf(buf, sizeof(buf), "%s ...", f);
printf("Running %-60s ", buf);
@@ -377,11 +378,9 @@ static void run(int i, char *f) {
if (!(outfile = fopen(outpath, "w")))
perror("fopen");
- FD_ZERO(&master_set);
- FD_SET(fds[1], &master_set);
while ((w = wait4(pid, &st, WNOHANG, &usage)) == 0) {
if ((fullbuffer && fullbuffer++ == 8000) ||
- time(NULL) - start > 180) // a 3 minute timeout
+ (no_write > 180 * 2)) /* a 3 minute timeout */
{
system("echo t > /proc/sysrq-trigger");
kill(pid, SIGINT);
@@ -394,12 +393,16 @@ static void run(int i, char *f) {
break;
}
- memcpy(©_set, &master_set, sizeof(master_set));
+ FD_ZERO(&set);
+ FD_SET(fds[1], &set);
selectwait.tv_sec = 0;
- selectwait.tv_usec = 500000;
- if (select(fds[1] + 1, ©_set, NULL, NULL, &selectwait) <= 0)
+ selectwait.tv_usec = 500000; /* timeout 0.5s */
+ if (select(fds[1] + 1, &set, NULL, NULL, &selectwait) <= 0) {
+ no_write++;
continue;
+ }
drain();
+ no_write = 0;
}
if (w != pid) {
perror("waitpid");
10 years, 8 months
master - deactivate: drop readahead calc in deactivation
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f5832d8c49bfe9...
Commit: f5832d8c49bfe96d0162d1b59125a169117c52b2
Parent: 0670bfeb5942508c3d2e2573a50980f82abe1bcf
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sat Sep 7 02:48:19 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Sat Sep 7 09:13:20 2013 +0200
deactivate: drop readahead calc in deactivation
Skip readahead when device will be deactivated.
---
WHATS_NEW | 1 +
lib/activate/activate.c | 2 --
2 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 342f15b..b1060af 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.101 -
===================================
+ Drop calculation of read ahead for deactivated volume.
Check for exactly one lv segment in validation of thin pools and volumes.
Fix dmeventd unmonitoring of thin pools.
Fix lvresize for stacked thin pool volumes (i.e. mirrors).
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 1706ae5..e5033c6 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -1947,8 +1947,6 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, struct logical_vo
if (!lv_read_replicator_vgs(lv))
goto_out;
- lv_calculate_readahead(lv, NULL);
-
if (!monitor_dev_for_events(cmd, lv, &laopts, 0))
stack;
10 years, 8 months
master - thin: validation catch multiseg thin pool/volumes
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=0670bfeb594250...
Commit: 0670bfeb5942508c3d2e2573a50980f82abe1bcf
Parent: 655296609eaab2d3255178b22b15910c4771b864
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Sep 6 14:07:39 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Sat Sep 7 03:32:07 2013 +0200
thin: validation catch multiseg thin pool/volumes
Multisegment thin pools and volumes are not supported.
Catch such error code path early.
---
WHATS_NEW | 1 +
lib/metadata/merge.c | 30 ++++++++++++++++++++----------
2 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 8bc95c2..342f15b 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.101 -
===================================
+ Check for exactly one lv segment in validation of thin pools and volumes.
Fix dmeventd unmonitoring of thin pools.
Fix lvresize for stacked thin pool volumes (i.e. mirrors).
Write Completed debug message before reinstating log defaults after command.
diff --git a/lib/metadata/merge.c b/lib/metadata/merge.c
index 477d7bb..c22e922 100644
--- a/lib/metadata/merge.c
+++ b/lib/metadata/merge.c
@@ -76,18 +76,28 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
/* Check LV flags match first segment type */
if (complete_vg) {
- if (lv_is_thin_volume(lv) &&
- (!(seg2 = first_seg(lv)) || !seg_is_thin_volume(seg2))) {
- log_error("LV %s is thin volume without first thin volume segment",
- lv->name);
- inc_error_count;
+ if (lv_is_thin_volume(lv)) {
+ if (dm_list_size(&lv->segments) != 1) {
+ log_error("LV %s is thin volume without exactly one segment.",
+ lv->name);
+ inc_error_count;
+ } else if (!seg_is_thin_volume(first_seg(lv))) {
+ log_error("LV %s is thin volume without first thin volume segment.",
+ lv->name);
+ inc_error_count;
+ }
}
- if (lv_is_thin_pool(lv) &&
- (!(seg2 = first_seg(lv)) || !seg_is_thin_pool(seg2))) {
- log_error("LV %s is thin pool without first thin pool segment",
- lv->name);
- inc_error_count;
+ if (lv_is_thin_pool(lv)) {
+ if (dm_list_size(&lv->segments) != 1) {
+ log_error("LV %s is thin pool volume without exactly one segment.",
+ lv->name);
+ inc_error_count;
+ } else if (!seg_is_thin_pool(first_seg(lv))) {
+ log_error("LV %s is thin pool without first thin pool segment.",
+ lv->name);
+ inc_error_count;
+ }
}
if (lv_is_thin_pool_data(lv) &&
10 years, 8 months
master - thin: fix monitoring of thin pool volume
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=655296609eaab2...
Commit: 655296609eaab2d3255178b22b15910c4771b864
Parent: 4c001a78544d29688f6609b1ceafe123af280323
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sat Sep 7 02:46:48 2013 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Sat Sep 7 03:31:04 2013 +0200
thin: fix monitoring of thin pool volume
Properly skip unmonitoring of thin pool volume in deactivation code
path. Code makes sure if there is just any thin pool user
it stays monitored with all its resources.
---
WHATS_NEW | 1 +
lib/activate/activate.c | 16 ++++++++--------
2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 11f31aa..8bc95c2 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.101 -
===================================
+ Fix dmeventd unmonitoring of thin pools.
Fix lvresize for stacked thin pool volumes (i.e. mirrors).
Write Completed debug message before reinstating log defaults after command.
Skip pvmove of RAID, thin, snapshot, origin, or mirror LVs in a cluster.
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 61dbc02..1706ae5 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -1416,7 +1416,6 @@ int monitor_dev_for_events(struct cmd_context *cmd, struct logical_volume *lv,
int (*monitor_fn) (struct lv_segment *s, int e);
uint32_t s;
static const struct lv_activate_opts zlaopts = { 0 };
- static const struct lv_activate_opts thinopts = { .skip_in_use = 1 };
struct lvinfo info;
if (!laopts)
@@ -1435,11 +1434,12 @@ int monitor_dev_for_events(struct cmd_context *cmd, struct logical_volume *lv,
/*
* Allow to unmonitor thin pool via explicit pool unmonitor
* or unmonitor before the last thin pool user deactivation
- * Skip unmonitor, if invoked via unmonitor of thin volume
+ * Skip unmonitor, if invoked via deactivation of thin volume
* and there is another thin pool user (open_count > 1)
+ * FIXME think about watch ruler influence.
*/
- if (laopts->skip_in_use && lv_info(lv->vg->cmd, lv, 1, &info, 1, 0) &&
- (info.open_count != 1)) {
+ if (laopts->skip_in_use && lv_is_thin_pool(lv) &&
+ lv_info(lv->vg->cmd, lv, 1, &info, 1, 0) && (info.open_count > 1)) {
log_debug_activation("Skipping unmonitor of opened %s (open:%d)",
lv->name, info.open_count);
return 1;
@@ -1495,14 +1495,13 @@ int monitor_dev_for_events(struct cmd_context *cmd, struct logical_volume *lv,
}
/*
- * If requested unmonitoring of thin volume, request test
- * if there is no other thin pool user
+ * If requested unmonitoring of thin volume, preserve skip_in_use flag.
*
* FIXME: code here looks like _lv_postorder()
*/
if (seg->pool_lv &&
!monitor_dev_for_events(cmd, seg->pool_lv,
- (!monitor) ? &thinopts : NULL, monitor))
+ (!monitor) ? laopts : NULL, monitor))
r = 0;
if (seg->metadata_lv &&
@@ -1912,6 +1911,7 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, struct logical_vo
{
struct logical_volume *lv_to_free = NULL;
struct lvinfo info;
+ static const struct lv_activate_opts laopts = { .skip_in_use = 1 };
int r = 0;
if (!activation())
@@ -1949,7 +1949,7 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, struct logical_vo
lv_calculate_readahead(lv, NULL);
- if (!monitor_dev_for_events(cmd, lv, NULL, 0))
+ if (!monitor_dev_for_events(cmd, lv, &laopts, 0))
stack;
critical_section_inc(cmd, "deactivating");
10 years, 8 months