aboutsummaryrefslogtreecommitdiff
path: root/daemons
diff options
context:
space:
mode:
authorZdenek Kabelac <zkabelac@redhat.com>2012-12-14 16:35:26 +0100
committerZdenek Kabelac <zkabelac@redhat.com>2012-12-15 17:23:26 +0100
commita4269aadf320f36d3d6fa3a3b66dda98855e7bc3 (patch)
treee66cf6ce7c8c3e327c389bb31921a87d1c1a15a9 /daemons
parent788ac7fa547fb98f0edd38685d40b80609f298dc (diff)
downloadlvm2-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.c24
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) {