mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
lvmcache: Invalidate cached VG if PV is orphaned.
If a PV in an existing VG becomes orphaned (with 'pvcreate -ff', for
example) the VG struct cached against its vginfo must be invalidated.
This is because the struct device it references no longer contains
the PV label so becomes incorrect.
This triggers the error:
Internal error: PV $dev unexpectedly not in cache.
when the PV from the cached VG metadata is subsequently looked up
in the cache.
Bug introduced in 2.02.87 by commit 7ad0d47c3c
("Cache and share generated VG structs").
Before:
lvm> pvs
PV VG Fmt Attr PSize PFree
/dev/loop3 vg12 lvm2 a-- 28.00m 28.00m
/dev/loop4 vg12 lvm2 a-- 28.00m 28.00m
lvm> pvcreate -ff /dev/loop3
Really INITIALIZE physical volume "/dev/loop3" of volume group "vg12" [y/n]? y
WARNING: Forcing physical volume creation on /dev/loop3 of volume group "vg12"
Physical volume "/dev/loop3" successfully created
lvm> pvs
Internal error: PV /dev/loop3 unexpectedly not in cache.
PV VG Fmt Attr PSize PFree
/dev/loop3 vg12 lvm2 a-- 28.00m 28.00m
/dev/loop3 lvm2 a-- 32.00m 32.00m
/dev/loop4 vg12 lvm2 a-- 28.00m 28.00m
After:
lvm> pvs
PV VG Fmt Attr PSize PFree
/dev/loop3 vg12 lvm2 a-- 28.00m 28.00m
/dev/loop4 vg12 lvm2 a-- 28.00m 28.00m
lvm> pvcreate -ff /dev/loop3
Really INITIALIZE physical volume "/dev/loop3" of volume group "vg12" [y/n]? y
WARNING: Forcing physical volume creation on /dev/loop3 of volume group "vg12"
Physical volume "/dev/loop3" successfully created
lvm> pvs
PV VG Fmt Attr PSize PFree
/dev/loop3 lvm2 a-- 32.00m 32.00m
/dev/loop4 vg12 lvm2 a-- 28.00m 28.00m
unknown device vg12 lvm2 a-m 28.00m 28.00m
This commit is contained in:
parent
9c445f3c2c
commit
4c2b4c37e7
@ -1,5 +1,7 @@
|
|||||||
Version 2.02.105 -
|
Version 2.02.105 -
|
||||||
=====================================
|
=====================================
|
||||||
|
Invalidate cached VG struct after a PV in it gets orphaned. (2.02.87)
|
||||||
|
Mark pool format metadata as FMT_OBSOLETE.
|
||||||
Use major:minor in lvm2-pvscan@.service for proper global_filter application.
|
Use major:minor in lvm2-pvscan@.service for proper global_filter application.
|
||||||
Syntax and spelling fixes in some man pages.
|
Syntax and spelling fixes in some man pages.
|
||||||
Dependency scan counts with snapshots and external origins.
|
Dependency scan counts with snapshots and external origins.
|
||||||
|
12
lib/cache/lvmcache.c
vendored
12
lib/cache/lvmcache.c
vendored
@ -64,6 +64,7 @@ struct lvmcache_vginfo {
|
|||||||
unsigned holders;
|
unsigned holders;
|
||||||
unsigned vg_use_count; /* Counter of vg reusage */
|
unsigned vg_use_count; /* Counter of vg reusage */
|
||||||
unsigned precommitted; /* Is vgmetadata live or precommitted? */
|
unsigned precommitted; /* Is vgmetadata live or precommitted? */
|
||||||
|
unsigned cached_vg_invalidated; /* Signal to regenerate cached_vg */
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct dm_hash_table *_pvid_hash = NULL;
|
static struct dm_hash_table *_pvid_hash = NULL;
|
||||||
@ -763,9 +764,11 @@ struct volume_group *lvmcache_get_vg(struct cmd_context *cmd, const char *vgname
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Use already-cached VG struct when available */
|
/* Use already-cached VG struct when available */
|
||||||
if ((vg = vginfo->cached_vg))
|
if ((vg = vginfo->cached_vg) && !vginfo->cached_vg_invalidated)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
release_vg(vginfo->cached_vg);
|
||||||
|
|
||||||
fic.type = FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
|
fic.type = FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
|
||||||
fic.context.vg_ref.vg_name = vginfo->vgname;
|
fic.context.vg_ref.vg_name = vginfo->vgname;
|
||||||
fic.context.vg_ref.vg_id = vgid;
|
fic.context.vg_ref.vg_id = vgid;
|
||||||
@ -785,6 +788,7 @@ struct volume_group *lvmcache_get_vg(struct cmd_context *cmd, const char *vgname
|
|||||||
vginfo->cached_vg = vg;
|
vginfo->cached_vg = vg;
|
||||||
vginfo->holders = 1;
|
vginfo->holders = 1;
|
||||||
vginfo->vg_use_count = 0;
|
vginfo->vg_use_count = 0;
|
||||||
|
vginfo->cached_vg_invalidated = 0;
|
||||||
vg->vginfo = vginfo;
|
vg->vginfo = vginfo;
|
||||||
|
|
||||||
if (!dm_pool_lock(vg->vgmem, detect_internal_vg_cache_corruption()))
|
if (!dm_pool_lock(vg->vgmem, detect_internal_vg_cache_corruption()))
|
||||||
@ -1407,6 +1411,12 @@ int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
|
|||||||
!is_orphan_vg(info->vginfo->vgname) && critical_section())
|
!is_orphan_vg(info->vginfo->vgname) && critical_section())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
/* If making a PV into an orphan, any cached VG metadata may become
|
||||||
|
* invalid, incorrectly still referencing device structs.
|
||||||
|
* (Example: pvcreate -ff) */
|
||||||
|
if (is_orphan_vg(vgname) && info->vginfo && !is_orphan_vg(info->vginfo->vgname))
|
||||||
|
info->vginfo->cached_vg_invalidated = 1;
|
||||||
|
|
||||||
/* If moving PV from orphan to real VG, always mark it valid */
|
/* If moving PV from orphan to real VG, always mark it valid */
|
||||||
if (!is_orphan_vg(vgname))
|
if (!is_orphan_vg(vgname))
|
||||||
info->status &= ~CACHE_INVALID;
|
info->status &= ~CACHE_INVALID;
|
||||||
|
Loading…
Reference in New Issue
Block a user