Blame SOURCES/lvm2-2_02_181-reject-conversions-trackchanges-SubLVs.patch

0d8a0a
 WHATS_NEW                                        |  1 +
0d8a0a
 test/shell/lvconvert-raid1-split-trackchanges.sh | 36 +++++++++++++++++++
0d8a0a
 tools/lvconvert.c                                | 45 ++++++++++++++++++++++++
0d8a0a
 3 files changed, 82 insertions(+)
0d8a0a
 create mode 100644 test/shell/lvconvert-raid1-split-trackchanges.sh
0d8a0a
0d8a0a
diff --git a/WHATS_NEW b/WHATS_NEW
0d8a0a
index bdd2fa6..7c74c50 100644
0d8a0a
--- a/WHATS_NEW
0d8a0a
+++ b/WHATS_NEW
0d8a0a
@@ -1,5 +1,6 @@
0d8a0a
 Version 2.02.181 - 
0d8a0a
 =================================
0d8a0a
+  lvconvert: reject conversions on raid1 split tracked SubLVs
0d8a0a
 
0d8a0a
 Version 2.02.180 - 19th July 2018
0d8a0a
 =================================
0d8a0a
diff --git a/test/shell/lvconvert-raid1-split-trackchanges.sh b/test/shell/lvconvert-raid1-split-trackchanges.sh
0d8a0a
new file mode 100644
0d8a0a
index 0000000..e25a632
0d8a0a
--- /dev/null
0d8a0a
+++ b/test/shell/lvconvert-raid1-split-trackchanges.sh
0d8a0a
@@ -0,0 +1,36 @@
0d8a0a
+#!/usr/bin/env bash
0d8a0a
+
0d8a0a
+# Copyright (C) 2018 Red Hat, Inc. All rights reserved.
0d8a0a
+#
0d8a0a
+# This copyrighted material is made available to anyone wishing to use,
0d8a0a
+# modify, copy, or redistribute it subject to the terms and conditions
0d8a0a
+# of the GNU General Public License v.2.
0d8a0a
+#
0d8a0a
+# You should have received a copy of the GNU General Public License
0d8a0a
+# along with this program; if not, write to the Free Software Foundation,
0d8a0a
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
0d8a0a
+
0d8a0a
+
0d8a0a
+SKIP_WITH_LVMPOLLD=1
0d8a0a
+
0d8a0a
+. lib/inittest
0d8a0a
+
0d8a0a
+# rhbz1579072/rhbz1579438
0d8a0a
+
0d8a0a
+aux have_raid 1 3 0 || skip
0d8a0a
+
0d8a0a
+# 8 PVs needed for RAID10 testing (4-stripes/2-mirror)
0d8a0a
+aux prepare_pvs 4 2
0d8a0a
+get_devs
0d8a0a
+vgcreate $SHARED -s 512k "$vg" "${DEVICES[@]}"
0d8a0a
+
0d8a0a
+lvcreate -y --ty raid1 -m 2 -n $lv1 -l 1 $vg
0d8a0a
+lvconvert -y --splitmirrors 1 --trackchanges $vg/$lv1
0d8a0a
+
0d8a0a
+not lvconvert -y --ty striped -m 1 $vg/${lv1}_rimage_2
0d8a0a
+not lvconvert -y --ty raid1 -m 1 $vg/${lv1}_rimage_2
0d8a0a
+not lvconvert -y --ty mirror -m 1 $vg/${lv1}_rimage_2
0d8a0a
+not lvconvert -y --ty cache-pool $vg/${lv1}_rimage_2
0d8a0a
+not lvconvert -y --ty thin-pool $vg/${lv1}_rimage_2
0d8a0a
+
0d8a0a
+vgremove -ff $vg
0d8a0a
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
0d8a0a
index 3fad02c..079c3cd 100644
0d8a0a
--- a/tools/lvconvert.c
0d8a0a
+++ b/tools/lvconvert.c
0d8a0a
@@ -1165,6 +1165,36 @@ static int _lvconvert_validate_thin(struct logical_volume *lv,
0d8a0a
 	return 0;
0d8a0a
 }
0d8a0a
 
0d8a0a
+/* Check for raid1 split trackchanges image to reject conversions on it. */
0d8a0a
+static int _raid_split_image_conversion(struct logical_volume *lv)
0d8a0a
+{
0d8a0a
+	const char *s;
0d8a0a
+
0d8a0a
+	if (lv_is_raid_image(lv) &&
0d8a0a
+	    (s = strstr(lv->name, "_rimage_"))) {
0d8a0a
+		size_t len = s - lv->name;
0d8a0a
+		char raidlv_name[len + 1];
0d8a0a
+		const struct logical_volume *tmp_lv;
0d8a0a
+
0d8a0a
+		strncpy(raidlv_name, lv->name, len);
0d8a0a
+		raidlv_name[len] = '\0';
0d8a0a
+
0d8a0a
+		if (!(tmp_lv = find_lv(lv->vg, raidlv_name))) {
0d8a0a
+			log_error(INTERNAL_ERROR "Failed to find RaidLV of RAID subvolume %s.",
0d8a0a
+				  display_lvname(lv));
0d8a0a
+			return 1;
0d8a0a
+		}
0d8a0a
+
0d8a0a
+		if (lv_is_raid_with_tracking(tmp_lv)) {
0d8a0a
+			log_error("Conversion of tracked raid1 subvolume %s is not supported.",
0d8a0a
+				  display_lvname(lv));
0d8a0a
+			return 1;
0d8a0a
+		}
0d8a0a
+	}
0d8a0a
+
0d8a0a
+	return 0;
0d8a0a
+}
0d8a0a
+
0d8a0a
 /*
0d8a0a
  * _lvconvert_mirrors
0d8a0a
  *
0d8a0a
@@ -1180,6 +1210,9 @@ static int _lvconvert_mirrors(struct cmd_context *cmd,
0d8a0a
 	uint32_t new_mimage_count = 0;
0d8a0a
 	uint32_t new_log_count = 0;
0d8a0a
 
0d8a0a
+	if (_raid_split_image_conversion(lv))
0d8a0a
+		return 0;
0d8a0a
+
0d8a0a
 	if ((lp->corelog || lp->mirrorlog) && *lp->type_str && strcmp(lp->type_str, SEG_TYPE_NAME_MIRROR)) {
0d8a0a
 		log_error("--corelog and --mirrorlog are only compatible with mirror devices.");
0d8a0a
 		return 0;
0d8a0a
@@ -1296,6 +1329,9 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
0d8a0a
 	struct cmd_context *cmd = lv->vg->cmd;
0d8a0a
 	struct lv_segment *seg = first_seg(lv);
0d8a0a
 
0d8a0a
+	if (_raid_split_image_conversion(lv))
0d8a0a
+		return 0;
0d8a0a
+
0d8a0a
 	if (_linear_type_requested(lp->type_str)) {
0d8a0a
 		if (arg_is_set(cmd, mirrors_ARG) && (arg_uint_value(cmd, mirrors_ARG, 0) != 0)) {
0d8a0a
 			log_error("Cannot specify mirrors with linear type.");
0d8a0a
@@ -2579,6 +2615,9 @@ static int _lvconvert_to_thin_with_external(struct cmd_context *cmd,
0d8a0a
 		.virtual_extents = lv->le_count,
0d8a0a
 	};
0d8a0a
 
0d8a0a
+	if (_raid_split_image_conversion(lv))
0d8a0a
+		return 0;
0d8a0a
+
0d8a0a
 	if (lv == thinpool_lv) {
0d8a0a
 		log_error("Can't use same LV %s for thin pool and thin volume.",
0d8a0a
 			  display_lvname(thinpool_lv));
0d8a0a
@@ -2888,6 +2927,9 @@ static int _lvconvert_to_pool(struct cmd_context *cmd,
0d8a0a
 	struct id lockd_meta_id;
0d8a0a
 	const char *str_seg_type = to_cachepool ? SEG_TYPE_NAME_CACHE_POOL : SEG_TYPE_NAME_THIN_POOL;
0d8a0a
 
0d8a0a
+	if (_raid_split_image_conversion(lv))
0d8a0a
+		return 0;
0d8a0a
+
0d8a0a
 	if (lv_is_thin_pool(lv) || lv_is_cache_pool(lv)) {
0d8a0a
 		log_error(INTERNAL_ERROR "LV %s is already a pool.", display_lvname(lv));
0d8a0a
 		return 0;
0d8a0a
@@ -3339,6 +3381,9 @@ static int _lvconvert_to_cache_vol(struct cmd_context *cmd,
0d8a0a
 	struct dm_config_tree *policy_settings = NULL;
0d8a0a
 	int r = 0;
0d8a0a
 
0d8a0a
+	if (_raid_split_image_conversion(lv))
0d8a0a
+		return 0;
0d8a0a
+
0d8a0a
 	/* If LV is inactive here, ensure it's not active elsewhere. */
0d8a0a
 	if (!lockd_lv(cmd, lv, "ex", 0))
0d8a0a
 		return_0;