diff --git a/src/core/unit.c b/src/core/unit.c index 70a2b57fa3..2b356e2854 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2876,13 +2876,32 @@ int unit_add_node_link(Unit *u, const char *what, bool wants) { } int unit_coldplug(Unit *u) { + Unit *other; + Iterator i; int r; assert(u); - if (UNIT_VTABLE(u)->coldplug) - if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0) + /* Make sure we don't enter a loop, when coldplugging + * recursively. */ + if (u->coldplugged) + return 0; + + u->coldplugged = true; + + /* Make sure everything that we might pull in through + * triggering is coldplugged before us */ + SET_FOREACH(other, u->dependencies[UNIT_TRIGGERS], i) { + r = unit_coldplug(other); + if (r < 0) return r; + } + + if (UNIT_VTABLE(u)->coldplug) { + r = UNIT_VTABLE(u)->coldplug(u); + if (r < 0) + return r; + } if (u->job) { r = job_coldplug(u->job); diff --git a/src/core/unit.h b/src/core/unit.h index be306a004b..1a44271bc6 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -104,6 +104,7 @@ struct Unit { char *fragment_path; /* if loaded from a config file this is the primary path to it */ char *source_path; /* if converted, the source file */ char **dropin_paths; + usec_t fragment_mtime; usec_t source_mtime; usec_t dropin_mtime; @@ -233,6 +234,9 @@ struct Unit { bool cgroup_realized:1; bool cgroup_members_mask_valid:1; bool cgroup_subtree_mask_valid:1; + + /* Did we already invoke unit_coldplug() for this unit? */ + bool coldplugged; }; struct UnitStatusMessageFormats {