mirror of
git://sourceware.org/git/lvm2.git
synced 2025-02-01 09:47:48 +03:00
Fix new mirror_seg pointer.
This commit is contained in:
parent
5727a8fa85
commit
e6c20c6100
4
lib/cache/lvmcache.c
vendored
4
lib/cache/lvmcache.c
vendored
@ -512,6 +512,10 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
|
|||||||
"using dm %s", pvid,
|
"using dm %s", pvid,
|
||||||
dev_name(existing->dev),
|
dev_name(existing->dev),
|
||||||
dev_name(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
|
else
|
||||||
log_error("Found duplicate PV %s: using %s not "
|
log_error("Found duplicate PV %s: using %s not "
|
||||||
"%s", pvid, dev_name(dev),
|
"%s", pvid, dev_name(dev),
|
||||||
|
@ -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.
|
* Check there are no gaps or overlaps in the lv.
|
||||||
*/
|
*/
|
||||||
if (!check_lv_segments(lv)) {
|
if (!check_lv_segments(lv, 0)) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -757,6 +757,12 @@ static struct volume_group *_read_vg(struct format_instance *fid,
|
|||||||
goto bad;
|
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);
|
dm_hash_destroy(pv_hash);
|
||||||
|
|
||||||
if (vg->status & PARTIAL_VG) {
|
if (vg->status & PARTIAL_VG) {
|
||||||
|
@ -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;
|
area_multiple = segtype_is_striped(segtype) ? area_count : 1;
|
||||||
|
|
||||||
/* FIXME Shouldn't log_lv always be NULL here? */
|
/* log_lv gets set up elsehere */
|
||||||
/* (As we set up log segments elsewhere) */
|
|
||||||
|
|
||||||
if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv,
|
if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv,
|
||||||
lv->le_count,
|
lv->le_count,
|
||||||
aa[0].len * area_multiple,
|
aa[0].len * area_multiple,
|
||||||
status, stripe_size, log_lv,
|
status, stripe_size, NULL,
|
||||||
area_count + extra_areas,
|
area_count + extra_areas,
|
||||||
aa[0].len, 0u, region_size, 0u))) {
|
aa[0].len, 0u, region_size, 0u))) {
|
||||||
log_error("Couldn't allocate new LV segment.");
|
log_error("Couldn't allocate new LV segment.");
|
||||||
|
@ -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.
|
* 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;
|
uint32_t le = 0;
|
||||||
unsigned seg_count = 0;
|
unsigned seg_count = 0;
|
||||||
int r = 1;
|
int r = 1;
|
||||||
@ -85,7 +85,7 @@ int check_lv_segments(struct logical_volume *lv)
|
|||||||
r = 0;
|
r = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seg->log_lv) {
|
if (complete_vg && seg->log_lv) {
|
||||||
if (!seg_is_mirrored(seg)) {
|
if (!seg_is_mirrored(seg)) {
|
||||||
log_error("LV %s: segment %u has log LV but "
|
log_error("LV %s: segment %u has log LV but "
|
||||||
"is not mirrored",
|
"is not mirrored",
|
||||||
@ -100,8 +100,8 @@ int check_lv_segments(struct logical_volume *lv)
|
|||||||
r = 0;
|
r = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!find_seg_by_le(seg->log_lv, 0) ||
|
if (!(seg2 = find_seg_by_le(seg->log_lv, 0)) ||
|
||||||
find_seg_by_le(seg->log_lv, 0)->mirror_seg != seg) {
|
seg2->mirror_seg != seg) {
|
||||||
log_error("LV %s: segment %u log LV does not "
|
log_error("LV %s: segment %u log LV does not "
|
||||||
"point back to mirror segment",
|
"point back to mirror segment",
|
||||||
lv->name, seg_count);
|
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 ||
|
if (!seg->mirror_seg ||
|
||||||
!seg_is_mirrored(seg->mirror_seg)) {
|
!seg_is_mirrored(seg->mirror_seg)) {
|
||||||
log_error("LV %s: segment %u mirror image "
|
log_error("LV %s: segment %u mirror image "
|
||||||
@ -144,7 +144,7 @@ int check_lv_segments(struct logical_volume *lv)
|
|||||||
r = 0;
|
r = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seg_lv(seg, s) &&
|
if (complete_vg && seg_lv(seg, s) &&
|
||||||
(seg_lv(seg, s)->status & MIRROR_IMAGE) &&
|
(seg_lv(seg, s)->status & MIRROR_IMAGE) &&
|
||||||
(find_seg_by_le(seg_lv(seg, s),
|
(find_seg_by_le(seg_lv(seg, s),
|
||||||
seg_le(seg, s))->mirror_seg
|
seg_le(seg, s))->mirror_seg
|
||||||
|
@ -715,7 +715,7 @@ int vg_validate(struct volume_group *vg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
list_iterate_items(lvl, &vg->lvs) {
|
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.",
|
log_error("Internal error: LV segments corrupted in %s.",
|
||||||
lvl->lv->name);
|
lvl->lv->name);
|
||||||
return 0;
|
return 0;
|
||||||
@ -1076,7 +1076,7 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
list_iterate_items(lvl, &vg->lvs) {
|
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.",
|
log_error("Internal error: LV segments corrupted in %s.",
|
||||||
lvl->lv->name);
|
lvl->lv->name);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -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.
|
* 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
|
* 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
|
* Given mirror image or mirror log segment, find corresponding mirror segment
|
||||||
*/
|
*/
|
||||||
struct lv_segment *find_mirror_seg(struct lv_segment *seg);
|
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,
|
int insert_pvmove_mirrors(struct cmd_context *cmd,
|
||||||
struct logical_volume *lv_mirr,
|
struct logical_volume *lv_mirr,
|
||||||
|
@ -551,3 +551,29 @@ float copy_percent(struct logical_volume *lv_mirr)
|
|||||||
|
|
||||||
return denominator ? (float) numerator *100 / denominator : 100.0;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user