WHATS_NEW | 6 ++++++
lib/activate/activate.c | 21 +++++++++++++++++++++
lib/activate/dev_manager.c | 2 +-
lib/metadata/lv.c | 4 ++++
lib/metadata/raid_manip.c | 30 ++++++++++--------------------
test/shell/lvconvert-raid.sh | 6 ++++++
test/shell/lvconvert-repair-thin.sh | 9 ++++++++-
tools/lvconvert.c | 1 +
8 files changed, 57 insertions(+), 22 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 75c4569..ef5cc83 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,3 +1,9 @@
+Version 2.02.116 -
+====================================
+ Preserve chunk size with repair and metadata swap of a thin pool.
+ Fix raid --splitmirror 1 functionality (2.02.112).
+ Fix tree preload to handle splitting raid images.
+
Version 2.02.115 - 21st January 2015
====================================
Report segment types without monitoring support as undefined.
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 424786c..00d3a10 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -1760,6 +1760,22 @@ static int _preload_detached_lv(struct logical_volume *lv, void *data)
struct detached_lv_data *detached = data;
struct lv_list *lvl_pre;
+ /* Check and preload removed raid image leg */
+ if (lv_is_raid_image(lv)) {
+ if ((lvl_pre = find_lv_in_vg_by_lvid(detached->lv_pre->vg, &lv->lvid)) &&
+ !lv_is_raid_image(lvl_pre->lv) &&
+ !_lv_preload(lvl_pre->lv, detached->laopts, detached->flush_required))
+ return_0;
+ }
+
+ /* Check and preload removed of raid metadata */
+ if (lv_is_raid_metadata(lv)) {
+ if ((lvl_pre = find_lv_in_vg_by_lvid(detached->lv_pre->vg, &lv->lvid)) &&
+ !lv_is_raid_metadata(lvl_pre->lv) &&
+ !_lv_preload(lvl_pre->lv, detached->laopts, detached->flush_required))
+ return_0;
+ }
+
if ((lvl_pre = find_lv_in_vg(detached->lv_pre->vg, lv->name))) {
if (lv_is_visible(lvl_pre->lv) && lv_is_active(lv) &&
(!lv_is_cow(lv) || !lv_is_cow(lvl_pre->lv)) &&
@@ -1863,6 +1879,11 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
if (!for_each_sub_lv((struct logical_volume *)ondisk_lv, &_preload_detached_lv, &detached))
goto_out;
+ /* ATM cache/thin pool is not scanned in 'for_each_sub_lv()', TODO explore better way */
+ if (lv_is_cache(ondisk_lv) &&
+ !for_each_sub_lv(first_seg(ondisk_lv)->pool_lv, &_preload_detached_lv, &detached))
+ goto_out;
+
/*
* Preload any snapshots that are being removed.
*/
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 015af5b..dcb2c5d 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -2295,7 +2295,7 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
* is used in the CTR table.
*/
if ((seg_type(seg, s) == AREA_UNASSIGNED) ||
- ((seg_lv(seg, s)->status & VISIBLE_LV) &&
+ (lv_is_visible(seg_lv(seg, s)) &&
!(seg_lv(seg, s)->status & LVM_WRITE))) {
/* One each for metadata area and data area */
if (!dm_tree_node_add_null_area(node, 0) ||
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index 683ec47..9052e63 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -1018,6 +1018,10 @@ const struct logical_volume *lv_lock_holder(const struct logical_volume *lv)
return sl->seg->lv;
}
+ /* RAID changes visibility of splitted LVs but references them still as leg/meta */
+ if ((lv_is_raid_image(lv) || lv_is_raid_metadata(lv)) && lv_is_visible(lv))
+ return lv;
+
/* For other types, by default look for the first user */
dm_list_iterate_items(sl, &lv->segs_using_this_lv) {
/* FIXME: complete this exception list */
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index d502379..22f71c7 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -1149,12 +1149,6 @@ int lv_raid_split(struct logical_volume *lv, const char *split_name,
return 0;
}
- if (!resume_lv(lv->vg->cmd, lv_lock_holder(lv))) {
- log_error("Failed to resume %s/%s after committing changes",
- lv->vg->name, lv->name);
- return 0;
- }
-
/*
* First activate the newly split LV and LVs on the removal list.
* This is necessary so that there are no name collisions due to
@@ -1164,26 +1158,22 @@ int lv_raid_split(struct logical_volume *lv, const char *split_name,
if (!activate_lv_excl_local(cmd, lvl->lv))
return_0;
+ dm_list_iterate_items(lvl, &removal_list)
+ if (!activate_lv_excl_local(cmd, lvl->lv))
+ return_0;
+
+ if (!resume_lv(cmd, lv_lock_holder(lv))) {
+ log_error("Failed to resume %s/%s after committing changes",
+ lv->vg->name, lv->name);
+ return 0;
+ }
+
/*
* Since newly split LV is typically already active - we need to call
* suspend() and resume() to also rename it.
*
* TODO: activate should recognize it and avoid these 2 calls
*/
- if (!suspend_lv(cmd, lvl->lv)) {
- log_error("Failed to suspend %s.", lvl->lv->name);
- return 0;
- }
-
- if (!resume_lv(cmd, lvl->lv)) {
- log_error("Failed to reactivate %s.", lvl->lv->name);
- return 0;
- }
-
- dm_list_iterate_items(lvl, &removal_list)
- if (!activate_lv_excl_local(cmd, lvl->lv))
- return_0;
-
/*
* Eliminate the residual LVs
diff --git a/test/shell/lvconvert-raid.sh b/test/shell/lvconvert-raid.sh
index 8621311..12e0420 100644
--- a/test/shell/lvconvert-raid.sh
+++ b/test/shell/lvconvert-raid.sh
@@ -121,6 +121,12 @@ check active $vg $lv2
# FIXME: ensure no residual devices
lvremove -ff $vg
+# 4-way
+lvcreate --type raid1 -m 4 -l 2 -n $lv1 $vg
+aux wait_for_sync $vg $lv1
+lvconvert --yes --splitmirrors 1 --name $lv2 $vg/$lv1 "$dev2"
+lvremove -ff $vg
+
###########################################
# RAID1 split + trackchanges / merge
###########################################
diff --git a/test/shell/lvconvert-repair-thin.sh b/test/shell/lvconvert-repair-thin.sh
index 0e9534b..73f061c 100644
--- a/test/shell/lvconvert-repair-thin.sh
+++ b/test/shell/lvconvert-repair-thin.sh
@@ -24,7 +24,9 @@ aux have_thin 1 0 0 || skip
aux prepare_vg 4
# Create LV
-lvcreate -T -L20 -V10 -n $lv1 $vg/pool "$dev1" "$dev2"
+# TODO: investigate problem with --zero n and my repairable damage trick
+#lvcreate -T -L20 -V10 -n $lv1 $vg/pool --discards ignore --zero n --chunksize 128 "$dev1" "$dev2"
+lvcreate -T -L20 -V10 -n $lv1 $vg/pool --chunksize 128 --discards ignore "$dev1" "$dev2"
lvcreate -T -V10 -n $lv2 $vg/pool
mkfs.ext2 "$DM_DEV_DIR/$vg/$lv1"
@@ -71,6 +73,11 @@ lvchange -an $vg
# Swap repaired metadata back
lvconvert -y -f --poolmetadata $vg/fixed --thinpool $vg/pool
+# Check pool still preserves its original settings
+check lv_field $vg/pool chunksize "128.00k"
+check lv_field $vg/pool discards "ignore"
+check lv_field $vg/pool zero "zero"
+
# Activate pool - this should now work
vgchange -ay $vg
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index c7acd5d..20f017a 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -2956,6 +2956,7 @@ static int _lvconvert_pool(struct cmd_context *cmd,
return 0;
}
+ lp->passed_args |= PASS_ARG_CHUNK_SIZE | PASS_ARG_DISCARDS | PASS_ARG_ZERO;
seg = first_seg(pool_lv);
/* Normally do NOT change chunk size when swapping */