0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-10-18 01:54:08 +00:00

TMP/CLI: show proto rework to not lock all protocols

This commit is contained in:
Maria Matejka 2024-10-15 11:32:48 +02:00
parent 6f4a973113
commit 8fae41780c
8 changed files with 115 additions and 25 deletions

View File

@ -692,10 +692,10 @@ CF_CLI(SHOW MEMORY,,, [[Show memory usage]])
{ cmd_show_memory(); } ; { cmd_show_memory(); } ;
CF_CLI(SHOW PROTOCOLS, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocols]]) CF_CLI(SHOW PROTOCOLS, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocols]])
{ proto_apply_cmd($3, proto_cmd_show, 0, 0); } ; { proto_apply_cmd_no_lock($3, proto_cmd_show, 0, (union cmd_arg){.verbose = 0}); } ;
CF_CLI(SHOW PROTOCOLS ALL, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocol details]]) CF_CLI(SHOW PROTOCOLS ALL, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocol details]])
{ proto_apply_cmd($4, proto_cmd_show, 0, 1); } ; { proto_apply_cmd_no_lock($4, proto_cmd_show, 0, (union cmd_arg){.verbose = 1}); } ;
optproto: optproto:
CF_SYM_KNOWN { cf_assert_symbol($1, SYM_PROTO); $$ = $1; } CF_SYM_KNOWN { cf_assert_symbol($1, SYM_PROTO); $$ = $1; }

View File

@ -293,6 +293,19 @@ proto_add_channel(struct proto *p, struct channel_config *cf)
return c; return c;
} }
struct channel *
proto_add_main_channel(struct proto *p, struct channel_config *cf)
{
p->main_channel = proto_add_channel(p, cf);
ea_list *eal;
eal = p->ea_state;
ea_set_attr(&eal, EA_LITERAL_EMBEDDED(&ea_main_table_id, 0, p->main_channel->table->id));
proto_announce_state(p, eal);
return p->main_channel;
}
void void
proto_remove_channel(struct proto *p UNUSED, struct channel *c) proto_remove_channel(struct proto *p UNUSED, struct channel *c)
{ {
@ -2090,6 +2103,7 @@ extern void bfd_init_all(void);
void protos_build_gen(void); void protos_build_gen(void);
/** /**
* protos_build - build a protocol list * protos_build - build a protocol list
* *
@ -2489,6 +2503,19 @@ proto_state_name(struct proto *p)
} }
} }
static char *
proto_state_name_from_int(int state)
{
switch (state)
{
case PS_DOWN: return "flush or down";
case PS_START: return "start";
case PS_UP: return "up";
case PS_STOP: return "stop";
default: return "???";
}
}
static void static void
channel_show_stats(struct channel *c) channel_show_stats(struct channel *c)
{ {
@ -2582,7 +2609,7 @@ channel_cmd_debug(struct channel *c, uint mask)
} }
void void
proto_cmd_show(struct proto *p, uintptr_t verbose, int cnt) proto_cmd_show(struct proto *p, union cmd_arg verbose, int cnt)
{ {
byte buf[256], tbuf[TM_DATETIME_BUFFER_SIZE]; byte buf[256], tbuf[TM_DATETIME_BUFFER_SIZE];
@ -2591,23 +2618,37 @@ proto_cmd_show(struct proto *p, uintptr_t verbose, int cnt)
cli_msg(-2002, "%-10s %-10s %-10s %-6s %-12s %s", cli_msg(-2002, "%-10s %-10s %-10s %-6s %-12s %s",
"Name", "Proto", "Table", "State", "Since", "Info"); "Name", "Proto", "Table", "State", "Since", "Info");
buf[0] = 0; PST_LOCKED(ts)
if (p->proto->get_status)
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);
rcu_read_unlock();
cli_msg(-1002, "%-10s %-10s %-10s %-6s %-12s %s",
p->name,
p->proto->name,
p->main_channel ? p->main_channel->table->name : "---",
proto_state_name(p),
tbuf,
buf);
if (verbose)
{ {
ea_list *eal = ts->states[p->id];
const char *name = ea_get_adata(eal, &ea_name)->data;
struct protocol *proto = (struct protocol *) ea_get_ptr(eal, &ea_protocol_type, 0);
const int state = ea_get_int(eal, &ea_state, 0);
ea_list *chan_ea = ts->channels[ea_get_int(eal, &ea_main_table_id, 0)];
const char *table = ea_get_adata(chan_ea, &ea_name)->data;
buf[0] = 0;
if (p->proto->get_status)
{
PROTO_LOCKED_FROM_MAIN(p)
p->proto->get_status(p, buf);
}
const btime *time = (btime *)ea_get_adata(eal, &ea_last_modified)->data;
tm_format_time(tbuf, &atomic_load_explicit(&global_runtime, memory_order_acquire)->tf_proto, *time);
cli_msg(-1002, "%-10s %-10s %-10s %-6s %-12s %s",
name,
proto->name,
table ? table : "---",
proto_state_name_from_int(state),
tbuf,
buf);
}
if (verbose.verbose)
{
PROTO_LOCKED_FROM_MAIN(p)
{
if (p->cf->dsc) if (p->cf->dsc)
cli_msg(-1006, " Description: %s", p->cf->dsc); cli_msg(-1006, " Description: %s", p->cf->dsc);
if (p->message) if (p->message)
@ -2627,6 +2668,7 @@ proto_cmd_show(struct proto *p, uintptr_t verbose, int cnt)
} }
cli_msg(-1006, ""); cli_msg(-1006, "");
}
} }
} }
@ -2829,6 +2871,46 @@ proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, uintptr_t, in
proto_apply_cmd_symbol(ps.ptr, cmd, arg); proto_apply_cmd_symbol(ps.ptr, cmd, arg);
} }
void
proto_apply_cmd_no_lock(struct proto_spec ps, void (* cmd)(struct proto *, union cmd_arg, int),
int restricted, union cmd_arg arg)
{
if (restricted && cli_access_restricted())
return;
if (ps.patt)
{
int cnt = 0;
const char *patt = ps.ptr;
WALK_TLIST(proto, p, &global_proto_list)
if (!patt || patmatch(patt, p->name))
cmd(p, arg, cnt++);
if (!cnt)
cli_msg(8003, "No protocols match");
else
cli_msg(0, "");
}
else
{
const struct symbol *s = ps.ptr;
if (s->class != SYM_PROTO)
{
cli_msg(9002, "%s is not a protocol", s->name);
return;
}
if (s->proto->proto)
{
struct proto *p = s->proto->proto;
cmd(p, arg, 0);
cli_msg(0, "");
}
else
cli_msg(9002, "%s does not exist", s->name);
}
}
struct proto * struct proto *
proto_get_named(struct symbol *sym, struct protocol *pr) proto_get_named(struct symbol *sym, struct protocol *pr)
{ {

View File

@ -262,7 +262,13 @@ void channel_show_limit(struct limit *l, const char *dsc, int active, int action
void channel_show_info(struct channel *c); void channel_show_info(struct channel *c);
void channel_cmd_debug(struct channel *c, uint mask); void channel_cmd_debug(struct channel *c, uint mask);
void proto_cmd_show(struct proto *, uintptr_t, int); union cmd_arg {
int verbose;
struct proto_reload_request *prr;
char *msg;
};
void proto_cmd_show(struct proto *, union cmd_arg verbose, int);
void proto_cmd_disable(struct proto *, uintptr_t, int); void proto_cmd_disable(struct proto *, uintptr_t, int);
void proto_cmd_enable(struct proto *, uintptr_t, int); void proto_cmd_enable(struct proto *, uintptr_t, int);
void proto_cmd_restart(struct proto *, uintptr_t, int); void proto_cmd_restart(struct proto *, uintptr_t, int);
@ -271,6 +277,7 @@ void proto_cmd_debug(struct proto *, uintptr_t, int);
void proto_cmd_mrtdump(struct proto *, uintptr_t, int); void proto_cmd_mrtdump(struct proto *, uintptr_t, int);
void proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, uintptr_t, int), int restricted, uintptr_t arg); void proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, uintptr_t, int), int restricted, uintptr_t arg);
void proto_apply_cmd_no_lock(struct proto_spec ps, void (* cmd)(struct proto *, union cmd_arg, int), int restricted, union cmd_arg arg);
struct proto *proto_get_named(struct symbol *, struct protocol *); struct proto *proto_get_named(struct symbol *, struct protocol *);
struct proto *proto_iterate_named(struct symbol *sym, struct protocol *proto, struct proto *old); struct proto *proto_iterate_named(struct symbol *sym, struct protocol *proto, struct proto *old);
@ -713,6 +720,7 @@ static inline struct channel_config *proto_cf_mpls_channel(struct proto_config *
struct channel *proto_find_channel_by_table(struct proto *p, rtable *t); struct channel *proto_find_channel_by_table(struct proto *p, rtable *t);
struct channel *proto_find_channel_by_name(struct proto *p, const char *n); struct channel *proto_find_channel_by_name(struct proto *p, const char *n);
struct channel *proto_add_channel(struct proto *p, struct channel_config *cf); struct channel *proto_add_channel(struct proto *p, struct channel_config *cf);
struct channel *proto_add_main_channel(struct proto *p, struct channel_config *cf);
void proto_remove_channel(struct proto *p, struct channel *c); void proto_remove_channel(struct proto *p, struct channel *c);
int proto_configure_channel(struct proto *p, struct channel **c, struct channel_config *cf); int proto_configure_channel(struct proto *p, struct channel **c, struct channel_config *cf);

View File

@ -368,7 +368,7 @@ ospf_init(struct proto_config *CF)
struct ospf_config *cf = (struct ospf_config *) CF; struct ospf_config *cf = (struct ospf_config *) CF;
struct proto *P = proto_new(CF); struct proto *P = proto_new(CF);
P->main_channel = proto_add_channel(P, proto_cf_main_channel(CF)); proto_add_main_channel(P, proto_cf_main_channel(CF));
P->rt_notify = ospf_rt_notify; P->rt_notify = ospf_rt_notify;
P->iface_sub.if_notify = ospf_if_notify; P->iface_sub.if_notify = ospf_if_notify;

View File

@ -579,7 +579,7 @@ radv_init(struct proto_config *CF)
{ {
struct proto *P = proto_new(CF); struct proto *P = proto_new(CF);
P->main_channel = proto_add_channel(P, proto_cf_main_channel(CF)); proto_add_main_channel(P, proto_cf_main_channel(CF));
P->preexport = radv_preexport; P->preexport = radv_preexport;
P->rt_notify = radv_rt_notify; P->rt_notify = radv_rt_notify;

View File

@ -1162,7 +1162,7 @@ rip_init(struct proto_config *CF)
{ {
struct proto *P = proto_new(CF); struct proto *P = proto_new(CF);
P->main_channel = proto_add_channel(P, proto_cf_main_channel(CF)); proto_add_main_channel(P, proto_cf_main_channel(CF));
P->iface_sub.if_notify = rip_if_notify; P->iface_sub.if_notify = rip_if_notify;
P->rt_notify = rip_rt_notify; P->rt_notify = rip_rt_notify;

View File

@ -507,7 +507,7 @@ static_init(struct proto_config *CF)
struct static_proto *p = (void *) P; struct static_proto *p = (void *) P;
struct static_config *cf = (void *) CF; struct static_config *cf = (void *) CF;
P->main_channel = proto_add_channel(P, proto_cf_main_channel(CF)); proto_add_main_channel(P, proto_cf_main_channel(CF));
proto_configure_mpls_channel(P, CF, RTS_STATIC); proto_configure_mpls_channel(P, CF, RTS_STATIC);

View File

@ -820,7 +820,7 @@ krt_init(struct proto_config *CF)
struct krt_proto *p = proto_new(CF); struct krt_proto *p = proto_new(CF);
// struct krt_config *cf = (void *) CF; // struct krt_config *cf = (void *) CF;
p->p.main_channel = proto_add_channel(&p->p, proto_cf_main_channel(CF)); proto_add_main_channel(&p->p, proto_cf_main_channel(CF));
p->p.preexport = krt_preexport; p->p.preexport = krt_preexport;
p->p.rt_notify = krt_rt_notify; p->p.rt_notify = krt_rt_notify;