From patchwork Wed Mar 7 14:17:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Wilck X-Patchwork-Id: 10264179 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 4BAD6602BD for ; Wed, 7 Mar 2018 14:18:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3BD0C29550 for ; Wed, 7 Mar 2018 14:18:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3080029554; Wed, 7 Mar 2018 14:18:39 +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 7C31929550 for ; Wed, 7 Mar 2018 14:18:38 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7803EC057FA4; Wed, 7 Mar 2018 14:18:37 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2230D5D6A3; Wed, 7 Mar 2018 14:18:37 +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 902B64CA99; Wed, 7 Mar 2018 14:18:36 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w27EIZbD030699 for ; Wed, 7 Mar 2018 09:18:35 -0500 Received: by smtp.corp.redhat.com (Postfix) id 76E75601A3; Wed, 7 Mar 2018 14:18:35 +0000 (UTC) Delivered-To: dm-devel@redhat.com Received: from mx1.redhat.com (ext-mx03.extmail.prod.ext.phx2.redhat.com [10.5.110.27]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0441C6017F; Wed, 7 Mar 2018 14:18:33 +0000 (UTC) Received: from smtp.nue.novell.com (smtp.nue.novell.com [195.135.221.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1D9C7804E0; Wed, 7 Mar 2018 14:18:31 +0000 (UTC) Received: from emea4-mta.ukb.novell.com ([10.120.13.87]) by smtp.nue.novell.com with ESMTP (TLS encrypted); Wed, 07 Mar 2018 15:18:29 +0100 Received: from apollon.suse.de.de (nwb-a10-snat.microfocus.com [10.120.13.202]) by emea4-mta.ukb.novell.com with ESMTP (TLS encrypted); Wed, 07 Mar 2018 14:18:08 +0000 From: Martin Wilck To: Christophe Varoqui , Benjamin Marzinski Date: Wed, 7 Mar 2018 15:17:51 +0100 Message-Id: <20180307141751.29084-1-mwilck@suse.com> X-Greylist: Sender passed SPF test, Sender IP whitelisted by DNSRBL, ACL 207 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Wed, 07 Mar 2018 14:18:32 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Wed, 07 Mar 2018 14:18:32 +0000 (UTC) for IP:'195.135.221.5' DOMAIN:'smtp.nue.novell.com' HELO:'smtp.nue.novell.com' FROM:'mwilck@suse.com' RCPT:'' X-RedHat-Spam-Score: -2.301 (RCVD_IN_DNSWL_MED, SPF_PASS) 195.135.221.5 smtp.nue.novell.com 195.135.221.5 smtp.nue.novell.com X-Scanned-By: MIMEDefang 2.78 on 10.5.110.27 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-loop: dm-devel@redhat.com Cc: dm-devel@redhat.com, Martin Wilck Subject: [dm-devel] [RFC PATCH] multipathd: strict_timing without signals 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.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Wed, 07 Mar 2018 14:18:37 +0000 (UTC) X-Virus-Scanned: ClamAV using ClamSMTP The internal usage of SIGALRM by setitimer() function may cause subtle conflicts with other uses of SIGALRM, either by multipath-tools code itself (e.g. lock_file()) or libc (e.g. glob()). This patch changes the checkerloop to use an interval timer and a pthread condition variable. No signals are used except those used by libpthread behind the scenes. Signed-off-by: Martin Wilck --- multipathd/Makefile | 2 +- multipathd/main.c | 113 ++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 85 insertions(+), 30 deletions(-) diff --git a/multipathd/Makefile b/multipathd/Makefile index 4c9d29634160..c348f02ef7f8 100644 --- a/multipathd/Makefile +++ b/multipathd/Makefile @@ -10,7 +10,7 @@ CFLAGS += $(BIN_CFLAGS) -I$(multipathdir) -I$(mpathpersistdir) \ -I$(mpathcmddir) -I$(thirdpartydir) LDFLAGS += $(BIN_LDFLAGS) LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ - -L$(mpathcmddir) -lmpathcmd -ludev -ldl -lurcu -lpthread \ + -L$(mpathcmddir) -lmpathcmd -ludev -ldl -lurcu -lpthread -lrt \ -ldevmapper -lreadline ifdef SYSTEMD diff --git a/multipathd/main.c b/multipathd/main.c index 6e6c52a52783..c9c57c5baece 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -1848,6 +1848,68 @@ static void init_path_check_interval(struct vectors *vecs) } } +static pthread_mutex_t checker_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t checker_cond = PTHREAD_COND_INITIALIZER; + +static void checker_notify(union sigval sv) { + + pthread_mutex_lock(&checker_lock); + pthread_cond_broadcast(&checker_cond); + pthread_mutex_unlock(&checker_lock); +} + +static void unlock_mutex(void *arg) +{ + pthread_mutex_unlock((pthread_mutex_t*)arg); +} + +void cleanup_timer(void *arg) +{ + timer_t tmr = (timer_t)arg; + + if (tmr != 0) + timer_delete(tmr); +} + +static timer_t setup_check_timer(void) +{ + timer_t tmr = (timer_t)0; + struct sigevent se; + + memset(&se, 0, sizeof(se)); + se.sigev_notify = SIGEV_THREAD; + se.sigev_notify_function = checker_notify; + + if (timer_create(CLOCK_MONOTONIC, &se, &tmr)) { + condlog(2, "%s: errno %d creating monotonic timer", + __func__, errno); + if (timer_create(CLOCK_REALTIME, &se, &tmr)) + condlog(0, "%s: errno %d creating timer", + __func__, errno); + } + return tmr; +} + +static int set_check_timer(timer_t tmr, bool arm) +{ + struct itimerspec is; + + if (tmr == 0) + return -1; + + if (arm) { + is.it_value.tv_sec = 1; + is.it_interval.tv_sec = 1; + } else { + is.it_value.tv_sec = 0; + is.it_interval.tv_sec = 0; + } + is.it_value.tv_nsec = 0; + is.it_interval.tv_nsec = 0; + + return timer_settime(tmr, 0, &is, NULL); +} + static void * checkerloop (void *ap) { @@ -1855,9 +1917,10 @@ checkerloop (void *ap) struct path *pp; int count = 0; unsigned int i; - struct itimerval timer_tick_it; struct timespec last_time; struct config *conf; + timer_t check_timer; + int old_strict_timing = 0; pthread_cleanup_push(rcu_unregister, NULL); rcu_register_thread(); @@ -1865,6 +1928,9 @@ checkerloop (void *ap) vecs = (struct vectors *)ap; condlog(2, "path checkers start up"); + check_timer = setup_check_timer(); + pthread_cleanup_push(cleanup_timer, (void*)check_timer); + /* Tweak start time for initial path check */ if (clock_gettime(CLOCK_MONOTONIC, &last_time) != 0) last_time.tv_sec = 0; @@ -1873,8 +1939,7 @@ checkerloop (void *ap) while (1) { struct timespec diff_time, start_time, end_time; - int num_paths = 0, ticks = 0, signo, strict_timing, rc = 0; - sigset_t mask; + int num_paths = 0, ticks = 0, strict_timing, rc = 0; if (clock_gettime(CLOCK_MONOTONIC, &start_time) != 0) start_time.tv_sec = 0; @@ -1956,40 +2021,30 @@ checkerloop (void *ap) } check_foreign(); post_config_state(DAEMON_IDLE); + conf = get_multipath_config(); strict_timing = conf->strict_timing; put_multipath_config(conf); - if (!strict_timing) + + if (check_timer && (old_strict_timing != strict_timing) && + set_check_timer(check_timer, !!strict_timing) != 0) { + condlog(1, "%s: errno %d %sarming interrupt timer", + __func__, errno, strict_timing ? "" : "dis"); + strict_timing = 0; + } + old_strict_timing = strict_timing; + + if (!strict_timing || !check_timer) sleep(1); else { - timer_tick_it.it_interval.tv_sec = 0; - timer_tick_it.it_interval.tv_usec = 0; - if (diff_time.tv_nsec) { - timer_tick_it.it_value.tv_sec = 0; - timer_tick_it.it_value.tv_usec = - 1000UL * 1000 * 1000 - diff_time.tv_nsec; - } else { - timer_tick_it.it_value.tv_sec = 1; - timer_tick_it.it_value.tv_usec = 0; - } - setitimer(ITIMER_REAL, &timer_tick_it, NULL); - - sigemptyset(&mask); - sigaddset(&mask, SIGALRM); - condlog(3, "waiting for %lu.%06lu secs", - timer_tick_it.it_value.tv_sec, - timer_tick_it.it_value.tv_usec); - if (sigwait(&mask, &signo) != 0) { - condlog(3, "sigwait failed with error %d", - errno); - conf = get_multipath_config(); - conf->strict_timing = 0; - put_multipath_config(conf); - break; - } + pthread_mutex_lock(&checker_lock); + pthread_cleanup_push(unlock_mutex, &checker_lock); + pthread_cond_wait(&checker_cond, &checker_lock); + pthread_cleanup_pop(1); } } pthread_cleanup_pop(1); + pthread_cleanup_pop(1); return NULL; }