lifecycle: handle executors in reverse order when taking an interface down

This commit is contained in:
Ariadne Conill 2020-08-24 11:04:48 -06:00
parent dfb979d00d
commit de20e5f8a9
2 changed files with 26 additions and 11 deletions

View file

@ -35,6 +35,9 @@ struct lif_dict_entry {
#define LIF_DICT_FOREACH_SAFE(iter, iter_next, dict) \
LIF_LIST_FOREACH_SAFE((iter), (iter_next), (dict)->list.head)
#define LIF_DICT_FOREACH_REVERSE(iter, dict) \
LIF_LIST_FOREACH_REVERSE((iter), (dict)->list.tail)
typedef int (*lif_dict_cmp_t)(const void *, const void *);
extern void lif_dict_init(struct lif_dict *dict);

View file

@ -43,21 +43,33 @@ handle_commands_for_phase(const struct lif_execute_opts *opts, char *const envp[
return true;
}
static inline bool
handle_single_executor_for_phase(const struct lif_dict_entry *entry, const struct lif_execute_opts *opts, char *const envp[])
{
if (strcmp(entry->key, "use"))
return true;
const char *cmd = entry->data;
if (!lif_maybe_run_executor(opts, envp, cmd))
return false;
return true;
}
static bool
handle_executors_for_phase(const struct lif_execute_opts *opts, char *const envp[], struct lif_interface *iface)
handle_executors_for_phase(const struct lif_execute_opts *opts, char *const envp[], struct lif_interface *iface, bool up)
{
struct lif_node *iter;
LIF_DICT_FOREACH(iter, &iface->vars)
if (up)
{
struct lif_dict_entry *entry = iter->data;
if (strcmp(entry->key, "use"))
continue;
const char *cmd = entry->data;
if (!lif_maybe_run_executor(opts, envp, cmd))
return false;
LIF_DICT_FOREACH(iter, &iface->vars)
handle_single_executor_for_phase(iter->data, opts, envp);
}
else
{
LIF_DICT_FOREACH_REVERSE(iter, &iface->vars)
handle_single_executor_for_phase(iter->data, opts, envp);
}
return true;
@ -219,7 +231,7 @@ lif_lifecycle_run_phase(const struct lif_execute_opts *opts, struct lif_interfac
build_environment(&envp, opts, iface, lifname, phase, up ? "start" : "stop");
if (!handle_executors_for_phase(opts, envp, iface))
if (!handle_executors_for_phase(opts, envp, iface, up))
goto handle_error;
if (!handle_commands_for_phase(opts, envp, iface, phase))