lifecycle: break dependency cycles when calculating the full dependency graph
This commit is contained in:
parent
b2e657cdf0
commit
122a54377d
1 changed files with 12 additions and 0 deletions
|
@ -476,18 +476,26 @@ lif_lifecycle_run(const struct lif_execute_opts *opts, struct lif_interface *ifa
|
||||||
static bool
|
static bool
|
||||||
count_interface_rdepends(const struct lif_execute_opts *opts, struct lif_dict *collection, struct lif_interface *parent, size_t depth)
|
count_interface_rdepends(const struct lif_execute_opts *opts, struct lif_dict *collection, struct lif_interface *parent, size_t depth)
|
||||||
{
|
{
|
||||||
|
/* if we have looped, return true immediately to break the loop. */
|
||||||
|
if (parent->is_pending)
|
||||||
|
return true;
|
||||||
|
|
||||||
/* query our dependents if we don't have them already */
|
/* query our dependents if we don't have them already */
|
||||||
if (!lif_lifecycle_query_dependents(opts, parent, parent->ifname))
|
if (!lif_lifecycle_query_dependents(opts, parent, parent->ifname))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* set rdepends_count to depth, dependents will be depth + 1 */
|
/* set rdepends_count to depth, dependents will be depth + 1 */
|
||||||
|
parent->is_pending = true;
|
||||||
parent->rdepends_count = depth;
|
parent->rdepends_count = depth;
|
||||||
|
|
||||||
struct lif_dict_entry *requires = lif_dict_find(&parent->vars, "requires");
|
struct lif_dict_entry *requires = lif_dict_find(&parent->vars, "requires");
|
||||||
|
|
||||||
/* no dependents, nothing to worry about */
|
/* no dependents, nothing to worry about */
|
||||||
if (requires == NULL)
|
if (requires == NULL)
|
||||||
|
{
|
||||||
|
parent->is_pending = false;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* walk any dependents */
|
/* walk any dependents */
|
||||||
char require_ifs[4096] = {};
|
char require_ifs[4096] = {};
|
||||||
|
@ -499,9 +507,13 @@ count_interface_rdepends(const struct lif_execute_opts *opts, struct lif_dict *c
|
||||||
struct lif_interface *iface = lif_interface_collection_find(collection, tokenp);
|
struct lif_interface *iface = lif_interface_collection_find(collection, tokenp);
|
||||||
|
|
||||||
if (!count_interface_rdepends(opts, collection, iface, depth + 1))
|
if (!count_interface_rdepends(opts, collection, iface, depth + 1))
|
||||||
|
{
|
||||||
|
parent->is_pending = false;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parent->is_pending = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue