Only multipathd uses the code in waiter.[ch] and the functions that call it directly, so they should all live in the multipathd directory. This patch is simply moving the waiter.[ch] files and the functions in structs_vec that use them. None of the moved code has been changed. Reviewed-by: Martin Wilck <mwilck@xxxxxxxx> Signed-off-by: Benjamin Marzinski <bmarzins@xxxxxxxxxx> --- libmultipath/Makefile | 2 +- libmultipath/structs_vec.c | 98 --------------------- libmultipath/structs_vec.h | 4 +- libmultipath/waiter.c | 215 --------------------------------------------- libmultipath/waiter.h | 17 ---- multipathd/Makefile | 2 +- multipathd/main.c | 96 ++++++++++++++++++++ multipathd/waiter.c | 215 +++++++++++++++++++++++++++++++++++++++++++++ multipathd/waiter.h | 17 ++++ 9 files changed, 332 insertions(+), 334 deletions(-) delete mode 100644 libmultipath/waiter.c delete mode 100644 libmultipath/waiter.h create mode 100644 multipathd/waiter.c create mode 100644 multipathd/waiter.h diff --git a/libmultipath/Makefile b/libmultipath/Makefile index 806aaa2..f51786d 100644 --- a/libmultipath/Makefile +++ b/libmultipath/Makefile @@ -42,7 +42,7 @@ OBJS = memory.o parser.o vector.o devmapper.o callout.o \ pgpolicies.o debug.o defaults.o uevent.o time-util.o \ switchgroup.o uxsock.o print.o alias.o log_pthread.o \ log.o configure.o structs_vec.o sysfs.o prio.o checkers.o \ - lock.o waiter.o file.o wwids.o prioritizers/alua_rtpg.o prkey.o \ + lock.o file.o wwids.o prioritizers/alua_rtpg.o prkey.o \ io_err_stat.o dm-generic.o generic.o foreign.o all: $(LIBS) diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c index 41e5d88..9a01631 100644 --- a/libmultipath/structs_vec.c +++ b/libmultipath/structs_vec.c @@ -10,7 +10,6 @@ #include "structs.h" #include "structs_vec.h" #include "sysfs.h" -#include "waiter.h" #include "devmapper.h" #include "dmparser.h" #include "propsel.h" @@ -108,17 +107,6 @@ void orphan_paths(vector pathvec, struct multipath *mpp) } } -static void -set_multipath_wwid (struct multipath * mpp) -{ - if (strlen(mpp->wwid)) - return; - - dm_get_uuid(mpp->alias, mpp->wwid); -} - -#define PURGE_VEC 1 - void remove_map(struct multipath * mpp, struct vectors * vecs, int purge_vec) { @@ -380,92 +368,6 @@ sync_map_state(struct multipath *mpp) } } -int -update_map (struct multipath *mpp, struct vectors *vecs) -{ - int retries = 3; - char params[PARAMS_SIZE] = {0}; - -retry: - condlog(4, "%s: updating new map", mpp->alias); - if (adopt_paths(vecs->pathvec, mpp)) { - condlog(0, "%s: failed to adopt paths for new map update", - mpp->alias); - retries = -1; - goto fail; - } - verify_paths(mpp, vecs); - mpp->action = ACT_RELOAD; - - extract_hwe_from_path(mpp); - if (setup_map(mpp, params, PARAMS_SIZE, vecs)) { - condlog(0, "%s: failed to setup new map in update", mpp->alias); - retries = -1; - goto fail; - } - if (domap(mpp, params, 1) <= 0 && retries-- > 0) { - condlog(0, "%s: map_udate sleep", mpp->alias); - sleep(1); - goto retry; - } - dm_lib_release(); - -fail: - if (setup_multipath(vecs, mpp)) - return 1; - - sync_map_state(mpp); - - if (retries < 0) - condlog(0, "%s: failed reload in new map update", mpp->alias); - return 0; -} - -struct multipath *add_map_without_path (struct vectors *vecs, const char *alias) -{ - struct multipath * mpp = alloc_multipath(); - struct config *conf; - - if (!mpp) - return NULL; - if (!alias) { - FREE(mpp); - return NULL; - } - - mpp->alias = STRDUP(alias); - - if (dm_get_info(mpp->alias, &mpp->dmi)) { - condlog(3, "%s: cannot access table", mpp->alias); - goto out; - } - set_multipath_wwid(mpp); - conf = get_multipath_config(); - mpp->mpe = find_mpe(conf->mptable, mpp->wwid); - put_multipath_config(conf); - - if (update_multipath_table(mpp, vecs->pathvec, 1)) - goto out; - if (update_multipath_status(mpp)) - goto out; - - if (!vector_alloc_slot(vecs->mpvec)) - goto out; - - vector_set_slot(vecs->mpvec, mpp); - - if (update_map(mpp, vecs) != 0) /* map removed */ - return NULL; - - if (start_waiter_thread(mpp, vecs)) - goto out; - - return mpp; -out: - remove_map(mpp, vecs, PURGE_VEC); - return NULL; -} - static void find_existing_alias (struct multipath * mpp, struct vectors *vecs) diff --git a/libmultipath/structs_vec.h b/libmultipath/structs_vec.h index 2a0be93..ceab6d9 100644 --- a/libmultipath/structs_vec.h +++ b/libmultipath/structs_vec.h @@ -26,12 +26,12 @@ int update_multipath_strings (struct multipath *mpp, vector pathvec, int is_daemon); void extract_hwe_from_path(struct multipath * mpp); +#define PURGE_VEC 1 + void remove_map (struct multipath * mpp, struct vectors * vecs, int purge_vec); void remove_maps (struct vectors * vecs); void sync_map_state (struct multipath *); -int update_map (struct multipath *mpp, struct vectors *vecs); -struct multipath * add_map_without_path (struct vectors * vecs, const char * alias); struct multipath * add_map_with_path (struct vectors * vecs, struct path * pp, int add_vec); int update_multipath (struct vectors *vecs, char *mapname, int reset); diff --git a/libmultipath/waiter.c b/libmultipath/waiter.c deleted file mode 100644 index cb9708b..0000000 --- a/libmultipath/waiter.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (c) 2004, 2005 Christophe Varoqui - * Copyright (c) 2005 Kiyoshi Ueda, NEC - * Copyright (c) 2005 Benjamin Marzinski, Redhat - * Copyright (c) 2005 Edward Goggin, EMC - */ -#include <unistd.h> -#include <libdevmapper.h> -#include <sys/mman.h> -#include <pthread.h> -#include <signal.h> -#include <urcu.h> - -#include "vector.h" -#include "memory.h" -#include "checkers.h" -#include "config.h" -#include "structs.h" -#include "structs_vec.h" -#include "devmapper.h" -#include "debug.h" -#include "lock.h" -#include "waiter.h" - -pthread_attr_t waiter_attr; - -static struct event_thread *alloc_waiter (void) -{ - - struct event_thread *wp; - - wp = (struct event_thread *)MALLOC(sizeof(struct event_thread)); - memset(wp, 0, sizeof(struct event_thread)); - - return wp; -} - -static void free_waiter (void *data) -{ - struct event_thread *wp = (struct event_thread *)data; - - if (wp->dmt) - dm_task_destroy(wp->dmt); - - rcu_unregister_thread(); - FREE(wp); -} - -void stop_waiter_thread (struct multipath *mpp, struct vectors *vecs) -{ - pthread_t thread; - - if (mpp->waiter == (pthread_t)0) { - condlog(3, "%s: event checker thread already stopped", - mpp->alias); - return; - } - condlog(2, "%s: stop event checker thread (%lu)", mpp->alias, - mpp->waiter); - thread = mpp->waiter; - mpp->waiter = (pthread_t)0; - pthread_cancel(thread); - pthread_kill(thread, SIGUSR2); -} - -/* - * returns the reschedule delay - * negative means *stop* - */ -static int waiteventloop (struct event_thread *waiter) -{ - sigset_t set, oldset; - int event_nr; - int r; - - if (!waiter->event_nr) - waiter->event_nr = dm_geteventnr(waiter->mapname); - - if (!(waiter->dmt = libmp_dm_task_create(DM_DEVICE_WAITEVENT))) { - condlog(0, "%s: devmap event #%i dm_task_create error", - waiter->mapname, waiter->event_nr); - return 1; - } - - if (!dm_task_set_name(waiter->dmt, waiter->mapname)) { - condlog(0, "%s: devmap event #%i dm_task_set_name error", - waiter->mapname, waiter->event_nr); - dm_task_destroy(waiter->dmt); - waiter->dmt = NULL; - return 1; - } - - if (waiter->event_nr && !dm_task_set_event_nr(waiter->dmt, - waiter->event_nr)) { - condlog(0, "%s: devmap event #%i dm_task_set_event_nr error", - waiter->mapname, waiter->event_nr); - dm_task_destroy(waiter->dmt); - waiter->dmt = NULL; - return 1; - } - - dm_task_no_open_count(waiter->dmt); - - /* wait */ - sigemptyset(&set); - sigaddset(&set, SIGUSR2); - pthread_sigmask(SIG_UNBLOCK, &set, &oldset); - - pthread_testcancel(); - r = dm_task_run(waiter->dmt); - pthread_testcancel(); - - pthread_sigmask(SIG_SETMASK, &oldset, NULL); - dm_task_destroy(waiter->dmt); - waiter->dmt = NULL; - - if (!r) /* wait interrupted by signal */ - return -1; - - waiter->event_nr++; - - /* - * upon event ... - */ - while (1) { - condlog(3, "%s: devmap event #%i", - waiter->mapname, waiter->event_nr); - - /* - * event might be : - * - * 1) a table reload, which means our mpp structure is - * obsolete : refresh it through update_multipath() - * 2) a path failed by DM : mark as such through - * update_multipath() - * 3) map has gone away : stop the thread. - * 4) a path reinstate : nothing to do - * 5) a switch group : nothing to do - */ - pthread_cleanup_push(cleanup_lock, &waiter->vecs->lock); - lock(&waiter->vecs->lock); - pthread_testcancel(); - r = update_multipath(waiter->vecs, waiter->mapname, 1); - lock_cleanup_pop(waiter->vecs->lock); - - if (r) { - condlog(2, "%s: event checker exit", - waiter->mapname); - return -1; /* stop the thread */ - } - - event_nr = dm_geteventnr(waiter->mapname); - - if (waiter->event_nr == event_nr) - return 1; /* upon problem reschedule 1s later */ - - waiter->event_nr = event_nr; - } - return -1; /* never reach there */ -} - -static void *waitevent (void *et) -{ - int r; - struct event_thread *waiter; - - mlockall(MCL_CURRENT | MCL_FUTURE); - - waiter = (struct event_thread *)et; - pthread_cleanup_push(free_waiter, et); - - rcu_register_thread(); - while (1) { - r = waiteventloop(waiter); - - if (r < 0) - break; - - sleep(r); - } - - pthread_cleanup_pop(1); - return NULL; -} - -int start_waiter_thread (struct multipath *mpp, struct vectors *vecs) -{ - struct event_thread *wp; - - if (!mpp) - return 0; - - wp = alloc_waiter(); - - if (!wp) - goto out; - - strncpy(wp->mapname, mpp->alias, WWID_SIZE - 1); - wp->vecs = vecs; - - if (pthread_create(&wp->thread, &waiter_attr, waitevent, wp)) { - condlog(0, "%s: cannot create event checker", wp->mapname); - goto out1; - } - mpp->waiter = wp->thread; - condlog(2, "%s: event checker started", wp->mapname); - - return 0; -out1: - free_waiter(wp); - mpp->waiter = (pthread_t)0; -out: - condlog(0, "failed to start waiter thread"); - return 1; -} diff --git a/libmultipath/waiter.h b/libmultipath/waiter.h deleted file mode 100644 index 0cfae46..0000000 --- a/libmultipath/waiter.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _WAITER_H -#define _WAITER_H - -extern pthread_attr_t waiter_attr; - -struct event_thread { - struct dm_task *dmt; - pthread_t thread; - int event_nr; - char mapname[WWID_SIZE]; - struct vectors *vecs; -}; - -void stop_waiter_thread (struct multipath *mpp, struct vectors *vecs); -int start_waiter_thread (struct multipath *mpp, struct vectors *vecs); - -#endif /* _WAITER_H */ diff --git a/multipathd/Makefile b/multipathd/Makefile index 4c9d296..7800e47 100644 --- a/multipathd/Makefile +++ b/multipathd/Makefile @@ -22,7 +22,7 @@ ifdef SYSTEMD endif endif -OBJS = main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o +OBJS = main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o waiter.o EXEC = multipathd diff --git a/multipathd/main.c b/multipathd/main.c index 32cd6fe..2924d53 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -316,6 +316,102 @@ remove_maps_and_stop_waiters(struct vectors *vecs) remove_maps(vecs); } +static void +set_multipath_wwid (struct multipath * mpp) +{ + if (strlen(mpp->wwid)) + return; + + dm_get_uuid(mpp->alias, mpp->wwid); +} + +static int +update_map (struct multipath *mpp, struct vectors *vecs) +{ + int retries = 3; + char params[PARAMS_SIZE] = {0}; + +retry: + condlog(4, "%s: updating new map", mpp->alias); + if (adopt_paths(vecs->pathvec, mpp)) { + condlog(0, "%s: failed to adopt paths for new map update", + mpp->alias); + retries = -1; + goto fail; + } + verify_paths(mpp, vecs); + mpp->action = ACT_RELOAD; + + extract_hwe_from_path(mpp); + if (setup_map(mpp, params, PARAMS_SIZE, vecs)) { + condlog(0, "%s: failed to setup new map in update", mpp->alias); + retries = -1; + goto fail; + } + if (domap(mpp, params, 1) <= 0 && retries-- > 0) { + condlog(0, "%s: map_udate sleep", mpp->alias); + sleep(1); + goto retry; + } + dm_lib_release(); + +fail: + if (setup_multipath(vecs, mpp)) + return 1; + + sync_map_state(mpp); + + if (retries < 0) + condlog(0, "%s: failed reload in new map update", mpp->alias); + return 0; +} + +static struct multipath * +add_map_without_path (struct vectors *vecs, const char *alias) +{ + struct multipath * mpp = alloc_multipath(); + struct config *conf; + + if (!mpp) + return NULL; + if (!alias) { + FREE(mpp); + return NULL; + } + + mpp->alias = STRDUP(alias); + + if (dm_get_info(mpp->alias, &mpp->dmi)) { + condlog(3, "%s: cannot access table", mpp->alias); + goto out; + } + set_multipath_wwid(mpp); + conf = get_multipath_config(); + mpp->mpe = find_mpe(conf->mptable, mpp->wwid); + put_multipath_config(conf); + + if (update_multipath_table(mpp, vecs->pathvec, 1)) + goto out; + if (update_multipath_status(mpp)) + goto out; + + if (!vector_alloc_slot(vecs->mpvec)) + goto out; + + vector_set_slot(vecs->mpvec, mpp); + + if (update_map(mpp, vecs) != 0) /* map removed */ + return NULL; + + if (start_waiter_thread(mpp, vecs)) + goto out; + + return mpp; +out: + remove_map(mpp, vecs, PURGE_VEC); + return NULL; +} + static int coalesce_maps(struct vectors *vecs, vector nmpv) { diff --git a/multipathd/waiter.c b/multipathd/waiter.c new file mode 100644 index 0000000..cb9708b --- /dev/null +++ b/multipathd/waiter.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2004, 2005 Christophe Varoqui + * Copyright (c) 2005 Kiyoshi Ueda, NEC + * Copyright (c) 2005 Benjamin Marzinski, Redhat + * Copyright (c) 2005 Edward Goggin, EMC + */ +#include <unistd.h> +#include <libdevmapper.h> +#include <sys/mman.h> +#include <pthread.h> +#include <signal.h> +#include <urcu.h> + +#include "vector.h" +#include "memory.h" +#include "checkers.h" +#include "config.h" +#include "structs.h" +#include "structs_vec.h" +#include "devmapper.h" +#include "debug.h" +#include "lock.h" +#include "waiter.h" + +pthread_attr_t waiter_attr; + +static struct event_thread *alloc_waiter (void) +{ + + struct event_thread *wp; + + wp = (struct event_thread *)MALLOC(sizeof(struct event_thread)); + memset(wp, 0, sizeof(struct event_thread)); + + return wp; +} + +static void free_waiter (void *data) +{ + struct event_thread *wp = (struct event_thread *)data; + + if (wp->dmt) + dm_task_destroy(wp->dmt); + + rcu_unregister_thread(); + FREE(wp); +} + +void stop_waiter_thread (struct multipath *mpp, struct vectors *vecs) +{ + pthread_t thread; + + if (mpp->waiter == (pthread_t)0) { + condlog(3, "%s: event checker thread already stopped", + mpp->alias); + return; + } + condlog(2, "%s: stop event checker thread (%lu)", mpp->alias, + mpp->waiter); + thread = mpp->waiter; + mpp->waiter = (pthread_t)0; + pthread_cancel(thread); + pthread_kill(thread, SIGUSR2); +} + +/* + * returns the reschedule delay + * negative means *stop* + */ +static int waiteventloop (struct event_thread *waiter) +{ + sigset_t set, oldset; + int event_nr; + int r; + + if (!waiter->event_nr) + waiter->event_nr = dm_geteventnr(waiter->mapname); + + if (!(waiter->dmt = libmp_dm_task_create(DM_DEVICE_WAITEVENT))) { + condlog(0, "%s: devmap event #%i dm_task_create error", + waiter->mapname, waiter->event_nr); + return 1; + } + + if (!dm_task_set_name(waiter->dmt, waiter->mapname)) { + condlog(0, "%s: devmap event #%i dm_task_set_name error", + waiter->mapname, waiter->event_nr); + dm_task_destroy(waiter->dmt); + waiter->dmt = NULL; + return 1; + } + + if (waiter->event_nr && !dm_task_set_event_nr(waiter->dmt, + waiter->event_nr)) { + condlog(0, "%s: devmap event #%i dm_task_set_event_nr error", + waiter->mapname, waiter->event_nr); + dm_task_destroy(waiter->dmt); + waiter->dmt = NULL; + return 1; + } + + dm_task_no_open_count(waiter->dmt); + + /* wait */ + sigemptyset(&set); + sigaddset(&set, SIGUSR2); + pthread_sigmask(SIG_UNBLOCK, &set, &oldset); + + pthread_testcancel(); + r = dm_task_run(waiter->dmt); + pthread_testcancel(); + + pthread_sigmask(SIG_SETMASK, &oldset, NULL); + dm_task_destroy(waiter->dmt); + waiter->dmt = NULL; + + if (!r) /* wait interrupted by signal */ + return -1; + + waiter->event_nr++; + + /* + * upon event ... + */ + while (1) { + condlog(3, "%s: devmap event #%i", + waiter->mapname, waiter->event_nr); + + /* + * event might be : + * + * 1) a table reload, which means our mpp structure is + * obsolete : refresh it through update_multipath() + * 2) a path failed by DM : mark as such through + * update_multipath() + * 3) map has gone away : stop the thread. + * 4) a path reinstate : nothing to do + * 5) a switch group : nothing to do + */ + pthread_cleanup_push(cleanup_lock, &waiter->vecs->lock); + lock(&waiter->vecs->lock); + pthread_testcancel(); + r = update_multipath(waiter->vecs, waiter->mapname, 1); + lock_cleanup_pop(waiter->vecs->lock); + + if (r) { + condlog(2, "%s: event checker exit", + waiter->mapname); + return -1; /* stop the thread */ + } + + event_nr = dm_geteventnr(waiter->mapname); + + if (waiter->event_nr == event_nr) + return 1; /* upon problem reschedule 1s later */ + + waiter->event_nr = event_nr; + } + return -1; /* never reach there */ +} + +static void *waitevent (void *et) +{ + int r; + struct event_thread *waiter; + + mlockall(MCL_CURRENT | MCL_FUTURE); + + waiter = (struct event_thread *)et; + pthread_cleanup_push(free_waiter, et); + + rcu_register_thread(); + while (1) { + r = waiteventloop(waiter); + + if (r < 0) + break; + + sleep(r); + } + + pthread_cleanup_pop(1); + return NULL; +} + +int start_waiter_thread (struct multipath *mpp, struct vectors *vecs) +{ + struct event_thread *wp; + + if (!mpp) + return 0; + + wp = alloc_waiter(); + + if (!wp) + goto out; + + strncpy(wp->mapname, mpp->alias, WWID_SIZE - 1); + wp->vecs = vecs; + + if (pthread_create(&wp->thread, &waiter_attr, waitevent, wp)) { + condlog(0, "%s: cannot create event checker", wp->mapname); + goto out1; + } + mpp->waiter = wp->thread; + condlog(2, "%s: event checker started", wp->mapname); + + return 0; +out1: + free_waiter(wp); + mpp->waiter = (pthread_t)0; +out: + condlog(0, "failed to start waiter thread"); + return 1; +} diff --git a/multipathd/waiter.h b/multipathd/waiter.h new file mode 100644 index 0000000..0cfae46 --- /dev/null +++ b/multipathd/waiter.h @@ -0,0 +1,17 @@ +#ifndef _WAITER_H +#define _WAITER_H + +extern pthread_attr_t waiter_attr; + +struct event_thread { + struct dm_task *dmt; + pthread_t thread; + int event_nr; + char mapname[WWID_SIZE]; + struct vectors *vecs; +}; + +void stop_waiter_thread (struct multipath *mpp, struct vectors *vecs); +int start_waiter_thread (struct multipath *mpp, struct vectors *vecs); + +#endif /* _WAITER_H */ -- 2.7.4 -- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel