From 5727a8fa858c086e5785ca94cdc8249e8caa7bdd Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Thu, 27 Oct 2005 19:58:22 +0000 Subject: [PATCH] Add mirror_seg pointer to lv_segment struct. (incomplete & untested) --- WHATS_NEW | 1 + lib/activate/dev_manager.c | 1 + lib/metadata/lv_manip.c | 12 ++++++++-- lib/metadata/merge.c | 46 ++++++++++++++++++++++++++++++++++++++ lib/metadata/metadata.h | 5 +++++ lib/metadata/mirror.c | 11 ++++++--- 6 files changed, 71 insertions(+), 5 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index 51cd7970e..ec79ede85 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.00 - =================================== + Add mirror_seg pointer to lv_segment struct. Only keep a device open if it's known to belong to a locked VG. Fix lvdisplay to show all mirror destinations. Replacement suspend code using libdevmapper dependency tree. diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c index a03b941d2..a41c18cc8 100644 --- a/lib/activate/dev_manager.c +++ b/lib/activate/dev_manager.c @@ -2164,6 +2164,7 @@ static int _fill_in_active_list(struct dev_manager *dm, struct volume_group *vg) static int _action_activate(struct dev_manager *dm, struct logical_volume *lv) { + // Replace with deptree code for lv + known deps only. if (!_scan_existing_devices(dm)) { stack; return 0; diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c index c7f9c807f..5f16ef2ec 100644 --- a/lib/metadata/lv_manip.c +++ b/lib/metadata/lv_manip.c @@ -97,10 +97,13 @@ struct lv_segment *alloc_lv_segment(struct dm_pool *mem, seg->region_size = region_size; seg->extents_copied = extents_copied; seg->log_lv = log_lv; + seg->mirror_seg = NULL; list_init(&seg->tags); - if (log_lv) + if (log_lv) { log_lv->status |= MIRROR_LOG; + find_seg_by_le(log_lv, 0)->mirror_seg = seg; + } return seg; } @@ -485,6 +488,9 @@ 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) */ + if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv, lv->le_count, aa[0].len * area_multiple, @@ -1059,8 +1065,10 @@ int lv_add_mirror_segment(struct alloc_handle *ah, return 0; } - for (m = 0; m < mirrors; m++) + for (m = 0; m < mirrors; m++) { set_lv_segment_area_lv(seg, m, sub_lvs[m], 0, MIRROR_IMAGE); + find_seg_by_le(sub_lvs[m], 0)->mirror_seg = seg; + } list_add(&lv->segments, &seg->list); lv->le_count += ah->total_area_len; diff --git a/lib/metadata/merge.c b/lib/metadata/merge.c index 0e0c6d544..a456a1a3f 100644 --- a/lib/metadata/merge.c +++ b/lib/metadata/merge.c @@ -85,6 +85,40 @@ int check_lv_segments(struct logical_volume *lv) r = 0; } + if (seg->log_lv) { + if (!seg_is_mirrored(seg)) { + log_error("LV %s: segment %u has log LV but " + "is not mirrored", + lv->name, seg_count); + r = 0; + } + + if (!(seg->log_lv->status & MIRROR_LOG)) { + log_error("LV %s: segment %u log LV %s is not " + "a mirror log", + lv->name, seg_count, seg->log_lv->name); + r = 0; + } + + if (!find_seg_by_le(seg->log_lv, 0) || + find_seg_by_le(seg->log_lv, 0)->mirror_seg != seg) { + log_error("LV %s: segment %u log LV does not " + "point back to mirror segment", + lv->name, seg_count); + r = 0; + } + } + + if (seg->status & MIRROR_IMAGE) { + if (!seg->mirror_seg || + !seg_is_mirrored(seg->mirror_seg)) { + log_error("LV %s: segment %u mirror image " + "is not mirrored", + lv->name, seg_count); + r = 0; + } + } + for (s = 0; s < seg->area_count; s++) { if (seg_type(seg, s) == AREA_UNASSIGNED) { log_error("LV %s: segment %u has unassigned " @@ -109,6 +143,18 @@ int check_lv_segments(struct logical_volume *lv) lv->name, seg_count, s); r = 0; } + + if (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 + != seg)) { + log_error("LV %s: segment %u mirror " + "image %u missing mirror ptr", + lv->name, seg_count, s); + r = 0; + } + /* FIXME I don't think this ever holds? if (seg_le(seg, s) != le) { log_error("LV %s: segment %u has " diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h index 7eaa231ad..1425136c1 100644 --- a/lib/metadata/metadata.h +++ b/lib/metadata/metadata.h @@ -251,6 +251,7 @@ struct lv_segment { uint32_t region_size; /* For mirrors - in sectors */ uint32_t extents_copied; struct logical_volume *log_lv; + struct lv_segment *mirror_seg; struct list tags; @@ -559,6 +560,10 @@ int create_mirror_layers(struct alloc_handle *ah, struct logical_volume *log_lv); int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors); 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 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 4952393e4..bc292f652 100644 --- a/lib/metadata/mirror.c +++ b/lib/metadata/mirror.c @@ -22,6 +22,11 @@ #include "lv_alloc.h" #include "lvm-string.h" +struct lv_segment *find_mirror_seg(struct lv_segment *seg) +{ + return seg->mirror_seg; +} + /* * Ensure region size is compatible with volume size. */ @@ -149,8 +154,8 @@ int create_mirror_layers(struct alloc_handle *ah, for (m = 0; m < num_mirrors; m++) { if (!(img_lvs[m] = lv_create_empty(lv->vg->fid, img_name, NULL, LVM_READ | LVM_WRITE, - ALLOC_INHERIT, 0, lv->vg))) {\ - log_error("Aborting. Failed to create submirror LV. " + ALLOC_INHERIT, 0, lv->vg))) { + log_error("Aborting. Failed to create mirror image LV. " "Remove new LV and retry."); return 0; } @@ -159,7 +164,7 @@ int create_mirror_layers(struct alloc_handle *ah, get_segtype_from_string(lv->vg->cmd, "striped"), 0, NULL, 0, 0, 0, NULL)) { - log_error("Aborting. Failed to add submirror segment " + log_error("Aborting. Failed to add mirror image segment " "to %s. Remove new LV and retry.", img_lvs[m]->name); return 0;