summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-04-24 16:04:50 +0200
committerLennart Poettering <lennart@poettering.net>2015-04-24 16:14:46 +0200
commitf78f265f405a61387c6c12a879ac0d6b6dc958db (patch)
treef9b3db24a37a12e06dab708b0aefc61896a529c2
parent0108f6ecc85eccc0177579f575d7bc3d56d43bc6 (diff)
core: always coldplug units that are triggered by other units before those
Let's make sure that we don't enqueue triggering jobs for units before those units are actually fully loaded. http://lists.freedesktop.org/archives/systemd-devel/2015-April/031176.html https://bugs.freedesktop.org/show_bug.cgi?id=88401
-rw-r--r--src/core/unit.c23
-rw-r--r--src/core/unit.h4
2 files changed, 25 insertions, 2 deletions
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 {