diff options
Diffstat (limited to '0009-move-waiter-code-from-libmultipath-to-multipathd.patch')
-rw-r--r-- | 0009-move-waiter-code-from-libmultipath-to-multipathd.patch | 793 |
1 files changed, 793 insertions, 0 deletions
diff --git a/0009-move-waiter-code-from-libmultipath-to-multipathd.patch b/0009-move-waiter-code-from-libmultipath-to-multipathd.patch new file mode 100644 index 0000000..4012267 --- /dev/null +++ b/0009-move-waiter-code-from-libmultipath-to-multipathd.patch @@ -0,0 +1,793 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski <bmarzins@redhat.com> +Date: Mon, 5 Feb 2018 18:50:45 -0600 +Subject: [PATCH] move waiter code from libmultipath to multipathd + +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@redhat.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 */ +-- +2.7.4 + |