]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
REORG: mworker: move signal handlers and related functions
authorWilliam Lallemand <wlallemand@haproxy.com>
Mon, 1 Apr 2019 09:29:56 +0000 (11:29 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 1 Apr 2019 12:45:37 +0000 (14:45 +0200)
Move the following functions to mworker.c:

void mworker_catch_sighup(struct sig_handler *sh);
void mworker_catch_sigterm(struct sig_handler *sh);
void mworker_catch_sigchld(struct sig_handler *sh);

static void mworker_kill(int sig);
int current_child(int pid);

include/proto/mworker.h
include/types/global.h
src/haproxy.c
src/mworker.c

index 25d8c8c7f7b7e90553056da246a91c741eaead07..becb123a1df226f4a0bb7a6e47e1c1ccb18f27f2 100644 (file)
@@ -13,6 +13,8 @@
 #ifndef PROTO_MWORKER_H_
 #define PROTO_MWORKER_H_
 
+#include <types/signal.h>
+
 void mworker_proc_list_to_env();
 void mworker_env_to_proc_list();
 
@@ -20,7 +22,13 @@ void mworker_env_to_proc_list();
 void mworker_block_signals();
 void mworker_unblock_signals();
 
+void mworker_catch_sighup(struct sig_handler *sh);
+void mworker_catch_sigterm(struct sig_handler *sh);
+void mworker_catch_sigchld(struct sig_handler *sh);
+
 void mworker_accept_wrapper(int fd);
 void mworker_pipe_register();
 
+extern int *children; /* store PIDs of children in master workers mode */
+
 #endif /* PROTO_MWORKER_H_ */
index 009814bcbb11996062d16776c44a8bdac42f6e10..6b06e7f0f576dac19575bdda780e895f8070aaa7 100644 (file)
@@ -224,6 +224,7 @@ extern struct mworker_proc *proc_self; /* process structure of current process *
 extern int master; /* 1 if in master, 0 otherwise */
 extern unsigned int rlim_fd_cur_at_boot;
 extern unsigned int rlim_fd_max_at_boot;
+extern int atexit_flag;
 
 /* bit values to go with "warned" above */
 #define WARN_BLOCK_DEPRECATED       0x00000001
@@ -254,6 +255,9 @@ static inline unsigned long thread_mask(unsigned long mask)
        return mask ? mask : all_threads_mask;
 }
 
+int tell_old_pids(int sig);
+int delete_oldpid(int pid);
+
 void deinit(void);
 void hap_register_build_opts(const char *str, int must_free);
 void hap_register_post_check(int (*fct)());
index f3209de9ce45bf6a18bceab4d93d17e8c2272e67..52bf2be836270f0e2692c62484bdbe3564edb2c6 100644 (file)
@@ -202,8 +202,6 @@ static char *cur_unixsocket = NULL;
 
 int atexit_flag = 0;
 
-static int exitcode = -1;
-
 int nb_oldpids = 0;
 const int zero = 0;
 const int one = 1;
@@ -217,8 +215,6 @@ char localpeer[MAX_HOSTNAME_LEN];
  */
 int shut_your_big_mouth_gcc_int = 0;
 
-int *children = NULL; /* store PIDs of children in master workers mode */
-
 static char **next_argv = NULL;
 
 struct list proc_list = LIST_HEAD_INIT(proc_list);
@@ -488,7 +484,7 @@ static void usage(char *name)
 /* sends the signal <sig> to all pids found in <oldpids>. Returns the number of
  * pids the signal was correctly delivered to.
  */
-static int tell_old_pids(int sig)
+int tell_old_pids(int sig)
 {
        int p;
        int ret = 0;
@@ -498,34 +494,6 @@ static int tell_old_pids(int sig)
        return ret;
 }
 
-/* return 1 if a pid is a current child otherwise 0 */
-
-int current_child(int pid)
-{
-       int i;
-
-       for (i = 0; i < global.nbproc; i++) {
-               if (children[i] == pid)
-                       return 1;
-       }
-       return 0;
-}
-
-/*
- * Send signal to every known children.
- */
-
-static void mworker_kill(int sig)
-{
-       int i;
-
-       tell_old_pids(sig);
-       if (children) {
-               for (i = 0; i < global.nbproc; i++)
-                       kill(children[i], sig);
-       }
-}
-
 
 /*
  * Upon a reload, the master worker needs to close all listeners FDs but the mworker_pipe
@@ -726,98 +694,6 @@ alloc_error:
        return;
 }
 
-/*
- * When called, this function reexec haproxy with -sf followed by current
- * children PIDs and possibly old children PIDs if they didn't leave yet.
- */
-static void mworker_catch_sighup(struct sig_handler *sh)
-{
-       mworker_reload();
-}
-
-static void mworker_catch_sigterm(struct sig_handler *sh)
-{
-       int sig = sh->arg;
-
-#if defined(USE_SYSTEMD)
-       if (global.tune.options & GTUNE_USE_SYSTEMD) {
-               sd_notify(0, "STOPPING=1");
-       }
-#endif
-       ha_warning("Exiting Master process...\n");
-       mworker_kill(sig);
-}
-
-/*
- * Wait for every children to exit
- */
-
-static void mworker_catch_sigchld(struct sig_handler *sh)
-{
-       int exitpid = -1;
-       int status = 0;
-       struct mworker_proc *child, *it;
-       int childfound;
-
-restart_wait:
-
-       childfound = 0;
-
-       exitpid = waitpid(-1, &status, WNOHANG);
-       if (exitpid > 0) {
-               if (WIFEXITED(status))
-                       status = WEXITSTATUS(status);
-               else if (WIFSIGNALED(status))
-                       status = 128 + WTERMSIG(status);
-               else if (WIFSTOPPED(status))
-                       status = 128 + WSTOPSIG(status);
-               else
-                       status = 255;
-
-               list_for_each_entry_safe(child, it, &proc_list, list) {
-                       if (child->pid != exitpid)
-                               continue;
-
-                       LIST_DEL(&child->list);
-                       close(child->ipc_fd[0]);
-                       childfound = 1;
-                       break;
-               }
-
-               if (!children || !childfound) {
-                       ha_warning("Worker %d exited with code %d (%s)\n", exitpid, status, (status >= 128) ? strsignal(status - 128) : "Exit");
-               } else {
-                       /* check if exited child was in the current children list */
-                       if (current_child(exitpid)) {
-                               ha_alert("Current worker #%d (%d) exited with code %d (%s)\n", child->relative_pid, exitpid, status, (status >= 128) ? strsignal(status - 128) : "Exit");
-                               if (status != 0 && status != 130 && status != 143
-                                   && !(global.tune.options & GTUNE_NOEXIT_ONFAILURE)) {
-                                       ha_alert("exit-on-failure: killing every workers with SIGTERM\n");
-                                       if (exitcode < 0)
-                                               exitcode = status;
-                                       mworker_kill(SIGTERM);
-                               }
-                       } else {
-                               ha_warning("Former worker #%d (%d) exited with code %d (%s)\n", child->relative_pid, exitpid, status, (status >= 128) ? strsignal(status - 128) : "Exit");
-                               delete_oldpid(exitpid);
-                       }
-                       free(child);
-               }
-
-               /* do it again to check if it was the last worker */
-               goto restart_wait;
-       }
-       /* Better rely on the system than on a list of process to check if it was the last one */
-       else if (exitpid == -1 && errno == ECHILD) {
-               ha_warning("All workers exited. Exiting... (%d)\n", (exitcode > 0) ? exitcode : status);
-               atexit_flag = 0;
-               if (exitcode > 0)
-                       exit(exitcode);
-               exit(status); /* parent must leave using the latest status code known */
-       }
-
-}
-
 static void mworker_loop()
 {
 
index 2631764986c1c4f4f4ae9f1ca2a22224b0e2cc3e..786cc44e745bacee7a9220a258ccf58c230a5850 100644 (file)
 #include <signal.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/wait.h>
 
 #include <common/mini-clist.h>
 
 #include <proto/fd.h>
 #include <proto/listener.h>
+#include <proto/log.h>
 #include <proto/mworker.h>
 #include <proto/signal.h>
 
 #include <types/global.h>
+#include <types/signal.h>
 
+#if defined(USE_SYSTEMD)
+#include <systemd/sd-daemon.h>
+#endif
+
+static int exitcode = -1;
+
+int *children = NULL; /* store PIDs of children in master workers mode */
+
+/* ----- children processes handling ----- */
+
+/*
+ * Send signal to every known children.
+ */
+
+static void mworker_kill(int sig)
+{
+       int i;
+
+       /* TODO: merge mworker_kill and tell_old_pids for mworker mode */
+       tell_old_pids(sig);
+       if (children) {
+               for (i = 0; i < global.nbproc; i++)
+                       kill(children[i], sig);
+       }
+}
+
+
+/* return 1 if a pid is a current child otherwise 0 */
+int current_child(int pid)
+{
+       int i;
+
+       for (i = 0; i < global.nbproc; i++) {
+               if (children[i] == pid)
+                       return 1;
+       }
+       return 0;
+}
 
 /*
  * serialize the proc list and put it in the environment
@@ -111,6 +152,101 @@ void mworker_unblock_signals()
        haproxy_unblock_signals();
 }
 
+/* ----- mworker signal handlers ----- */
+
+/*
+ * When called, this function reexec haproxy with -sf followed by current
+ * children PIDs and possibly old children PIDs if they didn't leave yet.
+ */
+void mworker_catch_sighup(struct sig_handler *sh)
+{
+       mworker_reload();
+}
+
+void mworker_catch_sigterm(struct sig_handler *sh)
+{
+       int sig = sh->arg;
+
+#if defined(USE_SYSTEMD)
+       if (global.tune.options & GTUNE_USE_SYSTEMD) {
+               sd_notify(0, "STOPPING=1");
+       }
+#endif
+       ha_warning("Exiting Master process...\n");
+       mworker_kill(sig);
+}
+
+/*
+ * Wait for every children to exit
+ */
+
+void mworker_catch_sigchld(struct sig_handler *sh)
+{
+       int exitpid = -1;
+       int status = 0;
+       struct mworker_proc *child, *it;
+       int childfound;
+
+restart_wait:
+
+       childfound = 0;
+
+       exitpid = waitpid(-1, &status, WNOHANG);
+       if (exitpid > 0) {
+               if (WIFEXITED(status))
+                       status = WEXITSTATUS(status);
+               else if (WIFSIGNALED(status))
+                       status = 128 + WTERMSIG(status);
+               else if (WIFSTOPPED(status))
+                       status = 128 + WSTOPSIG(status);
+               else
+                       status = 255;
+
+               list_for_each_entry_safe(child, it, &proc_list, list) {
+                       if (child->pid != exitpid)
+                               continue;
+
+                       LIST_DEL(&child->list);
+                       close(child->ipc_fd[0]);
+                       childfound = 1;
+                       break;
+               }
+
+               if (!children || !childfound) {
+                       ha_warning("Worker %d exited with code %d (%s)\n", exitpid, status, (status >= 128) ? strsignal(status - 128) : "Exit");
+               } else {
+                       /* check if exited child was in the current children list */
+                       if (current_child(exitpid)) {
+                               ha_alert("Current worker #%d (%d) exited with code %d (%s)\n", child->relative_pid, exitpid, status, (status >= 128) ? strsignal(status - 128) : "Exit");
+                               if (status != 0 && status != 130 && status != 143
+                                   && !(global.tune.options & GTUNE_NOEXIT_ONFAILURE)) {
+                                       ha_alert("exit-on-failure: killing every workers with SIGTERM\n");
+                                       if (exitcode < 0)
+                                               exitcode = status;
+                                       mworker_kill(SIGTERM);
+                               }
+                       } else {
+                               ha_warning("Former worker #%d (%d) exited with code %d (%s)\n", child->relative_pid, exitpid, status, (status >= 128) ? strsignal(status - 128) : "Exit");
+                               /* TODO: merge children and oldpids list in mworker mode */
+                               delete_oldpid(exitpid);
+                       }
+                       free(child);
+               }
+
+               /* do it again to check if it was the last worker */
+               goto restart_wait;
+       }
+       /* Better rely on the system than on a list of process to check if it was the last one */
+       else if (exitpid == -1 && errno == ECHILD) {
+               ha_warning("All workers exited. Exiting... (%d)\n", (exitcode > 0) ? exitcode : status);
+               atexit_flag = 0;
+               if (exitcode > 0)
+                       exit(exitcode);
+               exit(status); /* parent must leave using the latest status code known */
+       }
+
+}
+
 /* ----- IPC FD (sockpair) related ----- */
 
 /* This wrapper is called from the workers. It is registered instead of the