diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/metadata/lv.c | 4 | ||||
-rw-r--r-- | lib/metadata/lv_manip.c | 8 | ||||
-rw-r--r-- | lib/metadata/mirror.c | 4 | ||||
-rw-r--r-- | lib/metadata/raid_manip.c | 18 | ||||
-rw-r--r-- | lib/raid/raid.c | 15 |
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, |