lifecycle: add lif_interface.is_pending to break dependency cycles

This commit is contained in:
Ariadne Conill 2020-09-25 08:23:51 -06:00
parent 953b2274f7
commit 175f002b3e
2 changed files with 12 additions and 0 deletions

View file

@ -52,6 +52,7 @@ struct lif_interface {
bool is_bridge; bool is_bridge;
bool is_bond; bool is_bond;
bool is_template; bool is_template;
bool is_pending;
bool has_config_error; /* error found in interface configuration */ bool has_config_error; /* error found in interface configuration */

View file

@ -359,6 +359,9 @@ handle_dependents(const struct lif_execute_opts *opts, struct lif_interface *par
if (requires == NULL) if (requires == NULL)
return true; return true;
/* set the parent's pending flag to break dependency cycles */
parent->is_pending = true;
char require_ifs[4096] = {}; char require_ifs[4096] = {};
strlcpy(require_ifs, requires->data, sizeof require_ifs); strlcpy(require_ifs, requires->data, sizeof require_ifs);
char *bufp = require_ifs; char *bufp = require_ifs;
@ -399,15 +402,23 @@ handle_dependents(const struct lif_execute_opts *opts, struct lif_interface *par
iface->ifname, parent->ifname, up ? "up" : "down"); iface->ifname, parent->ifname, up ? "up" : "down");
if (!lif_lifecycle_run(opts, iface, collection, state, iface->ifname, up)) if (!lif_lifecycle_run(opts, iface, collection, state, iface->ifname, up))
{
parent->is_pending = false;
return false; return false;
} }
}
parent->is_pending = false;
return true; return true;
} }
bool bool
lif_lifecycle_run(const struct lif_execute_opts *opts, struct lif_interface *iface, struct lif_dict *collection, struct lif_dict *state, const char *lifname, bool up) lif_lifecycle_run(const struct lif_execute_opts *opts, struct lif_interface *iface, struct lif_dict *collection, struct lif_dict *state, const char *lifname, bool up)
{ {
/* if we're already pending, exit */
if (iface->is_pending)
return true;
if (iface->is_template) if (iface->is_template)
return false; return false;