]> sourceware.org Git - lvm2.git/commitdiff
lvcreate/lvconvert: fix validation of maximum mirrors/stripes
authorHeinz Mauelshagen <heinzm@redhat.com>
Fri, 12 Aug 2016 17:14:28 +0000 (19:14 +0200)
committerHeinz Mauelshagen <heinzm@redhat.com>
Fri, 12 Aug 2016 17:14:28 +0000 (19:14 +0200)
Enforce mirror/raid0/1/10/4/5/6 type specific maximum images when
creating LVs or converting them from mirror <-> raid1.

Document those maxima in the lvcreate/lvconvert man pages.

- resolves rhbz1366060

lib/config/defaults.h
lib/metadata/merge.c
man/lvconvert.8.in
man/lvcreate.8.in
tools/lvconvert.c
tools/lvcreate.c

index f1f1700306426d84c7b919d2f9775e53cc3f91bd..c6efcdc718bc94fe2833fcad58c24aeb78af2258 100644 (file)
 #define DEFAULT_MIRROR_LOG_FAULT_POLICY "allocate"
 #define DEFAULT_MIRROR_IMAGE_FAULT_POLICY "remove"
 #define DEFAULT_MIRROR_MAX_IMAGES 8 /* limited by kernel DM_KCOPYD_MAX_REGIONS */
-// FIXME Increase this to 64
-#define DEFAULT_RAID_MAX_IMAGES 8 /* limited by kernel failed devices bitfield in superblock (raid4/5/6 max 253) */
+/* Limited by kernel failed devices bitfield in superblock (raid4/5/6 MD max 253) */
+/*
+ * 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 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"
index ce33e28c1c6a8f99a7194f0888cfb52f3d7eb9eb..bf0d2c0a0daa86b982f190ab6c94fa33d8f332d9 100644 (file)
@@ -261,10 +261,17 @@ static void _check_raid_seg(struct lv_segment *seg, int *error_count)
        if (seg->extents_copied > seg->area_len)
                raid_seg_error_val("extents_copied too large", seg->extents_copied);
 
-       /* Default still 8, change! */
-       if (seg->area_count > DEFAULT_RAID_MAX_IMAGES) {
+       /* Default < 10, change once raid1 split shift and rename SubLVs works! */
+       if (seg_is_raid1(seg)) {
+               if (seg->area_count > DEFAULT_RAID1_MAX_IMAGES) {
+                       log_error("LV %s invalid: maximum supported areas %u (is %u) for %s segment",
+                               seg->lv->name, DEFAULT_RAID1_MAX_IMAGES, seg->area_count, lvseg_name(seg));
+                               if ((*error_count)++ > ERROR_MAX)
+                                       return;
+               }
+       } else if (seg->area_count > DEFAULT_RAID_MAX_IMAGES) {
                log_error("LV %s invalid: maximum supported areas %u (is %u) for %s segment",
-                         seg->lv->name, DEFAULT_RAID_MAX_IMAGES, seg->area_count, lvseg_name(seg));
+                       seg->lv->name, DEFAULT_RAID_MAX_IMAGES, seg->area_count, lvseg_name(seg));
                        if ((*error_count)++ > ERROR_MAX)
                                return;
        }
index 641e850a631d498fff0c742102c08b9505a5494b..4f4d05e4f2dd48874c72860b2703485cd8a1f38c 100644 (file)
@@ -338,6 +338,8 @@ VG/RaidLV
 \[bu]
 Change the number of images in raid1 RaidLV.
 
+Note the current maximum is 9 providing 10 raid1 legs.
+
 .B lvconvert \-\-splitmirrors
 Number
 VG/RaidLV
index 2873e72c19c0432cc1cef0376119ea6c2884d701..bf3c33f14576e26193aeee4c8491841d24996dde 100644 (file)
@@ -399,6 +399,9 @@ to configure default mirror segment type.
 The options
 \fB\-\-mirrorlog\fP and \fB\-\-corelog\fP apply
 to the legacy "\fImirror\fP" segment type only.
+
+Note the current maxima for mirrors are 7 for "mirror" providing
+8 mirror legs and 9 for "raid1" providing 10 legs.
 .
 .HP
 .BR \-\-mirrorlog
@@ -633,8 +636,12 @@ section of \fBlvm.conf (5)\fP or add
 \fB\-\-config allocation/raid_stripe_all_devices=1\fP
 .br
 to the command.
-.br
-Note the current limitation of 8 stripes total in any RaidLV including parity devices.
+
+Note the current maxima for stripes depend on the created RAID type.
+For raid10, the maximum of stripes is 32,
+for raid0, it is 64,
+for raid4/5, it is 63
+and for raid6 it is 62.
 
 See the \fB\-\-nosync\fP option to optionally avoid initial syncrhonization of RaidLVs.
 
index 72b4931237bcd2c99a35510fc99b3e3fba70c0a9..23e3cd54bcbb458511f3b5d56d9c79c25074bc2a 100644 (file)
@@ -1910,6 +1910,11 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
        if (lp->mirrors_supplied) {
                if (!*lp->type_str || !strcmp(lp->type_str, SEG_TYPE_NAME_RAID1) || !strcmp(lp->type_str, SEG_TYPE_NAME_LINEAR) ||
                    (!strcmp(lp->type_str, SEG_TYPE_NAME_STRIPED) && image_count == 1)) {
+                       if (image_count > DEFAULT_RAID1_MAX_IMAGES) {
+                               log_error("Only up to %u mirrors in %s LV %s supported currently.",
+                                         DEFAULT_RAID1_MAX_IMAGES, lp->segtype->name, display_lvname(lv));
+                               return 0;
+                       }
                        if (!lv_raid_change_image_count(lv, image_count, lp->pvh))
                                return_0;
 
index 28d8c92ce4dac8aa39709a52be08d75209462c0f..ccd07f054721994746bcf74e32c83e1702887b8c 100644 (file)
@@ -527,8 +527,21 @@ static int _read_mirror_and_raid_params(struct cmd_context *cmd,
                                        struct lvcreate_params *lp)
 {
        int pagesize = lvm_getpagesize();
-       unsigned max_images = segtype_is_raid(lp->segtype) ? DEFAULT_RAID_MAX_IMAGES :
-                                                            DEFAULT_MIRROR_MAX_IMAGES;
+       unsigned max_images;
+
+       if (seg_is_raid(lp)) {
+               if (seg_is_raid1(lp))
+                       max_images = DEFAULT_RAID1_MAX_IMAGES;
+               else {
+                       max_images = DEFAULT_RAID_MAX_IMAGES;
+                       if (seg_is_raid4(lp) ||
+                           seg_is_any_raid5(lp))
+                               max_images--;
+                       else if (seg_is_any_raid6(lp))
+                               max_images -= 2;
+               }
+       } else
+               max_images = DEFAULT_MIRROR_MAX_IMAGES;
 
        /* Common mirror and raid params */
        if (arg_is_set(cmd, mirrors_ARG)) {
@@ -556,8 +569,19 @@ static int _read_mirror_and_raid_params(struct cmd_context *cmd,
                /* Default to 2 mirrored areas if '--type mirror|raid1|raid10' */
                lp->mirrors = seg_is_mirrored(lp) ? 2 : 1;
 
-       if (max(lp->mirrors, lp->stripes) > max_images) {
-               log_error("Only up to %u images in %s supported currently.",
+       /* FIMXE: raid10 check has to change once we support data copies and odd numbers of stripes */
+       if (seg_is_raid10(lp) && lp->mirrors * lp->stripes > max_images) {
+               log_error("Only up to %u stripes in %s supported currently.",
+                         max_images, lp->segtype->name);
+               return 0;
+       } else if (seg_is_mirrored(lp)) {
+               if (lp->mirrors > max_images) {
+                       log_error("Only up to %u mirrors in %s supported currently.",
+                                 max_images, lp->segtype->name);
+                       return 0;
+               }
+       } else if (lp->stripes > max_images) {
+               log_error("Only up to %u stripes in %s supported currently.",
                          max_images, lp->segtype->name);
                return 0;
        }
This page took 0.053301 seconds and 5 git commands to generate.