On Fri, 2018-02-09 at 23:07 -0600, Benjamin Marzinski wrote: > 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. > > Signed-off-by: Benjamin Marzinski <bmarzins@xxxxxxxxxx> Reviewed-by: Martin Wilck <mwilck@xxxxxxxx> > --- > 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 6447d8d..a1005b2 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 > > all: $(LIBS) > diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c > index abf5327..77b045b 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" > @@ -107,17 +106,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) > { > @@ -379,92 +367,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)) { > - 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, 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 d6e17bb..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, 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 e6f140b..85f29a7 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 72c3c2f..94b2406 100644 > --- a/multipathd/main.c > +++ b/multipathd/main.c > @@ -311,6 +311,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)) { > + 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, 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 */ -- Dr. Martin Wilck <mwilck@xxxxxxxx>, Tel. +49 (0)911 74053 2107 SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) -- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel