From patchwork Tue Apr 30 22:41:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Wilck X-Patchwork-Id: 10924253 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-2.web.codeaurora.org (Postfix) with ESMTP id BB3A1912 for ; Tue, 30 Apr 2019 22:42:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A935028B0D for ; Tue, 30 Apr 2019 22:42:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9C5AB28DEB; Tue, 30 Apr 2019 22:42:16 +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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 2360F28B0D for ; Tue, 30 Apr 2019 22:42:16 +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 EA588308FECF; Tue, 30 Apr 2019 22:42:14 +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 A787A62661; Tue, 30 Apr 2019 22:42:14 +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 875043FB11; Tue, 30 Apr 2019 22:42:13 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x3UMgBB3018070 for ; Tue, 30 Apr 2019 18:42:11 -0400 Received: by smtp.corp.redhat.com (Postfix) id 911056F543; Tue, 30 Apr 2019 22:42:11 +0000 (UTC) Delivered-To: dm-devel@redhat.com Received: from mx1.redhat.com (ext-mx06.extmail.prod.ext.phx2.redhat.com [10.5.110.30]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3025E6B8FA; Tue, 30 Apr 2019 22:42:09 +0000 (UTC) Received: from smtp2.provo.novell.com (smtp2.provo.novell.com [137.65.250.81]) (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 9F5873680B; Tue, 30 Apr 2019 22:42:07 +0000 (UTC) Received: from apollon.suse.de.de (prva10-snat226-2.provo.novell.com [137.65.226.36]) by smtp2.provo.novell.com with ESMTP (TLS encrypted); Tue, 30 Apr 2019 16:41:55 -0600 From: Martin Wilck To: Christophe Varoqui , Benjamin Marzinski Date: Wed, 1 May 2019 00:41:38 +0200 Message-Id: <20190430224138.22391-1-mwilck@suse.com> MIME-Version: 1.0 X-Greylist: Sender passed SPF test, Sender IP whitelisted by DNSRBL, ACL 216 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Tue, 30 Apr 2019 22:42:08 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Tue, 30 Apr 2019 22:42:08 +0000 (UTC) for IP:'137.65.250.81' DOMAIN:'smtp2.provo.novell.com' HELO:'smtp2.provo.novell.com' FROM:'mwilck@suse.com' RCPT:'' X-RedHat-Spam-Score: -2.301 (RCVD_IN_DNSWL_MED, SPF_PASS) 137.65.250.81 smtp2.provo.novell.com 137.65.250.81 smtp2.provo.novell.com X-Scanned-By: MIMEDefang 2.78 on 10.5.110.30 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: dm-devel@redhat.com Cc: dm-devel@redhat.com, Martin Wilck Subject: [dm-devel] [PATCH v2] multipathd: fix client response for socket activation 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: , 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.49]); Tue, 30 Apr 2019 22:42:15 +0000 (UTC) X-Virus-Scanned: ClamAV using ClamSMTP When a client wakes up multipathd through the socket, it is likely that the ux listener responds to client requests before multipathd startup has completed. This means that client commands such as "show paths" or "show topology" return success with an empty result, which is quite confusing. Therefore, in the ux listener, don't start answering client requests while the daemon is configuring. Rather, wait for some other daemon state. We can't wait hard, because the ux listener must also handle signals. So just wait for some short time, and poll again. This has the side effect that command responses for commands that don't require full initialization, such as "show wildcards", "show config" or "shutdown", are also delayed until the configuration stage has completed. But that seems to be a relatively cheap price to pay for getting the expected response for other commands. To avoid this side effect, the client handling would need to be rewritten such that the uxlsnr thread would have a means to "know" which commands require the configuration stage to complete and which do not. v2: Removed an unrelated, unnecessary hunk in child(). Signed-off-by: Martin Wilck Reviewed-by: Benjamin Marzinski --- multipathd/main.c | 27 +++++++++++++++++++++++++++ multipathd/main.h | 2 ++ multipathd/uxlsnr.c | 12 ++++++++++++ 3 files changed, 41 insertions(+) diff --git a/multipathd/main.c b/multipathd/main.c index f203d77f..ad818320 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -220,6 +220,33 @@ static void config_cleanup(void *arg) pthread_mutex_unlock(&config_lock); } +/* + * If the current status is @oldstate, wait for at most @ms milliseconds + * for the state to change, and return the new state, which may still be + * @oldstate. + */ +enum daemon_status wait_for_state_change_if(enum daemon_status oldstate, + unsigned long ms) +{ + enum daemon_status st; + struct timespec tmo; + + if (oldstate == DAEMON_SHUTDOWN) + return DAEMON_SHUTDOWN; + + pthread_mutex_lock(&config_lock); + pthread_cleanup_push(config_cleanup, NULL); + st = running_state; + if (st == oldstate && clock_gettime(CLOCK_MONOTONIC, &tmo) == 0) { + tmo.tv_nsec += ms * 1000 * 1000; + normalize_timespec(&tmo); + (void)pthread_cond_timedwait(&config_cond, &config_lock, &tmo); + st = running_state; + } + pthread_cleanup_pop(1); + return st; +} + /* must be called with config_lock held */ static void __post_config_state(enum daemon_status state) { diff --git a/multipathd/main.h b/multipathd/main.h index e5c1398f..7bb8463f 100644 --- a/multipathd/main.h +++ b/multipathd/main.h @@ -20,6 +20,8 @@ extern int uxsock_timeout; void exit_daemon(void); const char * daemon_status(void); +enum daemon_status wait_for_state_change_if(enum daemon_status oldstate, + unsigned long ms); int need_to_delay_reconfig (struct vectors *); int reconfigure (struct vectors *); int ev_add_path (struct path *, struct vectors *, int); diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c index 773bc878..04cbb7c7 100644 --- a/multipathd/uxlsnr.c +++ b/multipathd/uxlsnr.c @@ -249,6 +249,18 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock, continue; } + /* + * Client connection. We shouldn't answer while we're + * configuring - nothing may be configured yet. + * But we can't wait forever either, because this thread + * must handle signals. So wait a short while only. + */ + if (wait_for_state_change_if(DAEMON_CONFIGURE, 10) + == DAEMON_CONFIGURE) { + handle_signals(false); + continue; + } + /* see if a client wants to speak to us */ for (i = 1; i < num_clients + 1; i++) { if (polls[i].revents & POLLIN) {