[dm-devel] [PATCH v2] multipathd: fix client response for socket activation
Benjamin Marzinski
bmarzins at redhat.com
Fri May 3 18:54:58 UTC 2019
On Wed, May 01, 2019 at 12:41:38AM +0200, Martin Wilck wrote:
> 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().
Reviewed-by: Benjamin Marzinski <bmarzins at redhat.com>
>
> Signed-off-by: Martin Wilck <mwilck at suse.com>
> ---
> 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) {
> --
> 2.21.0
More information about the dm-devel
mailing list