[libmultipath] a bit of code reorganisation
authorChristophe Varoqui <root@xa-s05.(none)>
Wed, 15 Mar 2006 10:15:06 +0000 (11:15 +0100)
committerChristophe Varoqui <root@xa-s05.(none)>
Wed, 15 Mar 2006 10:15:06 +0000 (11:15 +0100)
o locking primitives moved to libmultipath/lock.[ch]
o waiter threads control primitives moved to libmultipath/waiter.[ch]
o update_multipath() and queue_mode_{add,del}_path() moved to
libmultipath/structs_vec.c

libmultipath/Makefile
libmultipath/lock.c [new file with mode: 0644]
libmultipath/lock.h [new file with mode: 0644]
libmultipath/structs.c
libmultipath/structs.h
libmultipath/structs_vec.c
libmultipath/structs_vec.h
libmultipath/waiter.c [new file with mode: 0644]
libmultipath/waiter.h [new file with mode: 0644]
multipathd/main.c

index e5d5b10..5d8c586 100644 (file)
@@ -18,6 +18,7 @@ OBJS = memory.o parser.o vector.o devmapper.o callout.o \
 PREVBUILD = $(shell nm debug.o 2> /dev/null|grep log_safe)
 
 ifeq ($(strip $(DAEMON)),1)
+       OBJS += lock.o waiter.o
        CFLAGS += -DDAEMON
        CLEAN = $(shell if [ "x$(PREVBUILD)" = "x" ]; then echo clean; fi)
 else
diff --git a/libmultipath/lock.c b/libmultipath/lock.c
new file mode 100644 (file)
index 0000000..0ca8783
--- /dev/null
@@ -0,0 +1,8 @@
+#include <pthread.h>
+#include "lock.h"
+
+void cleanup_lock (void * data)
+{
+       unlock((pthread_mutex_t *)data);
+}
+
diff --git a/libmultipath/lock.h b/libmultipath/lock.h
new file mode 100644 (file)
index 0000000..6afecda
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef _LOCK_H
+#define _LOCK_H
+
+#ifdef LCKDBG
+#define lock(a) \
+               fprintf(stderr, "%s:%s(%i) lock %p\n", __FILE__, __FUNCTION__, __LINE__, a); \
+        pthread_mutex_lock(a)
+#define unlock(a) \
+               fprintf(stderr, "%s:%s(%i) unlock %p\n", __FILE__, __FUNCTION__, __LINE__, a); \
+        pthread_mutex_unlock(a)
+#define lock_cleanup_pop(a) \
+               fprintf(stderr, "%s:%s(%i) unlock %p\n", __FILE__, __FUNCTION__, __LINE__, a); \
+        pthread_cleanup_pop(1);
+#else
+#define lock(a) pthread_mutex_lock(a)
+#define unlock(a) pthread_mutex_unlock(a)
+#define lock_cleanup_pop(a) pthread_cleanup_pop(1);
+#endif
+
+void cleanup_lock (void * data);
+
+#endif /* _LOCK_H */
index 024e790..af1a9a7 100644 (file)
@@ -16,6 +16,7 @@
 #include "debug.h"
 #include "structs_vec.h"
 #include "blacklist.h"
+#include "waiter.h"
 
 struct path *
 alloc_path (void)
index 2b96cfb..a8f37aa 100644 (file)
@@ -142,7 +142,7 @@ struct multipath {
        struct mpentry * mpe;
        struct hwentry * hwe;
 
-       /* daemon store a data blob for DM event waiter threads */
+       /* threads */
        void * waiter;
 
        /* stats */
@@ -189,4 +189,4 @@ int pathcount (struct multipath *, int);
 
 char sysfs_path[FILE_NAME_SIZE];
 
-#endif
+#endif /* _STRUCTS_H */
index 86bf2a5..b0dc095 100644 (file)
@@ -14,6 +14,7 @@
 #include "config.h"
 #include "propsel.h"
 #include "discovery.h"
+#include "waiter.h"
 
 
 /*
@@ -382,3 +383,90 @@ verify_paths(struct multipath * mpp, struct vectors * vecs, vector rpvec)
        return count;
 }
 
+int update_multipath (struct vectors *vecs, char *mapname)
+{
+       struct multipath *mpp;
+       struct pathgroup  *pgp;
+       struct path *pp;
+       int i, j;
+       int r = 1;
+
+       mpp = find_mp_by_alias(vecs->mpvec, mapname);
+
+       if (!mpp)
+               goto out;
+
+       free_pgvec(mpp->pg, KEEP_PATHS);
+       mpp->pg = NULL;
+
+       if (setup_multipath(vecs, mpp))
+               goto out; /* mpp freed in setup_multipath */
+
+       /*
+        * compare checkers states with DM states
+        */
+       vector_foreach_slot (mpp->pg, pgp, i) {
+               vector_foreach_slot (pgp->paths, pp, j) {
+                       if (pp->dmstate != PSTATE_FAILED)
+                               continue;
+
+                       if (pp->state != PATH_DOWN) {
+                               int oldstate = pp->state;
+                               condlog(2, "%s: mark as failed", pp->dev_t);
+                               mpp->stat_path_failures++;
+                               pp->state = PATH_DOWN;
+                               if (oldstate == PATH_UP ||
+                                   oldstate == PATH_GHOST)
+                                       update_queue_mode_del_path(mpp);
+
+                               /*
+                                * if opportune,
+                                * schedule the next check earlier
+                                */
+                               if (pp->tick > conf->checkint)
+                                       pp->tick = conf->checkint;
+                       }
+               }
+       }
+       r = 0;
+out:
+       if (r)
+               condlog(0, "failed to update multipath");
+       return r;
+}
+
+/*
+ * mpp->no_path_retry:
+ *   -2 (QUEUE) : queue_if_no_path enabled, never turned off
+ *   -1 (FAIL)  : fail_if_no_path
+ *    0 (UNDEF) : nothing
+ *   >0         : queue_if_no_path enabled, turned off after polling n times
+ */
+void update_queue_mode_del_path(struct multipath *mpp)
+{
+       if (--mpp->nr_active == 0 && mpp->no_path_retry > 0) {
+               /*
+                * Enter retry mode.
+                * meaning of +1: retry_tick may be decremented in
+                *                checkerloop before starting retry.
+                */
+               mpp->stat_queueing_timeouts++;
+               mpp->retry_tick = mpp->no_path_retry * conf->checkint + 1;
+               condlog(1, "%s: Entering recovery mode: max_retries=%d",
+                       mpp->alias, mpp->no_path_retry);
+       }
+       condlog(2, "%s: remaining active paths: %d", mpp->alias, mpp->nr_active);
+}
+
+void update_queue_mode_add_path(struct multipath *mpp)
+{
+       if (mpp->nr_active++ == 0 && mpp->no_path_retry > 0) {
+               /* come back to normal mode from retry mode */
+               mpp->retry_tick = 0;
+               dm_queue_if_no_path(mpp->alias, 1);
+               condlog(2, "%s: queue_if_no_path enabled", mpp->alias);
+               condlog(1, "%s: Recovered to normal mode", mpp->alias);
+       }
+       condlog(2, "%s: remaining active paths: %d", mpp->alias, mpp->nr_active);
+}
+
index 348e9e5..81d9eaa 100644 (file)
@@ -9,17 +9,6 @@ struct vectors {
        vector mpvec;
 };
 
-#if DAEMON
-struct event_thread {
-       struct dm_task *dmt;
-       pthread_t thread;
-       int event_nr;
-       char mapname[WWID_SIZE];
-       struct vectors *vecs;
-       struct multipath *mpp;
-};
-#endif
-
 typedef void (stop_waiter_thread_func) (struct multipath *, struct vectors *);
 typedef int (start_waiter_thread_func) (struct multipath *, struct vectors *);
 
@@ -44,5 +33,8 @@ struct multipath * add_map_without_path (struct vectors * vecs,
                                start_waiter_thread_func *start_waiter);
 struct multipath * add_map_with_path (struct vectors * vecs,
                                struct path * pp, int add_vec);
+int update_multipath (struct vectors *vecs, char *mapname);
+void update_queue_mode_del_path(struct multipath *mpp);
+void update_queue_mode_add_path(struct multipath *mpp);
 
 #endif /* _STRUCTS_VEC_H */
diff --git a/libmultipath/waiter.c b/libmultipath/waiter.c
new file mode 100644 (file)
index 0000000..75ed90c
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * 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 "vector.h"
+#include "memory.h"
+#include "checkers.h"
+#include "structs.h"
+#include "structs_vec.h"
+#include "devmapper.h"
+#include "debug.h"
+#include "lock.h"
+#include "waiter.h"
+
+struct event_thread *alloc_waiter (void)
+{
+
+       struct event_thread *wp;
+
+       wp = (struct event_thread *)MALLOC(sizeof(struct event_thread));
+
+       return wp;
+}
+
+void free_waiter (void *data)
+{
+       struct event_thread *wp = (struct event_thread *)data;
+
+       /*
+        * indicate in mpp that the wp is already freed storage
+        */
+       lock(wp->vecs->lock);
+
+       if (wp->mpp)
+               /*
+                * be careful, mpp may already be freed -- null if so
+                */
+               wp->mpp->waiter = NULL;
+       else
+               condlog(3, "free_waiter, mpp freed before wp=%p,", wp);
+
+       unlock(wp->vecs->lock);
+
+       if (wp->dmt)
+               dm_task_destroy(wp->dmt);
+
+       FREE(wp);
+}
+
+void stop_waiter_thread (struct multipath *mpp, struct vectors *vecs)
+{
+       struct event_thread *wp = (struct event_thread *)mpp->waiter;
+       
+       if (!wp) {
+               condlog(3, "%s: no waiter thread", mpp->alias);
+               return;
+       }
+       condlog(2, "%s: stop event checker thread", wp->mapname);
+       pthread_kill((pthread_t)wp->thread, SIGUSR1);
+}
+
+static sigset_t unblock_signals(void)
+{
+       sigset_t set, old;
+
+       sigemptyset(&set);
+       sigaddset(&set, SIGHUP);
+       sigaddset(&set, SIGUSR1);
+       pthread_sigmask(SIG_UNBLOCK, &set, &old);
+       return old;
+}
+
+/*
+ * returns the reschedule delay
+ * negative means *stop*
+ */
+int waiteventloop (struct event_thread *waiter)
+{
+       sigset_t set;
+       int event_nr;
+       int r;
+
+       if (!waiter->event_nr)
+               waiter->event_nr = dm_geteventnr(waiter->mapname);
+
+       if (!(waiter->dmt = 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);
+               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);
+               return 1;
+       }
+
+       dm_task_no_open_count(waiter->dmt);
+       
+       /* accept wait interruption */
+       set = unblock_signals();
+
+       /* interruption spits messages */
+       dm_shut_log();
+
+       /* wait */
+       r = dm_task_run(waiter->dmt);
+
+       /* wait is over : event or interrupt */
+       pthread_sigmask(SIG_SETMASK, &set, NULL);
+       //dm_restore_log();
+
+       if (!r) /* wait interrupted by signal */
+               return -1;
+
+       dm_task_destroy(waiter->dmt);
+       waiter->dmt = NULL;
+       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);
+               r = update_multipath(waiter->vecs, waiter->mapname);
+               lock_cleanup_pop(waiter->vecs->lock);
+
+               if (r)
+                       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 */
+}
+
+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);
+
+       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)
+{
+       pthread_attr_t attr;
+       struct event_thread *wp;
+
+       if (!mpp)
+               return 0;
+
+       if (pthread_attr_init(&attr))
+               goto out;
+
+       pthread_attr_setstacksize(&attr, 32 * 1024);
+       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+       wp = alloc_waiter();
+
+       if (!wp)
+               goto out;
+
+       mpp->waiter = (void *)wp;
+       strncpy(wp->mapname, mpp->alias, WWID_SIZE);
+       wp->vecs = vecs;
+       wp->mpp = mpp;
+
+       if (pthread_create(&wp->thread, &attr, waitevent, wp)) {
+               condlog(0, "%s: cannot create event checker", wp->mapname);
+               goto out1;
+       }
+       condlog(2, "%s: event checker started", wp->mapname);
+
+       return 0;
+out1:
+       free_waiter(wp);
+       mpp->waiter = NULL;
+out:
+       condlog(0, "failed to start waiter thread");
+       return 1;
+}
+
diff --git a/libmultipath/waiter.h b/libmultipath/waiter.h
new file mode 100644 (file)
index 0000000..468ce5f
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef _WAITER_H
+#define _WAITER_H
+
+struct event_thread {
+       struct dm_task *dmt;
+       pthread_t thread;
+       int event_nr;
+       char mapname[WWID_SIZE];
+       struct vectors *vecs;
+       struct multipath *mpp;
+};
+
+struct event_thread * alloc_waiter (void);
+void free_waiter (void *data);
+void stop_waiter_thread (struct multipath *mpp, struct vectors *vecs);
+int start_waiter_thread (struct multipath *mpp, struct vectors *vecs);
+int waiteventloop (struct event_thread *waiter);
+void *waitevent (void *et);
+
+#endif /* _WAITER_H */
index 55a2c49..939fdd9 100644 (file)
@@ -55,6 +55,8 @@
 #include "uxclnt.h"
 #include "cli.h"
 #include "cli_handlers.h"
+#include "lock.h"
+#include "waiter.h"
 
 #define FILE_NAME_SIZE 256
 #define CMDSIZE 160
 #define LOG_MSG(a,b) \
        if (strlen(b)) condlog(a, "%s: %s", pp->dev_t, b);
 
-#ifdef LCKDBG
-#define lock(a) \
-       fprintf(stderr, "%s:%s(%i) lock %p\n", __FILE__, __FUNCTION__, __LINE__, a); \
-       pthread_mutex_lock(a)
-#define unlock(a) \
-       fprintf(stderr, "%s:%s(%i) unlock %p\n", __FILE__, __FUNCTION__, __LINE__, a); \
-       pthread_mutex_unlock(a)
-#define lock_cleanup_pop(a) \
-       fprintf(stderr, "%s:%s(%i) unlock %p\n", __FILE__, __FUNCTION__, __LINE__, a); \
-       pthread_cleanup_pop(1);
-#else
-#define lock(a) pthread_mutex_lock(a)
-#define unlock(a) pthread_mutex_unlock(a)
-#define lock_cleanup_pop(a) pthread_cleanup_pop(1);
-#endif
-
 pthread_cond_t exit_cond = PTHREAD_COND_INITIALIZER;
 pthread_mutex_t exit_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 /*
- * structs
+ * global copy of vecs for use in sig handlers
  */
-struct vectors * gvecs; /* global copy of vecs for use in sig handlers */
-
-static struct event_thread *
-alloc_waiter (void)
-{
-
-       struct event_thread * wp;
-
-       wp = (struct event_thread *)MALLOC(sizeof(struct event_thread));
-
-       return wp;
-}
-
-static void
-free_waiter (void * data)
-{
-       struct event_thread * wp = (struct event_thread *)data;
-
-       /*
-        * indicate in mpp that the wp is already freed storage
-        */
-       lock(wp->vecs->lock);
-
-       if (wp->mpp)
-               /*
-                * be careful, mpp may already be freed -- null if so
-                */
-               wp->mpp->waiter = NULL;
-       else
-               condlog(3, "free_waiter, mpp freed before wp=%p,", wp);
-
-       unlock(wp->vecs->lock);
-
-       if (wp->dmt)
-               dm_task_destroy(wp->dmt);
-
-       FREE(wp);
-}
-
-static void
-stop_waiter_thread (struct multipath * mpp, struct vectors * vecs)
-{
-       struct event_thread * wp = (struct event_thread *)mpp->waiter;
-       
-       if (!wp) {
-               condlog(3, "%s: no waiter thread", mpp->alias);
-               return;
-       }
-       condlog(2, "%s: stop event checker thread", wp->mapname);
-       pthread_kill((pthread_t)wp->thread, SIGUSR1);
-}
-
-static void
-cleanup_lock (void * data)
-{
-       unlock((pthread_mutex_t *)data);
-}
-
-/*
- * mpp->no_path_retry:
- *   -2 (QUEUE) : queue_if_no_path enabled, never turned off
- *   -1 (FAIL)  : fail_if_no_path
- *    0 (UNDEF) : nothing
- *   >0         : queue_if_no_path enabled, turned off after polling n times
- */
-static void
-update_queue_mode_del_path(struct multipath *mpp)
-{
-       if (--mpp->nr_active == 0 && mpp->no_path_retry > 0) {
-               /*
-                * Enter retry mode.
-                * meaning of +1: retry_tick may be decremented in
-                *                checkerloop before starting retry.
-                */
-               mpp->stat_queueing_timeouts++;
-               mpp->retry_tick = mpp->no_path_retry * conf->checkint + 1;
-               condlog(1, "%s: Entering recovery mode: max_retries=%d",
-                       mpp->alias, mpp->no_path_retry);
-       }
-       condlog(2, "%s: remaining active paths: %d", mpp->alias, mpp->nr_active);
-}
-
-static void
-update_queue_mode_add_path(struct multipath *mpp)
-{
-       if (mpp->nr_active++ == 0 && mpp->no_path_retry > 0) {
-               /* come back to normal mode from retry mode */
-               mpp->retry_tick = 0;
-               dm_queue_if_no_path(mpp->alias, 1);
-               condlog(2, "%s: queue_if_no_path enabled", mpp->alias);
-               condlog(1, "%s: Recovered to normal mode", mpp->alias);
-       }
-       condlog(2, "%s: remaining active paths: %d", mpp->alias, mpp->nr_active);
-}
+struct vectors * gvecs;
 
 static int
 need_switch_pathgroup (struct multipath * mpp, int refresh)
@@ -253,228 +146,6 @@ coalesce_maps(struct vectors *vecs, vector nmpv)
        return 0;
 }
 
-static int
-update_multipath (struct vectors *vecs, char *mapname)
-{
-       struct multipath *mpp;
-       struct pathgroup  *pgp;
-       struct path *pp;
-       int i, j;
-       int r = 1;
-
-       mpp = find_mp_by_alias(vecs->mpvec, mapname);
-
-       if (!mpp)
-               goto out;
-
-       free_pgvec(mpp->pg, KEEP_PATHS);
-       mpp->pg = NULL;
-
-       if (setup_multipath(vecs, mpp))
-               goto out; /* mpp freed in setup_multipath */
-
-       /*
-        * compare checkers states with DM states
-        */
-       vector_foreach_slot (mpp->pg, pgp, i) {
-               vector_foreach_slot (pgp->paths, pp, j) {
-                       if (pp->dmstate != PSTATE_FAILED)
-                               continue;
-
-                       if (pp->state != PATH_DOWN) {
-                               int oldstate = pp->state;
-                               condlog(2, "%s: mark as failed", pp->dev_t);
-                               mpp->stat_path_failures++;
-                               pp->state = PATH_DOWN;
-                               if (oldstate == PATH_UP ||
-                                   oldstate == PATH_GHOST)
-                                       update_queue_mode_del_path(mpp);
-
-                               /*
-                                * if opportune,
-                                * schedule the next check earlier
-                                */
-                               if (pp->tick > conf->checkint)
-                                       pp->tick = conf->checkint;
-                       }
-               }
-       }
-       r = 0;
-out:
-       if (r)
-               condlog(0, "failed to update multipath");
-
-       return r;
-}
-
-static sigset_t unblock_signals(void)
-{
-       sigset_t set, old;
-
-       sigemptyset(&set);
-       sigaddset(&set, SIGHUP);
-       sigaddset(&set, SIGUSR1);
-       pthread_sigmask(SIG_UNBLOCK, &set, &old);
-       return old;
-}
-
-/*
- * returns the reschedule delay
- * negative means *stop*
- */
-static int
-waiteventloop (struct event_thread * waiter)
-{
-       sigset_t set;
-       int event_nr;
-       int r;
-
-       if (!waiter->event_nr)
-               waiter->event_nr = dm_geteventnr(waiter->mapname);
-
-       if (!(waiter->dmt = 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);
-               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);
-               return 1;
-       }
-
-       dm_task_no_open_count(waiter->dmt);
-       
-       /* accept wait interruption */
-       set = unblock_signals();
-
-       /* interruption spits messages */
-       dm_shut_log();
-
-       /* wait */
-       r = dm_task_run(waiter->dmt);
-
-       /* wait is over : event or interrupt */
-       pthread_sigmask(SIG_SETMASK, &set, NULL);
-       //dm_restore_log();
-
-       if (!r) /* wait interrupted by signal */
-               return -1;
-
-       dm_task_destroy(waiter->dmt);
-       waiter->dmt = NULL;
-       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);
-               r = update_multipath(waiter->vecs, waiter->mapname);
-               lock_cleanup_pop(waiter->vecs->lock);
-
-               if (r)
-                       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);
-
-       while (1) {
-               r = waiteventloop(waiter);
-
-               if (r < 0)
-                       break;
-
-               sleep(r);
-       }
-
-       pthread_cleanup_pop(1);
-       return NULL;
-}
-
-static int
-start_waiter_thread (struct multipath * mpp, struct vectors * vecs)
-{
-       pthread_attr_t attr;
-       struct event_thread * wp;
-
-       if (!mpp)
-               return 0;
-
-       if (pthread_attr_init(&attr))
-               goto out;
-
-       pthread_attr_setstacksize(&attr, 32 * 1024);
-       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
-       wp = alloc_waiter();
-
-       if (!wp)
-               goto out;
-
-       mpp->waiter = (void *)wp;
-       strncpy(wp->mapname, mpp->alias, WWID_SIZE);
-       wp->vecs = vecs;
-       wp->mpp = mpp;
-
-       if (pthread_create(&wp->thread, &attr, waitevent, wp)) {
-               condlog(0, "%s: cannot create event checker", wp->mapname);
-               goto out1;
-       }
-       condlog(2, "%s: event checker started", wp->mapname);
-
-       return 0;
-out1:
-       free_waiter(wp);
-       mpp->waiter = NULL;
-out:
-       condlog(0, "failed to start waiter thread");
-       return 1;
-}
-
 static void
 sync_map_state(struct multipath *mpp)
 {