mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-09 17:06:28 +00:00
Merge pull request #8534 from opensourcerouting/threads-vs-fork
lib, pathd PCEP: creating threads before forking does _not_ work
This commit is contained in:
commit
8123bf2bd6
@ -134,6 +134,8 @@ lde(void)
|
|||||||
log_procname = log_procnames[PROC_LDE_ENGINE];
|
log_procname = log_procnames[PROC_LDE_ENGINE];
|
||||||
|
|
||||||
master = frr_init();
|
master = frr_init();
|
||||||
|
/* no frr_config_fork() here, allow frr_pthread to create threads */
|
||||||
|
frr_is_after_fork = true;
|
||||||
|
|
||||||
/* setup signal handler */
|
/* setup signal handler */
|
||||||
signal_init(master, array_size(lde_signals), lde_signals);
|
signal_init(master, array_size(lde_signals), lde_signals);
|
||||||
|
@ -111,6 +111,8 @@ ldpe(void)
|
|||||||
log_procname = log_procnames[ldpd_process];
|
log_procname = log_procnames[ldpd_process];
|
||||||
|
|
||||||
master = frr_init();
|
master = frr_init();
|
||||||
|
/* no frr_config_fork() here, allow frr_pthread to create threads */
|
||||||
|
frr_is_after_fork = true;
|
||||||
|
|
||||||
/* setup signal handler */
|
/* setup signal handler */
|
||||||
signal_init(master, array_size(ldpe_signals), ldpe_signals);
|
signal_init(master, array_size(ldpe_signals), ldpe_signals);
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "linklist.h"
|
#include "linklist.h"
|
||||||
#include "zlog.h"
|
#include "zlog.h"
|
||||||
|
#include "libfrr.h"
|
||||||
#include "libfrr_trace.h"
|
#include "libfrr_trace.h"
|
||||||
|
|
||||||
DEFINE_MTYPE_STATIC(LIB, FRR_PTHREAD, "FRR POSIX Thread");
|
DEFINE_MTYPE_STATIC(LIB, FRR_PTHREAD, "FRR POSIX Thread");
|
||||||
@ -162,6 +163,8 @@ int frr_pthread_run(struct frr_pthread *fpt, const pthread_attr_t *attr)
|
|||||||
int ret;
|
int ret;
|
||||||
sigset_t oldsigs, blocksigs;
|
sigset_t oldsigs, blocksigs;
|
||||||
|
|
||||||
|
assert(frr_is_after_fork || !"trying to start thread before fork()");
|
||||||
|
|
||||||
/* Ensure we never handle signals on a background thread by blocking
|
/* Ensure we never handle signals on a background thread by blocking
|
||||||
* everything here (new thread inherits signal mask)
|
* everything here (new thread inherits signal mask)
|
||||||
*/
|
*/
|
||||||
|
12
lib/libfrr.c
12
lib/libfrr.c
@ -46,7 +46,8 @@
|
|||||||
#include "frrscript.h"
|
#include "frrscript.h"
|
||||||
|
|
||||||
DEFINE_HOOK(frr_late_init, (struct thread_master * tm), (tm));
|
DEFINE_HOOK(frr_late_init, (struct thread_master * tm), (tm));
|
||||||
DEFINE_HOOK(frr_very_late_init, (struct thread_master * tm), (tm));
|
DEFINE_HOOK(frr_config_pre, (struct thread_master * tm), (tm));
|
||||||
|
DEFINE_HOOK(frr_config_post, (struct thread_master * tm), (tm));
|
||||||
DEFINE_KOOH(frr_early_fini, (), ());
|
DEFINE_KOOH(frr_early_fini, (), ());
|
||||||
DEFINE_KOOH(frr_fini, (), ());
|
DEFINE_KOOH(frr_fini, (), ());
|
||||||
|
|
||||||
@ -69,6 +70,8 @@ static char dbfile_default[512];
|
|||||||
#endif
|
#endif
|
||||||
static char vtypath_default[512];
|
static char vtypath_default[512];
|
||||||
|
|
||||||
|
/* cleared in frr_preinit(), then re-set after daemonizing */
|
||||||
|
bool frr_is_after_fork = true;
|
||||||
bool debug_memstats_at_exit = false;
|
bool debug_memstats_at_exit = false;
|
||||||
static bool nodetach_term, nodetach_daemon;
|
static bool nodetach_term, nodetach_daemon;
|
||||||
static uint64_t startup_fds;
|
static uint64_t startup_fds;
|
||||||
@ -307,6 +310,7 @@ void frr_init_vtydir(void)
|
|||||||
void frr_preinit(struct frr_daemon_info *daemon, int argc, char **argv)
|
void frr_preinit(struct frr_daemon_info *daemon, int argc, char **argv)
|
||||||
{
|
{
|
||||||
di = daemon;
|
di = daemon;
|
||||||
|
frr_is_after_fork = false;
|
||||||
|
|
||||||
/* basename(), opencoded. */
|
/* basename(), opencoded. */
|
||||||
char *p = strrchr(argv[0], '/');
|
char *p = strrchr(argv[0], '/');
|
||||||
@ -931,6 +935,8 @@ static void frr_daemonize(void)
|
|||||||
*/
|
*/
|
||||||
static int frr_config_read_in(struct thread *t)
|
static int frr_config_read_in(struct thread *t)
|
||||||
{
|
{
|
||||||
|
hook_call(frr_config_pre, master);
|
||||||
|
|
||||||
if (!vty_read_config(vty_shared_candidate_config, di->config_file,
|
if (!vty_read_config(vty_shared_candidate_config, di->config_file,
|
||||||
config_default)
|
config_default)
|
||||||
&& di->backup_config_file) {
|
&& di->backup_config_file) {
|
||||||
@ -964,7 +970,7 @@ static int frr_config_read_in(struct thread *t)
|
|||||||
__func__, nb_err_name(ret), errmsg);
|
__func__, nb_err_name(ret), errmsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
hook_call(frr_very_late_init, master);
|
hook_call(frr_config_post, master);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -987,6 +993,8 @@ void frr_config_fork(void)
|
|||||||
if (di->daemon_mode || di->terminal)
|
if (di->daemon_mode || di->terminal)
|
||||||
frr_daemonize();
|
frr_daemonize();
|
||||||
|
|
||||||
|
frr_is_after_fork = true;
|
||||||
|
|
||||||
if (!di->pid_file)
|
if (!di->pid_file)
|
||||||
di->pid_file = pidfile_default;
|
di->pid_file = pidfile_default;
|
||||||
pid_output(di->pid_file);
|
pid_output(di->pid_file);
|
||||||
|
@ -141,8 +141,12 @@ extern enum frr_cli_mode frr_get_cli_mode(void);
|
|||||||
extern uint32_t frr_get_fd_limit(void);
|
extern uint32_t frr_get_fd_limit(void);
|
||||||
extern bool frr_is_startup_fd(int fd);
|
extern bool frr_is_startup_fd(int fd);
|
||||||
|
|
||||||
|
/* call order of these hooks is as ordered here */
|
||||||
DECLARE_HOOK(frr_late_init, (struct thread_master * tm), (tm));
|
DECLARE_HOOK(frr_late_init, (struct thread_master * tm), (tm));
|
||||||
DECLARE_HOOK(frr_very_late_init, (struct thread_master * tm), (tm));
|
/* fork() happens between late_init and config_pre */
|
||||||
|
DECLARE_HOOK(frr_config_pre, (struct thread_master * tm), (tm));
|
||||||
|
DECLARE_HOOK(frr_config_post, (struct thread_master * tm), (tm));
|
||||||
|
|
||||||
extern void frr_config_fork(void);
|
extern void frr_config_fork(void);
|
||||||
|
|
||||||
extern void frr_run(struct thread_master *master);
|
extern void frr_run(struct thread_master *master);
|
||||||
@ -168,6 +172,8 @@ extern const char frr_scriptdir[];
|
|||||||
|
|
||||||
extern char frr_protoname[];
|
extern char frr_protoname[];
|
||||||
extern char frr_protonameinst[];
|
extern char frr_protonameinst[];
|
||||||
|
/* always set in the spot where we *would* fork even if we don't do so */
|
||||||
|
extern bool frr_is_after_fork;
|
||||||
|
|
||||||
extern bool debug_memstats_at_exit;
|
extern bool debug_memstats_at_exit;
|
||||||
|
|
||||||
|
@ -736,7 +736,7 @@ static int frr_sr_finish(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int frr_sr_module_very_late_init(struct thread_master *tm)
|
static int frr_sr_module_config_loaded(struct thread_master *tm)
|
||||||
{
|
{
|
||||||
master = tm;
|
master = tm;
|
||||||
|
|
||||||
@ -761,7 +761,7 @@ static int frr_sr_module_late_init(struct thread_master *tm)
|
|||||||
static int frr_sr_module_init(void)
|
static int frr_sr_module_init(void)
|
||||||
{
|
{
|
||||||
hook_register(frr_late_init, frr_sr_module_late_init);
|
hook_register(frr_late_init, frr_sr_module_late_init);
|
||||||
hook_register(frr_very_late_init, frr_sr_module_very_late_init);
|
hook_register(frr_config_post, frr_sr_module_config_loaded);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -264,7 +264,11 @@ int pathd_candidate_removed_handler(struct srte_candidate *candidate)
|
|||||||
|
|
||||||
/* ------------ Module Functions ------------ */
|
/* ------------ Module Functions ------------ */
|
||||||
|
|
||||||
int pcep_module_late_init(struct thread_master *tm)
|
/* this creates threads, therefore must run after fork(). but it must also
|
||||||
|
* run before config load, so the CLI commands don't try to touch things that
|
||||||
|
* aren't set up yet...
|
||||||
|
*/
|
||||||
|
static int pcep_module_config_pre(struct thread_master *tm)
|
||||||
{
|
{
|
||||||
assert(pcep_g->fpt == NULL);
|
assert(pcep_g->fpt == NULL);
|
||||||
assert(pcep_g->master == NULL);
|
assert(pcep_g->master == NULL);
|
||||||
@ -280,10 +284,16 @@ int pcep_module_late_init(struct thread_master *tm)
|
|||||||
pcep_g->master = tm;
|
pcep_g->master = tm;
|
||||||
pcep_g->fpt = fpt;
|
pcep_g->fpt = fpt;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pcep_module_late_init(struct thread_master *tm)
|
||||||
|
{
|
||||||
hook_register(pathd_candidate_created, pathd_candidate_created_handler);
|
hook_register(pathd_candidate_created, pathd_candidate_created_handler);
|
||||||
hook_register(pathd_candidate_updated, pathd_candidate_updated_handler);
|
hook_register(pathd_candidate_updated, pathd_candidate_updated_handler);
|
||||||
hook_register(pathd_candidate_removed, pathd_candidate_removed_handler);
|
hook_register(pathd_candidate_removed, pathd_candidate_removed_handler);
|
||||||
|
|
||||||
|
hook_register(frr_config_pre, pcep_module_config_pre);
|
||||||
hook_register(frr_fini, pcep_module_finish);
|
hook_register(frr_fini, pcep_module_finish);
|
||||||
|
|
||||||
pcep_cli_init();
|
pcep_cli_init();
|
||||||
|
Loading…
Reference in New Issue
Block a user