diff --git a/main/module.c b/main/module.c index 5ff0c6e57..96f540af9 100644 --- a/main/module.c +++ b/main/module.c @@ -11,6 +11,7 @@ #include #include +#include #include static STAILQ_HEAD(, gr_api_handler) handlers = STAILQ_HEAD_INITIALIZER(handlers); @@ -61,11 +62,21 @@ void gr_register_module(struct gr_module *mod) { static bool module_is_child(const void *mod, const void *maybe_child) { const struct gr_module *c = maybe_child; const struct gr_module *m = mod; + char depends_on[512]; if (c->depends_on == NULL) return false; - return fnmatch(c->depends_on, m->name, 0) == 0; + // split on commas + assert(strlen(c->depends_on) < sizeof(depends_on)); + memccpy(depends_on, c->depends_on, 0, sizeof(depends_on)); + + for (char *dep = strtok(depends_on, ","); dep != NULL; dep = strtok(NULL, ",")) { + if (fnmatch(dep, m->name, 0) == 0) + return true; + } + + return false; } void modules_init(struct event_base *ev_base) { diff --git a/modules/infra/control/control_output.c b/modules/infra/control/control_output.c index a68c31be3..6540227c4 100644 --- a/modules/infra/control/control_output.c +++ b/modules/infra/control/control_output.c @@ -129,7 +129,7 @@ static void control_output_fini(struct event_base *) { static struct gr_module control_output_module = { .name = "control_output", - .depends_on = "*", + .depends_on = "graph", .init = control_output_init, .fini = control_output_fini, }; diff --git a/modules/infra/control/graph.c b/modules/infra/control/graph.c index e678787d1..2e630d327 100644 --- a/modules/infra/control/graph.c +++ b/modules/infra/control/graph.c @@ -579,7 +579,6 @@ static void graph_fini(struct event_base *) { static struct gr_module graph_module = { .name = "graph", - .depends_on = "iface", .init = graph_init, .fini = graph_fini, }; diff --git a/modules/infra/control/iface.c b/modules/infra/control/iface.c index 8769f0a46..86ea1cb16 100644 --- a/modules/infra/control/iface.c +++ b/modules/infra/control/iface.c @@ -469,7 +469,7 @@ static void iface_fini(struct event_base *) { static struct gr_module iface_module = { .name = "iface", - .depends_on = "*route", + .depends_on = "*route,control_output", .init = iface_init, .fini = iface_fini, }; diff --git a/modules/infra/control/nexthop.c b/modules/infra/control/nexthop.c index 171bde150..d49c14495 100644 --- a/modules/infra/control/nexthop.c +++ b/modules/infra/control/nexthop.c @@ -693,7 +693,7 @@ static struct gr_event_serializer nh_serializer = { static struct gr_module module = { .name = "nexthop", - .depends_on = "rcu", + .depends_on = "rcu,control_output", .init = nh_init, .fini = nh_fini, }; diff --git a/smoke/_init.sh b/smoke/_init.sh index bb1f99f2a..bfad08d33 100644 --- a/smoke/_init.sh +++ b/smoke/_init.sh @@ -41,18 +41,21 @@ cleanup() { status="$?" set +e sh -x $tmp/cleanup - # delete all non-port interfaces first - grcli interface show | - grep -Ev -e ^NAME -e '\' | - while read -r name _; do - grcli interface del "$name" - done - # then delete all ports - grcli interface show | - grep -ve ^NAME -e '\' | - while read -r name _; do - grcli interface del "$name" - done + + if socat FILE:/dev/null UNIX-CONNECT:$GROUT_SOCK_PATH 2>/dev/null; then + # delete all non-port interfaces first + grcli interface show | + grep -Ev -e ^NAME -e '\' | + while read -r name _; do + grcli interface del "$name" + done + # then delete all ports + grcli interface show | + grep -ve ^NAME -e '\' | + while read -r name _; do + grcli interface del "$name" + done + fi [ -s $tmp/restore_interfaces ] && sh -x $tmp/restore_interfaces kill %?grcli diff --git a/smoke/shutdown_test.sh b/smoke/shutdown_test.sh new file mode 100755 index 000000000..45954e3f2 --- /dev/null +++ b/smoke/shutdown_test.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2024 Robin Jarry + +. $(dirname $0)/_init.sh + +grcli -xe <