From: Jonathan Brassow <jbrassow@redhat.com>
To: lvm-devel@redhat.com
Subject: [PATCH] First cut at RAID10 support
Date: Thu, 26 Jul 2012 17:20:45 -0500 [thread overview]
Message-ID: <1343341245.28351.2.camel@f16> (raw)
With this patch, I can create a RAID10 LV and increase it's size
(lvresize). I've not tested much beyond that. Man page updates are not
done yet either. Looking for early objections...
brassow
Index: lvm2/lib/raid/raid.c
===================================================================
--- lvm2.orig/lib/raid/raid.c
+++ lvm2/lib/raid/raid.c
@@ -379,6 +379,20 @@ static struct segment_type *_init_raid1_
return segtype;
}
+static struct segment_type *_init_raid10_segtype(struct cmd_context *cmd)
+{
+ struct segment_type *segtype;
+
+ segtype = _init_raid_segtype(cmd, "raid10");
+ if (!segtype)
+ return NULL;
+
+ segtype->flags |= SEG_AREAS_MIRRORED;
+ segtype->parity_devs = 0;
+
+ return segtype;
+}
+
static struct segment_type *_init_raid4_segtype(struct cmd_context *cmd)
{
return _init_raid_segtype(cmd, "raid4");
@@ -441,6 +455,7 @@ int init_multiple_segtypes(struct cmd_co
unsigned i = 0;
struct segment_type *(*raid_segtype_fn[])(struct cmd_context *) = {
_init_raid1_segtype,
+ _init_raid10_segtype,
_init_raid4_segtype,
_init_raid5_segtype,
_init_raid5_la_segtype,
Index: lvm2/tools/lvcreate.c
===================================================================
--- lvm2.orig/tools/lvcreate.c
+++ lvm2/tools/lvcreate.c
@@ -679,7 +679,12 @@ static int _lvcreate_params(struct lvcre
/* Set default segtype */
if (arg_count(cmd, mirrors_ARG))
- segtype_str = find_config_tree_str(cmd, "global/mirror_segtype_default", DEFAULT_MIRROR_SEGTYPE);
+ if (arg_uint_value(cmd, arg_count(cmd, stripes_long_ARG) ?
+ stripes_long_ARG : stripes_ARG, 1) > 1) {
+ segtype_str = "raid10";
+ } else {
+ 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";
else
@@ -712,7 +717,7 @@ static int _lvcreate_params(struct lvcre
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;
@@ -725,6 +730,18 @@ static int _lvcreate_params(struct lvcre
}
log_print("Redundant mirrors argument: default is 0");
}
+
+ if ((lp->mirrors > 2) && !strcmp(lp->segtype->name, "raid10")) {
+ /*
+ * FIXME: When this 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;
@@ -764,6 +781,16 @@ static int _lvcreate_params(struct lvcre
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) ||
Index: lvm2/libdm/libdm-deptree.c
===================================================================
--- lvm2.orig/libdm/libdm-deptree.c
+++ lvm2/libdm/libdm-deptree.c
@@ -42,6 +42,7 @@ enum {
SEG_THIN_POOL,
SEG_THIN,
SEG_RAID1,
+ SEG_RAID10,
SEG_RAID4,
SEG_RAID5_LA,
SEG_RAID5_RA,
@@ -73,6 +74,7 @@ struct {
{ SEG_THIN_POOL, "thin-pool"},
{ SEG_THIN, "thin"},
{ SEG_RAID1, "raid1"},
+ { SEG_RAID10, "raid10"},
{ SEG_RAID4, "raid4"},
{ SEG_RAID5_LA, "raid5_la"},
{ SEG_RAID5_RA, "raid5_ra"},
@@ -1913,6 +1915,7 @@ static int _emit_areas_line(struct dm_ta
}
break;
case SEG_RAID1:
+ case SEG_RAID10:
case SEG_RAID4:
case SEG_RAID5_LA:
case SEG_RAID5_RA:
@@ -2266,6 +2269,7 @@ static int _emit_segment_line(struct dm_
seg->iv_offset : *seg_start);
break;
case SEG_RAID1:
+ case SEG_RAID10:
case SEG_RAID4:
case SEG_RAID5_LA:
case SEG_RAID5_RA:
Index: lvm2/lib/metadata/lv.c
===================================================================
--- lvm2.orig/lib/metadata/lv.c
+++ lvm2/lib/metadata/lv.c
@@ -477,10 +477,10 @@ char *lv_attr_dup(struct dm_pool *mem, c
if (lv_is_thin_type(lv))
repstr[6] = 't';
- else if (lv_is_mirror_type(lv))
- repstr[6] = 'm';
else if (lv_is_raid_type(lv))
repstr[6] = 'r';
+ else if (lv_is_mirror_type(lv))
+ repstr[6] = 'm';
else if (lv_is_cow(lv) || lv_is_origin(lv))
repstr[6] = 's';
else if (lv_has_unknown_segments(lv))
Index: lvm2/lib/metadata/lv_manip.c
===================================================================
--- lvm2.orig/lib/metadata/lv_manip.c
+++ lvm2/lib/metadata/lv_manip.c
@@ -710,6 +710,14 @@ static uint32_t _calc_area_multiple(cons
return area_count - segtype->parity_devs;
}
+ /* RAID10 - only has 2-way mirror right now */
+ if (!strcmp(segtype->name, "raid10")) {
+ // FIXME: I'd like the 'stripes' arg always given
+ if (!stripes)
+ return area_count / 2;
+ return stripes;
+ }
+
/* Mirrored stripes */
if (stripes)
return stripes;
Index: lvm2/lib/metadata/mirror.c
===================================================================
--- lvm2.orig/lib/metadata/mirror.c
+++ lvm2/lib/metadata/mirror.c
@@ -115,6 +115,10 @@ uint32_t lv_mirror_count(const struct lo
seg = first_seg(lv);
+ /* FIXME: RAID10 only supports 2 copies right now */
+ if (!strcmp(seg->segtype->name, "raid10"))
+ return 2;
+
if (lv->status & PVMOVE)
return seg->area_count;
Index: lvm2/tools/lvresize.c
===================================================================
--- lvm2.orig/tools/lvresize.c
+++ lvm2/tools/lvresize.c
@@ -578,6 +578,7 @@ static int _lvresize(struct cmd_context
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
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;
reply other threads:[~2012-07-26 22:20 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1343341245.28351.2.camel@f16 \
--to=jbrassow@redhat.com \
--cc=lvm-devel@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.