[dm-devel] [PATCH v2 23/23] multipathd: fix signal blocking logic
Benjamin Marzinski
bmarzins at redhat.com
Wed Mar 7 20:24:39 UTC 2018
On Tue, Mar 06, 2018 at 12:15:07AM +0100, Martin Wilck wrote:
> multipathd is supposed to block all signals in all threads, except
> the uxlsnr thread which handles termination and reconfiguration
> signals (SIGUSR1) in its ppoll() call, SIGUSR2 in the waiter thread
> and the marginal path checker thread, and occasional SIGALRM. The current
> logic does exactly the oppsite, it blocks termination signals in SIGPOLL and
> allows multipathd to be killed e.g. by SIGALRM.
>
> Fix that by inverting the logic. The argument to pthread_sigmask and
> ppoll is the set of *blocked* signals, not vice versa.
>
> The marginal paths code needs to unblock SIGUSR2 now explicity, as
> the dm-event waiter code already does. Doing this with pselect()
> avoids asynchronous cancellation.
>
> Fixes: 810082e "libmultipath, multipathd: Rework SIGPIPE handling"
> Fixes: 534ec4c "multipathd: Ensure that SIGINT, SIGTERM, SIGHUP and SIGUSR1
> are delivered to the uxsock thread"
>
Reviewed-by: Benjamin Marzinski <bmarzins at redhat.com>
> Signed-off-by: Martin Wilck <mwilck at suse.com>
> ---
> libmultipath/io_err_stat.c | 17 ++++++++++++++++-
> multipathd/main.c | 7 +++++--
> multipathd/uxlsnr.c | 10 +++++-----
> 3 files changed, 26 insertions(+), 8 deletions(-)
>
> diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c
> index 5b10f0372f9f..00bac9e0e755 100644
> --- a/libmultipath/io_err_stat.c
> +++ b/libmultipath/io_err_stat.c
> @@ -21,6 +21,7 @@
> #include <libaio.h>
> #include <errno.h>
> #include <sys/mman.h>
> +#include <sys/select.h>
>
> #include "vector.h"
> #include "memory.h"
> @@ -691,14 +692,28 @@ static void service_paths(void)
>
> static void *io_err_stat_loop(void *data)
> {
> + sigset_t set;
> +
> vecs = (struct vectors *)data;
> pthread_cleanup_push(rcu_unregister, NULL);
> rcu_register_thread();
>
> + sigfillset(&set);
> + sigdelset(&set, SIGUSR2);
> +
> mlockall(MCL_CURRENT | MCL_FUTURE);
> while (1) {
> + struct timespec ts;
> +
> service_paths();
> - usleep(100000);
> +
> + ts.tv_sec = 0;
> + ts.tv_nsec = 100 * 1000 * 1000;
> + /*
> + * pselect() with no fds, a timeout, and a sigmask:
> + * sleep for 100ms and react on SIGUSR2.
> + */
> + pselect(1, NULL, NULL, NULL, &ts, &set);
> }
>
> pthread_cleanup_pop(1);
> diff --git a/multipathd/main.c b/multipathd/main.c
> index 4abdd8f071c3..68595836d723 100644
> --- a/multipathd/main.c
> +++ b/multipathd/main.c
> @@ -2261,10 +2261,13 @@ signal_init(void)
> {
> sigset_t set;
>
> - sigemptyset(&set);
> - sigaddset(&set, SIGUSR2);
> + /* block all signals */
> + sigfillset(&set);
> + /* SIGPIPE occurs if logging fails */
> + sigdelset(&set, SIGPIPE);
> pthread_sigmask(SIG_SETMASK, &set, NULL);
>
> + /* Other signals will be unblocked in the uxlsnr thread */
> signal_set(SIGHUP, sighup);
> signal_set(SIGUSR1, sigusr1);
> signal_set(SIGUSR2, sigusr2);
> diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c
> index 98ac25a68c43..a2ca36ba1653 100644
> --- a/multipathd/uxlsnr.c
> +++ b/multipathd/uxlsnr.c
> @@ -170,11 +170,11 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, void * trigger_data)
> condlog(0, "uxsock: failed to allocate poll fds");
> return NULL;
> }
> - sigemptyset(&mask);
> - sigaddset(&mask, SIGINT);
> - sigaddset(&mask, SIGTERM);
> - sigaddset(&mask, SIGHUP);
> - sigaddset(&mask, SIGUSR1);
> + sigfillset(&mask);
> + sigdelset(&mask, SIGINT);
> + sigdelset(&mask, SIGTERM);
> + sigdelset(&mask, SIGHUP);
> + sigdelset(&mask, SIGUSR1);
> while (1) {
> struct client *c, *tmp;
> int i, poll_count, num_clients;
> --
> 2.16.1
More information about the dm-devel
mailing list