1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-02 01:18:26 +03:00

Improve stripe size validation.

Increase maximum stripe size limit to physical extent size for lvm2 metadata.
This commit is contained in:
Alasdair Kergon 2006-04-29 22:08:43 +00:00
parent 8b4273d298
commit 12de747d3a
6 changed files with 73 additions and 15 deletions

View File

@ -1,5 +1,7 @@
Version 2.02.06 - Version 2.02.06 -
================================= =================================
Improve stripe size validation.
Increase maximum stripe size limit to physical extent size for lvm2 metadata.
Fix activation code to check for pre-existing mirror logs. Fix activation code to check for pre-existing mirror logs.
Tighten region size validation. Tighten region size validation.
Ignore empty strings in config files. Ignore empty strings in config files.

View File

@ -1754,7 +1754,8 @@ struct format_type *create_text_format(struct cmd_context *cmd)
fmt->name = FMT_TEXT_NAME; fmt->name = FMT_TEXT_NAME;
fmt->alias = FMT_TEXT_ALIAS; fmt->alias = FMT_TEXT_ALIAS;
fmt->features = FMT_SEGMENTS | FMT_MDAS | FMT_TAGS | FMT_PRECOMMIT | fmt->features = FMT_SEGMENTS | FMT_MDAS | FMT_TAGS | FMT_PRECOMMIT |
FMT_UNLIMITED_VOLS | FMT_RESIZE_PV; FMT_UNLIMITED_VOLS | FMT_RESIZE_PV |
FMT_UNLIMITED_STRIPESIZE;
if (!(mda_lists = dm_malloc(sizeof(struct mda_lists)))) { if (!(mda_lists = dm_malloc(sizeof(struct mda_lists)))) {
log_error("Failed to allocate dir_list"); log_error("Failed to allocate dir_list");

View File

@ -31,6 +31,7 @@
#define SECTOR_SIZE ( 1L << SECTOR_SHIFT ) #define SECTOR_SIZE ( 1L << SECTOR_SHIFT )
#define STRIPE_SIZE_MIN ( getpagesize() >> SECTOR_SHIFT) /* PAGESIZE in sectors */ #define STRIPE_SIZE_MIN ( getpagesize() >> SECTOR_SHIFT) /* PAGESIZE in sectors */
#define STRIPE_SIZE_MAX ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */ #define STRIPE_SIZE_MAX ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */
#define STRIPE_SIZE_LIMIT ((UINT_MAX >> 2) + 1)
#define PV_MIN_SIZE ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */ #define PV_MIN_SIZE ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */
#define PE_ALIGN (65536UL >> SECTOR_SHIFT) /* PE alignment */ #define PE_ALIGN (65536UL >> SECTOR_SHIFT) /* PE alignment */
#define MAX_RESTRICTED_LVS 255 /* Used by FMT_RESTRICTED_LVIDS */ #define MAX_RESTRICTED_LVS 255 /* Used by FMT_RESTRICTED_LVIDS */
@ -74,6 +75,7 @@
#define FMT_ORPHAN_ALLOCATABLE 0x00000020 /* Orphan PV allocatable? */ #define FMT_ORPHAN_ALLOCATABLE 0x00000020 /* Orphan PV allocatable? */
#define FMT_PRECOMMIT 0x00000040 /* Supports pre-commit? */ #define FMT_PRECOMMIT 0x00000040 /* Supports pre-commit? */
#define FMT_RESIZE_PV 0x00000080 /* Supports pvresize? */ #define FMT_RESIZE_PV 0x00000080 /* Supports pvresize? */
#define FMT_UNLIMITED_STRIPESIZE 0x00000080 /* Unlimited stripe size? */
typedef enum { typedef enum {
ALLOC_INVALID, ALLOC_INVALID,

View File

@ -58,7 +58,9 @@ the logical volume.
.I \-I, \-\-stripesize StripeSize .I \-I, \-\-stripesize StripeSize
Gives the number of kilobytes for the granularity of the stripes. Gives the number of kilobytes for the granularity of the stripes.
.br .br
StripeSize must be 2^n (n = 2 to 9) StripeSize must be 2^n (n = 2 to 9) for metadata in LVM1 format.
For metadata in LVM2 format, the stripe size may be a larger
power of 2 but must not exceed the physical extent size.
.TP .TP
.I \-l, \-\-extents LogicalExtentsNumber .I \-l, \-\-extents LogicalExtentsNumber
Gives the number of logical extents to allocate for the new Gives the number of logical extents to allocate for the new

View File

@ -181,6 +181,10 @@ static int _read_size_params(struct lvcreate_params *lp,
return 1; return 1;
} }
/* The stripe size is limited by the size of a uint32_t, but since the
* value given by the user is doubled, and the final result must be a
* power of 2, we must divide UINT_MAX by four and add 1 (to round it
* up to the power of 2) */
static int _read_stripe_params(struct lvcreate_params *lp, static int _read_stripe_params(struct lvcreate_params *lp,
struct cmd_context *cmd, struct cmd_context *cmd,
int *pargc, char ***pargv) int *pargc, char ***pargv)
@ -192,6 +196,12 @@ static int _read_stripe_params(struct lvcreate_params *lp,
log_error("Negative stripesize is invalid"); log_error("Negative stripesize is invalid");
return 0; return 0;
} }
/* Check to make sure we won't overflow lp->stripe_size */
if(arg_uint_value(cmd, stripesize_ARG, 0) > STRIPE_SIZE_LIMIT) {
log_error("Stripe size cannot be larger than %s",
display_size(cmd, STRIPE_SIZE_LIMIT, SIZE_SHORT));
return 0;
}
lp->stripe_size = 2 * arg_uint_value(cmd, stripesize_ARG, 0); lp->stripe_size = 2 * arg_uint_value(cmd, stripesize_ARG, 0);
} }
@ -204,7 +214,8 @@ static int _read_stripe_params(struct lvcreate_params *lp,
lp->stripe_size = find_config_int(cmd->cft->root, lp->stripe_size = find_config_int(cmd->cft->root,
"metadata/stripesize", "metadata/stripesize",
DEFAULT_STRIPESIZE) * 2; DEFAULT_STRIPESIZE) * 2;
log_print("Using default stripesize %dKB", lp->stripe_size / 2); log_print("Using default stripesize %s",
display_size(cmd, lp->stripe_size, SIZE_SHORT));
} }
if (argc && (unsigned) argc < lp->stripes) { if (argc && (unsigned) argc < lp->stripes) {
@ -219,10 +230,11 @@ static int _read_stripe_params(struct lvcreate_params *lp,
return 0; return 0;
} }
/* MAX size check is in _lvcreate */
if (lp->stripes > 1 && (lp->stripe_size < STRIPE_SIZE_MIN || if (lp->stripes > 1 && (lp->stripe_size < STRIPE_SIZE_MIN ||
lp->stripe_size > STRIPE_SIZE_MAX ||
lp->stripe_size & (lp->stripe_size - 1))) { lp->stripe_size & (lp->stripe_size - 1))) {
log_error("Invalid stripe size %d", lp->stripe_size); log_error("Invalid stripe size %s",
display_size(cmd, lp->stripe_size, SIZE_SHORT));
return 0; return 0;
} }
@ -505,12 +517,23 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
pvh = &vg->pvs; pvh = &vg->pvs;
if (lp->stripe_size > vg->extent_size) { if (lp->stripe_size > vg->extent_size) {
log_error("Setting stripe size %d KB to physical extent " log_error("Reducing requested stripe size %s to maximum, "
"size %u KB", lp->stripe_size / 2, "physical extent size %s",
vg->extent_size / 2); display_size(cmd, lp->stripe_size, SIZE_SHORT),
display_size(cmd, vg->extent_size, SIZE_SHORT));
lp->stripe_size = vg->extent_size; lp->stripe_size = vg->extent_size;
} }
/* Need to check the vg's format to verify this - the cmd format isn't setup properly yet */
if (lp->stripes > 1 &&
!(vg->fid->fmt->features & FMT_UNLIMITED_STRIPESIZE) &&
(lp->stripe_size > STRIPE_SIZE_MAX)) {
log_error("Stripe size may not exceed %s",
display_size(cmd, STRIPE_SIZE_MAX,
SIZE_SHORT));
return 0;
}
if (lp->size) { if (lp->size) {
/* No of 512-byte sectors */ /* No of 512-byte sectors */
tmp_size = lp->size; tmp_size = lp->size;

View File

@ -178,15 +178,35 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
log_error("Stripesize may not be negative."); log_error("Stripesize may not be negative.");
return ECMD_FAILED; return ECMD_FAILED;
} }
if (vg->fid->fmt->features & FMT_SEGMENTS)
if (arg_uint_value(cmd, stripesize_ARG, 0) > STRIPE_SIZE_LIMIT) {
log_error("Stripe size cannot be larger than %s",
display_size(cmd, STRIPE_SIZE_LIMIT, SIZE_SHORT));
return 0;
}
if (!(vg->fid->fmt->features & FMT_SEGMENTS))
log_print("Varied stripesize not supported. Ignoring.");
else if (arg_uint_value(cmd, stripesize_ARG, 0) > vg->extent_size) {
log_error("Reducing stripe size %s to maximum, "
"physical extent size %s",
display_size(cmd,
arg_uint_value(cmd, stripesize_ARG, 0) * 2,
SIZE_SHORT),
display_size(cmd, vg->extent_size, SIZE_SHORT));
lp->stripe_size = vg->extent_size;
} else
lp->stripe_size = 2 * arg_uint_value(cmd, lp->stripe_size = 2 * arg_uint_value(cmd,
stripesize_ARG, 0); stripesize_ARG, 0);
else
log_print("Varied stripesize not supported. Ignoring.");
if (lp->mirrors) { if (lp->mirrors) {
log_error("Mirrors and striping cannot be combined yet."); log_error("Mirrors and striping cannot be combined yet.");
return ECMD_FAILED; return ECMD_FAILED;
} }
if (lp->stripe_size & (lp->stripe_size - 1)) {
log_error("Stripe size must be power of 2");
return 0;
}
} }
lv = lvl->lv; lv = lvl->lv;
@ -279,16 +299,18 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
if (!lp->stripe_size && lp->stripes > 1) { if (!lp->stripe_size && lp->stripes > 1) {
if (seg_stripesize) { if (seg_stripesize) {
log_print("Using stripesize of last segment " log_print("Using stripesize of last segment %s",
"%dKB", seg_stripesize / 2); display_size(cmd, seg_stripesize,
SIZE_SHORT));
lp->stripe_size = seg_stripesize; lp->stripe_size = seg_stripesize;
} else { } else {
lp->stripe_size = lp->stripe_size =
find_config_int(cmd->cft->root, find_config_int(cmd->cft->root,
"metadata/stripesize", "metadata/stripesize",
DEFAULT_STRIPESIZE) * 2; DEFAULT_STRIPESIZE) * 2;
log_print("Using default stripesize %dKB", log_print("Using default stripesize %s",
lp->stripe_size / 2); display_size(cmd, lp->stripe_size,
SIZE_SHORT));
} }
} }
} }
@ -362,6 +384,12 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
lp->extents, lp->extents - size_rest); lp->extents, lp->extents - size_rest);
lp->extents = lp->extents - size_rest; lp->extents = lp->extents - size_rest;
} }
if (lp->stripe_size < STRIPE_SIZE_MIN) {
log_error("Invalid stripe size %s",
display_size(cmd, lp->stripe_size, SIZE_SHORT));
return 0;
}
} }
if (lp->extents == lv->le_count) { if (lp->extents == lv->le_count) {