diff options
author | Lennart Poettering <lennart@poettering.net> | 2013-04-23 15:53:16 -0300 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2013-04-23 16:00:32 -0300 |
commit | 3ecaa09bccd8a59c9f1e06756a1334a162206dc4 (patch) | |
tree | 5db15dc8f6fe6ea17e0d2449b8fee015b6066f47 /src/core/path.c | |
parent | a34cb32e54ed51125957f69622efef30f42d5fae (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.c | 69 |
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", |