[dm-devel] [RFC PATCH 2/5] move waiter code from libmultipath to multipathd

Martin Wilck mwilck at suse.com
Sat Feb 10 16:16:08 UTC 2018


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 at redhat.com>

Reviewed-by: Martin Wilck <mwilck at suse.com>

> ---
>  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 at suse.com>, Tel. +49 (0)911 74053 2107
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)




More information about the dm-devel mailing list