1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

lvcreate/lvconvert: fix validation of maximum mirrors/stripes

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
This commit is contained in:
Heinz Mauelshagen 2016-08-12 19:14:28 +02:00
parent 93b61c07eb
commit a185a2bea2
6 changed files with 61 additions and 11 deletions

View File

@ -66,8 +66,13 @@
#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"

View 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;
}

View 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

View 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.

View 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;

View 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;
}