mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-21 13:51:26 +02:00
REORG: startup: move mworker_reexec and mworker_reload in mworker.c
Let's move mworker_reexec() and mworker_reload() in mworker.c. mworker_reload() is called only within the functions, which are already in mworker.c. So, this reorganization allows to declare mworker_reload() as a static.
This commit is contained in:
parent
0c7b93eb1d
commit
dee247c14e
@ -51,6 +51,8 @@ extern unsigned char boot_seed[20]; // per-boot random seed (160 bits initially
|
||||
extern THREAD_LOCAL struct buffer trash;
|
||||
extern char **init_env;
|
||||
extern char *progname;
|
||||
extern char **old_argv;
|
||||
extern const char *old_unixsocket;
|
||||
|
||||
struct proxy;
|
||||
struct server;
|
||||
@ -68,7 +70,6 @@ int compare_current_version(const char *version);
|
||||
void display_version();
|
||||
|
||||
void mworker_accept_wrapper(int fd);
|
||||
void mworker_reload(int hardreload);
|
||||
|
||||
/* to be used with warned and WARN_* */
|
||||
static inline int already_warned(unsigned int warning)
|
||||
|
@ -14,6 +14,7 @@
|
||||
#ifndef _HAPROXY_MWORKER_H_
|
||||
#define _HAPROXY_MWORKER_H_
|
||||
|
||||
#include <haproxy/limits.h>
|
||||
#include <haproxy/mworker-t.h>
|
||||
#include <haproxy/signal-t.h>
|
||||
|
||||
|
176
src/haproxy.c
176
src/haproxy.c
@ -240,7 +240,7 @@ static int *oldpids = NULL;
|
||||
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;
|
||||
const char *old_unixsocket;
|
||||
|
||||
int atexit_flag = 0;
|
||||
|
||||
@ -253,7 +253,7 @@ char hostname[MAX_HOSTNAME_LEN];
|
||||
char *localpeer = NULL;
|
||||
static char *kwd_dump = NULL; // list of keyword dumps to produce
|
||||
|
||||
static char **old_argv = NULL; /* previous argv but cleaned up */
|
||||
char **old_argv = NULL; /* previous argv but cleaned up */
|
||||
|
||||
struct list proc_list = LIST_HEAD_INIT(proc_list);
|
||||
|
||||
@ -703,178 +703,6 @@ int delete_oldpid(int pid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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_reexec(int hardreload)
|
||||
{
|
||||
char **next_argv = NULL;
|
||||
int old_argc = 0; /* previous number of argument */
|
||||
int next_argc = 0;
|
||||
int i = 0;
|
||||
char *msg = NULL;
|
||||
struct rlimit limit;
|
||||
struct mworker_proc *current_child = NULL;
|
||||
int x_off = 0; /* disable -x by putting -x /dev/null */
|
||||
|
||||
mworker_block_signals();
|
||||
|
||||
/* restore initial environment (before parsing the config) and do re-exec.
|
||||
* The initial process environment should be restored here, preceded by
|
||||
* clean_env(), which do the same job as clearenv().
|
||||
* Otherwise, after the re-exec we will start the new worker in the
|
||||
* environment modified by '*env' keywords from the previous configuration,
|
||||
* i.e. existed before the reload.
|
||||
*/
|
||||
if (clean_env() != 0) {
|
||||
ha_alert("Master encountered a non-recoverable error, exiting.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (restore_env() != 0) {
|
||||
ha_alert("Master encountered a non-recoverable error, exiting.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
setenv("HAPROXY_MWORKER_REEXEC", "1", 1);
|
||||
|
||||
mworker_proc_list_to_env(); /* put the children description in the env */
|
||||
|
||||
/* during the reload we must ensure that every FDs that can't be
|
||||
* reuse (ie those that are not referenced in the proc_list)
|
||||
* are closed or they will leak. */
|
||||
|
||||
/* close the listeners FD */
|
||||
mworker_cli_proxy_stop();
|
||||
|
||||
if (fdtab)
|
||||
deinit_pollers();
|
||||
|
||||
#ifdef HAVE_SSL_RAND_KEEP_RANDOM_DEVICES_OPEN
|
||||
/* close random device FDs */
|
||||
RAND_keep_random_devices_open(0);
|
||||
#endif
|
||||
|
||||
/* restore the initial FD limits */
|
||||
limit.rlim_cur = rlim_fd_cur_at_boot;
|
||||
limit.rlim_max = rlim_fd_max_at_boot;
|
||||
if (raise_rlim_nofile(&limit, &limit) != 0) {
|
||||
ha_warning("Failed to restore initial FD limits (cur=%u max=%u), using cur=%u max=%u\n",
|
||||
rlim_fd_cur_at_boot, rlim_fd_max_at_boot,
|
||||
(unsigned int)limit.rlim_cur, (unsigned int)limit.rlim_max);
|
||||
}
|
||||
|
||||
/* compute length */
|
||||
while (old_argv[old_argc])
|
||||
old_argc++;
|
||||
|
||||
/* 1 for haproxy -sf, 2 for -x /socket */
|
||||
next_argv = calloc(old_argc + 1 + 2 + mworker_child_nb() + 1,
|
||||
sizeof(*next_argv));
|
||||
if (next_argv == NULL)
|
||||
goto alloc_error;
|
||||
|
||||
/* copy the program name */
|
||||
next_argv[next_argc++] = old_argv[0];
|
||||
|
||||
/* we need to reintroduce /dev/null every time */
|
||||
if (old_unixsocket && strcmp(old_unixsocket, "/dev/null") == 0)
|
||||
x_off = 1;
|
||||
|
||||
/* insert the new options just after argv[0] in case we have a -- */
|
||||
|
||||
/* add -sf <PID>* to argv */
|
||||
if (mworker_child_nb() > 0) {
|
||||
struct mworker_proc *child;
|
||||
|
||||
if (hardreload)
|
||||
next_argv[next_argc++] = "-st";
|
||||
else
|
||||
next_argv[next_argc++] = "-sf";
|
||||
|
||||
list_for_each_entry(child, &proc_list, list) {
|
||||
if (!(child->options & PROC_O_LEAVING) && (child->options & PROC_O_TYPE_WORKER))
|
||||
current_child = child;
|
||||
|
||||
if (!(child->options & (PROC_O_TYPE_WORKER|PROC_O_TYPE_PROG)) || child->pid <= -1)
|
||||
continue;
|
||||
if ((next_argv[next_argc++] = memprintf(&msg, "%d", child->pid)) == NULL)
|
||||
goto alloc_error;
|
||||
msg = NULL;
|
||||
}
|
||||
}
|
||||
if (!x_off && current_child) {
|
||||
/* add the -x option with the socketpair of the current worker */
|
||||
next_argv[next_argc++] = "-x";
|
||||
if ((next_argv[next_argc++] = memprintf(&msg, "sockpair@%d", current_child->ipc_fd[0])) == NULL)
|
||||
goto alloc_error;
|
||||
msg = NULL;
|
||||
}
|
||||
|
||||
if (x_off) {
|
||||
/* if the cmdline contained a -x /dev/null, continue to use it */
|
||||
next_argv[next_argc++] = "-x";
|
||||
next_argv[next_argc++] = "/dev/null";
|
||||
}
|
||||
|
||||
/* copy the previous options */
|
||||
for (i = 1; i < old_argc; i++)
|
||||
next_argv[next_argc++] = old_argv[i];
|
||||
|
||||
/* need to withdraw MODE_STARTING from master, because we have to free
|
||||
* the startup logs ring here, see more details in print_message()
|
||||
*/
|
||||
global.mode &= ~MODE_STARTING;
|
||||
startup_logs_free(startup_logs);
|
||||
|
||||
signal(SIGPROF, SIG_IGN);
|
||||
execvp(next_argv[0], next_argv);
|
||||
ha_warning("Failed to reexecute the master process [%d]: %s\n", pid, strerror(errno));
|
||||
ha_free(&next_argv);
|
||||
return;
|
||||
|
||||
alloc_error:
|
||||
ha_free(&next_argv);
|
||||
ha_warning("Failed to reexecute the master process [%d]: Cannot allocate memory\n", pid);
|
||||
return;
|
||||
}
|
||||
|
||||
/* reload haproxy and emit a warning */
|
||||
void mworker_reload(int hardreload)
|
||||
{
|
||||
struct mworker_proc *child;
|
||||
struct per_thread_deinit_fct *ptdf;
|
||||
|
||||
ha_notice("Reloading HAProxy%s\n", hardreload?" (hard-reload)":"");
|
||||
|
||||
/* close the poller FD and the thread waker pipe FD */
|
||||
list_for_each_entry(ptdf, &per_thread_deinit_list, list)
|
||||
ptdf->fct();
|
||||
|
||||
/* increment the number of reloads, child->reloads is checked in
|
||||
* mworker_env_to_proc_list() (after reload) in order to set
|
||||
* PROC_O_LEAVING flag for the process
|
||||
*/
|
||||
list_for_each_entry(child, &proc_list, list) {
|
||||
child->reloads++;
|
||||
}
|
||||
|
||||
if (global.tune.options & GTUNE_USE_SYSTEMD) {
|
||||
struct timespec ts;
|
||||
|
||||
(void)clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
|
||||
sd_notifyf(0,
|
||||
"RELOADING=1\n"
|
||||
"STATUS=Reloading Configuration.\n"
|
||||
"MONOTONIC_USEC=%" PRIu64 "\n",
|
||||
(ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000ULL));
|
||||
}
|
||||
mworker_reexec(hardreload);
|
||||
}
|
||||
|
||||
/*
|
||||
* Exit with an error message upon a master recovery mode failure.
|
||||
*/
|
||||
|
171
src/mworker.c
171
src/mworker.c
@ -294,6 +294,177 @@ void mworker_broadcast_signal(struct sig_handler *sh)
|
||||
mworker_kill(sh->arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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_reexec(int hardreload)
|
||||
{
|
||||
char **next_argv = NULL;
|
||||
int old_argc = 0; /* previous number of argument */
|
||||
int next_argc = 0;
|
||||
int i = 0;
|
||||
char *msg = NULL;
|
||||
struct rlimit limit;
|
||||
struct mworker_proc *current_child = NULL;
|
||||
int x_off = 0; /* disable -x by putting -x /dev/null */
|
||||
|
||||
mworker_block_signals();
|
||||
|
||||
/* restore initial environment (before parsing the config) and do re-exec.
|
||||
* The initial process environment should be restored here, preceded by
|
||||
* clean_env(), which do the same job as clearenv().
|
||||
* Otherwise, after the re-exec we will start the new worker in the
|
||||
* environment modified by '*env' keywords from the previous configuration,
|
||||
* i.e. existed before the reload.
|
||||
*/
|
||||
if (clean_env() != 0) {
|
||||
ha_alert("Master encountered a non-recoverable error, exiting.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (restore_env() != 0) {
|
||||
ha_alert("Master encountered a non-recoverable error, exiting.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
setenv("HAPROXY_MWORKER_REEXEC", "1", 1);
|
||||
|
||||
mworker_proc_list_to_env(); /* put the children description in the env */
|
||||
|
||||
/* during the reload we must ensure that every FDs that can't be
|
||||
* reuse (ie those that are not referenced in the proc_list)
|
||||
* are closed or they will leak. */
|
||||
|
||||
/* close the listeners FD */
|
||||
mworker_cli_proxy_stop();
|
||||
|
||||
if (fdtab)
|
||||
deinit_pollers();
|
||||
|
||||
#ifdef HAVE_SSL_RAND_KEEP_RANDOM_DEVICES_OPEN
|
||||
/* close random device FDs */
|
||||
RAND_keep_random_devices_open(0);
|
||||
#endif
|
||||
|
||||
/* restore the initial FD limits */
|
||||
limit.rlim_cur = rlim_fd_cur_at_boot;
|
||||
limit.rlim_max = rlim_fd_max_at_boot;
|
||||
if (raise_rlim_nofile(&limit, &limit) != 0) {
|
||||
ha_warning("Failed to restore initial FD limits (cur=%u max=%u), using cur=%u max=%u\n",
|
||||
rlim_fd_cur_at_boot, rlim_fd_max_at_boot,
|
||||
(unsigned int)limit.rlim_cur, (unsigned int)limit.rlim_max);
|
||||
}
|
||||
|
||||
/* compute length */
|
||||
while (old_argv[old_argc])
|
||||
old_argc++;
|
||||
|
||||
/* 1 for haproxy -sf, 2 for -x /socket */
|
||||
next_argv = calloc(old_argc + 1 + 2 + mworker_child_nb() + 1,
|
||||
sizeof(*next_argv));
|
||||
if (next_argv == NULL)
|
||||
goto alloc_error;
|
||||
|
||||
/* copy the program name */
|
||||
next_argv[next_argc++] = old_argv[0];
|
||||
|
||||
/* we need to reintroduce /dev/null every time */
|
||||
if (old_unixsocket && strcmp(old_unixsocket, "/dev/null") == 0)
|
||||
x_off = 1;
|
||||
|
||||
/* insert the new options just after argv[0] in case we have a -- */
|
||||
|
||||
/* add -sf <PID>* to argv */
|
||||
if (mworker_child_nb() > 0) {
|
||||
struct mworker_proc *child;
|
||||
|
||||
if (hardreload)
|
||||
next_argv[next_argc++] = "-st";
|
||||
else
|
||||
next_argv[next_argc++] = "-sf";
|
||||
|
||||
list_for_each_entry(child, &proc_list, list) {
|
||||
if (!(child->options & PROC_O_LEAVING) && (child->options & PROC_O_TYPE_WORKER))
|
||||
current_child = child;
|
||||
|
||||
if (!(child->options & (PROC_O_TYPE_WORKER|PROC_O_TYPE_PROG)) || child->pid <= -1)
|
||||
continue;
|
||||
if ((next_argv[next_argc++] = memprintf(&msg, "%d", child->pid)) == NULL)
|
||||
goto alloc_error;
|
||||
msg = NULL;
|
||||
}
|
||||
}
|
||||
if (!x_off && current_child) {
|
||||
/* add the -x option with the socketpair of the current worker */
|
||||
next_argv[next_argc++] = "-x";
|
||||
if ((next_argv[next_argc++] = memprintf(&msg, "sockpair@%d", current_child->ipc_fd[0])) == NULL)
|
||||
goto alloc_error;
|
||||
msg = NULL;
|
||||
}
|
||||
|
||||
if (x_off) {
|
||||
/* if the cmdline contained a -x /dev/null, continue to use it */
|
||||
next_argv[next_argc++] = "-x";
|
||||
next_argv[next_argc++] = "/dev/null";
|
||||
}
|
||||
|
||||
/* copy the previous options */
|
||||
for (i = 1; i < old_argc; i++)
|
||||
next_argv[next_argc++] = old_argv[i];
|
||||
|
||||
/* need to withdraw MODE_STARTING from master, because we have to free
|
||||
* the startup logs ring here, see more details in print_message()
|
||||
*/
|
||||
global.mode &= ~MODE_STARTING;
|
||||
startup_logs_free(startup_logs);
|
||||
|
||||
signal(SIGPROF, SIG_IGN);
|
||||
execvp(next_argv[0], next_argv);
|
||||
ha_warning("Failed to reexecute the master process [%d]: %s\n", pid, strerror(errno));
|
||||
ha_free(&next_argv);
|
||||
return;
|
||||
|
||||
alloc_error:
|
||||
ha_free(&next_argv);
|
||||
ha_warning("Failed to reexecute the master process [%d]: Cannot allocate memory\n", pid);
|
||||
return;
|
||||
}
|
||||
|
||||
/* reload haproxy and emit a warning */
|
||||
static void mworker_reload(int hardreload)
|
||||
{
|
||||
struct mworker_proc *child;
|
||||
struct per_thread_deinit_fct *ptdf;
|
||||
|
||||
ha_notice("Reloading HAProxy%s\n", hardreload?" (hard-reload)":"");
|
||||
|
||||
/* close the poller FD and the thread waker pipe FD */
|
||||
list_for_each_entry(ptdf, &per_thread_deinit_list, list)
|
||||
ptdf->fct();
|
||||
|
||||
/* increment the number of reloads, child->reloads is checked in
|
||||
* mworker_env_to_proc_list() (after reload) in order to set
|
||||
* PROC_O_LEAVING flag for the process
|
||||
*/
|
||||
list_for_each_entry(child, &proc_list, list) {
|
||||
child->reloads++;
|
||||
}
|
||||
|
||||
if (global.tune.options & GTUNE_USE_SYSTEMD) {
|
||||
struct timespec ts;
|
||||
|
||||
(void)clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
|
||||
sd_notifyf(0,
|
||||
"RELOADING=1\n"
|
||||
"STATUS=Reloading Configuration.\n"
|
||||
"MONOTONIC_USEC=%" PRIu64 "\n",
|
||||
(ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000ULL));
|
||||
}
|
||||
mworker_reexec(hardreload);
|
||||
}
|
||||
|
||||
/*
|
||||
* When called, this function reexec haproxy with -sf followed by current
|
||||
* children PIDs and possibly old children PIDs if they didn't leave yet.
|
||||
|
Loading…
x
Reference in New Issue
Block a user