diff options
author | Zdenek Kabelac <zkabelac@redhat.com> | 2012-12-14 16:35:26 +0100 |
---|---|---|
committer | Zdenek Kabelac <zkabelac@redhat.com> | 2012-12-15 17:23:26 +0100 |
commit | a4269aadf320f36d3d6fa3a3b66dda98855e7bc3 (patch) | |
tree | e66cf6ce7c8c3e327c389bb31921a87d1c1a15a9 /daemons | |
parent | 788ac7fa547fb98f0edd38685d40b80609f298dc (diff) | |
download | lvm2-a4269aadf320f36d3d6fa3a3b66dda98855e7bc3.tar.gz |
lvmetad: unlock vg on out-of-memory path
If we fail to get memory for mutex, hash the mutex
or fail somewhere along pthread function calls
return allocated resources back and unlock vg_lock_map mutex.
Diffstat (limited to 'daemons')
-rw-r--r-- | daemons/lvmetad/lvmetad-core.c | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c index e1cb583bd..6c0014686 100644 --- a/daemons/lvmetad/lvmetad-core.c +++ b/daemons/lvmetad/lvmetad-core.c @@ -121,19 +121,18 @@ static response reply_unknown(const char *reason) static struct dm_config_tree *lock_vg(lvmetad_state *s, const char *id) { pthread_mutex_t *vg; struct dm_config_tree *cft; + pthread_mutexattr_t rec; pthread_mutex_lock(&s->lock.vg_lock_map); - vg = dm_hash_lookup(s->lock.vg, id); - if (!vg) { - pthread_mutexattr_t rec; - pthread_mutexattr_init(&rec); - pthread_mutexattr_settype(&rec, PTHREAD_MUTEX_RECURSIVE_NP); - if (!(vg = malloc(sizeof(pthread_mutex_t)))) - return NULL; - pthread_mutex_init(vg, &rec); + if (!(vg = dm_hash_lookup(s->lock.vg, id))) { + if (!(vg = malloc(sizeof(pthread_mutex_t))) || + pthread_mutexattr_init(&rec) || + pthread_mutexattr_settype(&rec, PTHREAD_MUTEX_RECURSIVE_NP) || + pthread_mutex_init(vg, &rec)) + goto bad; if (!dm_hash_insert(s->lock.vg, id, vg)) { - free(vg); - return NULL; + pthread_mutex_destroy(vg); + goto bad; } } /* We never remove items from s->lock.vg => the pointer remains valid. */ @@ -147,6 +146,11 @@ static struct dm_config_tree *lock_vg(lvmetad_state *s, const char *id) { cft = dm_hash_lookup(s->vgid_to_metadata, id); unlock_vgid_to_metadata(s); return cft; +bad: + pthread_mutex_unlock(&s->lock.vg_lock_map); + free(vg); + ERROR(s, "Out of memory"); + return NULL; } static void unlock_vg(lvmetad_state *s, const char *id) { |