master - WHATS_NEW: add entry
by Heinz Mauelshagen
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d768fbe0109141...
Commit: d768fbe010914161e3e7bfff6e4e6e0e2cd3907d
Parent: 76f60cc4306deda481c45de7ebcde02a40668d85
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Fri Feb 24 05:24:59 2017 +0100
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Fri Feb 24 05:24:59 2017 +0100
WHATS_NEW: add entry
---
WHATS_NEW | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 14109fb..d2e750b 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.169 -
=====================================
+ Support conversion of raid type, stripesize and number of disks
Reject writemostly/writebehind in lvchange during resynchronization.
Deactivate active origin first before removal for improved workflow.
Fix regression of accepting options --type and -m with lvresize (2.02.158).
7 years, 1 month
master - lvconvert: add missed new test scripts for reshaping
by Heinz Mauelshagen
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=76f60cc4306ded...
Commit: 76f60cc4306deda481c45de7ebcde02a40668d85
Parent: 2574d3257ad41cad8dcbad3332774172e86f05da
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Fri Feb 24 05:16:21 2017 +0100
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Fri Feb 24 05:20:59 2017 +0100
lvconvert: add missed new test scripts for reshaping
Add aforementioned but forgotten new test scripts
lvconvert-raid-reshape-linear_to_striped.sh,
lvconvert-raid-reshape-striped_to_linear.sh and
lvconvert-raid-reshape.sh
Those presume dm-raid target version 1.10.2
provided by a following kernel patch.
Related: rhbz834579
Related: rhbz1191935
Related: rhbz1191978
---
.../lvconvert-raid-reshape-linear_to_striped.sh | 64 +++++++
.../lvconvert-raid-reshape-striped_to_linear.sh | 84 ++++++++
test/shell/lvconvert-raid-reshape.sh | 199 ++++++++++++++++++++
3 files changed, 347 insertions(+), 0 deletions(-)
diff --git a/test/shell/lvconvert-raid-reshape-linear_to_striped.sh b/test/shell/lvconvert-raid-reshape-linear_to_striped.sh
new file mode 100644
index 0000000..3b6120c
--- /dev/null
+++ b/test/shell/lvconvert-raid-reshape-linear_to_striped.sh
@@ -0,0 +1,64 @@
+#!/bin/sh
+# Copyright (C) 2017 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA2110-1301 USA
+
+SKIP_WITH_LVMLOCKD=1
+SKIP_WITH_LVMPOLLD=1
+
+. lib/inittest
+
+which mkfs.ext4 || skip
+aux have_raid 1 10 2 || skip
+
+aux prepare_vg 5
+
+#
+# Test single step linear -> striped conversion
+#
+
+# Create linear LV
+lvcreate -aey -L 16M -n $lv1 $vg
+check lv_field $vg/$lv1 segtype "linear"
+check lv_field $vg/$lv1 stripes 1
+echo y|mkfs -t ext4 $DM_DEV_DIR/$vg/$lv1
+fsck -fn $DM_DEV_DIR/$vg/$lv1
+
+# Convert linear -> raid1
+lvconvert -y -m 1 $vg/$lv1
+fsck -fn $DM_DEV_DIR/$vg/$lv1
+check lv_field $vg/$lv1 segtype "raid1"
+check lv_field $vg/$lv1 stripes 2
+check lv_field $vg/$lv1 regionsize "512.00k"
+aux wait_for_sync $vg $lv1
+fsck -fn $DM_DEV_DIR/$vg/$lv1
+
+# Convert raid1 -> raid5_n
+lvconvert -y --ty raid5_n $vg/$lv1
+fsck -fn $DM_DEV_DIR/$vg/$lv1
+check lv_field $vg/$lv1 segtype "raid5_n"
+check lv_field $vg/$lv1 stripes 2
+check lv_field $vg/$lv1 stripesize "64.00k"
+check lv_field $vg/$lv1 regionsize "512.00k"
+
+# Convert raid5_n adding stripes
+lvconvert -y --stripes 4 $vg/$lv1
+fsck -fn $DM_DEV_DIR/$vg/$lv1
+check lv_first_seg_field $vg/$lv1 segtype "raid5_n"
+check lv_first_seg_field $vg/$lv1 stripes 5
+check lv_first_seg_field $vg/$lv1 stripesize "64.00k"
+check lv_first_seg_field $vg/$lv1 regionsize "512.00k"
+aux wait_for_sync $vg $lv1
+fsck -fn $DM_DEV_DIR/$vg/$lv1
+
+# Convert raid5_n -> striped
+lvconvert -y --type striped $vg/$lv1
+fsck -fn $DM_DEV_DIR/$vg/$lv1
+
+vgremove -ff $vg
diff --git a/test/shell/lvconvert-raid-reshape-striped_to_linear.sh b/test/shell/lvconvert-raid-reshape-striped_to_linear.sh
new file mode 100644
index 0000000..fc87caf
--- /dev/null
+++ b/test/shell/lvconvert-raid-reshape-striped_to_linear.sh
@@ -0,0 +1,84 @@
+#!/bin/sh
+# Copyright (C) 2017 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA2110-1301 USA
+
+SKIP_WITH_LVMLOCKD=1
+SKIP_WITH_LVMPOLLD=1
+
+. lib/inittest
+
+which mkfs.ext4 || skip
+aux have_raid 1 10 2 || skip
+
+aux prepare_vg 5
+
+#
+# Test single step linear -> striped conversion
+#
+
+# Create 4-way striped LV
+lvcreate -aey -i 4 -I 32k -L 16M -n $lv1 $vg
+check lv_field $vg/$lv1 segtype "striped"
+check lv_field $vg/$lv1 stripes 4
+check lv_field $vg/$lv1 stripesize "32.00k"
+echo y|mkfs -t ext4 $DM_DEV_DIR/$vg/$lv1
+fsck -fn $DM_DEV_DIR/$vg/$lv1
+
+# Convert striped -> raid5(_n)
+lvconvert -y --ty raid5 -R 128k $vg/$lv1
+fsck -fn $DM_DEV_DIR/$vg/$lv1
+check lv_field $vg/$lv1 segtype "raid5_n"
+check lv_field $vg/$lv1 stripes 5
+check lv_field $vg/$lv1 stripesize "32.00k"
+check lv_field $vg/$lv1 regionsize "128.00k"
+aux wait_for_sync $vg $lv1
+fsck -fn $DM_DEV_DIR/$vg/$lv1
+
+# Extend raid5_n LV by factor 4 to keep size once linear
+lvresize -y -L 64 $vg/$lv1
+aux wait_for_sync $vg $lv1
+fsck -fn $DM_DEV_DIR/$vg/$lv1
+
+# Convert raid5_n LV to 1 stripe (2 legs total),
+# 64k stripesize and 1024k regionsize
+# FIXME: "--type" superfluous (cli fix needed)
+lvconvert -y -f --ty raid5_n --stripes 1 -I 64k -R 1024k $vg/$lv1
+fsck -fn $DM_DEV_DIR/$vg/$lv1
+check lv_first_seg_field $vg/$lv1 segtype "raid5_n"
+check lv_first_seg_field $vg/$lv1 stripes 5
+check lv_first_seg_field $vg/$lv1 stripesize "64.00k"
+check lv_first_seg_field $vg/$lv1 regionsize "1.00m"
+aux wait_for_sync $vg $lv1 1
+fsck -fn $DM_DEV_DIR/$vg/$lv1
+
+# Remove the now freed legs
+lvconvert --stripes 1 $vg/$lv1
+check lv_first_seg_field $vg/$lv1 segtype "raid5_n"
+check lv_first_seg_field $vg/$lv1 stripes 2
+check lv_first_seg_field $vg/$lv1 stripesize "64.00k"
+check lv_first_seg_field $vg/$lv1 regionsize "1.00m"
+
+# Convert raid5_n to raid1
+lvconvert -y --type raid1 $vg/$lv1
+fsck -fn $DM_DEV_DIR/$vg/$lv1
+check lv_first_seg_field $vg/$lv1 segtype "raid1"
+check lv_first_seg_field $vg/$lv1 stripes 2
+check lv_first_seg_field $vg/$lv1 stripesize "0"
+check lv_first_seg_field $vg/$lv1 regionsize "1.00m"
+
+# Convert raid5_n -> striped
+lvconvert -y --type linear $vg/$lv1
+fsck -fn $DM_DEV_DIR/$vg/$lv1
+check lv_first_seg_field $vg/$lv1 segtype "linear"
+check lv_first_seg_field $vg/$lv1 stripes 1
+check lv_first_seg_field $vg/$lv1 stripesize "0"
+check lv_first_seg_field $vg/$lv1 regionsize "0"
+
+vgremove -ff $vg
diff --git a/test/shell/lvconvert-raid-reshape.sh b/test/shell/lvconvert-raid-reshape.sh
new file mode 100644
index 0000000..2c302dd
--- /dev/null
+++ b/test/shell/lvconvert-raid-reshape.sh
@@ -0,0 +1,199 @@
+#!/bin/sh
+# Copyright (C) 2017 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA2110-1301 USA
+
+SKIP_WITH_LVMLOCKD=1
+SKIP_WITH_LVMPOLLD=1
+
+. lib/inittest
+
+which mkfs.ext4 || skip
+aux have_raid 1 10 2 || skip
+
+aux prepare_vg 64
+
+function _lvcreate
+{
+ local level=$1
+ local req_stripes=$2
+ local stripes=$3
+ local size=$4
+ local vg=$5
+ local lv=$6
+
+ lvcreate -y -aey --type $level -i $req_stripes -L $size -n $lv $vg
+ check lv_first_seg_field $vg/$lv segtype "$level"
+ check lv_first_seg_field $vg/$lv stripes $stripes
+ mkfs.ext4 "$DM_DEV_DIR/$vg/$lv"
+ fsck -fn "$DM_DEV_DIR/$vg/$lv"
+}
+
+function _lvconvert
+{
+ local req_level=$1
+ local level=$2
+ local stripes=$3
+ local vg=$4
+ local lv=$5
+ local region_size=$6
+ local wait_and_check=1
+ local R=""
+
+ [ -n "$region_size" ] && R="-R $region_size"
+ [ "${level:0:7}" = "striped" ] && wait_and_check=0
+ [ "${level:0:5}" = "raid0" ] && wait_and_check=0
+
+ lvconvert -y --ty $req_level $R $vg/$lv
+ [ $? -ne 0 ] && return $?
+ check lv_first_seg_field $vg/$lv segtype "$level"
+ check lv_first_seg_field $vg/$lv stripes $stripes
+ [ -n "$region_size" ] && check lv_field $vg/$lv regionsize $region_size
+ if [ "$wait_and_check" -eq 1 ]
+ then
+ fsck -fn "$DM_DEV_DIR/$vg/$lv"
+ aux wait_for_sync $vg $lv
+ fi
+ fsck -fn "$DM_DEV_DIR/$vg/$lv"
+}
+
+function _reshape_layout
+{
+ local type=$1
+ shift
+ local stripes=$1
+ shift
+ local vg=$1
+ shift
+ local lv=$1
+ shift
+ local opts="$*"
+ local ignore_a_chars=0
+
+ [[ "$opts" =~ "--stripes" ]] && ignore_a_chars=1
+
+ lvconvert -vvvv -y --ty $type $opts $vg/$lv
+ check lv_first_seg_field $vg/$lv segtype "$type"
+ check lv_first_seg_field $vg/$lv stripes $stripes
+ aux wait_for_sync $vg $lv $ignore_a_chars
+ fsck -fn "$DM_DEV_DIR/$vg/$lv"
+}
+
+# Delay leg so that rebuilding status characters
+# can be read before resync finished too quick.
+# aux delay_dev "$dev1" 1
+
+#
+# Start out with raid5(_ls)
+#
+
+# Create 3-way striped raid5 (4 legs total)
+_lvcreate raid5_ls 3 4 16M $vg $lv1
+check lv_first_seg_field $vg/$lv1 segtype "raid5_ls"
+aux wait_for_sync $vg $lv1
+
+# Reshape it to 256K stripe size
+_reshape_layout raid5_ls 4 $vg $lv1 --stripesize 256K
+check lv_first_seg_field $vg/$lv1 stripesize "256.00k"
+
+# Convert raid5(_n) -> striped
+not _lvconvert striped striped 3 $vg $lv1 512k
+_reshape_layout raid5_n 4 $vg $lv1
+_lvconvert striped striped 3 $vg $lv1
+
+# Convert striped -> raid5_n
+_lvconvert raid5_n raid5_n 4 $vg $lv1 "" 1
+
+# Convert raid5_n -> raid5_ls
+_reshape_layout raid5_ls 4 $vg $lv1
+
+# Convert raid5_ls to 5 stripes
+_reshape_layout raid5_ls 6 $vg $lv1 --stripes 5
+
+# Convert raid5_ls back to 3 stripes
+_reshape_layout raid5_ls 6 $vg $lv1 --stripes 3 --force
+_reshape_layout raid5_ls 4 $vg $lv1 --stripes 3
+
+# Convert raid5_ls to 7 stripes
+_reshape_layout raid5_ls 8 $vg $lv1 --stripes 7
+
+# Convert raid5_ls to 9 stripes
+_reshape_layout raid5_ls 10 $vg $lv1 --stripes 9
+
+# Convert raid5_ls to 14 stripes
+_reshape_layout raid5_ls 15 $vg $lv1 --stripes 14
+
+# Convert raid5_ls to 63 stripes
+_reshape_layout raid5_ls 64 $vg $lv1 --stripes 63
+
+# Convert raid5_ls back to 27 stripes
+_reshape_layout raid5_ls 64 $vg $lv1 --stripes 27 --force
+_reshape_layout raid5_ls 28 $vg $lv1 --stripes 27
+
+# Convert raid5_ls back to 4 stripes
+_reshape_layout raid5_ls 28 $vg $lv1 --stripes 4 --force
+_reshape_layout raid5_ls 5 $vg $lv1 --stripes 4
+
+# Convert raid5_ls back to 3 stripes
+_reshape_layout raid5_ls 5 $vg $lv1 --stripes 3 --force
+_reshape_layout raid5_ls 4 $vg $lv1 --stripes 3
+
+# Convert raid5_ls -> raid5_rs
+_reshape_layout raid5_rs 4 $vg $lv1
+
+# Convert raid5_rs -> raid5_la
+_reshape_layout raid5_la 4 $vg $lv1
+
+# Convert raid5_la -> raid5_ra
+_reshape_layout raid5_ra 4 $vg $lv1
+
+# Convert raid5_ra -> raid6_ra_6
+_lvconvert raid6_ra_6 raid6_ra_6 5 $vg $lv1 "4.00m" 1
+
+# Convert raid5_la -> raid6(_zr)
+_reshape_layout raid6 5 $vg $lv1
+
+# Convert raid6(_zr) -> raid6_nc
+_reshape_layout raid6_nc 5 $vg $lv1
+
+# Convert raid6(_nc) -> raid6_nr
+_reshape_layout raid6_nr 5 $vg $lv1
+
+# Convert raid6_nr) -> raid6_rs_6
+_reshape_layout raid6_rs_6 5 $vg $lv1
+
+# Convert raid6_rs_6 to 5 stripes
+_reshape_layout raid6_rs_6 7 $vg $lv1 --stripes 5
+
+# Convert raid6_rs_6 to 4 stripes
+_reshape_layout raid6_rs_6 7 $vg $lv1 --stripes 4 --force
+_reshape_layout raid6_rs_6 6 $vg $lv1 --stripes 4
+check lv_first_seg_field $vg/$lv1 stripesize "256.00k"
+
+# Convert raid6_rs_6 to raid6_n_6
+_reshape_layout raid6_n_6 6 $vg $lv1
+
+# Convert raid6_n_6 -> striped
+_lvconvert striped striped 4 $vg $lv1
+check lv_first_seg_field $vg/$lv1 stripesize "256.00k"
+
+# Convert striped -> raid10(_near)
+_lvconvert raid10 raid10 8 $vg $lv1
+
+# Convert raid10 to 10 stripes and 64K stripesize
+# FIXME: change once we support odd numbers of raid10 stripes
+not _reshape_layout raid10 9 $vg $lv1 --stripes 9 --stripesize 64K
+_reshape_layout raid10 10 $vg $lv1 --stripes 10 --stripesize 64K
+check lv_first_seg_field $vg/$lv1 stripesize "64.00k"
+
+# Convert raid6_n_6 -> striped
+_lvconvert striped striped 5 $vg $lv1
+check lv_first_seg_field $vg/$lv1 stripesize "64.00k"
+
+vgremove -ff $vg
7 years, 1 month
master - lvconvert: allow regionsize on upconvert from linear
by Heinz Mauelshagen
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=2574d3257ad41c...
Commit: 2574d3257ad41cad8dcbad3332774172e86f05da
Parent: 64a2fad5d6c65e81269251408dff10854f0ace7e
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Fri Feb 24 05:00:55 2017 +0100
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Fri Feb 24 05:20:58 2017 +0100
lvconvert: allow regionsize on upconvert from linear
Allow to provide regionsize with "lvconvert -m1 -R N " on
upconverts from linear and on N -> M raid1 leg conversions.
Resolves: rhbz1394427
---
lib/metadata/metadata-exported.h | 1 +
lib/metadata/raid_manip.c | 13 ++++++++++---
tools/lvconvert.c | 2 +-
3 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 11fb247..376fee9 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -1213,6 +1213,7 @@ int lv_is_raid_with_tracking(const struct logical_volume *lv);
uint32_t lv_raid_image_count(const struct logical_volume *lv);
int lv_raid_change_image_count(struct logical_volume *lv,
uint32_t new_count,
+ uint32_t new_region_size,
struct dm_list *allocate_pvs);
int lv_raid_split(struct logical_volume *lv, const char *split_name,
uint32_t new_count, struct dm_list *splittable_pvs);
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index e21e6cc..ab0bfab 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -2866,11 +2866,11 @@ static int _raid_extract_images(struct logical_volume *lv,
display_lvname(lv),
display_lvname(seg_lv(seg, s)));
- log_error("Try removing the PV list and rerun"
+ log_error("Try removing the PV list and rerun."
" the command.");
return 0;
}
- log_debug("LVs with error segments to be removed: %s %s.",
+ log_debug("LVs with error segments to be removed: %s %s",
display_lvname(seg_metalv(seg, s)),
display_lvname(seg_lv(seg, s)));
} else {
@@ -3013,8 +3013,15 @@ static int _lv_raid_change_image_count(struct logical_volume *lv, uint32_t new_c
}
int lv_raid_change_image_count(struct logical_volume *lv, uint32_t new_count,
- struct dm_list *allocate_pvs)
+ const uint32_t new_region_size, struct dm_list *allocate_pvs)
{
+ struct lv_segment *seg = first_seg(lv);
+
+ if (new_region_size) {
+ seg->region_size = new_region_size;
+ _check_and_adjust_region_size(lv);
+ }
+
return _lv_raid_change_image_count(lv, new_count, allocate_pvs, NULL, 1, 0);
}
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index abec04a..0db10cb 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -1359,7 +1359,7 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
DEFAULT_RAID1_MAX_IMAGES, lp->segtype->name, display_lvname(lv));
return 0;
}
- if (!lv_raid_change_image_count(lv, image_count, /* lp->region_size, */ lp->pvh))
+ if (!lv_raid_change_image_count(lv, image_count, lp->region_size, lp->pvh))
return_0;
log_print_unless_silent("Logical volume %s successfully converted.",
7 years, 1 month
master - lvconvert/lvcreate: raise maximum number of raid images
by Heinz Mauelshagen
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=64a2fad5d6c65e...
Commit: 64a2fad5d6c65e81269251408dff10854f0ace7e
Parent: 34caf8317243b3b30e6fc858b4440ebf3ffb8810
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Fri Feb 24 04:41:46 2017 +0100
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Fri Feb 24 05:20:58 2017 +0100
lvconvert/lvcreate: raise maximum number of raid images
Because of contraints in renaming shifted rimage/rmeta LV names
the current RaidLV limit is a maximum of 10 SubLV pairs.
With the previous introduction of reshaping infratructure that
constriant got removed.
Kernel supports 253 since dm-raid target 1.9.0, older kernels 64.
Raise the maximum number of RaidLV rimage/rmeta pairs to 64.
If we want to raise past 64, we have to introdce a check for
the kernel supporting it in lvcreate/lvconvert.
Related: rhbz834579
Related: rhbz1191935
Related: rhbz1191978
---
lib/config/defaults.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index db78f0c..5554c9c 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -71,8 +71,8 @@
* FIXME: Increase these to 64 and further to the MD maximum
* once the SubLVs split and name shift got enhanced
*/
-#define DEFAULT_RAID1_MAX_IMAGES 10
-#define DEFAULT_RAID_MAX_IMAGES 10
+#define DEFAULT_RAID1_MAX_IMAGES 64
+#define DEFAULT_RAID_MAX_IMAGES 64
#define DEFAULT_ALLOCATION_STRIPE_ALL_DEVICES 0 /* Don't stripe across all devices if not -i/--stripes given */
#define DEFAULT_RAID_FAULT_POLICY "warn"
7 years, 1 month
master - lvconvert: add infrastructure for RaidLV reshaping support
by Heinz Mauelshagen
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=34caf8317243b3...
Commit: 34caf8317243b3b30e6fc858b4440ebf3ffb8810
Parent: f79bd30a8be0d189c417a76d1ca6b64f70a8832e
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Fri Feb 24 04:36:03 2017 +0100
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Fri Feb 24 05:20:58 2017 +0100
lvconvert: add infrastructure for RaidLV reshaping support
In order to support striped raid5/6/10 LV reshaping (change
of LV type, stripesize or number of legs), this patch
introduces the changes to call the reshaping infratructure
from lv_raid_convert().
Changes:
- add reshaping calls from lv_raid_convert()
- add command definitons for reshaping to tools/command-lines.in
- fix raid_rimage_extents()
- add 2 new test scripts lvconvert-raid-reshape-linear_to_striped.sh
and lvconvert-raid-reshape-striped_to_linear.sh to test
the linear <-> striped multi-step conversions
- add lvconvert-raid-reshape.sh reshaping tests
- enhance lvconvert-raid-takeover.sh with new raid10 tests
Related: rhbz834579
Related: rhbz1191935
Related: rhbz1191978
---
lib/config/defaults.h | 2 +-
lib/metadata/raid_manip.c | 50 +++++++++++++++++++++------------
test/lib/aux.sh | 2 +-
test/lib/check.sh | 13 +++++++-
test/lib/get.sh | 5 +++
test/shell/lvconvert-raid-takeover.sh | 11 +++++--
tools/command-lines.in | 29 +++++++++++++++++++
7 files changed, 87 insertions(+), 25 deletions(-)
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 26bbc69..db78f0c 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -72,7 +72,7 @@
* once the SubLVs split and name shift got enhanced
*/
#define DEFAULT_RAID1_MAX_IMAGES 10
-#define DEFAULT_RAID_MAX_IMAGES 64
+#define DEFAULT_RAID_MAX_IMAGES 10
#define DEFAULT_ALLOCATION_STRIPE_ALL_DEVICES 0 /* Don't stripe across all devices if not -i/--stripes given */
#define DEFAULT_RAID_FAULT_POLICY "warn"
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index c465bd4..e21e6cc 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -1135,7 +1135,7 @@ uint32_t raid_rimage_extents(const struct segment_type *segtype,
uint64_t r;
if (!extents ||
- segtype_is_striped_raid(segtype))
+ !segtype_is_striped_raid(segtype))
return extents;
r = extents;
@@ -2111,7 +2111,6 @@ static int _post_raid_dummy(struct logical_volume *lv, void *data)
* In case of disk addition, any PVs listed in mandatory
* @allocate_pvs will be used for allocation of new stripes.
*/
-__attribute__ ((__unused__))
static int _raid_reshape(struct logical_volume *lv,
const struct segment_type *new_segtype,
int yes, int force,
@@ -2289,7 +2288,6 @@ static int _raid_reshape(struct logical_volume *lv,
* 2 -> prohibited reshape request
* 3 -> allowed region size change request
*/
-__attribute__ ((__unused__))
static int _reshape_requested(const struct logical_volume *lv, const struct segment_type *segtype,
const int data_copies, const uint32_t region_size,
const uint32_t stripes, const uint32_t stripe_size)
@@ -5842,8 +5840,10 @@ int lv_raid_convert(struct logical_volume *lv,
uint32_t stripes, stripe_size;
uint32_t new_image_count = seg->area_count;
uint32_t region_size = new_region_size;
+ uint32_t data_copies = seg->data_copies;
takeover_fn_t takeover_fn;
+ new_segtype = new_segtype ? : seg->segtype;
if (!new_segtype) {
log_error(INTERNAL_ERROR "New segtype not specified.");
return 0;
@@ -5853,33 +5853,47 @@ int lv_raid_convert(struct logical_volume *lv,
/* FIXME Ensure caller does *not* set wrong default value! */
/* Define new stripe size if not passed in */
- stripe_size = new_stripe_size ? : seg->stripe_size;
+ stripe_size = new_stripe_size_supplied ? new_stripe_size : seg->stripe_size;
if (segtype_is_striped(new_segtype))
- new_image_count = stripes;
+ new_image_count = stripes ? : seg->area_count;
- if (segtype_is_raid(new_segtype) && !_check_max_raid_devices(new_image_count))
+ if (!_check_max_raid_devices(new_image_count))
return_0;
- /* Change RAID region size */
+ region_size = new_region_size ? : seg->region_size;
+ region_size = region_size ? : get_default_region_size(lv->vg->cmd);
+
/*
- * FIXME: workaround with new_region_size until the
- * cli validation patches got merged when we'll change
- * the API to have new_region_size_supplied to check for.
+ * reshape of capable raid type requested
*/
- if (new_region_size) {
- if (new_segtype == seg->segtype &&
- new_region_size != seg->region_size &&
- seg_is_raid(seg) && !seg_is_any_raid0(seg))
- return _region_size_change_requested(lv, yes, new_region_size);
- } else
- region_size = seg->region_size ? : get_default_region_size(lv->vg->cmd);
+ switch (_reshape_requested(lv, new_segtype, data_copies, region_size, stripes, stripe_size)) {
+ case 0:
+ break;
+ case 1:
+ if (!_raid_reshape(lv, new_segtype, yes, force,
+ data_copies, region_size,
+ stripes, stripe_size, allocate_pvs)) {
+ log_error("Reshape request failed on LV %s.", display_lvname(lv));
+ return 0;
+ }
+
+ return 1;
+ case 2:
+ log_error("Invalid conversion request on %s.", display_lvname(lv));
+ /* Error if we got here with stripes and/or stripe size change requested */
+ return 0;
+ default:
+ log_error(INTERNAL_ERROR "_reshape_requested failed.");
+ return 0;
+ }
/*
* Check acceptible options mirrors, region_size,
* stripes and/or stripe_size have been provided.
*/
- if (!_conversion_options_allowed(seg, &new_segtype, yes, 0 /* Takeover */, 0 /*new_data_copies*/, new_region_size,
+ if (!_conversion_options_allowed(seg, &new_segtype, yes,
+ 0 /* Takeover */, 0 /*new_data_copies*/, new_region_size,
new_stripes, new_stripe_size_supplied))
return _log_possible_conversion_types(lv, new_segtype);
diff --git a/test/lib/aux.sh b/test/lib/aux.sh
index 9779358..b0e6556 100644
--- a/test/lib/aux.sh
+++ b/test/lib/aux.sh
@@ -1317,7 +1317,7 @@ udev_wait() {
wait_for_sync() {
local i
for i in {1..100} ; do
- check in_sync $1 $2 && return
+ check in_sync $1 $2 $3 && return
sleep .2
done
diff --git a/test/lib/check.sh b/test/lib/check.sh
index 916d2df..64812fb 100644
--- a/test/lib/check.sh
+++ b/test/lib/check.sh
@@ -178,7 +178,7 @@ linear() {
$(lvl $lv -o+devices)
}
-# in_sync <VG> <LV>
+# in_sync <VG> <LV> <ignore 'a'>
# Works for "mirror" and "raid*"
in_sync() {
local a
@@ -187,8 +187,11 @@ in_sync() {
local type
local snap=""
local lvm_name="$1/$2"
+ local ignore_a="$3"
local dm_name=$(echo $lvm_name | sed s:-:--: | sed s:/:-:)
+ [ -z "$ignore_a" ] && ignore_a=0
+
a=( $(dmsetup status $dm_name) ) || \
die "Unable to get sync status of $1"
@@ -225,7 +228,7 @@ in_sync() {
return 1
fi
- [[ ${a[$(($idx - 1))]} =~ a ]] && \
+ [[ ${a[$(($idx - 1))]} =~ a ]] && [ $ignore_a -eq 0 ] && \
die "$lvm_name ($type$snap) in-sync, but 'a' characters in health status"
echo "$lvm_name ($type$snap) is in-sync \"${a[@]}\""
@@ -310,6 +313,12 @@ lv_field() {
die "lv_field: lv=$1, field=\"$2\", actual=\"$actual\", expected=\"$3\""
}
+lv_first_seg_field() {
+ local actual=$(get lv_first_seg_field "$1" "$2" "${@:4}")
+ test "$actual" = "$3" || \
+ die "lv_field: lv=$1, field=\"$2\", actual=\"$actual\", expected=\"$3\""
+}
+
lvh_field() {
local actual=$(get lvh_field "$1" "$2" "${@:4}")
test "$actual" = "$3" || \
diff --git a/test/lib/get.sh b/test/lib/get.sh
index f650417..0a8c943 100644
--- a/test/lib/get.sh
+++ b/test/lib/get.sh
@@ -42,6 +42,11 @@ lv_field() {
trim_ "$r"
}
+lv_first_seg_field() {
+ local r=$(lvs --config 'log{prefix=""}' --noheadings -o "$2" "${@:3}" "$1" | head -1)
+ trim_ "$r"
+}
+
lvh_field() {
local r=$(lvs -H --config 'log{prefix=""}' --noheadings -o "$2" "${@:3}" "$1")
trim_ "$r"
diff --git a/test/shell/lvconvert-raid-takeover.sh b/test/shell/lvconvert-raid-takeover.sh
index aa41dba..5d8f858 100644
--- a/test/shell/lvconvert-raid-takeover.sh
+++ b/test/shell/lvconvert-raid-takeover.sh
@@ -117,8 +117,7 @@ fsck -fn "$DM_DEV_DIR/$vg/$lv1"
lvconvert -m 4 -R 128K $vg/$lv1
check lv_field $vg/$lv1 segtype "raid1"
check lv_field $vg/$lv1 stripes 5
-# FIXME: once lv_raid_chanage_image_count() supports region_size changes
-not check lv_field $vg/$lv1 regionsize "128.00k"
+check lv_field $vg/$lv1 regionsize "128.00k"
fsck -fn "$DM_DEV_DIR/$vg/$lv1"
aux wait_for_sync $vg $lv1
fsck -fn "$DM_DEV_DIR/$vg/$lv1"
@@ -258,7 +257,13 @@ _lvconvert raid0 raid0 3 $vg $lv1
# Convert raid0 -> raid10
_lvconvert raid10 raid10 6 $vg $lv1
-# Convert raid10 -> raid0
+# Convert raid10 -> raid0_meta
+_lvconvert raid0_meta raid0_meta 3 $vg $lv1
+
+# Convert raid0_meta -> raid5
+_lvconvert raid5_n raid5_n 4 $vg $lv1
+
+# Convert raid5_n -> raid0_meta
_lvconvert raid0_meta raid0_meta 3 $vg $lv1
# Convert raid0_meta -> raid10
diff --git a/tools/command-lines.in b/tools/command-lines.in
index 348e7a4..c3d684e 100644
--- a/tools/command-lines.in
+++ b/tools/command-lines.in
@@ -345,6 +345,13 @@ ID: lvconvert_raid_types
DESC: Convert LV to raid.
RULE: all not lv_is_locked lv_is_pvmove
+lvconvert --type raid LV_raid
+OO: OO_LVCONVERT_RAID, OO_LVCONVERT
+ID: lvconvert_raid_types
+DESC: Convert raid LV to different layout algorithm.
+RULE: all not lv_is_locked lv_is_pvmove
+RULE: all not LV_raid0 LV_raid1
+
lvconvert --mirrors SNumber LV
OO: OO_LVCONVERT_RAID, OO_LVCONVERT, --mirrorlog MirrorLog
OP: PV ...
@@ -352,6 +359,21 @@ ID: lvconvert_raid_types
DESC: Convert LV to raid1 or mirror, or change number of mirror images.
RULE: all not lv_is_locked lv_is_pvmove
+lvconvert --stripes_long SNumber LV_raid
+OO: OO_LVCONVERT_RAID, OO_LVCONVERT
+OP: PV ...
+ID: lvconvert_raid_types
+DESC: Convert raid LV to change number of stripe images.
+RULE: all not lv_is_locked lv_is_pvmove
+RULE: all not LV_raid0 LV_raid1
+
+lvconvert --stripesize SizeKB LV_raid
+OO: OO_LVCONVERT_RAID, OO_LVCONVERT
+ID: lvconvert_raid_types
+DESC: Convert raid LV to change the stripe size.
+RULE: all not lv_is_locked lv_is_pvmove
+RULE: all not LV_raid0 LV_raid1
+
lvconvert --regionsize RegionSize LV_raid
OO: OO_LVCONVERT
ID: lvconvert_change_region_size
@@ -359,6 +381,13 @@ DESC: Change the region size of an LV.
RULE: all not lv_is_locked lv_is_pvmove
RULE: all not LV_raid0
+lvconvert LV_mirror_raid
+OO: OO_LVCONVERT
+ID: lvconvert_raid_types
+DESC: Remove out-of-place reshape space
+RULE: all not lv_is_locked lv_is_pvmove
+RULE: all not LV_raid0 LV_raid1
+
---
# lvconvert raid-related utilities
7 years, 1 month
master - lvconvert: add infrastructure for RaidLV reshaping support
by Heinz Mauelshagen
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f79bd30a8be0d1...
Commit: f79bd30a8be0d189c417a76d1ca6b64f70a8832e
Parent: 1784cc990e6941e93cfcf1204526cec75d287a89
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Fri Feb 24 04:00:17 2017 +0100
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Fri Feb 24 05:20:58 2017 +0100
lvconvert: add infrastructure for RaidLV reshaping support
In order to support striped raid5/6/10 LV reshaping (change
of LV type, stripesize or number of legs), this patch
introduces more local infrastructure to raid_manip.c
used by followup patches.
Change:
- allow raid_rimage_extents() to calculate raid10
- remove an __unused__ attribute
Related: rhbz834579
Related: rhbz1191935
Related: rhbz1191978
---
lib/metadata/raid_manip.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index 40bc45e..c465bd4 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -1135,8 +1135,7 @@ uint32_t raid_rimage_extents(const struct segment_type *segtype,
uint64_t r;
if (!extents ||
- segtype_is_mirror(segtype) ||
- segtype_is_raid1(segtype))
+ segtype_is_striped_raid(segtype))
return extents;
r = extents;
@@ -1576,7 +1575,6 @@ static int _lv_free_reshape_space_with_status(struct logical_volume *lv, enum al
return 1;
}
-__attribute__ ((__unused__))
static int _lv_free_reshape_space(struct logical_volume *lv)
{
return _lv_free_reshape_space_with_status(lv, NULL);
7 years, 1 month
master - lvconvert: add infrastructure for RaidLV reshaping support
by Heinz Mauelshagen
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=1784cc990e6941...
Commit: 1784cc990e6941e93cfcf1204526cec75d287a89
Parent: 2d74de3f05d44b2ac5f651e49d29878731a114a1
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Fri Feb 24 03:56:10 2017 +0100
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Fri Feb 24 05:20:58 2017 +0100
lvconvert: add infrastructure for RaidLV reshaping support
In order to support striped raid5/6/10 LV reshaping (change
of LV type, stripesize or number of legs), this patch
introduces more local infrastructure to raid_manip.c
used by followup patches.
Change:
- add missing raid1 <-> raid5 conversions to support
linear <-> raid5 <-> raid0(_meta)/striped conversions
- rename related new takeover functions to
_takeover_from_raid1_to_raid5 and _takeover_from_raid5_to_raid1,
because a reshape to > 2 legs is only possible with
raid5 layout
Related: rhbz834579
Related: rhbz1191935
Related: rhbz1191978
---
lib/metadata/raid_manip.c | 13 +++++++++----
lib/metadata/takeover_matrix.h | 8 ++++----
2 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index fc02d3d..40bc45e 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -5323,9 +5323,11 @@ static int _takeover_from_raid1_to_raid10(TAKEOVER_FN_ARGS)
return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
}
-static int _takeover_from_raid1_to_raid45(TAKEOVER_FN_ARGS)
+static int _takeover_from_raid1_to_raid5(TAKEOVER_FN_ARGS)
{
- return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
+ return _takeover_upconvert_wrapper(lv, new_segtype, yes, force,
+ first_seg(lv)->area_count /* unchanged new_image_count */,
+ 2 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
}
static int _takeover_from_raid1_to_striped(TAKEOVER_FN_ARGS)
@@ -5357,9 +5359,12 @@ static int _takeover_from_raid45_to_raid0_meta(TAKEOVER_FN_ARGS)
1 /* data_copies */, 0, 0, 0, allocate_pvs);
}
-static int _takeover_from_raid45_to_raid1(TAKEOVER_FN_ARGS)
+
+static int _takeover_from_raid5_to_raid1(TAKEOVER_FN_ARGS)
{
- return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
+ return _takeover_downconvert_wrapper(lv, new_segtype, yes, force,
+ first_seg(lv)->area_count,
+ 2 /* data_copies */, 0, 0, 0, allocate_pvs);
}
static int _takeover_from_raid45_to_raid54(TAKEOVER_FN_ARGS)
diff --git a/lib/metadata/takeover_matrix.h b/lib/metadata/takeover_matrix.h
index bb3e6cb..8ac2f75 100644
--- a/lib/metadata/takeover_matrix.h
+++ b/lib/metadata/takeover_matrix.h
@@ -58,13 +58,13 @@
#define r1__r0m _takeover_from_raid1_to_raid0_meta
#define r1__r1 _takeover_from_raid1_to_raid1
#define r1__r10 _takeover_from_raid1_to_raid10
-#define r1__r45 _takeover_from_raid1_to_raid45
+#define r1__r5 _takeover_from_raid1_to_raid5
#define r1__str _takeover_from_raid1_to_striped
#define r45_lin _takeover_from_raid45_to_linear
#define r45_mir _takeover_from_raid45_to_mirrored
#define r45_r0 _takeover_from_raid45_to_raid0
#define r45_r0m _takeover_from_raid45_to_raid0_meta
-#define r45_r1 _takeover_from_raid45_to_raid1
+#define r5_r1 _takeover_from_raid5_to_raid1
#define r45_r54 _takeover_from_raid45_to_raid54
#define r45_r6 _takeover_from_raid45_to_raid6
#define r45_str _takeover_from_raid45_to_striped
@@ -109,8 +109,8 @@ static takeover_fn_t _takeover_fns[][11] = {
/* mirror */ { X , X , N , mir_r0, mir_r0m, mir_r1, mir_r45, X , mir_r10, X , X },
/* raid0 */ { r0__lin, r0__str, r0__mir, N , r0__r0m, r0__r1, r0__r45, r0__r6, r0__r10, X , X },
/* raid0_meta */ { r0m_lin, r0m_str, r0m_mir, r0m_r0, N , r0m_r1, r0m_r45, r0m_r6, r0m_r10, X , X },
- /* raid1 */ { r1__lin, r1__str, r1__mir, r1__r0, r1__r0m, r1__r1, r1__r45, X , r1__r10, X , X },
- /* raid4/5 */ { r45_lin, r45_str, r45_mir, r45_r0, r45_r0m, r45_r1, r45_r54, r45_r6, X , X , X },
+ /* raid1 */ { r1__lin, r1__str, r1__mir, r1__r0, r1__r0m, r1__r1, r1__r5, X , r1__r10, X , X },
+ /* raid4/5 */ { r45_lin, r45_str, r45_mir, r45_r0, r45_r0m, r5_r1 , r45_r54, r45_r6, X , X , X },
/* raid6 */ { X , r6__str, X , r6__r0, r6__r0m, X , r6__r45, X , X , X , X },
/* raid10 */ { r10_lin, r10_str, r10_mir, r10_r0, r10_r0m, r10_r1, X , X , X , X , X },
/* raid01 */ // { X , r01_str, X , X , X , X , X , X , r01_r10, r01_r01, X },
7 years, 1 month
master - lvconvert: add infrastructure for RaidLV reshaping support
by Heinz Mauelshagen
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=2d74de3f05d44b...
Commit: 2d74de3f05d44b2ac5f651e49d29878731a114a1
Parent: 34a8d3c2fdc9da2bb1974781070d01f901862b9a
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Fri Feb 24 03:46:14 2017 +0100
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Fri Feb 24 05:20:58 2017 +0100
lvconvert: add infrastructure for RaidLV reshaping support
In order to support striped raid5/6/10 LV reshaping (change
of LV type, stripesize or number of legs), this patch
introduces more local infrastructure to raid_manip.c
used by followup patches.
Change:
- enhance _clear_meta_lvs() to support raid0 allowing
raid0_meta -> raid10 conversions to succeed by clearing
the raid0 rmeta images or the kernel will fail because
of discovering reordered raid devices
Related: rhbz834579
Related: rhbz1191935
Related: rhbz1191978
---
lib/metadata/raid_manip.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index 2b5559a..fc02d3d 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -4579,6 +4579,7 @@ static int _raid1_to_mirrored_wrapper(TAKEOVER_FN_ARGS)
* order to wipe them then reattach and set back to raid0_meta.
*
* Same applies to raid4 <-> raid5.
+ * Same applies to raid10 -> raid0_meta.
*/
static int _clear_meta_lvs(struct logical_volume *lv)
{
@@ -4588,11 +4589,11 @@ static int _clear_meta_lvs(struct logical_volume *lv)
const struct segment_type *tmp_segtype;
struct dm_list meta_lvs;
struct lv_list *lvl_array, *lvl;
- int is_raid4_or_5N = seg_is_raid4(seg) || seg_is_raid5_n(seg);
+ int is_raid45n10 = seg_is_raid4(seg) || seg_is_raid5_n(seg) || seg_is_raid10(seg);
/* Reject non-raid0_meta/raid4/raid5_n segment types cautiously */
if (!seg->meta_areas ||
- (!seg_is_raid0_meta(seg) && !is_raid4_or_5N))
+ (!seg_is_raid0_meta(seg) && !is_raid45n10))
return_0;
if (!(lvl_array = dm_pool_alloc(lv->vg->vgmem, seg->area_count * sizeof(*lvl_array))))
7 years, 1 month
master - lvconvert: add infrastructure for RaidLV reshaping support
by Heinz Mauelshagen
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=34a8d3c2fdc9da...
Commit: 34a8d3c2fdc9da2bb1974781070d01f901862b9a
Parent: 932db3db535734f03cec973182dcc73adef9d3a5
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Fri Feb 24 03:37:12 2017 +0100
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Fri Feb 24 05:20:58 2017 +0100
lvconvert: add infrastructure for RaidLV reshaping support
In order to support striped raid5/6/10 LV reshaping (change
of LV type, stripesize or number of legs), this patch
introduces more local infrastructure to raid_manip.c
used by followup patches.
Changes:
- enhance _raid45610_to_raid0_or_striped_wrapper() to support
raid5_n with 2 areas to raid1 conversion to allow for
striped/raid0(_meta)/raid4/5/6 -> raid1/linear conversions;
rename it to _takeover_downconvert_wrapper to discontinue the
illegible function name
- enhance _striped_or_raid0_to_raid45610_wrapper() to support
raid1 with 2 areas to raid5* conversions to allow for
linear/raid1 -> striped/raid0(_meta)/raid4/5/6 conversions;
rename it to _takeover_upconvert_wrapper for the same reason
Related: rhbz834579
Related: rhbz1191935
Related: rhbz1191978
---
lib/metadata/raid_manip.c | 258 ++++++++++++++++++++++++++++++++-------------
1 files changed, 183 insertions(+), 75 deletions(-)
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index 81360d2..2b5559a 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -4748,14 +4748,14 @@ static int _shift_parity_dev(struct lv_segment *seg)
return 1;
}
-/* raid456 -> raid0* / striped */
+/* raid45610 -> raid0* / stripe, raid5_n -> raid4 */
static int _raid45_to_raid54_wrapper(TAKEOVER_FN_ARGS);
-static int _raid45610_to_raid0_or_striped_wrapper(TAKEOVER_FN_ARGS)
+static int _takeover_downconvert_wrapper(TAKEOVER_FN_ARGS)
{
int rename_sublvs = 0;
struct lv_segment *seg = first_seg(lv);
struct dm_list removal_lvs;
- uint32_t region_size = seg->region_size;
+ char res_str[30];
dm_list_init(&removal_lvs);
@@ -4766,10 +4766,35 @@ static int _raid45610_to_raid0_or_striped_wrapper(TAKEOVER_FN_ARGS)
return 0;
}
- if (!yes && yes_no_prompt("Are you sure you want to convert \"%s\" LV %s to \"%s\" "
- "type losing %s resilience? [y/n]: ",
- lvseg_name(seg), display_lvname(lv), new_segtype->name,
- segtype_is_striped(new_segtype) ? "all" : "some") == 'n') {
+ if (seg_is_any_raid10(seg) && (seg->area_count % seg->data_copies)) {
+ log_error("Can't convert %s LV %s to %s with odd number of stripes.",
+ lvseg_name(seg), display_lvname(lv), new_segtype->name);
+ return 0;
+ }
+
+ if (seg_is_any_raid5(seg) &&
+ segtype_is_raid1(new_segtype)) {
+ if (seg->area_count != 2) {
+ log_error("Can't convert %s LV %s to %s with != 2 legs.",
+ lvseg_name(seg), display_lvname(lv), new_segtype->name);
+ return 0;
+ }
+ if (seg->area_count != new_image_count) {
+ log_error(INTERNAL_ERROR "Bogus new_image_count converting %s LV %s to %s.",
+ lvseg_name(seg), display_lvname(lv), new_segtype->name);
+ return 0;
+ }
+ }
+
+ if (seg->area_count > 2) {
+ if (dm_snprintf(res_str, sizeof(res_str), " losing %s resilience",
+ segtype_is_striped(new_segtype) ? "all" : "some") < 0)
+ return_0;
+ } else
+ *res_str = '\0';
+
+ if (!yes && yes_no_prompt("Are you sure you want to convert \"%s\" LV %s to \"%s\" type%s? [y/n]: ",
+ lvseg_name(seg), display_lvname(lv), new_segtype->name, res_str) == 'n') {
log_error("Logical volume %s NOT converted to \"%s\"",
display_lvname(lv), new_segtype->name);
return 0;
@@ -4779,6 +4804,9 @@ static int _raid45610_to_raid0_or_striped_wrapper(TAKEOVER_FN_ARGS)
if (!archive(lv->vg))
return_0;
+ if (!_lv_free_reshape_space(lv))
+ return_0;
+
/*
* raid4 (which actually gets mapped to raid5/dedicated first parity disk)
* needs shifting of SubLVs to move the parity SubLV pair in the first area
@@ -4790,28 +4818,35 @@ static int _raid45610_to_raid0_or_striped_wrapper(TAKEOVER_FN_ARGS)
if (!_shift_parity_dev(seg))
return 0;
- if (segtype_is_any_raid0(new_segtype) &&
- !(rename_sublvs = _rename_area_lvs(lv, "_"))) {
- log_error("Failed to rename %s LV %s MetaLVs.", lvseg_name(seg), display_lvname(lv));
- return 0;
- }
} else if (seg_is_raid10_near(seg)) {
- log_debug_metadata("Reordering areas for raid10 -> raid0 takeover");
+ log_debug_metadata("Reordering areas for raid10 -> raid0 takeover.");
if (!_reorder_raid10_near_seg_areas(seg, reorder_from_raid10_near))
return 0;
}
- /* Remove meta and data LVs requested */
- if (!_lv_raid_change_image_count(lv, new_image_count, allocate_pvs, &removal_lvs, 0, 0))
+ if (segtype_is_any_raid0(new_segtype) &&
+ !(rename_sublvs = _rename_area_lvs(lv, "_"))) {
+ log_error("Failed to rename %s LV %s MetaLVs.", lvseg_name(seg), display_lvname(lv));
return 0;
+ }
+
+ /* Remove meta and data LVs requested */
+ if (new_image_count != seg->area_count) {
+ log_debug_metadata("Removing %" PRIu32 " component LV pair(s) to %s.",
+ lv_raid_image_count(lv) - new_image_count,
+ display_lvname(lv));
+ if (!_lv_raid_change_image_count(lv, new_image_count, allocate_pvs, &removal_lvs, 0, 0))
+ return 0;
+
+ seg->area_count = new_image_count;
+ }
/* FIXME Hard-coded raid4/5/6 to striped/raid0 */
if (segtype_is_striped_target(new_segtype) || segtype_is_any_raid0(new_segtype)) {
- seg->area_len = seg->extents_copied = seg->area_len / seg->area_count;
+ seg->area_len = seg->extents_copied = seg->len / seg->area_count;
+ seg->region_size = 0;
if (!(seg->segtype = get_segtype_from_flag(lv->vg->cmd, SEG_RAID0_META)))
return_0;
-
- region_size = 0;
}
if (segtype_is_striped_target(new_segtype)) {
@@ -4827,12 +4862,18 @@ static int _raid45610_to_raid0_or_striped_wrapper(TAKEOVER_FN_ARGS)
} else
seg->segtype = new_segtype;
- seg->region_size = new_region_size ?: region_size;
+ if (seg_is_raid1(seg))
+ seg->stripe_size = 0;
if (!_lv_update_reload_fns_reset_eliminate_lvs(lv, 0, &removal_lvs, NULL))
return_0;
if (rename_sublvs) {
+ /* Got to clear the meta lvs from raid10 content to be able to convert to e.g. raid6 */
+ if (segtype_is_raid0_meta(new_segtype) &&
+ !_clear_meta_lvs(lv))
+ return_0;
+
if (!_rename_area_lvs(lv, NULL)) {
log_error("Failed to rename %s LV %s MetaLVs.", lvseg_name(seg), display_lvname(lv));
return 0;
@@ -4942,8 +4983,8 @@ static int _striped_to_raid0_wrapper(struct logical_volume *lv,
return 1;
}
-/* Helper: striped/raid0* -> raid4/5/6/10, raid45 -> raid6 wrapper */
-static int _striped_or_raid0_to_raid45610_wrapper(TAKEOVER_FN_ARGS)
+/* Helper: striped/raid0/raid0_meta/raid1 -> raid4/5/6/10, raid45 -> raid6 wrapper */
+static int _takeover_upconvert_wrapper(TAKEOVER_FN_ARGS)
{
uint32_t extents_copied, region_size, seg_len, stripe_size;
struct lv_segment *seg = first_seg(lv);
@@ -4961,10 +5002,40 @@ static int _striped_or_raid0_to_raid45610_wrapper(TAKEOVER_FN_ARGS)
return 0;
}
+ if (seg_is_any_raid5(seg) && segtype_is_any_raid6(new_segtype) && seg->area_count < 4) {
+ log_error("Minimum of 3 stripes needed for conversion from %s to %s.",
+ lvseg_name(seg), new_segtype->name);
+ return 0;
+ }
+
+ if (seg_is_raid1(seg)) {
+ if (seg->area_count != 2) {
+ log_error("Can't convert %s LV %s to %s with != 2 legs.",
+ lvseg_name(seg), display_lvname(lv), new_segtype->name);
+ return 0;
+ }
+ if (!segtype_is_any_raid5(new_segtype)) {
+ log_error("Can't convert %s LV %s to %s.",
+ lvseg_name(seg), display_lvname(lv), new_segtype->name);
+ return 0;
+ }
+ if (seg->area_count != new_image_count) {
+ log_error(INTERNAL_ERROR "Bogus new_image_count converting %s LV %s to %s.",
+ lvseg_name(seg), display_lvname(lv), new_segtype->name);
+ return 0;
+ }
+
+ if (!new_stripe_size)
+ new_stripe_size = 128;
+ }
+
/* Archive metadata */
if (!archive(lv->vg))
return_0;
+ if (!_lv_free_reshape_space(lv))
+ return_0;
+
/* This helper can be used to convert from striped/raid0* -> raid10 too */
if (seg_is_striped_target(seg)) {
log_debug_metadata("Converting LV %s from %s to %s.",
@@ -4979,15 +5050,14 @@ static int _striped_or_raid0_to_raid45610_wrapper(TAKEOVER_FN_ARGS)
if (!_raid0_add_or_remove_metadata_lvs(lv, 1 /* update_and_reload */, allocate_pvs, NULL))
return 0;
/* raid0_meta -> raid4 needs clearing of MetaLVs in order to avoid raid disk role change issues in the kernel */
- } else if (segtype_is_raid4(new_segtype) &&
- !_clear_meta_lvs(lv))
+ }
+
+ if (seg_is_raid0_meta(seg) &&
+ segtype_is_raid4(new_segtype) &&
+ !_clear_meta_lvs(lv))
return_0;
- /* Add the additional component LV pairs */
- log_debug_metadata("Adding %" PRIu32 " component LV pair(s) to %s.",
- new_image_count - lv_raid_image_count(lv),
- display_lvname(lv));
extents_copied = seg->extents_copied;
region_size = seg->region_size;
seg_len = seg->len;
@@ -4998,11 +5068,21 @@ static int _striped_or_raid0_to_raid45610_wrapper(TAKEOVER_FN_ARGS)
return_0;
seg->area_len = seg_lv(seg, 0)->le_count;
lv->le_count = seg->len = seg->area_len * seg->area_count;
+ seg->area_len = seg->len;
seg->extents_copied = seg->region_size = 0;
}
- if (!_lv_raid_change_image_count(lv, new_image_count, allocate_pvs, NULL, 0, 1))
- return 0;
+ /* Add the additional component LV pairs */
+ if (new_image_count != seg->area_count) {
+ log_debug_metadata("Adding %" PRIu32 " component LV pair(s) to %s.",
+ new_image_count - lv_raid_image_count(lv),
+ display_lvname(lv));
+ if (!_lv_raid_change_image_count(lv, new_image_count, allocate_pvs, NULL, 0, 1))
+ return 0;
+
+ seg = first_seg(lv);
+ }
+
if (segtype_is_raid4(new_segtype) &&
(!_shift_parity_dev(seg) ||
@@ -5010,25 +5090,40 @@ static int _striped_or_raid0_to_raid45610_wrapper(TAKEOVER_FN_ARGS)
log_error("Can't convert %s to %s.", display_lvname(lv), new_segtype->name);
return 0;
} else if (segtype_is_raid10_near(new_segtype)) {
- log_debug_metadata("Reordering areas for raid0 -> raid10 takeover");
+ uint32_t s;
+
+ /* FIXME: raid10 ; needs to change once more than 2 data copies! */
+ seg->data_copies = 2;
+
+ log_debug_metadata("Reordering areas for raid0 -> raid10 takeover.");
if (!_reorder_raid10_near_seg_areas(seg, reorder_to_raid10_near))
return 0;
+ /* Set rebuild flags accordingly */
+ for (s = 0; s < seg->area_count; s++) {
+ seg_lv(seg, s)->status &= ~LV_REBUILD;
+ seg_metalv(seg, s)->status &= ~LV_REBUILD;
+ if (s % seg->data_copies)
+ seg_lv(seg, s)->status |= LV_REBUILD;
+ }
+
}
seg->segtype = new_segtype;
seg->region_size = new_region_size ?: region_size;
+ seg->stripe_size = new_stripe_size ?: stripe_size;
+ seg->extents_copied = extents_copied;
- /* FIXME Hard-coded raid0 to raid4/5/6 */
- seg->stripe_size = stripe_size;
+ /* FIXME Hard-coded to raid4/5/6/10 */
lv->le_count = seg->len = seg->area_len = seg_len;
- seg->extents_copied = extents_copied;
_check_and_adjust_region_size(lv);
log_debug_metadata("Updating VG metadata and reloading %s LV %s.",
lvseg_name(seg), display_lvname(lv));
- if (!_lv_update_reload_fns_reset_eliminate_lvs(lv, 0, NULL, NULL))
- return_0;
+ if (!_lv_update_reload_fns_reset_eliminate_lvs(lv, 0, &removal_lvs,
+ _post_raid_dummy, NULL,
+ _pre_raid_add_legs, NULL))
+ return 0;
if (segtype_is_raid4(new_segtype)) {
/* We had to rename SubLVs because of collision free shifting, rename back... */
@@ -5118,23 +5213,23 @@ static int _takeover_from_raid0_to_raid1(TAKEOVER_FN_ARGS)
static int _takeover_from_raid0_to_raid10(TAKEOVER_FN_ARGS)
{
- return _striped_or_raid0_to_raid45610_wrapper(lv, new_segtype, yes, force,
- first_seg(lv)->area_count * 2 /* new_image_count */,
- 2 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
+ return _takeover_upconvert_wrapper(lv, new_segtype, yes, force,
+ first_seg(lv)->area_count * 2 /* new_image_count */,
+ 2 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
}
static int _takeover_from_raid0_to_raid45(TAKEOVER_FN_ARGS)
{
- return _striped_or_raid0_to_raid45610_wrapper(lv, new_segtype, yes, force,
- first_seg(lv)->area_count + 1 /* new_image_count */,
- 2 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
+ return _takeover_upconvert_wrapper(lv, new_segtype, yes, force,
+ first_seg(lv)->area_count + 1 /* new_image_count */,
+ 2 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
}
static int _takeover_from_raid0_to_raid6(TAKEOVER_FN_ARGS)
{
- return _striped_or_raid0_to_raid45610_wrapper(lv, new_segtype, yes, force,
- first_seg(lv)->area_count + 2 /* new_image_count */,
- 3 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
+ return _takeover_upconvert_wrapper(lv, new_segtype, yes, force,
+ first_seg(lv)->area_count + 2 /* new_image_count */,
+ 3 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
}
static int _takeover_from_raid0_to_striped(TAKEOVER_FN_ARGS)
@@ -5170,21 +5265,21 @@ static int _takeover_from_raid0_meta_to_raid1(TAKEOVER_FN_ARGS)
static int _takeover_from_raid0_meta_to_raid10(TAKEOVER_FN_ARGS)
{
- return _striped_or_raid0_to_raid45610_wrapper(lv, new_segtype, yes, force,
+ return _takeover_upconvert_wrapper(lv, new_segtype, yes, force,
first_seg(lv)->area_count * 2 /* new_image_count */,
2 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
}
static int _takeover_from_raid0_meta_to_raid45(TAKEOVER_FN_ARGS)
{
- return _striped_or_raid0_to_raid45610_wrapper(lv, new_segtype, yes, force,
+ return _takeover_upconvert_wrapper(lv, new_segtype, yes, force,
first_seg(lv)->area_count + 1 /* new_image_count */,
2 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
}
static int _takeover_from_raid0_meta_to_raid6(TAKEOVER_FN_ARGS)
{
- return _striped_or_raid0_to_raid45610_wrapper(lv, new_segtype, yes, force,
+ return _takeover_upconvert_wrapper(lv, new_segtype, yes, force,
first_seg(lv)->area_count + 2 /* new_image_count */,
3 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
}
@@ -5249,12 +5344,16 @@ static int _takeover_from_raid45_to_mirrored(TAKEOVER_FN_ARGS)
static int _takeover_from_raid45_to_raid0(TAKEOVER_FN_ARGS)
{
- return _raid45610_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1, 1 /* data_copies */, 0, 0, 0, allocate_pvs);
+ return _takeover_downconvert_wrapper(lv, new_segtype, yes, force,
+ first_seg(lv)->area_count - 1,
+ 1 /* data_copies */, 0, 0, 0, allocate_pvs);
}
static int _takeover_from_raid45_to_raid0_meta(TAKEOVER_FN_ARGS)
{
- return _raid45610_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1, 1 /* data_copies */, 0, 0, 0, allocate_pvs);
+ return _takeover_downconvert_wrapper(lv, new_segtype, yes, force,
+ first_seg(lv)->area_count - 1,
+ 1 /* data_copies */, 0, 0, 0, allocate_pvs);
}
static int _takeover_from_raid45_to_raid1(TAKEOVER_FN_ARGS)
@@ -5278,38 +5377,44 @@ static int _takeover_from_raid45_to_raid6(TAKEOVER_FN_ARGS)
1 /* data_copies */, 0, 0, 0, allocate_pvs))
return 0;
}
- return _striped_or_raid0_to_raid45610_wrapper(lv, new_segtype, yes, force,
- first_seg(lv)->area_count + 1 /* new_image_count */,
- 3 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
+ return _takeover_upconvert_wrapper(lv, new_segtype, yes, force,
+ first_seg(lv)->area_count + 1 /* new_image_count */,
+ 3 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
}
static int _takeover_from_raid45_to_striped(TAKEOVER_FN_ARGS)
{
- return _raid45610_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1, 1 /* data_copies */, 0, 0, 0, allocate_pvs);
+ return _takeover_downconvert_wrapper(lv, new_segtype, yes, force,
+ first_seg(lv)->area_count - 1,
+ 1 /* data_copies */, 0, 0, 0, allocate_pvs);
}
static int _takeover_from_raid6_to_raid0(TAKEOVER_FN_ARGS)
{
- return _raid45610_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2,
- 1 /* data_copies */, 0, 0, 0, allocate_pvs);
+ return _takeover_downconvert_wrapper(lv, new_segtype, yes, force,
+ first_seg(lv)->area_count - 2,
+ 1 /* data_copies */, 0, 0, 0, allocate_pvs);
}
static int _takeover_from_raid6_to_raid0_meta(TAKEOVER_FN_ARGS)
{
- return _raid45610_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2,
- 1 /* data_copies */, 0, 0, 0, allocate_pvs);
+ return _takeover_downconvert_wrapper(lv, new_segtype, yes, force,
+ first_seg(lv)->area_count - 2,
+ 1 /* data_copies */, 0, 0, 0, allocate_pvs);
}
static int _takeover_from_raid6_to_raid45(TAKEOVER_FN_ARGS)
{
- return _raid45610_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 1,
- 2 /* data_copies */, 0, 0, 0, allocate_pvs);
+ return _takeover_downconvert_wrapper(lv, new_segtype, yes, force,
+ first_seg(lv)->area_count - 1,
+ 2 /* data_copies */, 0, 0, 0, allocate_pvs);
}
static int _takeover_from_raid6_to_striped(TAKEOVER_FN_ARGS)
{
- return _raid45610_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count - 2,
- 2 /* data_copies */, 0, 0, 0, allocate_pvs);
+ return _takeover_downconvert_wrapper(lv, new_segtype, yes, force,
+ first_seg(lv)->area_count - 2,
+ 2 /* data_copies */, 0, 0, 0, allocate_pvs);
}
static int _takeover_from_striped_to_raid0(TAKEOVER_FN_ARGS)
@@ -5335,22 +5440,22 @@ static int _takeover_from_striped_to_raid0_meta(TAKEOVER_FN_ARGS)
static int _takeover_from_striped_to_raid10(TAKEOVER_FN_ARGS)
{
- return _striped_or_raid0_to_raid45610_wrapper(lv, new_segtype, yes, force,
- first_seg(lv)->area_count * 2 /* new_image_count */,
- 2 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
+ return _takeover_upconvert_wrapper(lv, new_segtype, yes, force,
+ first_seg(lv)->area_count * 2 /* new_image_count */,
+ 2 /* FIXME: variable data_copies */, 0, 0, new_region_size, allocate_pvs);
}
static int _takeover_from_striped_to_raid45(TAKEOVER_FN_ARGS)
{
- return _striped_or_raid0_to_raid45610_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count + 1,
- 2 /* data_copies*/, 0, 0, new_region_size, allocate_pvs);
+ return _takeover_upconvert_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count + 1,
+ 2 /* data_copies*/, 0, 0, new_region_size, allocate_pvs);
}
static int _takeover_from_striped_to_raid6(TAKEOVER_FN_ARGS)
{
- return _striped_or_raid0_to_raid45610_wrapper(lv, new_segtype, yes, force,
- first_seg(lv)->area_count + 2 /* new_image_count */,
- 3 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
+ return _takeover_upconvert_wrapper(lv, new_segtype, yes, force,
+ first_seg(lv)->area_count + 2 /* new_image_count */,
+ 3 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
}
/*
@@ -5384,8 +5489,9 @@ static int _takeover_from_raid10_to_mirrored(TAKEOVER_FN_ARGS)
static int _takeover_from_raid10_to_raid0(TAKEOVER_FN_ARGS)
{
- return _raid45610_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count / 2,
- 1 /* data_copies */, 0, 0, 0, allocate_pvs);
+ return _takeover_downconvert_wrapper(lv, new_segtype, yes, force,
+ first_seg(lv)->area_count / first_seg(lv)->data_copies,
+ 1 /* data_copies */, 0, 0, 0, allocate_pvs);
}
/*
@@ -5398,8 +5504,9 @@ static int _takeover_from_raid10_to_raid01(TAKEOVER_FN_ARGS)
static int _takeover_from_raid10_to_raid0_meta(TAKEOVER_FN_ARGS)
{
- return _raid45610_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count / 2,
- 1 /* data_copies */, 0, 0, 0, allocate_pvs);
+ return _takeover_downconvert_wrapper(lv, new_segtype, yes, force,
+ first_seg(lv)->area_count / first_seg(lv)->data_copies,
+ 1 /* data_copies */, 0, 0, 0, allocate_pvs);
}
static int _takeover_from_raid10_to_raid1(TAKEOVER_FN_ARGS)
@@ -5418,8 +5525,9 @@ static int _takeover_from_raid10_to_raid10(TAKEOVER_FN_ARGS)
static int _takeover_from_raid10_to_striped(TAKEOVER_FN_ARGS)
{
- return _raid45610_to_raid0_or_striped_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count / 2,
- 1 /* data_copies */, 0, 0, 0, allocate_pvs);
+ return _takeover_downconvert_wrapper(lv, new_segtype, yes, force,
+ first_seg(lv)->area_count / first_seg(lv)->data_copies,
+ 1 /* data_copies */, 0, 0, 0, allocate_pvs);
}
/*
7 years, 1 month
master - lvconvert: add infrastructure for RaidLV reshaping support
by Heinz Mauelshagen
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=932db3db535734...
Commit: 932db3db535734f03cec973182dcc73adef9d3a5
Parent: fe18e5e77a488618510648c7801ea3375ce5aac4
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Fri Feb 24 03:11:41 2017 +0100
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Fri Feb 24 05:20:58 2017 +0100
lvconvert: add infrastructure for RaidLV reshaping support
In order to support striped raid5/6/10 LV reshaping (change
of LV type, stripesize or number of legs), this patch
introduces more local infrastructure to raid_manip.c
used by followup patches.
Changes:
- add missing possible reshape conversions and conversion options
to allow/prohibit changing stripesize or number fo stripes
- enhance setting convenient riad types in reshape conversions
(e.g. raid1 with 2 legs -> radi5_n)
Related: rhbz834579
Related: rhbz1191935
Related: rhbz1191978
---
lib/metadata/raid_manip.c | 149 +++++++++++++++++++++++++++++++++++----------
1 files changed, 117 insertions(+), 32 deletions(-)
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index cc074f6..81360d2 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -26,6 +26,7 @@ typedef int (*fn_on_lv_t)(struct logical_volume *lv, void *data);
static int _eliminate_extracted_lvs_optional_write_vg(struct volume_group *vg,
struct dm_list *removal_lvs,
int vg_write_requested);
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a))
static int _check_restriping(uint32_t new_stripes, struct logical_volume *lv)
{
@@ -4211,37 +4212,68 @@ static struct possible_takeover_reshape_type _possible_takeover_reshape_types[]
{ .current_types = SEG_RAID4|SEG_RAID5_N|SEG_RAID6_N_6,
.possible_types = SEG_RAID4|SEG_RAID5_N|SEG_RAID6_N_6,
.current_areas = ~0U,
- .options = ALLOW_REGION_SIZE },
+ .options = ALLOW_REGION_SIZE|ALLOW_STRIPES|ALLOW_STRIPE_SIZE },
+
+ /* Reshape raid5* <-> raid5* */
+ { .current_types = SEG_RAID5_LS|SEG_RAID5_RS|SEG_RAID5_RA|SEG_RAID5_LA|SEG_RAID5_N,
+ .possible_types = SEG_RAID5_LS|SEG_RAID5_RS|SEG_RAID5_RA|SEG_RAID5_LA|SEG_RAID5_N,
+ .current_areas = ~0U,
+ .options = ALLOW_REGION_SIZE|ALLOW_STRIPES|ALLOW_STRIPE_SIZE },
+ /* Reshape raid6* <-> raid6* */
+ { .current_types = SEG_RAID6_ZR|SEG_RAID6_NR|SEG_RAID6_NC|SEG_RAID6_LS_6|\
+ SEG_RAID6_RS_6|SEG_RAID6_RA_6|SEG_RAID6_LA_6|SEG_RAID6_N_6,
+ .possible_types = SEG_RAID6_ZR|SEG_RAID6_NR|SEG_RAID6_NC|SEG_RAID6_LS_6|\
+ SEG_RAID6_RS_6|SEG_RAID6_RA_6|SEG_RAID6_LA_6|SEG_RAID6_N_6,
+ .current_areas = ~0U,
+ .options = ALLOW_REGION_SIZE|ALLOW_STRIPES|ALLOW_STRIPE_SIZE },
/* raid5_ls <-> raid6_ls_6 */
{ .current_types = SEG_RAID5_LS|SEG_RAID6_LS_6,
.possible_types = SEG_RAID5_LS|SEG_RAID6_LS_6,
.current_areas = ~0U,
- .options = ALLOW_REGION_SIZE },
+ .options = ALLOW_REGION_SIZE|ALLOW_STRIPES|ALLOW_STRIPE_SIZE },
/* raid5_rs -> raid6_rs_6 */
{ .current_types = SEG_RAID5_RS|SEG_RAID6_RS_6,
.possible_types = SEG_RAID5_RS|SEG_RAID6_RS_6,
.current_areas = ~0U,
- .options = ALLOW_REGION_SIZE },
+ .options = ALLOW_REGION_SIZE|ALLOW_STRIPES|ALLOW_STRIPE_SIZE },
/* raid5_ls -> raid6_la_6 */
{ .current_types = SEG_RAID5_LA|SEG_RAID6_LA_6,
.possible_types = SEG_RAID5_LA|SEG_RAID6_LA_6,
.current_areas = ~0U,
- .options = ALLOW_REGION_SIZE },
+ .options = ALLOW_REGION_SIZE|ALLOW_STRIPES|ALLOW_STRIPE_SIZE },
/* raid5_ls -> raid6_ra_6 */
{ .current_types = SEG_RAID5_RA|SEG_RAID6_RA_6,
.possible_types = SEG_RAID5_RA|SEG_RAID6_RA_6,
.current_areas = ~0U,
- .options = ALLOW_REGION_SIZE },
+ .options = ALLOW_REGION_SIZE|ALLOW_STRIPES|ALLOW_STRIPE_SIZE },
+
+ /* Reshape raid10 <-> raid10 */
+ { .current_types = SEG_RAID10_NEAR,
+ .possible_types = SEG_RAID10_NEAR,
+ .current_areas = ~0U,
+ .options = ALLOW_REGION_SIZE|ALLOW_STRIPES|ALLOW_STRIPE_SIZE },
/* mirror <-> raid1 with arbitrary number of legs */
{ .current_types = SEG_MIRROR|SEG_RAID1,
.possible_types = SEG_MIRROR|SEG_RAID1,
.current_areas = ~0U,
+ .options = ALLOW_REGION_SIZE|ALLOW_STRIPES|ALLOW_STRIPE_SIZE },
+
+ /* raid1 -> raid5* with 2 legs */
+ { .current_types = SEG_RAID1,
+ .possible_types = SEG_RAID5_LS|SEG_RAID5_RS|SEG_RAID5_RA|SEG_RAID5_LA|SEG_RAID5_N,
+ .current_areas = 2U,
+ .options = ALLOW_REGION_SIZE|ALLOW_STRIPE_SIZE },
+
+ /* raid5* -> raid1 with 2 legs */
+ { .current_types = SEG_RAID5_LS|SEG_RAID5_RS|SEG_RAID5_RA|SEG_RAID5_LA|SEG_RAID5_N,
+ .possible_types = SEG_RAID1,
+ .current_areas = 2U,
.options = ALLOW_REGION_SIZE },
/* END */
@@ -5323,7 +5355,7 @@ static int _takeover_from_striped_to_raid6(TAKEOVER_FN_ARGS)
/*
* Only if we decide to support raid01 at all.
-
+
static int _takeover_from_raid01_to_raid01(TAKEOVER_FN_ARGS)
{
return _takeover_unsupported_yet(lv, new_stripes, new_segtype);
@@ -5437,11 +5469,51 @@ static int _log_prohibited_option(const struct lv_segment *seg_from,
return 1;
}
-/* Change segtype for raid4 <-> raid5 <-> raid6 takeover where necessary. */
-static int _set_convenient_raid456_segtype_to(const struct lv_segment *seg_from,
- const struct segment_type **segtype)
+/*
+ * Find takeover raid flag for segment type flag of @seg
+ */
+/* Segment type flag correspondence for raid5 <-> raid6 conversions */
+static uint64_t _r5_to_r6[][2] = {
+ { SEG_RAID5_LS, SEG_RAID6_LS_6 },
+ { SEG_RAID5_LA, SEG_RAID6_LA_6 },
+ { SEG_RAID5_RS, SEG_RAID6_RS_6 },
+ { SEG_RAID5_RA, SEG_RAID6_RA_6 },
+ { SEG_RAID5_N, SEG_RAID6_N_6 },
+};
+
+
+/* Return segment type flag for raid5 -> raid6 conversions */
+static uint64_t _get_r56_flag(const struct lv_segment *seg, unsigned idx)
+{
+ unsigned elems = ARRAY_SIZE(_r5_to_r6);
+
+ while (elems--)
+ if (seg->segtype->flags & _r5_to_r6[elems][idx])
+ return _r5_to_r6[elems][!idx];
+
+ return 0;
+}
+
+/* Return segment type flag for raid5 -> raid6 conversions */
+static uint64_t _raid_seg_flag_5_to_6(const struct lv_segment *seg)
+{
+ return _get_r56_flag(seg, 0);
+}
+
+/* Return segment type flag for raid6 -> raid5 conversions */
+static uint64_t _raid_seg_flag_6_to_5(const struct lv_segment *seg)
+{
+ return _get_r56_flag(seg, 1);
+}
+
+/* Change segtype for raid4 <-> raid5 <-> raid6 or raid1 <-> raid5 takeover where necessary. */
+static int _set_convenient_raid1456_segtype_to(const struct lv_segment *seg_from,
+ const struct segment_type **segtype,
+ int yes)
{
size_t len = min(strlen((*segtype)->name), strlen(lvseg_name(seg_from)));
+ uint64_t seg_flag;
+ struct cmd_context *cmd = seg_from->lv->vg->cmd;
const struct segment_type *segtype_sav = *segtype;
/* Bail out if same RAID level is requested. */
@@ -5451,54 +5523,66 @@ static int _set_convenient_raid456_segtype_to(const struct lv_segment *seg_from,
/* Striped/raid0 -> raid5/6 */
if (seg_is_striped(seg_from) || seg_is_any_raid0(seg_from)) {
/* If this is any raid5 conversion request -> enforce raid5_n, because we convert from striped */
- if (segtype_is_any_raid5(*segtype) &&
- !segtype_is_raid5_n(*segtype)) {
- if (!(*segtype = get_segtype_from_flag(seg_from->lv->vg->cmd, SEG_RAID5_N)))
- return_0;
+ if (segtype_is_any_raid5(*segtype) && !segtype_is_raid5_n(*segtype)) {
+ seg_flag = SEG_RAID5_N;
goto replaced;
/* If this is any raid6 conversion request -> enforce raid6_n_6, because we convert from striped */
- } else if (segtype_is_any_raid6(*segtype) &&
- !segtype_is_raid6_n_6(*segtype)) {
- if (!(*segtype = get_segtype_from_flag(seg_from->lv->vg->cmd, SEG_RAID6_N_6)))
- return_0;
+ } else if (segtype_is_any_raid6(*segtype) && !segtype_is_raid6_n_6(*segtype)) {
+ seg_flag = SEG_RAID6_N_6;
goto replaced;
}
+ /* raid1 -> raid5_n with 2 areas */
+ } else if (seg_is_raid1(seg_from) && seg_from->area_count == 2 &&
+ segtype_is_any_raid5(*segtype) && !segtype_is_raid5_n(*segtype)) {
+ seg_flag = SEG_RAID5_N;
+ goto replaced;
+
/* raid4 -> raid5_n */
- } else if (seg_is_raid4(seg_from) &&
- segtype_is_any_raid5(*segtype)) {
- if (!(*segtype = get_segtype_from_flag(seg_from->lv->vg->cmd, SEG_RAID5_N)))
- return_0;
+ } else if (seg_is_raid4(seg_from) && segtype_is_any_raid5(*segtype)) {
+ seg_flag = SEG_RAID5_N;
goto replaced;
/* raid4/raid5_n -> striped/raid0/raid6 */
} else if ((seg_is_raid4(seg_from) || seg_is_raid5_n(seg_from)) &&
!segtype_is_striped(*segtype) &&
!segtype_is_any_raid0(*segtype) &&
+ !segtype_is_raid1(*segtype) &&
!segtype_is_raid4(*segtype) &&
!segtype_is_raid5_n(*segtype) &&
!segtype_is_raid6_n_6(*segtype)) {
- if (!(*segtype = get_segtype_from_flag(seg_from->lv->vg->cmd, SEG_RAID6_N_6)))
- return_0;
+ seg_flag = SEG_RAID6_N_6;
goto replaced;
- /* ... and raid6 -> striped/raid0/raid4/raid5_n */
- } else if (seg_is_raid6_n_6(seg_from) &&
- !segtype_is_striped(*segtype) &&
- !segtype_is_any_raid0(*segtype) &&
- !segtype_is_raid4(*segtype) &&
- !segtype_is_raid5_n(*segtype)) {
- if (!(*segtype = get_segtype_from_flag(seg_from->lv->vg->cmd, SEG_RAID5_N)))
+ /* Got to do check for raid5 -> raid6 ... */
+ } else if (seg_is_any_raid5(seg_from) && segtype_is_any_raid6(*segtype)) {
+ if (!(seg_flag = _raid_seg_flag_5_to_6(seg_from)))
return_0;
goto replaced;
+
+ /* ... and raid6 -> raid5 */
+ } else if (seg_is_any_raid6(seg_from) && segtype_is_any_raid5(*segtype)) {
+ /* No result for raid6_{zr,nr,nc} */
+ if (!(seg_flag = _raid_seg_flag_6_to_5(seg_from)))
+ return 0;
+ goto replaced;
}
return 1;
replaced:
+ if (!(*segtype = get_segtype_from_flag(cmd, seg_flag)))
+ return_0;
log_warn("Replaced LV type %s with possible type %s.",
segtype_sav->name, (*segtype)->name);
+ if (!yes && yes_no_prompt("Do you want to convert %s LV %s to %s? [y/n]: ",
+ segtype_sav->name, display_lvname(seg_from->lv),
+ (*segtype)->name) == 'n') {
+ log_error("Logical volume %s NOT converted.", display_lvname(seg_from->lv));
+ return 0;
+ }
+
return 1;
}
@@ -5584,6 +5668,7 @@ static int _region_size_change_requested(struct logical_volume *lv, int yes, con
/* Check allowed conversion from seg_from to *segtype_to */
static int _conversion_options_allowed(const struct lv_segment *seg_from,
const struct segment_type **segtype_to,
+ int yes,
uint32_t new_image_count,
int new_data_copies, int new_region_size,
int stripes, unsigned new_stripe_size_supplied)
@@ -5591,7 +5676,7 @@ static int _conversion_options_allowed(const struct lv_segment *seg_from,
int r = 1;
uint32_t opts;
- if (!new_image_count && !_set_convenient_raid456_segtype_to(seg_from, segtype_to))
+ if (!new_image_count && !_set_convenient_raid1456_segtype_to(seg_from, segtype_to, yes))
return_0;
if (!_get_allowed_conversion_options(seg_from, *segtype_to, new_image_count, &opts)) {
@@ -5682,7 +5767,7 @@ int lv_raid_convert(struct logical_volume *lv,
* Check acceptible options mirrors, region_size,
* stripes and/or stripe_size have been provided.
*/
- if (!_conversion_options_allowed(seg, &new_segtype, 0 /* Takeover */, 0 /*new_data_copies*/, new_region_size,
+ if (!_conversion_options_allowed(seg, &new_segtype, yes, 0 /* Takeover */, 0 /*new_data_copies*/, new_region_size,
new_stripes, new_stripe_size_supplied))
return _log_possible_conversion_types(lv, new_segtype);
7 years, 1 month