multipath-tools: handle exit signal immediately
authorMartin Wilck <mwilck@suse.com>
Tue, 30 Jan 2018 14:16:24 +0000 (15:16 +0100)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Wed, 7 Mar 2018 09:02:16 +0000 (10:02 +0100)
multipathd shouldn't try to service any more client connections
when it receives an exit signal. Moreover, ppoll() can return
success even if signals occured. So check for reconfigure or
log_reset signals after handling pending client requests.

Based on an analysis by Chongyun Wu.

Reported-by: Chongyun Wu <wu.chongyun@h3c.com>
Signed-off-by: Martin Wilck <mwilck@suse.com>
multipathd/main.c
multipathd/main.h
multipathd/uxlsnr.c

index a8a0c30..b6075e0 100644 (file)
@@ -2183,12 +2183,15 @@ signal_set(int signo, void (*func) (int))
 }
 
 void
-handle_signals(void)
+handle_signals(bool nonfatal)
 {
        if (exit_sig) {
                condlog(2, "exit (signal)");
+               exit_sig = 0;
                exit_daemon();
        }
+       if (!nonfatal)
+               return;
        if (reconfig_sig) {
                condlog(2, "reconfigure (signal)");
                set_config_state(DAEMON_CONFIGURE);
@@ -2199,7 +2202,6 @@ handle_signals(void)
                log_reset("multipathd");
                pthread_mutex_unlock(&logq_lock);
        }
-       exit_sig = 0;
        reconfig_sig = 0;
        log_reset_sig = 0;
 }
index ee44dab..0e9c5e3 100644 (file)
@@ -38,6 +38,6 @@ int mpath_pr_event_handle(struct path *pp);
 void * mpath_pr_event_handler_fn (void * );
 int update_map_pr(struct multipath *mpp);
 void * mpath_pr_event_handler_fn (void * pathp );
-void handle_signals(void);
+void handle_signals(bool);
 
 #endif /* MAIN_H */
index 8aa0f83..52901a5 100644 (file)
@@ -240,9 +240,10 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, void * trigger_data)
                /* most of our life is spent in this call */
                poll_count = ppoll(polls, i, &sleep_time, &mask);
 
+               handle_signals(false);
                if (poll_count == -1) {
                        if (errno == EINTR) {
-                               handle_signals();
+                               handle_signals(true);
                                continue;
                        }
 
@@ -252,7 +253,7 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, void * trigger_data)
                }
 
                if (poll_count == 0) {
-                       handle_signals();
+                       handle_signals(true);
                        continue;
                }
 
@@ -311,6 +312,8 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, void * trigger_data)
                                FREE(inbuf);
                        }
                }
+               /* see if we got a non-fatal signal */
+               handle_signals(true);
 
                /* see if we got a new client */
                if (polls[0].revents & POLLIN) {