summaryrefslogtreecommitdiff
path: root/src/core/path.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2013-04-23 15:53:16 -0300
committerLennart Poettering <lennart@poettering.net>2013-04-23 16:00:32 -0300
commit3ecaa09bccd8a59c9f1e06756a1334a162206dc4 (patch)
tree5db15dc8f6fe6ea17e0d2449b8fee015b6066f47 /src/core/path.c
parenta34cb32e54ed51125957f69622efef30f42d5fae (diff)
unit: rework trigger dependency logic
Instead of having explicit type-specific callbacks that inform the triggering unit when a triggered unit changes state, make this generic so that state changes are forwarded betwee any triggered and triggering unit. Also, get rid of UnitRef references from automount, timer, path units, to the units they trigger and rely exclsuively on UNIT_TRIGGER type dendencies.
Diffstat (limited to 'src/core/path.c')
-rw-r--r--src/core/path.c69
1 files changed, 32 insertions, 37 deletions
diff --git a/src/core/path.c b/src/core/path.c
index d5b5eeb4a1..e1330f6c95 100644
--- a/src/core/path.c
+++ b/src/core/path.c
@@ -298,7 +298,6 @@ static void path_done(Unit *u) {
assert(p);
- unit_ref_unset(&p->unit);
path_free_specs(p);
}
@@ -390,21 +389,18 @@ static int path_load(Unit *u) {
if (u->load_state == UNIT_LOADED) {
- if (!UNIT_DEREF(p->unit)) {
+ if (set_isempty(u->dependencies[UNIT_TRIGGERS])) {
Unit *x;
r = unit_load_related_unit(u, ".service", &x);
if (r < 0)
return r;
- unit_ref_set(&p->unit, x);
+ r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, x, true);
+ if (r < 0)
+ return r;
}
- r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS,
- UNIT_DEREF(p->unit), true);
- if (r < 0)
- return r;
-
r = path_add_mount_links(p);
if (r < 0)
return r;
@@ -421,11 +417,14 @@ static int path_load(Unit *u) {
static void path_dump(Unit *u, FILE *f, const char *prefix) {
Path *p = PATH(u);
+ Unit *trigger;
PathSpec *s;
assert(p);
assert(f);
+ trigger = UNIT_TRIGGER(u);
+
fprintf(f,
"%sPath State: %s\n"
"%sResult: %s\n"
@@ -434,7 +433,7 @@ static void path_dump(Unit *u, FILE *f, const char *prefix) {
"%sDirectoryMode: %04o\n",
prefix, path_state_to_string(p->state),
prefix, path_result_to_string(p->result),
- prefix, UNIT_DEREF(p->unit)->id,
+ prefix, trigger ? trigger->id : "n/a",
prefix, yes_no(p->make_directory),
prefix, p->directory_mode);
@@ -516,17 +515,18 @@ static void path_enter_dead(Path *p, PathResult f) {
}
static void path_enter_running(Path *p) {
+ _cleanup_dbus_error_free_ DBusError error;
int r;
- DBusError error;
assert(p);
+
dbus_error_init(&error);
/* Don't start job if we are supposed to go down */
- if (UNIT(p)->job && UNIT(p)->job->type == JOB_STOP)
+ if (unit_pending_inactive(UNIT(p)))
return;
- r = manager_add_job(UNIT(p)->manager, JOB_START, UNIT_DEREF(p->unit),
+ r = manager_add_job(UNIT(p)->manager, JOB_START, UNIT_TRIGGER(UNIT(p)),
JOB_REPLACE, true, &error, NULL);
if (r < 0)
goto fail;
@@ -544,8 +544,6 @@ fail:
log_warning("%s failed to queue unit startup job: %s",
UNIT(p)->id, bus_error(&error, r));
path_enter_dead(p, PATH_FAILURE_RESOURCES);
-
- dbus_error_free(&error);
}
static bool path_check_good(Path *p, bool initial) {
@@ -616,7 +614,7 @@ static int path_start(Unit *u) {
assert(p);
assert(p->state == PATH_DEAD || p->state == PATH_FAILED);
- if (UNIT_DEREF(p->unit)->load_state != UNIT_LOADED)
+ if (UNIT_TRIGGER(u)->load_state != UNIT_LOADED)
return -ENOENT;
path_mkdir(p);
@@ -737,33 +735,28 @@ fail:
path_enter_dead(p, PATH_FAILURE_RESOURCES);
}
-void path_unit_notify(Unit *u, UnitActiveState new_state) {
- Iterator i;
- Unit *k;
-
- if (u->type == UNIT_PATH)
- return;
+static void path_trigger_notify(Unit *u, Unit *other) {
+ Path *p = PATH(u);
- SET_FOREACH(k, u->dependencies[UNIT_TRIGGERED_BY], i) {
- Path *p;
+ assert(u);
+ assert(other);
- if (k->type != UNIT_PATH)
- continue;
+ /* Invoked whenever the unit we trigger changes state or gains
+ * or loses a job */
- if (k->load_state != UNIT_LOADED)
- continue;
-
- p = PATH(k);
+ if (other->load_state != UNIT_LOADED)
+ return;
- if (p->state == PATH_RUNNING && new_state == UNIT_INACTIVE) {
- log_debug("%s got notified about unit deactivation.",
- UNIT(p)->id);
+ if (p->state == PATH_RUNNING &&
+ UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) {
+ log_debug_unit(UNIT(p)->id,
+ "%s got notified about unit deactivation.",
+ UNIT(p)->id);
- /* Hmm, so inotify was triggered since the
- * last activation, so I guess we need to
- * recheck what is going on. */
- path_enter_waiting(p, false, p->inotify_triggered);
- }
+ /* Hmm, so inotify was triggered since the
+ * last activation, so I guess we need to
+ * recheck what is going on. */
+ path_enter_waiting(p, false, p->inotify_triggered);
}
}
@@ -830,6 +823,8 @@ const UnitVTable path_vtable = {
.fd_event = path_fd_event,
+ .trigger_notify = path_trigger_notify,
+
.reset_failed = path_reset_failed,
.bus_interface = "org.freedesktop.systemd1.Path",