[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