You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
4.5 KiB
131 lines
4.5 KiB
From 41d8039e12ebad0727f8c7455ad9392bc61e6414 Mon Sep 17 00:00:00 2001 |
|
From: Zdenek Kabelac <zkabelac@redhat.com> |
|
Date: Mon, 27 Aug 2018 10:18:26 +0200 |
|
Subject: [PATCH 1/2] dmeventd: lvm2 plugin uses envvar registry |
|
|
|
Thin plugin started to use configuble setting to allow to configure |
|
usage of external scripts - however to read this value it needed to |
|
execute internal command as dmeventd itself has no access to lvm.conf |
|
and the API for dmeventd plugin has been kept stable. |
|
|
|
The call of command itself was not normally 'a big issue' until users |
|
started to use higher number of monitored LVs and execution of command |
|
got stuck because other monitored resource already started to execute |
|
some other lvm2 command and become blocked waiting on VG lock. |
|
|
|
This scenario revealed necesity to somehow avoid calling lvm2 command |
|
during resource registration - but this requires bigger changes - so |
|
meanwhile this patch tries to minimize the possibility to hit this race |
|
by obtaining any configurable setting just once - such patch is small |
|
and covers majority of problem - yet better solution needs to be |
|
introduced likely with bigger rework of dmeventd. |
|
|
|
TODO: Avoid blocking registration of resource with execution of lvm2 |
|
commands since those can get stuck waiting on mutexes. |
|
|
|
(cherry picked from commit a8d59404f7713ae4f9a3b172dd560ed1364d8bee) |
|
|
|
Conflicts: |
|
WHATS_NEW_DM |
|
--- |
|
WHATS_NEW_DM | 4 +++ |
|
daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c | 49 +++++++++++++++++++++------- |
|
2 files changed, 42 insertions(+), 11 deletions(-) |
|
|
|
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM |
|
index c42ee17..42cf2a8 100644 |
|
--- a/WHATS_NEW_DM |
|
+++ b/WHATS_NEW_DM |
|
@@ -1,3 +1,7 @@ |
|
+Version 1.02.151 - |
|
+============================== |
|
+ Add hot fix to avoiding locking collision when monitoring thin-pools. |
|
+ |
|
Version 1.02.150 - |
|
================================= |
|
Add vdo plugin for monitoring VDO devices. |
|
diff --git a/daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c b/daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c |
|
index 930f9fc..5be11f1 100644 |
|
--- a/daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c |
|
+++ b/daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c |
|
@@ -31,6 +31,13 @@ static pthread_mutex_t _register_mutex = PTHREAD_MUTEX_INITIALIZER; |
|
static int _register_count = 0; |
|
static struct dm_pool *_mem_pool = NULL; |
|
static void *_lvm_handle = NULL; |
|
+static DM_LIST_INIT(_env_registry); |
|
+ |
|
+struct env_data { |
|
+ struct dm_list list; |
|
+ const char *cmd; |
|
+ const char *data; |
|
+}; |
|
|
|
DM_EVENT_LOG_FN("#lvm") |
|
|
|
@@ -100,6 +107,7 @@ void dmeventd_lvm2_exit(void) |
|
lvm2_run(_lvm_handle, "_memlock_dec"); |
|
dm_pool_destroy(_mem_pool); |
|
_mem_pool = NULL; |
|
+ dm_list_init(&_env_registry); |
|
lvm2_exit(_lvm_handle); |
|
_lvm_handle = NULL; |
|
log_debug("lvm plugin exited."); |
|
@@ -124,6 +132,8 @@ int dmeventd_lvm2_command(struct dm_pool *mem, char *buffer, size_t size, |
|
static char _internal_prefix[] = "_dmeventd_"; |
|
char *vg = NULL, *lv = NULL, *layer; |
|
int r; |
|
+ struct env_data *env_data; |
|
+ const char *env = NULL; |
|
|
|
if (!dm_split_lvm_name(mem, device, &vg, &lv, &layer)) { |
|
log_error("Unable to determine VG name from %s.", |
|
@@ -137,18 +147,35 @@ int dmeventd_lvm2_command(struct dm_pool *mem, char *buffer, size_t size, |
|
*layer = '\0'; |
|
|
|
if (!strncmp(cmd, _internal_prefix, sizeof(_internal_prefix) - 1)) { |
|
- dmeventd_lvm2_lock(); |
|
- /* output of internal command passed via env var */ |
|
- if (!dmeventd_lvm2_run(cmd)) |
|
- cmd = NULL; |
|
- else if ((cmd = getenv(cmd))) |
|
- cmd = dm_pool_strdup(mem, cmd); /* copy with lock */ |
|
- dmeventd_lvm2_unlock(); |
|
- |
|
- if (!cmd) { |
|
- log_error("Unable to find configured command."); |
|
- return 0; |
|
+ /* check if ENVVAR wasn't already resolved */ |
|
+ dm_list_iterate_items(env_data, &_env_registry) |
|
+ if (!strcmp(cmd, env_data->cmd)) { |
|
+ env = env_data->data; |
|
+ break; |
|
+ } |
|
+ |
|
+ if (!env) { |
|
+ /* run lvm2 command to find out setting value */ |
|
+ dmeventd_lvm2_lock(); |
|
+ if (!dmeventd_lvm2_run(cmd) || |
|
+ !(env = getenv(cmd))) { |
|
+ log_error("Unable to find configured command."); |
|
+ return 0; |
|
+ } |
|
+ /* output of internal command passed via env var */ |
|
+ env = dm_pool_strdup(_mem_pool, env); /* copy with lock */ |
|
+ dmeventd_lvm2_unlock(); |
|
+ if (!env || |
|
+ !(env_data = dm_pool_zalloc(_mem_pool, sizeof(*env_data))) || |
|
+ !(env_data->cmd = dm_pool_strdup(_mem_pool, cmd))) { |
|
+ log_error("Unable to allocate env memory."); |
|
+ return 0; |
|
+ } |
|
+ env_data->data = env; |
|
+ /* add to ENVVAR registry */ |
|
+ dm_list_add(&_env_registry, &env_data->list); |
|
} |
|
+ cmd = env; |
|
} |
|
|
|
r = dm_snprintf(buffer, size, "%s %s/%s", cmd, vg, lv); |
|
-- |
|
1.8.3.1 |
|
|
|
|