static int _read_raid_params(struct cmd_context *cmd,
struct lvcreate_params *lp)
{
- if ((lp->stripes < 2) && segtype_is_raid10(lp->segtype)) {
- if (arg_is_set(cmd, stripes_ARG)) {
- /* User supplied the bad argument */
- log_error("Segment type 'raid10' requires 2 or more stripes.");
+ if (seg_is_mirrored(lp)) {
+ if (segtype_is_raid10(lp->segtype)) {
+ if (lp->stripes < 2) {
+ /*
+ * RAID10 needs at least 4 stripes
+ */
+ log_warn("Adjusting stripes to the minimum of 2 for %s.",
+ lp->segtype->name);
+ lp->stripes = 2;
+ }
+
+ /*
+ * FIXME: _check_raid_parameters devides by 2, which
+ * needs to change if we start supporting
+ * odd numbers of stripes with raid10
+ */
+ lp->stripes *= 2;
+
+ } else if (lp->stripes > 1) {
+ /*
+ * RAID1 does not take a stripe arg
+ */
+ log_error("Stripe argument cannot be used with segment type, %s",
+ lp->segtype->name);
return 0;
}
- /* No stripe argument was given - default to 2 */
- lp->stripes = 2;
- lp->stripe_size = find_config_tree_int(cmd, metadata_stripesize_CFG, NULL) * 2;
- }
- /*
- * RAID1 does not take a stripe arg
- */
- if ((lp->stripes > 1) && seg_is_mirrored(lp) &&
- !segtype_is_raid10(lp->segtype)) {
- log_error("Stripe argument cannot be used with segment type, %s",
- lp->segtype->name);
- return 0;
- }
+ } else if (lp->stripes < 2)
+ /* No stripe argument was given */
+ lp->stripes = seg_is_any_raid6(lp) ? 3 : 2;
+
+ if (seg_is_raid1(lp)) {
+ if (lp->stripe_size) {
+ log_error("Stripe size argument cannot be used with segment type, %s",
+ lp->segtype->name);
+ return 0;
+ }
+
+ } else if (!lp->stripe_size)
+ lp->stripe_size = find_config_tree_int(cmd, metadata_stripesize_CFG, NULL) * 2;
if (arg_is_set(cmd, mirrors_ARG) && segtype_is_raid(lp->segtype) &&
!segtype_is_raid1(lp->segtype) && !segtype_is_raid10(lp->segtype)) {
return 0;
}
- /* Rates are recorded in kiB/sec/disk, not sectors/sec/disk */
- lp->min_recovery_rate = arg_uint_value(cmd, minrecoveryrate_ARG, 0) / 2;
- lp->max_recovery_rate = arg_uint_value(cmd, maxrecoveryrate_ARG, 0) / 2;
+ if (!seg_is_any_raid0(lp)) {
+ /* Rates are recorded in kiB/sec/disk, not sectors/sec/disk */
+ lp->min_recovery_rate = arg_uint_value(cmd, minrecoveryrate_ARG, 0) / 2;
+ lp->max_recovery_rate = arg_uint_value(cmd, maxrecoveryrate_ARG, 0) / 2;
- if (lp->min_recovery_rate > lp->max_recovery_rate) {
- log_error("Minimum recovery rate cannot be higher than maximum.");
- return 0;
+ if (lp->min_recovery_rate > lp->max_recovery_rate) {
+ log_error("Minimum recovery rate cannot be higher than maximum.");
+ return 0;
+ }
}
return 1;
/* Default to 2 mirrored areas if '--type mirror|raid1|raid10' */
lp->mirrors = seg_is_mirrored(lp) ? 2 : 1;
- if (lp->stripes < 2 && segtype_is_any_raid0(lp->segtype))
- if (arg_count(cmd, stripes_ARG)) {
- /* User supplied the bad argument */
- log_error("Segment type %s requires 2 or more stripes.", lp->segtype->name);
- return 0;
- }
-
lp->nosync = arg_is_set(cmd, nosync_ARG);
if (!(lp->region_size = arg_uint_value(cmd, regionsize_ARG, 0)) &&
return 0;
}
+ lp->stripe_size = arg_uint_value(cmd, stripesize_ARG, 0);
+
if (!is_power_of_2(lp->region_size)) {
log_error("Region size (%" PRIu32 ") must be a power of 2",
lp->region_size);
{
unsigned devs = lcp->pv_count ? : dm_list_size(&vg->pvs);
struct cmd_context *cmd = vg->cmd;
+ int old_stripes = !arg_is_set(cmd, stripes_ARG) &&
+ find_config_tree_bool(cmd, allocation_raid_stripe_all_devices_CFG, NULL);
- if (!seg_is_mirrored(lp) && !lp->stripe_size)
- lp->stripe_size = find_config_tree_int(cmd, metadata_stripesize_CFG, NULL) * 2;
+ /*
+ * If we requested the previous behaviour by setting
+ * "allocation/raid_stripe_all_devices = 1" and the
+ * number of devices was not supplied, we can infer
+ * from the PVs given.
+ */
+ if (old_stripes && seg_is_raid(lp) && !seg_is_raid1(lp))
+ lp->stripes = devs;
+
+ if (seg_is_raid10(lp)) {
+ lp->stripes /= lp->mirrors;
- if (seg_is_any_raid0(lp)) {
if (lp->stripes < 2) {
- log_error("Segment type 'raid0' requires 2 or more stripes.");
+ log_error("Unable to create RAID(1)0 LV: "
+ "insufficient number of devices.");
return 0;
}
- } else if (!seg_is_mirrored(lp)) {
- /*
- * If number of devices was not supplied, we can infer from
- * the PVs given.
- */
- if (!arg_is_set(cmd, stripes_ARG) &&
- (devs > 2 * lp->segtype->parity_devs))
- lp->stripes = devs - lp->segtype->parity_devs;
- if (lp->stripes <= lp->segtype->parity_devs) {
+ } else if (!seg_is_mirrored(lp)) {
+ if (old_stripes &&
+ lp->segtype->parity_devs &&
+ devs > 2 * lp->segtype->parity_devs)
+ lp->stripes -= lp->segtype->parity_devs;
+
+ if (seg_is_any_raid0(lp)) {
+ if (lp->stripes < 2) {
+ log_error("Segment type 'raid0' requires 2 or more stripes.");
+ return 0;
+ }
+ } else if (lp->stripes <= lp->segtype->parity_devs) {
log_error("Number of stripes must be at least %d for %s",
lp->segtype->parity_devs + 1,
lp->segtype->name);
return 0;
}
- } else if (segtype_is_any_raid0(lp->segtype) ||
- segtype_is_raid10(lp->segtype)) {
- if (!arg_is_set(cmd, stripes_ARG))
- lp->stripes = devs / lp->mirrors;
- if (lp->stripes < 2) {
- log_error("Unable to create RAID(1)0 LV: "
- "insufficient number of devices.");
- return 0;
- }
}
/* 'mirrors' defaults to 2 - not the number of PVs supplied */