From e6c20c610068029708be652a0640d15d4ef5e7d8 Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Thu, 27 Oct 2005 21:51:28 +0000 Subject: [PATCH] Fix new mirror_seg pointer. --- lib/cache/lvmcache.c | 4 ++++ lib/format_text/import_vsn1.c | 8 +++++++- lib/metadata/lv_manip.c | 6 ++---- lib/metadata/merge.c | 14 +++++++------- lib/metadata/metadata.c | 4 ++-- lib/metadata/metadata.h | 4 +++- lib/metadata/mirror.c | 26 ++++++++++++++++++++++++++ 7 files changed, 51 insertions(+), 15 deletions(-) diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c index 654ac2561..4ac298be3 100644 --- a/lib/cache/lvmcache.c +++ b/lib/cache/lvmcache.c @@ -512,6 +512,10 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid, "using dm %s", pvid, dev_name(existing->dev), dev_name(dev)); + /* FIXME If both dm, check dependencies */ + //else if (dm_is_dm_major(MAJOR(existing->dev->dev)) && + //dm_is_dm_major(MAJOR(dev->dev))) + // else log_error("Found duplicate PV %s: using %s not " "%s", pvid, dev_name(dev), diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c index a70dfe29d..14d9abf3f 100644 --- a/lib/format_text/import_vsn1.c +++ b/lib/format_text/import_vsn1.c @@ -428,7 +428,7 @@ static int _read_segments(struct dm_pool *mem, struct volume_group *vg, /* * Check there are no gaps or overlaps in the lv. */ - if (!check_lv_segments(lv)) { + if (!check_lv_segments(lv, 0)) { stack; return 0; } @@ -757,6 +757,12 @@ static struct volume_group *_read_vg(struct format_instance *fid, goto bad; } + if (!fixup_imported_mirrors(vg)) { + log_error("Failed to fixup mirror pointers after import for " + "volume group %s.", vg->name); + goto bad; + } + dm_hash_destroy(pv_hash); if (vg->status & PARTIAL_VG) { diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c index 5f16ef2ec..d96c77475 100644 --- a/lib/metadata/lv_manip.c +++ b/lib/metadata/lv_manip.c @@ -488,13 +488,11 @@ static int _setup_alloced_segment(struct logical_volume *lv, uint32_t status, area_multiple = segtype_is_striped(segtype) ? area_count : 1; - /* FIXME Shouldn't log_lv always be NULL here? */ - /* (As we set up log segments elsewhere) */ - + /* log_lv gets set up elsehere */ if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv, lv->le_count, aa[0].len * area_multiple, - status, stripe_size, log_lv, + status, stripe_size, NULL, area_count + extra_areas, aa[0].len, 0u, region_size, 0u))) { log_error("Couldn't allocate new LV segment."); diff --git a/lib/metadata/merge.c b/lib/metadata/merge.c index a456a1a3f..f861c5288 100644 --- a/lib/metadata/merge.c +++ b/lib/metadata/merge.c @@ -58,9 +58,9 @@ int lv_merge_segments(struct logical_volume *lv) /* * Verify that an LV's segments are consecutive, complete and don't overlap. */ -int check_lv_segments(struct logical_volume *lv) +int check_lv_segments(struct logical_volume *lv, int complete_vg) { - struct lv_segment *seg; + struct lv_segment *seg, *seg2; uint32_t le = 0; unsigned seg_count = 0; int r = 1; @@ -85,7 +85,7 @@ int check_lv_segments(struct logical_volume *lv) r = 0; } - if (seg->log_lv) { + if (complete_vg && seg->log_lv) { if (!seg_is_mirrored(seg)) { log_error("LV %s: segment %u has log LV but " "is not mirrored", @@ -100,8 +100,8 @@ int check_lv_segments(struct logical_volume *lv) r = 0; } - if (!find_seg_by_le(seg->log_lv, 0) || - find_seg_by_le(seg->log_lv, 0)->mirror_seg != seg) { + if (!(seg2 = find_seg_by_le(seg->log_lv, 0)) || + seg2->mirror_seg != seg) { log_error("LV %s: segment %u log LV does not " "point back to mirror segment", lv->name, seg_count); @@ -109,7 +109,7 @@ int check_lv_segments(struct logical_volume *lv) } } - if (seg->status & MIRROR_IMAGE) { + if (complete_vg && seg->status & MIRROR_IMAGE) { if (!seg->mirror_seg || !seg_is_mirrored(seg->mirror_seg)) { log_error("LV %s: segment %u mirror image " @@ -144,7 +144,7 @@ int check_lv_segments(struct logical_volume *lv) r = 0; } - if (seg_lv(seg, s) && + if (complete_vg && seg_lv(seg, s) && (seg_lv(seg, s)->status & MIRROR_IMAGE) && (find_seg_by_le(seg_lv(seg, s), seg_le(seg, s))->mirror_seg diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c index d68071945..c44d56ff7 100644 --- a/lib/metadata/metadata.c +++ b/lib/metadata/metadata.c @@ -715,7 +715,7 @@ int vg_validate(struct volume_group *vg) } list_iterate_items(lvl, &vg->lvs) { - if (!check_lv_segments(lvl->lv)) { + if (!check_lv_segments(lvl->lv, 1)) { log_error("Internal error: LV segments corrupted in %s.", lvl->lv->name); return 0; @@ -1076,7 +1076,7 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname, } list_iterate_items(lvl, &vg->lvs) { - if (!check_lv_segments(lvl->lv)) { + if (!check_lv_segments(lvl->lv, 1)) { log_error("Internal error: LV segments corrupted in %s.", lvl->lv->name); return NULL; diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h index 1425136c1..233729bce 100644 --- a/lib/metadata/metadata.h +++ b/lib/metadata/metadata.h @@ -512,8 +512,9 @@ const char *strip_dir(const char *vg_name, const char *dir); /* * Checks that an lv has no gaps or overlapping segments. + * Set complete_vg to perform additional VG level checks. */ -int check_lv_segments(struct logical_volume *lv); +int check_lv_segments(struct logical_volume *lv, int complete_vg); /* * Sometimes (eg, after an lvextend), it is possible to merge two @@ -564,6 +565,7 @@ int remove_all_mirror_images(struct logical_volume *lv); * Given mirror image or mirror log segment, find corresponding mirror segment */ struct lv_segment *find_mirror_seg(struct lv_segment *seg); +int fixup_imported_mirrors(struct volume_group *vg); int insert_pvmove_mirrors(struct cmd_context *cmd, struct logical_volume *lv_mirr, diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c index bc292f652..f48b808f4 100644 --- a/lib/metadata/mirror.c +++ b/lib/metadata/mirror.c @@ -551,3 +551,29 @@ float copy_percent(struct logical_volume *lv_mirr) return denominator ? (float) numerator *100 / denominator : 100.0; } + +/* + * Fixup mirror pointers after single-pass segment import + */ +int fixup_imported_mirrors(struct volume_group *vg) +{ + struct lv_list *lvl; + struct lv_segment *seg; + uint32_t s; + + list_iterate_items(lvl, &vg->lvs) { + list_iterate_items(seg, &lvl->lv->segments) { + if (seg->segtype != + get_segtype_from_string(vg->cmd, "mirror")) + continue; + + if (seg->log_lv) + find_seg_by_le(seg->log_lv, 0)->mirror_seg = seg; + for (s = 0; s < seg->area_count; s++) + if (seg_type(seg, s) == AREA_LV) + find_seg_by_le(seg_lv(seg, s), 0)-> + mirror_seg = seg; + } + } +} +