0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 09:41:54 +00:00

Global runtime splitout to BIRD specific and lib things

This commit is contained in:
Maria Matejka 2024-08-27 17:50:30 +02:00
parent 9f19dc0b3c
commit d55a15a569
16 changed files with 127 additions and 110 deletions

View File

@ -113,9 +113,9 @@ config_alloc(const char *name)
c->pool = p;
c->mem = l;
c->file_name = ndup;
c->tf_route = c->tf_proto = TM_ISO_SHORT_MS;
c->tf_base = c->tf_log = TM_ISO_LONG_MS;
c->gr_wait = DEFAULT_GR_WAIT;
c->runtime.tf_route = c->runtime.tf_proto = TM_ISO_SHORT_MS;
c->runtime.tf_base = c->runtime.tf_log = TM_ISO_LONG_MS;
c->runtime.gr_wait = DEFAULT_GR_WAIT;
callback_init(&c->obstacles_cleared, config_obstacles_cleared, &main_birdloop);
obstacle_target_init(&c->obstacles, &c->obstacles_cleared, p, "Config");
@ -229,42 +229,15 @@ config_free_old(void)
old_config = NULL;
}
struct global_runtime global_runtime_internal[2] = {{
.tf_log = {
.fmt1 = "%F %T.%3f",
},
}};
struct global_runtime * _Atomic global_runtime = &global_runtime_internal[0];
static void
global_commit(struct config *new, struct config *old)
{
/* Updating the global runtime. */
struct global_runtime *og = atomic_load_explicit(&global_runtime, memory_order_relaxed);
struct global_runtime *ng = &global_runtime_internal[og == &global_runtime_internal[0]];
ASSERT_DIE(ng != og);
union bird_global_runtime *ng = &new->runtime;
SKIP_BACK_DECLARE(union bird_global_runtime, og, generic,
atomic_load_explicit(&global_runtime, memory_order_relaxed));
#define COPY(x) ng->x = new->x;
MACRO_FOREACH(COPY,
tf_route,
tf_proto,
tf_log,
tf_base,
cli_debug,
latency_debug,
latency_limit,
watchdog_warning,
watchdog_timeout,
gr_wait,
hostname
);
#undef COPY
ng->load_time = current_time();
if (new->router_id)
ng->router_id = new->router_id;
else if (old)
if (!ng->router_id && old)
{
/* The startup router ID must be determined after start of device protocol,
* thus if old == NULL then we do nothing */
@ -280,10 +253,7 @@ global_commit(struct config *new, struct config *old)
}
}
atomic_store_explicit(&global_runtime, ng, memory_order_release);
/* We have to wait until every reader surely doesn't read the old values */
synchronize_rcu();
switch_runtime(&ng->generic);
}
static int
@ -306,11 +276,11 @@ config_do_commit(config_ref *cr, int type)
OBSREF_CLEAR(config);
OBSREF_SET(config, OBSREF_GET(*cr));
if (!c->hostname)
if (!c->runtime.hostname)
{
c->hostname = get_hostname(c->mem);
c->runtime.hostname = get_hostname(c->mem);
if (!c->hostname)
if (!c->runtime.hostname)
log(L_WARN "Cannot determine hostname");
}

View File

@ -13,6 +13,7 @@
#include "lib/ip.h"
#include "lib/hash.h"
#include "lib/resource.h"
#include "lib/runtime.h"
#include "lib/obstacle.h"
#include "lib/timer.h"
@ -32,33 +33,30 @@ struct config {
struct symbol *def_tables[NET_MAX]; /* Default routing tables for each network */
struct iface_patt *router_id_from; /* Configured list of router ID iface patterns */
u32 router_id; /* Our Router ID */
u32 proto_default_debug; /* Default protocol debug mask */
u32 proto_default_mrtdump; /* Default protocol mrtdump mask */
u32 channel_default_debug; /* Default channel debug mask */
u32 table_default_debug; /* Default table debug mask */
u32 show_route_debug; /* Exports to CLI debug mask */
u16 filter_vstk, filter_estk; /* Filter stack depth */
struct timeformat tf_route; /* Time format for 'show route' */
struct timeformat tf_proto; /* Time format for 'show protocol' */
struct timeformat tf_log; /* Time format for the logfile */
struct timeformat tf_base; /* Time format for other purposes */
u32 gr_wait; /* Graceful restart wait timeout (sec) */
const char *hostname; /* Hostname */
int cli_debug; /* Tracing of CLI connections and commands */
enum latency_debug_flags {
DL_PING = 1,
DL_WAKEUP = 2,
DL_SCHEDULING = 4,
DL_ALLOCATOR = 8,
DL_SOCKETS = 0x10,
DL_EVENTS = 0x20,
DL_TIMERS = 0x40,
} latency_debug; /* I/O loops log information about task scheduling */
u32 latency_limit; /* Events with longer duration are logged (us) */
u32 watchdog_warning; /* I/O loop watchdog limit for warning (us) */
u32 watchdog_timeout; /* Watchdog timeout (in seconds, 0 = disabled) */
union bird_global_runtime {
struct global_runtime generic;
struct {
GLOBAL_RUNTIME_CONTENTS;
struct timeformat tf_route; /* Time format for 'show route' */
struct timeformat tf_proto; /* Time format for 'show protocol' */
u32 gr_wait; /* Graceful restart wait timeout (sec) */
u32 router_id; /* Our Router ID */
int cli_debug; /* Tracing of CLI connections and commands */
u32 watchdog_timeout; /* Watchdog timeout (in seconds, 0 = disabled) */
};
} runtime;
char *err_msg; /* Parser error message */
int err_lino; /* Line containing error */
int err_chno; /* Character where the parser stopped */
@ -76,26 +74,8 @@ struct config {
int gr_down; /* This is a pseudo-config for graceful restart */
};
struct global_runtime {
struct timeformat tf_route; /* Time format for 'show route' */
struct timeformat tf_proto; /* Time format for 'show protocol' */
struct timeformat tf_log; /* Time format for the logfile */
struct timeformat tf_base; /* Time format for other purposes */
u32 gr_wait; /* Graceful restart wait timeout (sec) */
u32 router_id; /* Our Router ID */
const char *hostname; /* Hostname */
btime load_time; /* When we reconfigured last time */
int cli_debug; /* Tracing of CLI connections and commands */
enum latency_debug_flags latency_debug;
u32 latency_limit; /* Events with longer duration are logged (us) */
u32 watchdog_warning; /* I/O loop watchdog limit for warning (us) */
u32 watchdog_timeout; /* Watchdog timeout (in seconds, 0 = disabled) */
};
extern struct global_runtime * _Atomic global_runtime;
/* BIRD's global runtime accessor */
#define BIRD_GLOBAL_RUNTIME SKIP_BACK(union bird_global_runtime, generic, atomic_load_explicit(&global_runtime, memory_order_relaxed))
/* Please don't use these variables in protocols. Use proto_config->global instead. */
typedef OBSREF(struct config) config_ref;

View File

@ -1,4 +1,4 @@
src := a-path.c a-set.c bitmap.c bitops.c blake2s.c blake2b.c checksum.c defer.c event.c flowspec.c idm.c ip.c lists.c lockfree.c mac.c md5.c mempool.c net.c netindex.c patmatch.c printf.c rcu.c resource.c sha1.c sha256.c sha512.c slab.c slists.c strtoul.c tbf.c timer.c xmalloc.c
src := a-path.c a-set.c bitmap.c bitops.c blake2s.c blake2b.c checksum.c defer.c event.c flowspec.c idm.c ip.c lists.c lockfree.c mac.c md5.c mempool.c net.c netindex.c patmatch.c printf.c rcu.c resource.c runtime.c sha1.c sha256.c sha512.c slab.c slists.c strtoul.c tbf.c timer.c xmalloc.c
obj := $(src-o-files)
$(all-daemon)

32
lib/runtime.c Normal file
View File

@ -0,0 +1,32 @@
/*
* BIRD Internet Routing Daemon -- Global runtime context
*
* (c) 2024 Maria Matejka <mq@jmq.cz>
* (c) 2024 CZ.NIC, z.s.p.o.
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#include "lib/runtime.h"
struct global_runtime global_runtime_initial = {
.tf_log = {
.fmt1 = "%F %T.%3f",
},
.tf_base = {
.fmt1 = "%F %T.%3f",
},
};
struct global_runtime * _Atomic global_runtime = &global_runtime_initial;
void
switch_runtime(struct global_runtime *new)
{
new->load_time = current_time();
atomic_store_explicit(&global_runtime, new, memory_order_release);
/* We have to wait until every reader surely doesn't read the old values */
synchronize_rcu();
}

35
lib/runtime.h Normal file
View File

@ -0,0 +1,35 @@
/*
* BIRD Internet Routing Daemon -- Global runtime context
*
* (c) 2024 Maria Matejka <mq@jmq.cz>
* (c) 2024 CZ.NIC, z.s.p.o.
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#include "lib/timer.h"
/* I/O loops log information about task scheduling */
enum latency_debug_flags {
DL_PING = 1,
DL_WAKEUP = 2,
DL_SCHEDULING = 4,
DL_ALLOCATOR = 8,
DL_SOCKETS = 0x10,
DL_EVENTS = 0x20,
DL_TIMERS = 0x40,
};
#define GLOBAL_RUNTIME_CONTENTS \
struct timeformat tf_log; /* Time format for the logfile */ \
struct timeformat tf_base; /* Time format for other purposes */ \
btime load_time; /* When we reconfigured last time */ \
enum latency_debug_flags latency_debug; /* What to log about IO loop */ \
u32 latency_limit; /* Events with longer duration are logged (us) */ \
u32 watchdog_warning; /* I/O loop watchdog limit for warning (us) */ \
const char *hostname; /* Hostname */ \
struct global_runtime { GLOBAL_RUNTIME_CONTENTS };
extern struct global_runtime * _Atomic global_runtime;
void switch_runtime(struct global_runtime *);

View File

@ -221,7 +221,7 @@ cli_command(struct cli *c)
struct config f;
int res;
if (OBSREF_GET(config)->cli_debug > 1)
if (BIRD_GLOBAL_RUNTIME->cli_debug > 1)
log(L_TRACE "CLI: %s", c->rx_buf);
bzero(&f, sizeof(f));
f.mem = c->parser_pool;

View File

@ -25,7 +25,7 @@ cmd_show_status(void)
byte tim[TM_DATETIME_BUFFER_SIZE];
rcu_read_lock();
struct global_runtime *gr = atomic_load_explicit(&global_runtime, memory_order_acquire);
union bird_global_runtime *gr = BIRD_GLOBAL_RUNTIME;
struct timeformat *tf = &gr->tf_base;
cli_msg(-1000, "BIRD " BIRD_VERSION);

View File

@ -202,7 +202,7 @@ CF_GRAMMAR
conf: rtrid ;
rtrid:
ROUTER ID idval ';' { new_config->router_id = $3; }
ROUTER ID idval ';' { new_config->runtime.router_id = $3; }
| ROUTER ID FROM iface_patt ';' { new_config->router_id_from = this_ipatt; }
;
@ -222,11 +222,11 @@ idval:
conf: hostname_override ;
hostname_override: HOSTNAME text ';' { new_config->hostname = $2; } ;
hostname_override: HOSTNAME text ';' { new_config->runtime.hostname = $2; } ;
conf: gr_opts ;
gr_opts: GRACEFUL RESTART WAIT expr ';' { new_config->gr_wait = $4; } ;
gr_opts: GRACEFUL RESTART WAIT expr ';' { new_config->runtime.gr_wait = $4; } ;
/* Network types (for tables, channels) */
@ -443,7 +443,7 @@ debug_default:
DEBUG PROTOCOLS debug_mask { new_config->proto_default_debug = $3; }
| DEBUG CHANNELS debug_mask { new_config->channel_default_debug = $3; }
| DEBUG TABLES debug_mask { new_config->table_default_debug = $3; }
| DEBUG COMMANDS expr { new_config->cli_debug = $3; }
| DEBUG COMMANDS expr { new_config->runtime.cli_debug = $3; }
| DEBUG SHOW ROUTE debug_mask { new_config->show_route_debug = $4; }
;
@ -452,10 +452,10 @@ debug_default:
conf: timeformat_base ;
timeformat_which:
ROUTE { $$ = &new_config->tf_route; }
| PROTOCOL { $$ = &new_config->tf_proto; }
| BASE { $$ = &new_config->tf_base; }
| LOG { $$ = &new_config->tf_log; }
ROUTE { $$ = &new_config->runtime.tf_route; }
| PROTOCOL { $$ = &new_config->runtime.tf_proto; }
| BASE { $$ = &new_config->runtime.tf_base; }
| LOG { $$ = &new_config->runtime.tf_log; }
;
timeformat_spec:
@ -736,7 +736,7 @@ r_args:
$$->filter = FILTER_ACCEPT;
OBSREF_SET($$->running_on_config, this_cli->main_config);
$$->cli = this_cli;
$$->tf_route = this_cli->main_config->tf_route;
$$->tf_route = this_cli->main_config->runtime.tf_route;
}
| r_args net_any {
$$ = $1;

View File

@ -165,7 +165,7 @@ if_dump_all(void)
IFACE_WALK(i)
if_dump(i);
rcu_read_lock();
debug("Router ID: %08x\n", atomic_load_explicit(&global_runtime, memory_order_relaxed)->router_id);
debug("Router ID: %08x\n", BIRD_GLOBAL_RUNTIME->router_id);
rcu_read_unlock();
}

View File

@ -1671,7 +1671,7 @@ protos_do_commit(struct config *new, struct config *old, int type)
global_commit() because it is postponed after start of device protocol */
if ((phase == PROTOCOL_STARTUP_NECESSARY) && !old)
{
struct global_runtime *gr = atomic_load_explicit(&global_runtime, memory_order_relaxed);
union bird_global_runtime *gr = BIRD_GLOBAL_RUNTIME;
if (!gr->router_id)
{
gr->router_id = if_choose_router_id(new->router_id_from, 0);
@ -1830,7 +1830,7 @@ graceful_restart_init(void)
graceful_restart_state = GRS_ACTIVE;
gr_wait_timer = tm_new_init(proto_pool, graceful_restart_done, NULL, 0, 0);
u32 gr_wait = atomic_load_explicit(&global_runtime, memory_order_relaxed)->gr_wait;
u32 gr_wait = BIRD_GLOBAL_RUNTIME->gr_wait;
tm_start(gr_wait_timer, gr_wait S);
}
@ -1884,7 +1884,7 @@ graceful_restart_show_status(void)
cli_msg(-24, "Graceful restart recovery in progress");
cli_msg(-24, " Waiting for %d channels to recover", graceful_restart_locks);
cli_msg(-24, " Wait timer is %t/%u", tm_remains(gr_wait_timer),
atomic_load_explicit(&global_runtime, memory_order_relaxed)->gr_wait);
BIRD_GLOBAL_RUNTIME->gr_wait);
}
/**
@ -2472,7 +2472,7 @@ proto_cmd_show(struct proto *p, uintptr_t verbose, int cnt)
p->proto->get_status(p, buf);
rcu_read_lock();
tm_format_time(tbuf, &atomic_load_explicit(&global_runtime, memory_order_acquire)->tf_proto, p->last_state_change);
tm_format_time(tbuf, &BIRD_GLOBAL_RUNTIME->tf_proto, p->last_state_change);
rcu_read_unlock();
cli_msg(-1002, "%-10s %-10s %-10s %-6s %-12s %s",
p->name,

View File

@ -303,7 +303,7 @@ static inline struct domain_generic *proto_domain(struct proto *p)
static inline u32
proto_get_router_id(struct proto_config *pc)
{
return pc->router_id ?: atomic_load_explicit(&global_runtime, memory_order_relaxed)->router_id;
return pc->router_id ?: BIRD_GLOBAL_RUNTIME->router_id;
}

View File

@ -1239,7 +1239,7 @@ bfd_show_session(struct bfd_session *s, int details)
byte tbuf[TM_DATETIME_BUFFER_SIZE];
rcu_read_lock();
struct global_runtime *gr = atomic_load_explicit(&global_runtime, memory_order_relaxed);
union bird_global_runtime *gr = BIRD_GLOBAL_RUNTIME;
tm_format_time(tbuf, &gr->tf_proto, s->last_state_change);
rcu_read_unlock();

View File

@ -284,7 +284,7 @@ bgp_prepare_capabilities(struct bgp_conn *conn)
caps->llgr_aware = 1;
rcu_read_lock();
struct global_runtime *gr = atomic_load_explicit(&global_runtime, memory_order_relaxed);
union bird_global_runtime *gr = BIRD_GLOBAL_RUNTIME;
if (p->cf->enable_hostname && gr->hostname)
{
size_t length = strlen(gr->hostname);

View File

@ -132,10 +132,10 @@ conf: THREADS expr {
conf: debug_unix ;
debug_unix:
DEBUG LATENCY latency_debug_mask { new_config->latency_debug = $3; }
| DEBUG LATENCY LIMIT expr_us { new_config->latency_limit = $4; }
| WATCHDOG WARNING expr_us { new_config->watchdog_warning = $3; }
| WATCHDOG TIMEOUT expr_us { new_config->watchdog_timeout = ($3 + 999999) TO_S; }
DEBUG LATENCY latency_debug_mask { new_config->runtime.latency_debug = $3; }
| DEBUG LATENCY LIMIT expr_us { new_config->runtime.latency_limit = $4; }
| WATCHDOG WARNING expr_us { new_config->runtime.watchdog_warning = $3; }
| WATCHDOG TIMEOUT expr_us { new_config->runtime.watchdog_timeout = ($3 + 999999) TO_S; }
;
latency_debug_mask:

View File

@ -464,7 +464,7 @@ watchdog_start(void)
loop_time = last_io_time;
event_log_num = 0;
struct global_runtime *gr = atomic_load_explicit(&global_runtime, memory_order_relaxed);
union bird_global_runtime *gr = BIRD_GLOBAL_RUNTIME;
if (gr->watchdog_timeout)
{
alarm(gr->watchdog_timeout);
@ -484,7 +484,7 @@ watchdog_stop(void)
}
btime duration = last_io_time - loop_time;
struct global_runtime *gr = atomic_load_explicit(&global_runtime, memory_order_relaxed);
union bird_global_runtime *gr = BIRD_GLOBAL_RUNTIME;
if (duration > gr->watchdog_warning)
log(L_WARN "I/O loop cycle took %u.%03u ms for %d events",
(uint) (duration TO_MS), (uint) (duration % 1000), event_log_num);

View File

@ -191,8 +191,8 @@ sysdep_preconfig(struct config *c)
{
init_list(&c->logfiles);
c->latency_limit = UNIX_DEFAULT_LATENCY_LIMIT;
c->watchdog_warning = UNIX_DEFAULT_WATCHDOG_WARNING;
c->runtime.latency_limit = UNIX_DEFAULT_LATENCY_LIMIT;
c->runtime.watchdog_warning = UNIX_DEFAULT_WATCHDOG_WARNING;
#ifdef PATH_IPROUTE_DIR
read_iproute_table(c, PATH_IPROUTE_DIR "/rt_protos", "ipp_", 255);
@ -489,7 +489,7 @@ cli_rx(sock *s, uint size UNUSED)
return 0;
}
#define GLOBAL_CLI_DEBUG (atomic_load_explicit(&global_runtime, memory_order_relaxed)->cli_debug)
#define GLOBAL_CLI_DEBUG (BIRD_GLOBAL_RUNTIME->cli_debug)
static void
cli_err(sock *s, int err)