summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2016-05-10 14:42:26 -0500
committerDavid Teigland <teigland@redhat.com>2016-05-16 14:38:04 -0500
commit9f72a52302587fef27d845e218e6a81be6022dca (patch)
tree5467d2fc5d8ec2749ffac11323b67e09ba9875c7
parent7ef152c07290c79f47a64b0fc81975ae52554919 (diff)
downloadlvm2-9f72a52302587fef27d845e218e6a81be6022dca.tar.gz
lvmetad: add request level thread locking
Use an rwlock for requests that read/write cache state. Use a mutex for requests that read/write global info.
-rw-r--r--daemons/lvmetad/lvmetad-core.c103
1 files changed, 75 insertions, 28 deletions
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c
index 54ecd4a9a..5ff148bb4 100644
--- a/daemons/lvmetad/lvmetad-core.c
+++ b/daemons/lvmetad/lvmetad-core.c
@@ -232,6 +232,8 @@ typedef struct {
char token[128];
uint32_t flags; /* GLFL_ */
pthread_mutex_t token_lock;
+ pthread_mutex_t info_lock;
+ pthread_rwlock_t cache_lock;
} lvmetad_state;
static void destroy_metadata_hashes(lvmetad_state *s)
@@ -2783,10 +2785,13 @@ static response dump(lvmetad_state *s)
static response handler(daemon_state s, client_handle h, request r)
{
+ response res = { 0 };
lvmetad_state *state = s.private;
const char *rq = daemon_request_str(r, "request", "NONE");
const char *token = daemon_request_str(r, "token", "NONE");
char prev_token[128] = { 0 };
+ int cache_lock = 0;
+ int info_lock = 0;
pthread_mutex_lock(&state->token_lock);
if (!strcmp(rq, "token_update")) {
@@ -2813,49 +2818,89 @@ static response handler(daemon_state s, client_handle h, request r)
* TODO Add a stats call, with transaction count/rate, time since last
* update &c.
*/
+
+ if (!strcmp(rq, "pv_found") ||
+ !strcmp(rq, "pv_gone") ||
+ !strcmp(rq, "vg_update") ||
+ !strcmp(rq, "vg_remove") ||
+ !strcmp(rq, "set_vg_info") ||
+ !strcmp(rq, "pv_clear_all") ||
+ !strcmp(rq, "vg_clear_outdated_pvs")) {
+ pthread_rwlock_wrlock(&state->cache_lock);
+ cache_lock = 1;
+ goto do_rq;
+ }
+
+ if (!strcmp(rq, "pv_lookup") ||
+ !strcmp(rq, "vg_lookup") ||
+ !strcmp(rq, "pv_list") ||
+ !strcmp(rq, "vg_list") ||
+ !strcmp(rq, "dump")) {
+ pthread_rwlock_rdlock(&state->cache_lock);
+ cache_lock = 1;
+ goto do_rq;
+ }
+
+ if (!strcmp(rq, "set_global_info") ||
+ !strcmp(rq, "get_global_info")) {
+ pthread_mutex_lock(&state->info_lock);
+ info_lock = 1;
+ goto do_rq;
+ }
+
+ do_rq:
+
if (!strcmp(rq, "pv_found"))
- return pv_found(state, r);
+ res = pv_found(state, r);
- if (!strcmp(rq, "pv_gone"))
- return pv_gone(state, r);
+ else if (!strcmp(rq, "pv_gone"))
+ res = pv_gone(state, r);
- if (!strcmp(rq, "pv_clear_all"))
- return pv_clear_all(state, r);
+ else if (!strcmp(rq, "pv_clear_all"))
+ res = pv_clear_all(state, r);
- if (!strcmp(rq, "pv_lookup"))
- return pv_lookup(state, r);
+ else if (!strcmp(rq, "pv_lookup"))
+ res = pv_lookup(state, r);
- if (!strcmp(rq, "vg_update"))
- return vg_update(state, r);
+ else if (!strcmp(rq, "vg_update"))
+ res = vg_update(state, r);
- if (!strcmp(rq, "vg_clear_outdated_pvs"))
- return vg_clear_outdated_pvs(state, r);
+ else if (!strcmp(rq, "vg_clear_outdated_pvs"))
+ res = vg_clear_outdated_pvs(state, r);
- if (!strcmp(rq, "vg_remove"))
- return vg_remove(state, r);
+ else if (!strcmp(rq, "vg_remove"))
+ res = vg_remove(state, r);
- if (!strcmp(rq, "vg_lookup"))
- return vg_lookup(state, r);
+ else if (!strcmp(rq, "vg_lookup"))
+ res = vg_lookup(state, r);
- if (!strcmp(rq, "pv_list"))
- return pv_list(state, r);
+ else if (!strcmp(rq, "pv_list"))
+ res = pv_list(state, r);
- if (!strcmp(rq, "vg_list"))
- return vg_list(state, r);
+ else if (!strcmp(rq, "vg_list"))
+ res = vg_list(state, r);
- if (!strcmp(rq, "set_global_info"))
- return set_global_info(state, r);
+ else if (!strcmp(rq, "set_global_info"))
+ res = set_global_info(state, r);
- if (!strcmp(rq, "get_global_info"))
- return get_global_info(state, r);
+ else if (!strcmp(rq, "get_global_info"))
+ res = get_global_info(state, r);
- if (!strcmp(rq, "set_vg_info"))
- return set_vg_info(state, r);
+ else if (!strcmp(rq, "set_vg_info"))
+ res = set_vg_info(state, r);
- if (!strcmp(rq, "dump"))
- return dump(state);
+ else if (!strcmp(rq, "dump"))
+ res = dump(state);
- return reply_fail("request not implemented");
+ else
+ res = reply_fail("request not implemented");
+
+ if (cache_lock)
+ pthread_rwlock_unlock(&state->cache_lock);
+ if (info_lock)
+ pthread_mutex_unlock(&state->info_lock);
+
+ return res;
}
static int init(daemon_state *s)
@@ -2871,6 +2916,8 @@ static int init(daemon_state *s)
pthread_mutex_init(&ls->lock.pvid_to_vgid, NULL);
pthread_mutex_init(&ls->lock.vg_lock_map, NULL);
pthread_mutex_init(&ls->token_lock, NULL);
+ pthread_mutex_init(&ls->info_lock, NULL);
+ pthread_rwlock_init(&ls->cache_lock, NULL);
create_metadata_hashes(ls);
ls->lock.vg = dm_hash_create(32);