summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/metadata/lv.c4
-rw-r--r--lib/metadata/lv_manip.c8
-rw-r--r--lib/metadata/mirror.c4
-rw-r--r--lib/metadata/raid_manip.c18
-rw-r--r--lib/raid/raid.c15
5 files changed, 47 insertions, 2 deletions
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index bb6043d9..003e18d6 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -476,10 +476,10 @@ char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv)
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))
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 51abae0f..59e14291 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -710,6 +710,14 @@ static uint32_t _calc_area_multiple(const struct segment_type *segtype,
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;
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c
index ac885d6d..e3662c12 100644
--- a/lib/metadata/mirror.c
+++ b/lib/metadata/mirror.c
@@ -114,6 +114,10 @@ uint32_t lv_mirror_count(const struct logical_volume *lv)
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;
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index c86bb9a7..0d4640f5 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -1620,6 +1620,24 @@ int lv_raid_replace(struct logical_volume *lv,
raid_seg->segtype->parity_devs,
raid_seg->segtype->name, lv->vg->name, lv->name);
return 0;
+ } else if (!strcmp(raid_seg->segtype->name, "raid10")) {
+ uint32_t i, rebuilds_per_group = 0;
+ /* FIXME: We only support 2-way mirrors in RAID10 currently */
+ uint32_t copies = 2;
+
+ for (i = 0; i < raid_seg->area_count * copies; i++) {
+ s = i % raid_seg->area_count;
+ if (!(i % copies))
+ rebuilds_per_group = 0;
+ if (_lv_is_on_pvs(seg_lv(raid_seg, s), remove_pvs) ||
+ _lv_is_on_pvs(seg_metalv(raid_seg, s), remove_pvs))
+ rebuilds_per_group++;
+ if (rebuilds_per_group >= copies) {
+ log_error("Unable to replace all the devices "
+ "in a RAID10 mirror group.");
+ return 0;
+ }
+ }
}
/*
diff --git a/lib/raid/raid.c b/lib/raid/raid.c
index 097d36f4..78fe074e 100644
--- a/lib/raid/raid.c
+++ b/lib/raid/raid.c
@@ -379,6 +379,20 @@ static struct segment_type *_init_raid1_segtype(struct cmd_context *cmd)
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_context *cmd, struct segtype_library *segl
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,