1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

Add some basic internal VG lock validation.

This commit is contained in:
Alasdair Kergon 2008-04-03 18:56:40 +00:00
parent c6cb6ddfb2
commit 906935e580
3 changed files with 31 additions and 4 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.34 - Version 2.02.34 -
=================================== ===================================
Add some basic internal VG lock validation.
Add per-command flags to control which commands use the VG metadata cache. Add per-command flags to control which commands use the VG metadata cache.
Fix vgsplit locking of new VG (2.02.30). Fix vgsplit locking of new VG (2.02.30).
Avoid erroneous vgsplit error message for new VG. (2.02.29) Avoid erroneous vgsplit error message for new VG. (2.02.29)

32
lib/cache/lvmcache.c vendored
View File

@ -17,6 +17,7 @@
#include "lvmcache.h" #include "lvmcache.h"
#include "toolcontext.h" #include "toolcontext.h"
#include "dev-cache.h" #include "dev-cache.h"
#include "locking.h"
#include "metadata.h" #include "metadata.h"
#include "filter.h" #include "filter.h"
#include "memlock.h" #include "memlock.h"
@ -29,6 +30,7 @@ static struct dm_hash_table *_lock_hash = NULL;
static struct list _vginfos; static struct list _vginfos;
static int _has_scanned = 0; static int _has_scanned = 0;
static int _vgs_locked = 0; static int _vgs_locked = 0;
static int _vg_global_lock_held = 0; /* Global lock held when cache wiped? */
int lvmcache_init(void) int lvmcache_init(void)
{ {
@ -46,6 +48,9 @@ int lvmcache_init(void)
if (!(_lock_hash = dm_hash_create(128))) if (!(_lock_hash = dm_hash_create(128)))
return 0; return 0;
if (_vg_global_lock_held)
lvmcache_lock_vgname(VG_GLOBAL, 0);
return 1; return 1;
} }
@ -134,6 +139,10 @@ void lvmcache_lock_vgname(const char *vgname, int read_only __attribute((unused)
return; return;
} }
if (dm_hash_lookup(_lock_hash, vgname))
log_error("Internal error: Nested locking attempted on VG %s.",
vgname);
if (!dm_hash_insert(_lock_hash, vgname, (void *) 1)) if (!dm_hash_insert(_lock_hash, vgname, (void *) 1))
log_error("Cache locking failure for %s", vgname); log_error("Cache locking failure for %s", vgname);
@ -152,6 +161,10 @@ int vgname_is_locked(const char *vgname)
void lvmcache_unlock_vgname(const char *vgname) void lvmcache_unlock_vgname(const char *vgname)
{ {
if (!dm_hash_lookup(_lock_hash, vgname))
log_error("Internal error: Attempt to unlock unlocked VG %s.",
vgname);
_update_cache_lock_state(vgname, 0); _update_cache_lock_state(vgname, 0);
dm_hash_remove(_lock_hash, vgname); dm_hash_remove(_lock_hash, vgname);
@ -1007,13 +1020,25 @@ static void _lvmcache_destroy_vgnamelist(struct lvmcache_vginfo *vginfo)
} while ((vginfo = next)); } while ((vginfo = next));
} }
static void _lvmcache_destroy_lockname(int present __attribute((unused))) static void _lvmcache_destroy_lockname(struct dm_hash_node *n)
{ {
/* Nothing to do */ char *vgname;
if (!dm_hash_get_data(_lock_hash, n))
return;
vgname = dm_hash_get_key(_lock_hash, n);
if (!strcmp(vgname, VG_GLOBAL))
_vg_global_lock_held = 1;
else
log_error("Internal error: Volume Group %s was not unlocked",
dm_hash_get_key(_lock_hash, n));
} }
void lvmcache_destroy(void) void lvmcache_destroy(void)
{ {
struct dm_hash_node *n;
log_verbose("Wiping internal VG cache"); log_verbose("Wiping internal VG cache");
_has_scanned = 0; _has_scanned = 0;
@ -1037,7 +1062,8 @@ void lvmcache_destroy(void)
} }
if (_lock_hash) { if (_lock_hash) {
dm_hash_iter(_lock_hash, (dm_hash_iterate_fn) _lvmcache_destroy_lockname); dm_hash_iterate(n, _lock_hash)
_lvmcache_destroy_lockname(n);
dm_hash_destroy(_lock_hash); dm_hash_destroy(_lock_hash);
_lock_hash = NULL; _lock_hash = NULL;
} }

View File

@ -221,7 +221,7 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
"%s/V_%s", _lock_dir, resource); "%s/V_%s", _lock_dir, resource);
if (!_lock_file(lockfile, flags)) if (!_lock_file(lockfile, flags))
return 0; return_0;
switch (flags & LCK_TYPE_MASK) { switch (flags & LCK_TYPE_MASK) {
case LCK_UNLOCK: case LCK_UNLOCK: