From patchwork Wed Mar 14 17:46:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Marzinski X-Patchwork-Id: 10284177 X-Patchwork-Delegate: christophe.varoqui@free.fr Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5710560291 for ; Thu, 15 Mar 2018 09:34:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 550E828962 for ; Thu, 15 Mar 2018 09:34:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4967F28971; Thu, 15 Mar 2018 09:34:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0B97F28962 for ; Thu, 15 Mar 2018 09:34:27 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 442087FEC2; Thu, 15 Mar 2018 09:34:26 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 222AF17101; Thu, 15 Mar 2018 09:34:26 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id EAB84181B9FF; Thu, 15 Mar 2018 09:34:25 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w2EHl3Ex031408 for ; Wed, 14 Mar 2018 13:47:15 -0400 Received: by smtp.corp.redhat.com (Postfix) id 46148AFD5C; Wed, 14 Mar 2018 17:47:03 +0000 (UTC) Delivered-To: dm-devel@redhat.com Received: from redhat.com (octiron.msp.redhat.com [10.15.80.209]) by smtp.corp.redhat.com (Postfix) with SMTP id 1852EAFD58; Wed, 14 Mar 2018 17:47:02 +0000 (UTC) Received: by redhat.com (sSMTP sendmail emulation); Wed, 14 Mar 2018 12:47:01 -0500 From: "Benjamin Marzinski" To: dm-devel@redhat.com Date: Wed, 14 Mar 2018 12:46:41 -0500 Message-Id: <1521049605-22050-9-git-send-email-bmarzins@redhat.com> In-Reply-To: <1521049605-22050-1-git-send-email-bmarzins@redhat.com> References: <1521049605-22050-1-git-send-email-bmarzins@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-loop: dm-devel@redhat.com X-Mailman-Approved-At: Thu, 15 Mar 2018 05:30:53 -0400 Cc: Martin Wilck , christophe.varoqui@free.fr Subject: [dm-devel] [PATCH 08/12] move waiter code from libmultipath to multipathd X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: device-mapper development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Thu, 15 Mar 2018 09:34:26 +0000 (UTC) X-Virus-Scanned: ClamAV using ClamSMTP 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. Reviewed-by: Martin Wilck Signed-off-by: Benjamin Marzinski --- 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 806aaa2..f51786d 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 dm-generic.o generic.o foreign.o all: $(LIBS) diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c index 41e5d88..9a01631 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" @@ -108,17 +107,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) { @@ -380,92 +368,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, vecs)) { - 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, const 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 2a0be93..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, const 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 -#include -#include -#include -#include -#include - -#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 4c9d296..7800e47 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 32cd6fe..2924d53 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -316,6 +316,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, vecs)) { + 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, const 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 +#include +#include +#include +#include +#include + +#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 */