Skip to content

Commit dee247c

Browse files
einval22wlallemand
authored andcommitted
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.
1 parent 0c7b93e commit dee247c

File tree

4 files changed

+176
-175
lines changed

4 files changed

+176
-175
lines changed

include/haproxy/global.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ extern unsigned char boot_seed[20]; // per-boot random seed (160 bits initially
5151
extern THREAD_LOCAL struct buffer trash;
5252
extern char **init_env;
5353
extern char *progname;
54+
extern char **old_argv;
55+
extern const char *old_unixsocket;
5456

5557
struct proxy;
5658
struct server;
@@ -68,7 +70,6 @@ int compare_current_version(const char *version);
6870
void display_version();
6971

7072
void mworker_accept_wrapper(int fd);
71-
void mworker_reload(int hardreload);
7273

7374
/* to be used with warned and WARN_* */
7475
static inline int already_warned(unsigned int warning)

include/haproxy/mworker.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#ifndef _HAPROXY_MWORKER_H_
1515
#define _HAPROXY_MWORKER_H_
1616

17+
#include <haproxy/limits.h>
1718
#include <haproxy/mworker-t.h>
1819
#include <haproxy/signal-t.h>
1920

src/haproxy.c

Lines changed: 2 additions & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ static int *oldpids = NULL;
240240
int oldpids_sig; /* use USR1 or TERM */
241241

242242
/* Path to the unix socket we use to retrieve listener sockets from the old process */
243-
static const char *old_unixsocket;
243+
const char *old_unixsocket;
244244

245245
int atexit_flag = 0;
246246

@@ -253,7 +253,7 @@ char hostname[MAX_HOSTNAME_LEN];
253253
char *localpeer = NULL;
254254
static char *kwd_dump = NULL; // list of keyword dumps to produce
255255

256-
static char **old_argv = NULL; /* previous argv but cleaned up */
256+
char **old_argv = NULL; /* previous argv but cleaned up */
257257

258258
struct list proc_list = LIST_HEAD_INIT(proc_list);
259259

@@ -703,178 +703,6 @@ int delete_oldpid(int pid)
703703
return 0;
704704
}
705705

706-
707-
/*
708-
* When called, this function reexec haproxy with -sf followed by current
709-
* children PIDs and possibly old children PIDs if they didn't leave yet.
710-
*/
711-
static void mworker_reexec(int hardreload)
712-
{
713-
char **next_argv = NULL;
714-
int old_argc = 0; /* previous number of argument */
715-
int next_argc = 0;
716-
int i = 0;
717-
char *msg = NULL;
718-
struct rlimit limit;
719-
struct mworker_proc *current_child = NULL;
720-
int x_off = 0; /* disable -x by putting -x /dev/null */
721-
722-
mworker_block_signals();
723-
724-
/* restore initial environment (before parsing the config) and do re-exec.
725-
* The initial process environment should be restored here, preceded by
726-
* clean_env(), which do the same job as clearenv().
727-
* Otherwise, after the re-exec we will start the new worker in the
728-
* environment modified by '*env' keywords from the previous configuration,
729-
* i.e. existed before the reload.
730-
*/
731-
if (clean_env() != 0) {
732-
ha_alert("Master encountered a non-recoverable error, exiting.\n");
733-
exit(EXIT_FAILURE);
734-
}
735-
736-
if (restore_env() != 0) {
737-
ha_alert("Master encountered a non-recoverable error, exiting.\n");
738-
exit(EXIT_FAILURE);
739-
}
740-
741-
setenv("HAPROXY_MWORKER_REEXEC", "1", 1);
742-
743-
mworker_proc_list_to_env(); /* put the children description in the env */
744-
745-
/* during the reload we must ensure that every FDs that can't be
746-
* reuse (ie those that are not referenced in the proc_list)
747-
* are closed or they will leak. */
748-
749-
/* close the listeners FD */
750-
mworker_cli_proxy_stop();
751-
752-
if (fdtab)
753-
deinit_pollers();
754-
755-
#ifdef HAVE_SSL_RAND_KEEP_RANDOM_DEVICES_OPEN
756-
/* close random device FDs */
757-
RAND_keep_random_devices_open(0);
758-
#endif
759-
760-
/* restore the initial FD limits */
761-
limit.rlim_cur = rlim_fd_cur_at_boot;
762-
limit.rlim_max = rlim_fd_max_at_boot;
763-
if (raise_rlim_nofile(&limit, &limit) != 0) {
764-
ha_warning("Failed to restore initial FD limits (cur=%u max=%u), using cur=%u max=%u\n",
765-
rlim_fd_cur_at_boot, rlim_fd_max_at_boot,
766-
(unsigned int)limit.rlim_cur, (unsigned int)limit.rlim_max);
767-
}
768-
769-
/* compute length */
770-
while (old_argv[old_argc])
771-
old_argc++;
772-
773-
/* 1 for haproxy -sf, 2 for -x /socket */
774-
next_argv = calloc(old_argc + 1 + 2 + mworker_child_nb() + 1,
775-
sizeof(*next_argv));
776-
if (next_argv == NULL)
777-
goto alloc_error;
778-
779-
/* copy the program name */
780-
next_argv[next_argc++] = old_argv[0];
781-
782-
/* we need to reintroduce /dev/null every time */
783-
if (old_unixsocket && strcmp(old_unixsocket, "/dev/null") == 0)
784-
x_off = 1;
785-
786-
/* insert the new options just after argv[0] in case we have a -- */
787-
788-
/* add -sf <PID>* to argv */
789-
if (mworker_child_nb() > 0) {
790-
struct mworker_proc *child;
791-
792-
if (hardreload)
793-
next_argv[next_argc++] = "-st";
794-
else
795-
next_argv[next_argc++] = "-sf";
796-
797-
list_for_each_entry(child, &proc_list, list) {
798-
if (!(child->options & PROC_O_LEAVING) && (child->options & PROC_O_TYPE_WORKER))
799-
current_child = child;
800-
801-
if (!(child->options & (PROC_O_TYPE_WORKER|PROC_O_TYPE_PROG)) || child->pid <= -1)
802-
continue;
803-
if ((next_argv[next_argc++] = memprintf(&msg, "%d", child->pid)) == NULL)
804-
goto alloc_error;
805-
msg = NULL;
806-
}
807-
}
808-
if (!x_off && current_child) {
809-
/* add the -x option with the socketpair of the current worker */
810-
next_argv[next_argc++] = "-x";
811-
if ((next_argv[next_argc++] = memprintf(&msg, "sockpair@%d", current_child->ipc_fd[0])) == NULL)
812-
goto alloc_error;
813-
msg = NULL;
814-
}
815-
816-
if (x_off) {
817-
/* if the cmdline contained a -x /dev/null, continue to use it */
818-
next_argv[next_argc++] = "-x";
819-
next_argv[next_argc++] = "/dev/null";
820-
}
821-
822-
/* copy the previous options */
823-
for (i = 1; i < old_argc; i++)
824-
next_argv[next_argc++] = old_argv[i];
825-
826-
/* need to withdraw MODE_STARTING from master, because we have to free
827-
* the startup logs ring here, see more details in print_message()
828-
*/
829-
global.mode &= ~MODE_STARTING;
830-
startup_logs_free(startup_logs);
831-
832-
signal(SIGPROF, SIG_IGN);
833-
execvp(next_argv[0], next_argv);
834-
ha_warning("Failed to reexecute the master process [%d]: %s\n", pid, strerror(errno));
835-
ha_free(&next_argv);
836-
return;
837-
838-
alloc_error:
839-
ha_free(&next_argv);
840-
ha_warning("Failed to reexecute the master process [%d]: Cannot allocate memory\n", pid);
841-
return;
842-
}
843-
844-
/* reload haproxy and emit a warning */
845-
void mworker_reload(int hardreload)
846-
{
847-
struct mworker_proc *child;
848-
struct per_thread_deinit_fct *ptdf;
849-
850-
ha_notice("Reloading HAProxy%s\n", hardreload?" (hard-reload)":"");
851-
852-
/* close the poller FD and the thread waker pipe FD */
853-
list_for_each_entry(ptdf, &per_thread_deinit_list, list)
854-
ptdf->fct();
855-
856-
/* increment the number of reloads, child->reloads is checked in
857-
* mworker_env_to_proc_list() (after reload) in order to set
858-
* PROC_O_LEAVING flag for the process
859-
*/
860-
list_for_each_entry(child, &proc_list, list) {
861-
child->reloads++;
862-
}
863-
864-
if (global.tune.options & GTUNE_USE_SYSTEMD) {
865-
struct timespec ts;
866-
867-
(void)clock_gettime(CLOCK_MONOTONIC, &ts);
868-
869-
sd_notifyf(0,
870-
"RELOADING=1\n"
871-
"STATUS=Reloading Configuration.\n"
872-
"MONOTONIC_USEC=%" PRIu64 "\n",
873-
(ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000ULL));
874-
}
875-
mworker_reexec(hardreload);
876-
}
877-
878706
/*
879707
* Exit with an error message upon a master recovery mode failure.
880708
*/

src/mworker.c

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,177 @@ void mworker_broadcast_signal(struct sig_handler *sh)
294294
mworker_kill(sh->arg);
295295
}
296296

297+
/*
298+
* When called, this function reexec haproxy with -sf followed by current
299+
* children PIDs and possibly old children PIDs if they didn't leave yet.
300+
*/
301+
static void mworker_reexec(int hardreload)
302+
{
303+
char **next_argv = NULL;
304+
int old_argc = 0; /* previous number of argument */
305+
int next_argc = 0;
306+
int i = 0;
307+
char *msg = NULL;
308+
struct rlimit limit;
309+
struct mworker_proc *current_child = NULL;
310+
int x_off = 0; /* disable -x by putting -x /dev/null */
311+
312+
mworker_block_signals();
313+
314+
/* restore initial environment (before parsing the config) and do re-exec.
315+
* The initial process environment should be restored here, preceded by
316+
* clean_env(), which do the same job as clearenv().
317+
* Otherwise, after the re-exec we will start the new worker in the
318+
* environment modified by '*env' keywords from the previous configuration,
319+
* i.e. existed before the reload.
320+
*/
321+
if (clean_env() != 0) {
322+
ha_alert("Master encountered a non-recoverable error, exiting.\n");
323+
exit(EXIT_FAILURE);
324+
}
325+
326+
if (restore_env() != 0) {
327+
ha_alert("Master encountered a non-recoverable error, exiting.\n");
328+
exit(EXIT_FAILURE);
329+
}
330+
331+
setenv("HAPROXY_MWORKER_REEXEC", "1", 1);
332+
333+
mworker_proc_list_to_env(); /* put the children description in the env */
334+
335+
/* during the reload we must ensure that every FDs that can't be
336+
* reuse (ie those that are not referenced in the proc_list)
337+
* are closed or they will leak. */
338+
339+
/* close the listeners FD */
340+
mworker_cli_proxy_stop();
341+
342+
if (fdtab)
343+
deinit_pollers();
344+
345+
#ifdef HAVE_SSL_RAND_KEEP_RANDOM_DEVICES_OPEN
346+
/* close random device FDs */
347+
RAND_keep_random_devices_open(0);
348+
#endif
349+
350+
/* restore the initial FD limits */
351+
limit.rlim_cur = rlim_fd_cur_at_boot;
352+
limit.rlim_max = rlim_fd_max_at_boot;
353+
if (raise_rlim_nofile(&limit, &limit) != 0) {
354+
ha_warning("Failed to restore initial FD limits (cur=%u max=%u), using cur=%u max=%u\n",
355+
rlim_fd_cur_at_boot, rlim_fd_max_at_boot,
356+
(unsigned int)limit.rlim_cur, (unsigned int)limit.rlim_max);
357+
}
358+
359+
/* compute length */
360+
while (old_argv[old_argc])
361+
old_argc++;
362+
363+
/* 1 for haproxy -sf, 2 for -x /socket */
364+
next_argv = calloc(old_argc + 1 + 2 + mworker_child_nb() + 1,
365+
sizeof(*next_argv));
366+
if (next_argv == NULL)
367+
goto alloc_error;
368+
369+
/* copy the program name */
370+
next_argv[next_argc++] = old_argv[0];
371+
372+
/* we need to reintroduce /dev/null every time */
373+
if (old_unixsocket && strcmp(old_unixsocket, "/dev/null") == 0)
374+
x_off = 1;
375+
376+
/* insert the new options just after argv[0] in case we have a -- */
377+
378+
/* add -sf <PID>* to argv */
379+
if (mworker_child_nb() > 0) {
380+
struct mworker_proc *child;
381+
382+
if (hardreload)
383+
next_argv[next_argc++] = "-st";
384+
else
385+
next_argv[next_argc++] = "-sf";
386+
387+
list_for_each_entry(child, &proc_list, list) {
388+
if (!(child->options & PROC_O_LEAVING) && (child->options & PROC_O_TYPE_WORKER))
389+
current_child = child;
390+
391+
if (!(child->options & (PROC_O_TYPE_WORKER|PROC_O_TYPE_PROG)) || child->pid <= -1)
392+
continue;
393+
if ((next_argv[next_argc++] = memprintf(&msg, "%d", child->pid)) == NULL)
394+
goto alloc_error;
395+
msg = NULL;
396+
}
397+
}
398+
if (!x_off && current_child) {
399+
/* add the -x option with the socketpair of the current worker */
400+
next_argv[next_argc++] = "-x";
401+
if ((next_argv[next_argc++] = memprintf(&msg, "sockpair@%d", current_child->ipc_fd[0])) == NULL)
402+
goto alloc_error;
403+
msg = NULL;
404+
}
405+
406+
if (x_off) {
407+
/* if the cmdline contained a -x /dev/null, continue to use it */
408+
next_argv[next_argc++] = "-x";
409+
next_argv[next_argc++] = "/dev/null";
410+
}
411+
412+
/* copy the previous options */
413+
for (i = 1; i < old_argc; i++)
414+
next_argv[next_argc++] = old_argv[i];
415+
416+
/* need to withdraw MODE_STARTING from master, because we have to free
417+
* the startup logs ring here, see more details in print_message()
418+
*/
419+
global.mode &= ~MODE_STARTING;
420+
startup_logs_free(startup_logs);
421+
422+
signal(SIGPROF, SIG_IGN);
423+
execvp(next_argv[0], next_argv);
424+
ha_warning("Failed to reexecute the master process [%d]: %s\n", pid, strerror(errno));
425+
ha_free(&next_argv);
426+
return;
427+
428+
alloc_error:
429+
ha_free(&next_argv);
430+
ha_warning("Failed to reexecute the master process [%d]: Cannot allocate memory\n", pid);
431+
return;
432+
}
433+
434+
/* reload haproxy and emit a warning */
435+
static void mworker_reload(int hardreload)
436+
{
437+
struct mworker_proc *child;
438+
struct per_thread_deinit_fct *ptdf;
439+
440+
ha_notice("Reloading HAProxy%s\n", hardreload?" (hard-reload)":"");
441+
442+
/* close the poller FD and the thread waker pipe FD */
443+
list_for_each_entry(ptdf, &per_thread_deinit_list, list)
444+
ptdf->fct();
445+
446+
/* increment the number of reloads, child->reloads is checked in
447+
* mworker_env_to_proc_list() (after reload) in order to set
448+
* PROC_O_LEAVING flag for the process
449+
*/
450+
list_for_each_entry(child, &proc_list, list) {
451+
child->reloads++;
452+
}
453+
454+
if (global.tune.options & GTUNE_USE_SYSTEMD) {
455+
struct timespec ts;
456+
457+
(void)clock_gettime(CLOCK_MONOTONIC, &ts);
458+
459+
sd_notifyf(0,
460+
"RELOADING=1\n"
461+
"STATUS=Reloading Configuration.\n"
462+
"MONOTONIC_USEC=%" PRIu64 "\n",
463+
(ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000ULL));
464+
}
465+
mworker_reexec(hardreload);
466+
}
467+
297468
/*
298469
* When called, this function reexec haproxy with -sf followed by current
299470
* children PIDs and possibly old children PIDs if they didn't leave yet.

0 commit comments

Comments
 (0)