From 64fa83ec3f6d33b1dfd325b25f342b94dcee775e Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Mon, 8 Jan 2007 14:24:20 +0000 Subject: [PATCH] Add dmeventd_mirror register_mutex, tidy initialisation & add memlock. --- WHATS_NEW | 1 + .../dmeventd/plugins/mirror/dmeventd_mirror.c | 67 ++++++++++++++----- dmeventd/mirror/dmeventd_mirror.c | 67 ++++++++++++++----- tools/lvmcmdlib.c | 8 ++- 4 files changed, 110 insertions(+), 33 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index 068ca1623..97e8761fb 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.18 - ==================================== + Add dmeventd_mirror register_mutex, tidy initialisation & add memlock. Fix create mirror with name longer than 22 chars. Fix some activate.c prototypes when compiled without devmapper. Fix dmeventd mirror to cope if monitored device disappears. diff --git a/daemons/dmeventd/plugins/mirror/dmeventd_mirror.c b/daemons/dmeventd/plugins/mirror/dmeventd_mirror.c index 1d57e91af..a76a0f3ea 100644 --- a/daemons/dmeventd/plugins/mirror/dmeventd_mirror.c +++ b/daemons/dmeventd/plugins/mirror/dmeventd_mirror.c @@ -32,19 +32,30 @@ #define ME_INSYNC 1 #define ME_FAILURE 2 -static pthread_mutex_t _lock = PTHREAD_MUTEX_INITIALIZER; +/* + * register_device() is called first and performs initialisation. + * Only one device may be registered or unregistered at a time. + */ +static pthread_mutex_t _register_mutex = PTHREAD_MUTEX_INITIALIZER; -/* FIXME: We may need to lock around operations to these */ +/* + * Number of active registrations. + */ static int _register_count = 0; -/* FIXME Unsafe static? */ static struct dm_pool *_mem_pool = NULL; +static void *_lvm_handle = NULL; + +/* + * Currently only one event can be processed at a time. + */ +static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER; static int _get_mirror_event(char *params) { int i, r = ME_INSYNC; -#define MAX_ARGS 30; /* should support at least 8-way mirrors */ +#define MAX_ARGS 30 /* should support at least 8-way mirrors */ /* FIXME Remove unnecessary limit. It tells you how many devices there are - use it! */ char *args[MAX_ARGS]; @@ -122,7 +133,6 @@ static void _temporary_log_fn(int level, const char *file, static int _remove_failed_devices(const char *device) { int r; - void *handle; #define CMD_SIZE 256 /* FIXME Use system restriction */ char cmd_str[CMD_SIZE]; char *vg = NULL, *lv = NULL, *layer = NULL; @@ -144,10 +154,7 @@ static int _remove_failed_devices(const char *device) return -ENAMETOOLONG; /* FIXME Replace with generic error return - reason for failure has already got logged */ } - lvm2_log_fn(_temporary_log_fn); - handle = lvm2_init(); - lvm2_log_level(handle, 1); - r = lvm2_run(handle, cmd_str); + r = lvm2_run(_lvm_handle, cmd_str); dm_pool_empty(_mem_pool); /* FIXME: not safe with multiple threads */ return (r == 1) ? 0 : -1; @@ -161,9 +168,9 @@ void process_event(const char *device, enum dm_event_type event) char *target_type = NULL; char *params; - if (pthread_mutex_trylock(&_lock)) { + if (pthread_mutex_trylock(&_event_mutex)) { syslog(LOG_NOTICE, "Another thread is handling an event. Waiting..."); - pthread_mutex_lock(&_lock); + pthread_mutex_lock(&_event_mutex); } /* FIXME Move inside libdevmapper */ if (!(dmt = dm_task_create(DM_DEVICE_STATUS))) { @@ -185,9 +192,10 @@ void process_event(const char *device, enum dm_event_type event) next = dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms); - if (!target_type) + if (!target_type) { syslog(LOG_INFO, "%s mapping lost.\n", device); continue; + } if (strcmp(target_type, "mirror")) { syslog(LOG_INFO, "%s has unmirrored portion.\n", device); @@ -225,11 +233,15 @@ void process_event(const char *device, enum dm_event_type event) fail: if (dmt) dm_task_destroy(dmt); - pthread_mutex_unlock(&_lock); + pthread_mutex_unlock(&_event_mutex); } int register_device(const char *device) { + int r = 0; + + pthread_mutex_lock(&_register_mutex); + syslog(LOG_INFO, "Monitoring mirror device, %s for events\n", device); /* @@ -237,19 +249,42 @@ int register_device(const char *device) * than enough for what we need (device mapper name splitting) */ if (!_mem_pool && !(_mem_pool = dm_pool_create("mirror_dso", 1024))) - return 0; + goto out; + + if (!_lvm_handle) { + lvm2_log_fn(_temporary_log_fn); + if (!(_lvm_handle = lvm2_init())) { + dm_pool_destroy(_mem_pool); + _mem_pool = NULL; + goto out; + } + lvm2_log_level(_lvm_handle, LVM2_LOG_SUPPRESS); + /* FIXME Temporary: move to dmeventd core */ + lvm2_run(_lvm_handle, "_memlock_inc"); + } _register_count++; + r = 1; - return 1; +out: + pthread_mutex_unlock(&_register_mutex); + + return r; } int unregister_device(const char *device) { + pthread_mutex_lock(&_register_mutex); + if (!--_register_count) { dm_pool_destroy(_mem_pool); _mem_pool = NULL; + lvm2_run(_lvm_handle, "_memlock_dec"); + lvm2_exit(_lvm_handle); + _lvm_handle = NULL; } - return 1; + pthread_mutex_unlock(&_register_mutex); + + return 1; } diff --git a/dmeventd/mirror/dmeventd_mirror.c b/dmeventd/mirror/dmeventd_mirror.c index 1d57e91af..a76a0f3ea 100644 --- a/dmeventd/mirror/dmeventd_mirror.c +++ b/dmeventd/mirror/dmeventd_mirror.c @@ -32,19 +32,30 @@ #define ME_INSYNC 1 #define ME_FAILURE 2 -static pthread_mutex_t _lock = PTHREAD_MUTEX_INITIALIZER; +/* + * register_device() is called first and performs initialisation. + * Only one device may be registered or unregistered at a time. + */ +static pthread_mutex_t _register_mutex = PTHREAD_MUTEX_INITIALIZER; -/* FIXME: We may need to lock around operations to these */ +/* + * Number of active registrations. + */ static int _register_count = 0; -/* FIXME Unsafe static? */ static struct dm_pool *_mem_pool = NULL; +static void *_lvm_handle = NULL; + +/* + * Currently only one event can be processed at a time. + */ +static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER; static int _get_mirror_event(char *params) { int i, r = ME_INSYNC; -#define MAX_ARGS 30; /* should support at least 8-way mirrors */ +#define MAX_ARGS 30 /* should support at least 8-way mirrors */ /* FIXME Remove unnecessary limit. It tells you how many devices there are - use it! */ char *args[MAX_ARGS]; @@ -122,7 +133,6 @@ static void _temporary_log_fn(int level, const char *file, static int _remove_failed_devices(const char *device) { int r; - void *handle; #define CMD_SIZE 256 /* FIXME Use system restriction */ char cmd_str[CMD_SIZE]; char *vg = NULL, *lv = NULL, *layer = NULL; @@ -144,10 +154,7 @@ static int _remove_failed_devices(const char *device) return -ENAMETOOLONG; /* FIXME Replace with generic error return - reason for failure has already got logged */ } - lvm2_log_fn(_temporary_log_fn); - handle = lvm2_init(); - lvm2_log_level(handle, 1); - r = lvm2_run(handle, cmd_str); + r = lvm2_run(_lvm_handle, cmd_str); dm_pool_empty(_mem_pool); /* FIXME: not safe with multiple threads */ return (r == 1) ? 0 : -1; @@ -161,9 +168,9 @@ void process_event(const char *device, enum dm_event_type event) char *target_type = NULL; char *params; - if (pthread_mutex_trylock(&_lock)) { + if (pthread_mutex_trylock(&_event_mutex)) { syslog(LOG_NOTICE, "Another thread is handling an event. Waiting..."); - pthread_mutex_lock(&_lock); + pthread_mutex_lock(&_event_mutex); } /* FIXME Move inside libdevmapper */ if (!(dmt = dm_task_create(DM_DEVICE_STATUS))) { @@ -185,9 +192,10 @@ void process_event(const char *device, enum dm_event_type event) next = dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms); - if (!target_type) + if (!target_type) { syslog(LOG_INFO, "%s mapping lost.\n", device); continue; + } if (strcmp(target_type, "mirror")) { syslog(LOG_INFO, "%s has unmirrored portion.\n", device); @@ -225,11 +233,15 @@ void process_event(const char *device, enum dm_event_type event) fail: if (dmt) dm_task_destroy(dmt); - pthread_mutex_unlock(&_lock); + pthread_mutex_unlock(&_event_mutex); } int register_device(const char *device) { + int r = 0; + + pthread_mutex_lock(&_register_mutex); + syslog(LOG_INFO, "Monitoring mirror device, %s for events\n", device); /* @@ -237,19 +249,42 @@ int register_device(const char *device) * than enough for what we need (device mapper name splitting) */ if (!_mem_pool && !(_mem_pool = dm_pool_create("mirror_dso", 1024))) - return 0; + goto out; + + if (!_lvm_handle) { + lvm2_log_fn(_temporary_log_fn); + if (!(_lvm_handle = lvm2_init())) { + dm_pool_destroy(_mem_pool); + _mem_pool = NULL; + goto out; + } + lvm2_log_level(_lvm_handle, LVM2_LOG_SUPPRESS); + /* FIXME Temporary: move to dmeventd core */ + lvm2_run(_lvm_handle, "_memlock_inc"); + } _register_count++; + r = 1; - return 1; +out: + pthread_mutex_unlock(&_register_mutex); + + return r; } int unregister_device(const char *device) { + pthread_mutex_lock(&_register_mutex); + if (!--_register_count) { dm_pool_destroy(_mem_pool); _mem_pool = NULL; + lvm2_run(_lvm_handle, "_memlock_dec"); + lvm2_exit(_lvm_handle); + _lvm_handle = NULL; } - return 1; + pthread_mutex_unlock(&_register_mutex); + + return 1; } diff --git a/tools/lvmcmdlib.c b/tools/lvmcmdlib.c index 97e4e4c15..91536ce57 100644 --- a/tools/lvmcmdlib.c +++ b/tools/lvmcmdlib.c @@ -77,7 +77,13 @@ int lvm2_run(void *handle, const char *cmdline) goto out; } - ret = lvm_run_command(cmd, argc, argv); + /* FIXME Temporary - move to libdevmapper */ + if (!strcmp(cmdline, "_memlock_inc")) + memlock_inc(); + if (!strcmp(cmdline, "_memlock_dec")) + memlock_dec(); + else + ret = lvm_run_command(cmd, argc, argv); out: dm_free(cmdcopy);