This is an experience generating task; and not necessarily something that must go into the LVM tree. We currently have two DM targets that perform mirroring. We have been moving away from dm-raid1.c ('mirror' segment type) use in favor of dm-raid.c ('raid1'), such that it is the default for any new mirror LV in LVM. The 'pvmove' command still utilizes the 'mirror' segment type. As a POC, it would be nice to see if we could remove all dependencies on the 'mirror' segment type.
From 8947a65f109bed50640fbf02aae95aa0ee385e51 Mon Sep 17 00:00:00 2001 From: Nigel Croxon <ncroxon> Date: Thu, 21 Oct 2021 14:49:10 -0400 Subject: [PATCH] My version of pvmove using mirror or raid1 based on lvm.conf Signed-off-by: Nigel Croxon <ncroxon> --- lib/metadata/lv_manip.c | 15 ++++++++++----- lib/metadata/mirror.c | 5 ++++- tools/pvmove.c | 21 ++++++++++++++++----- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c index 003748d6f..6553504bf 100644 --- a/lib/metadata/lv_manip.c +++ b/lib/metadata/lv_manip.c @@ -3872,9 +3872,10 @@ int lv_add_segment(struct alloc_handle *ah, * So, when adding mirrors to linear LV segment, first split it, * then convert it to "mirror" and add areas. */ -static struct lv_segment *_convert_seg_to_mirror(struct lv_segment *seg, +static struct lv_segment *_convert_seg_to_mirror_or_raid1(struct lv_segment *seg, uint32_t region_size, - struct logical_volume *log_lv) + struct logical_volume *log_lv, + struct segment_type *segtype) { struct lv_segment *newseg; uint32_t s; @@ -3890,7 +3891,7 @@ static struct lv_segment *_convert_seg_to_mirror(struct lv_segment *seg, return NULL; } - if (!(newseg = alloc_lv_segment(get_segtype_from_string(seg->lv->vg->cmd, SEG_TYPE_NAME_MIRROR), + if (!(newseg = alloc_lv_segment(segtype, seg->lv, seg->le, seg->len, 0, seg->status, seg->stripe_size, log_lv, @@ -4034,6 +4035,7 @@ int lv_add_mirror_areas(struct alloc_handle *ah, struct lv_segment *seg; uint32_t current_le = le; uint32_t s, old_area_count, new_area_count; + struct segment_type *segtype; dm_list_iterate_items(aa, &ah->alloced_areas[0]) { if (!(seg = find_seg_by_le(lv, current_le))) { @@ -4051,8 +4053,11 @@ int lv_add_mirror_areas(struct alloc_handle *ah, } } + segtype = get_segtype_from_string(lv->vg->cmd, SEG_TYPE_NAME_MIRROR); + if (!seg_is_mirrored(seg) && - (!(seg = _convert_seg_to_mirror(seg, region_size, NULL)))) + (!(seg = _convert_seg_to_mirror_or_raid1(seg, region_size, + NULL, segtype)))) return_0; old_area_count = seg->area_count; @@ -4099,7 +4104,7 @@ int lv_add_mirror_lvs(struct logical_volume *lv, mirror_segtype = get_segtype_from_string(lv->vg->cmd, SEG_TYPE_NAME_MIRROR); if (seg->segtype != mirror_segtype) - if (!(seg = _convert_seg_to_mirror(seg, region_size, NULL))) + if (!(seg = _convert_seg_to_mirror_or_raid1(seg, region_size, NULL, mirror_segtype))) return_0; if (region_size && region_size != seg->region_size) { diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c index e2bf191a1..32827b403 100644 --- a/lib/metadata/mirror.c +++ b/lib/metadata/mirror.c @@ -1386,11 +1386,14 @@ static int _add_mirrors_that_preserve_segments(struct logical_volume *lv, struct dm_list *parallel_areas; uint32_t adjusted_region_size; int r = 1; + const char *segtype_str; + int pvmove_default_cfg = global_mirror_segtype_default_CFG; if (!(parallel_areas = build_parallel_areas_from_lv(lv, 1, 0))) return_0; - if (!(segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_MIRROR))) + segtype_str = find_config_tree_str(cmd, pvmove_default_cfg, NULL); + if (!(segtype = get_segtype_from_string(cmd, segtype_str))) return_0; if (!(adjusted_region_size = adjusted_mirror_region_size(cmd, diff --git a/tools/pvmove.c b/tools/pvmove.c index ed92f3ce4..7c0a228b5 100644 --- a/tools/pvmove.c +++ b/tools/pvmove.c @@ -41,9 +41,11 @@ static int _pvmove_target_present(struct cmd_context *cmd, int clustered) { const struct segment_type *segtype; int found = 1; - - if (!(segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_MIRROR))) - return_0; + const char *segtype_str; + int pvmove_default_cfg = global_mirror_segtype_default_CFG; + + segtype_str = find_config_tree_str(cmd, pvmove_default_cfg, NULL); + segtype = get_segtype_from_string(cmd, segtype_str); if (activation() && segtype->ops->target_present && !segtype->ops->target_present(cmd, NULL, NULL)) @@ -327,6 +329,10 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd, int needs_exclusive = *exclusive; const struct logical_volume *holder; const char *new_lv_name; + const char *segtype_str; + int pvmove_default_cfg = global_mirror_segtype_default_CFG; + const char *raid1_str = "raid1"; + int segment; /* FIXME Cope with non-contiguous => splitting existing segments */ if (!(lv_mirr = lv_create_empty("pvmove%d", NULL, @@ -519,11 +525,16 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd, return NULL; } + segtype_str = find_config_tree_str(cmd, pvmove_default_cfg, NULL); + if (!strcmp(segtype_str, raid1_str )) + segment = MIRROR_BY_SEGMENTED_LV; + else + segment = MIRROR_BY_SEG; + if (!lv_add_mirrors(cmd, lv_mirr, 1, 1, 0, get_default_region_size(cmd), log_count, allocatable_pvs, alloc, - (arg_is_set(cmd, atomic_ARG)) ? - MIRROR_BY_SEGMENTED_LV : MIRROR_BY_SEG)) { + segment)) { log_error("Failed to convert pvmove LV to mirrored."); return NULL; } -- 2.27.0
One of the requirements here will be that the RAID1 segment type used does not use any on-disk metadata areas (no bitmaps, superblock, etc). dm-raid accepts this table configuration by specifying a '-' instead of a device for the metadata area.