X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=unit.c;h=980c3711eb147d60075c416643d54e74bd57f69a;hb=6be1e7d538e12f4e5c79c1271dba90e66726d8fd;hp=f1dc3ddf871db69be0805cc5afc3f79e487a90d6;hpb=ea4309869e75497ba6a97c540646cb66a157a4d9;p=elogind.git diff --git a/unit.c b/unit.c index f1dc3ddf8..980c3711e 100644 --- a/unit.c +++ b/unit.c @@ -1,5 +1,24 @@ /*-*- Mode: C; c-basic-offset: 8 -*-*/ +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + #include #include #include @@ -155,6 +174,7 @@ int unit_add_name(Unit *u, const char *text) { if (!u->meta.id) u->meta.id = s; + unit_add_to_dbus_queue(u); return 0; } @@ -170,6 +190,8 @@ int unit_choose_id(Unit *u, const char *name) { return -ENOENT; u->meta.id = s; + + unit_add_to_dbus_queue(u); return 0; } @@ -183,6 +205,8 @@ int unit_set_description(Unit *u, const char *description) { free(u->meta.description); u->meta.description = s; + + unit_add_to_dbus_queue(u); return 0; } @@ -196,6 +220,16 @@ void unit_add_to_load_queue(Unit *u) { u->meta.in_load_queue = true; } +void unit_add_to_dbus_queue(Unit *u) { + assert(u); + + if (u->meta.load_state == UNIT_STUB || u->meta.in_dbus_queue || set_isempty(u->meta.manager->subscribed)) + return; + + LIST_PREPEND(Meta, dbus_queue, u->meta.manager->dbus_unit_queue, &u->meta); + u->meta.in_dbus_queue = true; +} + static void bidi_set_free(Unit *u, Set *s) { Iterator i; Unit *other; @@ -222,6 +256,8 @@ void unit_free(Unit *u) { assert(u); + bus_unit_send_removed_signal(u); + /* Detach from next 'bigger' objects */ SET_FOREACH(t, u->meta.names, i) @@ -233,6 +269,9 @@ void unit_free(Unit *u) { if (u->meta.in_load_queue) LIST_REMOVE(Meta, load_queue, u->meta.manager->load_queue, &u->meta); + if (u->meta.in_dbus_queue) + LIST_REMOVE(Meta, dbus_queue, u->meta.manager->dbus_unit_queue, &u->meta); + if (u->meta.load_state == UNIT_LOADED) if (UNIT_VTABLE(u)->done) UNIT_VTABLE(u)->done(u); @@ -245,7 +284,7 @@ void unit_free(Unit *u) { bidi_set_free(u, u->meta.dependencies[d]); free(u->meta.description); - free(u->meta.load_path); + free(u->meta.fragment_path); while ((t = set_steal_first(u->meta.names))) free(t); @@ -306,6 +345,8 @@ int unit_merge(Unit *u, Unit *other) { if ((r = ensure_merge(&u->meta.dependencies[d], other->meta.dependencies[d])) < 0) return r; + unit_add_to_dbus_queue(u); + return 0; } @@ -332,15 +373,15 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { char *t; UnitDependency d; Iterator i; - char *prefix2; + char *p2; + const char *prefix2; assert(u); if (!prefix) prefix = ""; - prefix2 = strappend(prefix, "\t"); - if (!prefix2) - prefix2 = ""; + p2 = strappend(prefix, "\t"); + prefix2 = p2 ? p2 : prefix; fprintf(f, "%s→ Unit %s:\n" @@ -356,8 +397,8 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { prefix, yes_no(u->meta.recursive_stop), prefix, yes_no(u->meta.stop_when_unneeded)); - if (u->meta.load_path) - fprintf(f, "%s\tLoad Path: %s\n", prefix, u->meta.load_path); + if (u->meta.fragment_path) + fprintf(f, "%s\tFragment Path: %s\n", prefix, u->meta.fragment_path); SET_FOREACH(t, u->meta.names, i) fprintf(f, "%s\tName: %s\n", prefix, t); @@ -378,7 +419,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { if (u->meta.job) job_dump(u->meta.job, f, prefix2); - free(prefix2); + free(p2); } /* Common implementation for multiple backends */ @@ -418,10 +459,12 @@ int unit_load(Unit *u) { goto fail; u->meta.load_state = UNIT_LOADED; + unit_add_to_dbus_queue(u); return 0; fail: u->meta.load_state = UNIT_FAILED; + unit_add_to_dbus_queue(u); return r; } @@ -435,19 +478,25 @@ int unit_start(Unit *u) { assert(u); - if (!UNIT_VTABLE(u)->start) - return -EBADR; - + /* If this is already (being) started, then this will + * succeed. Note that this will even succeed if this unit is + * not startable by the user. This is relied on to detect when + * we need to wait for units and when waiting is finished. */ state = unit_active_state(u); if (UNIT_IS_ACTIVE_OR_RELOADING(state)) return -EALREADY; + /* If it is stopped, but we cannot start it, then fail */ + if (!UNIT_VTABLE(u)->start) + return -EBADR; + /* We don't suppress calls to ->start() here when we are * already starting, to allow this request to be used as a * "hurry up" call, for example when the unit is in some "auto * restart" state where it waits for a holdoff timer to elapse * before it will start again. */ + unit_add_to_dbus_queue(u); return UNIT_VTABLE(u)->start(u); } @@ -467,16 +516,17 @@ int unit_stop(Unit *u) { assert(u); - if (!UNIT_VTABLE(u)->stop) - return -EBADR; - state = unit_active_state(u); if (state == UNIT_INACTIVE) return -EALREADY; + if (!UNIT_VTABLE(u)->stop) + return -EBADR; + if (state == UNIT_DEACTIVATING) return 0; + unit_add_to_dbus_queue(u); return UNIT_VTABLE(u)->stop(u); } @@ -500,6 +550,7 @@ int unit_reload(Unit *u) { if (unit_active_state(u) != UNIT_ACTIVE) return -ENOEXEC; + unit_add_to_dbus_queue(u); return UNIT_VTABLE(u)->reload(u); } @@ -630,7 +681,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { /* So we reached a different state for this * job. Let's see if we can run it now if it * failed previously due to EAGAIN. */ - job_schedule_run(u->meta.job); + job_add_to_run_queue(u->meta.job); else { assert(u->meta.job->state == JOB_RUNNING); @@ -699,6 +750,8 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { /* Maybe we finished startup and are now ready for being * stopped because unneeded? */ unit_check_uneeded(u); + + unit_add_to_dbus_queue(u); } int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w) { @@ -902,6 +955,7 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other) { return r; } + unit_add_to_dbus_queue(u); return 0; } @@ -918,16 +972,6 @@ int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name) { return 0; } -const char *unit_path(void) { - char *e; - - if ((e = getenv("UNIT_PATH"))) - if (path_is_absolute(e)) - return e; - - return UNIT_PATH; -} - int set_unit_path(const char *p) { char *cwd, *c; int r; @@ -948,7 +992,7 @@ int set_unit_path(const char *p) { return -ENOMEM; } - if (setenv("UNIT_PATH", c, 0) < 0) { + if (setenv("SYSTEMD_UNIT_PATH", c, 0) < 0) { r = -errno; free(c); return r;