diff --git a/include/haproxy/global.h b/include/haproxy/global.h index 17cfff3ae..f5c2628d1 100644 --- a/include/haproxy/global.h +++ b/include/haproxy/global.h @@ -35,6 +35,7 @@ extern int unstoppable_jobs; /* # of active jobs that can't be stopped during extern int active_peers; /* # of active peers (connection attempts and successes) */ extern int connected_peers; /* # of really connected peers */ extern int nb_oldpids; /* contains the number of old pids found */ +extern int oldpids_sig; /* signal to sent in order to stop the previous (old) process */ extern const int zero; extern const int one; extern const struct linger nolinger; diff --git a/include/haproxy/mworker.h b/include/haproxy/mworker.h index 0251a9de2..72c5f94a1 100644 --- a/include/haproxy/mworker.h +++ b/include/haproxy/mworker.h @@ -17,6 +17,7 @@ #include #include +extern int max_reloads; extern struct mworker_proc *proc_self; /* master CLI configuration (-S flag) */ extern struct list mworker_cli_conf; diff --git a/src/cli.c b/src/cli.c index bbd11c1d1..11fc1b561 100644 --- a/src/cli.c +++ b/src/cli.c @@ -2463,6 +2463,42 @@ static int cli_parse_simple(char **args, char *payload, struct appctx *appctx, v return 1; } +static int _send_status(char **args, char *payload, struct appctx *appctx, void *private) +{ + struct mworker_proc *proc; + int pid; + + BUG_ON((strcmp(args[0], "_send_status") != 0), + "Triggered in _send_status by unsupported command name.\n"); + + pid = atoi(args[2]); + + list_for_each_entry(proc, &proc_list, list) { + /* update status of the new worker */ + if (proc->pid == pid) + proc->options &= ~PROC_O_INIT; + /* send TERM to workers, which have exceeded max_reloads counter */ + if (max_reloads != -1) { + if ((proc->options & PROC_O_TYPE_WORKER) && + (proc->options & PROC_O_LEAVING) && + (proc->reloads > max_reloads) && (proc->pid > 0)) { + kill(proc->pid, SIGTERM); + } + + } + } + /* stop previous worker process, if it wasn't signaled during max reloads check */ + list_for_each_entry(proc, &proc_list, list) { + if ((proc->options & PROC_O_TYPE_WORKER) && + (proc->options & PROC_O_LEAVING) && + (proc->reloads >= 1)) { + kill(proc->pid, oldpids_sig); + } + } + + return 1; +} + void pcli_write_prompt(struct stream *s) { struct buffer *msg = get_trash_chunk(); @@ -3594,6 +3630,7 @@ static struct cli_kw_list cli_kws = {{ },{ { { "operator", NULL }, "operator : lower the level of the current CLI session to operator", cli_parse_set_lvl, NULL, NULL, NULL, ACCESS_MASTER}, { { "user", NULL }, "user : lower the level of the current CLI session to user", cli_parse_set_lvl, NULL, NULL, NULL, ACCESS_MASTER}, { { "wait", NULL }, "wait {-h|} cond [args...] : wait the specified delay or condition (-h to see list)", cli_parse_wait, cli_io_handler_wait, cli_release_wait, NULL }, + { { "_send_status", NULL }, NULL, _send_status, NULL, NULL, NULL, ACCESS_MASTER_ONLY }, {{},} }}; diff --git a/src/haproxy.c b/src/haproxy.c index d16399862..cbbbb3728 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -238,7 +238,7 @@ char *check_condition = NULL; /* check condition passed to -cc */ */ #define MAX_START_RETRIES 200 static int *oldpids = NULL; -static int oldpids_sig; /* use USR1 or TERM */ +int oldpids_sig; /* use USR1 or TERM */ /* Path to the unix socket we use to retrieve listener sockets from the old process */ static const char *old_unixsocket; diff --git a/src/mworker.c b/src/mworker.c index 46211c222..431935852 100644 --- a/src/mworker.c +++ b/src/mworker.c @@ -46,7 +46,7 @@ #endif static int exitcode = -1; -static int max_reloads = -1; /* number max of reloads a worker can have until they are killed */ +int max_reloads = INT_MAX; /* max number of reloads a worker can have until they are killed */ struct mworker_proc *proc_self = NULL; /* process structure of current process */ struct list mworker_cli_conf = LIST_HEAD_INIT(mworker_cli_conf); /* master CLI configuration (-S flag) */