summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorJonathan Brassow <jbrassow@redhat.com>2012-08-24 15:34:19 -0500
committerJonathan Brassow <jbrassow@redhat.com>2012-08-24 15:34:19 -0500
commit4047e4dfb16175daec348bf44032c02181bd4c70 (patch)
treec65d274f9d8058e77771d439652d49c7af9d4c6b /tools
parent99d1e264a87eb256debe2eaa02d9fc4e2b08c815 (diff)
downloadlvm2-4047e4dfb16175daec348bf44032c02181bd4c70.tar.gz
lvm2-4047e4dfb16175daec348bf44032c02181bd4c70.tar.xz
lvm2-4047e4dfb16175daec348bf44032c02181bd4c70.zip
RAID: Add support for RAID10
This patch adds support for RAID10. It is not the default at this stage. The user needs to specify '--type raid10' if they would like RAID10 instead of stacked mirror over stripe.
Diffstat (limited to 'tools')
-rw-r--r--tools/lvcreate.c28
-rw-r--r--tools/lvresize.c13
2 files changed, 38 insertions, 3 deletions
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 2cb6ac02..aac8c22b 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -702,6 +702,10 @@ static int _lvcreate_params(struct lvcreate_params *lp,
/* Set default segtype */
if (arg_count(cmd, mirrors_ARG))
+ /*
+ * FIXME: Add default setting for when -i and -m arguments
+ * are both given. We should default to "raid10".
+ */
segtype_str = find_config_tree_str(cmd, "global/mirror_segtype_default", DEFAULT_MIRROR_SEGTYPE);
else if (arg_count(cmd, thin_ARG) || arg_count(cmd, thinpool_ARG))
segtype_str = "thin";
@@ -735,7 +739,7 @@ static int _lvcreate_params(struct lvcreate_params *lp,
lp->mirrors = 1;
- /* Default to 2 mirrored areas if '--type mirror|raid1' */
+ /* Default to 2 mirrored areas if '--type mirror|raid1|raid10' */
if (segtype_is_mirrored(lp->segtype))
lp->mirrors = 2;
@@ -748,6 +752,18 @@ static int _lvcreate_params(struct lvcreate_params *lp,
}
log_print("Redundant mirrors argument: default is 0");
}
+
+ if ((lp->mirrors > 2) && !strcmp(lp->segtype->name, "raid10")) {
+ /*
+ * FIXME: When RAID10 is no longer limited to
+ * 2-way mirror, 'lv_mirror_count()'
+ * must also change for RAID10.
+ */
+ log_error("RAID10 currently supports "
+ "only 2-way mirroring (i.e. '-m 1')");
+ return 0;
+ }
+
if (arg_sign_value(cmd, mirrors_ARG, SIGN_NONE) == SIGN_MINUS) {
log_error("Mirrors argument may not be negative");
return 0;
@@ -787,6 +803,16 @@ static int _lvcreate_params(struct lvcreate_params *lp,
log_error("%s: Required device-mapper target(s) not "
"detected in your kernel", lp->segtype->name);
return 0;
+ } else if (!strcmp(lp->segtype->name, "raid10")) {
+ uint32_t maj, min, patchlevel;
+ if (!target_version("raid", &maj, &min, &patchlevel)) {
+ log_error("Failed to determine version of RAID kernel module");
+ return 0;
+ }
+ if ((maj != 1) || (min < 3)) {
+ log_error("RAID module does not support RAID10");
+ return 0;
+ }
}
if (!_lvcreate_name_params(lp, cmd, &argc, &argv) ||
diff --git a/tools/lvresize.c b/tools/lvresize.c
index 64474e07..05041afd 100644
--- a/tools/lvresize.c
+++ b/tools/lvresize.c
@@ -578,6 +578,7 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
seg_mirrors = 0;
break;
}
+
if (!arg_count(cmd, mirrors_ARG) && seg_mirrors) {
log_print("Extending %" PRIu32 " mirror images.",
seg_mirrors);
@@ -588,18 +589,26 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
log_error("Cannot vary number of mirrors in LV yet.");
return EINVALID_CMD_LINE;
}
+
+ if (seg_mirrors && !strcmp(mirr_seg->segtype->name, "raid10")) {
+ lp->stripes = mirr_seg->area_count / seg_mirrors;
+ lp->stripe_size = mirr_seg->stripe_size;
+ }
}
/* If extending, find stripes, stripesize & size of last segment */
if ((lp->extents > lv->le_count) &&
- !(lp->stripes == 1 || (lp->stripes > 1 && lp->stripe_size))) {
+ !(lp->stripes == 1 || (lp->stripes > 1 && lp->stripe_size)) &&
+ strcmp(mirr_seg->segtype->name, "raid10")) {
/* FIXME Don't assume mirror seg will always be AREA_LV */
/* FIXME We will need to support resize for metadata LV as well,
* and data LV could be any type (i.e. mirror)) */
dm_list_iterate_items(seg, seg_mirrors ? &seg_lv(mirr_seg, 0)->segments :
lv_is_thin_pool(lv) ? &seg_lv(first_seg(lv), 0)->segments : &lv->segments) {
+ /* Allow through "striped" and RAID 4/5/6/10 */
if (!seg_is_striped(seg) &&
- (!seg_is_raid(seg) || seg_is_mirrored(seg)))
+ (!seg_is_raid(seg) || seg_is_mirrored(seg)) &&
+ strcmp(seg->segtype->name, "raid10"))
continue;
sz = seg->stripe_size;