mrc0mmand / rpms / lvm2

Forked from rpms/lvm2 2 years ago
Clone

Blame SOURCES/lvm2-2_02_116-fix-raid-image-splitting.patch

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