X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=manager.c;h=9355a6a6f5f9dc79efc094f7838884acae1a5de8;hp=8ee560c5543f0eb570857b12ed4fa7edb1445a96;hb=f50e0a012340fa8dfe6ec7f0cd869f5f3a052d7a;hpb=98b5b2986fa1b85fd2d2e80f867f1647b4e4e3b5 diff --git a/manager.c b/manager.c index 8ee560c55..9355a6a6f 100644 --- a/manager.c +++ b/manager.c @@ -17,14 +17,6 @@ #include "log.h" #include "util.h" -static const char * const special_table[_SPECIAL_UNIT_MAX] = { - [SPECIAL_SYSLOG_SERVICE] = "syslog.service", - [SPECIAL_DBUS_SERVICE] = "messagebus.service", - [SPECIAL_LOGGER_SOCKET] = "systemd-logger.socket", - [SPECIAL_KBREQUEST_TARGET] = "kbrequest.target", - [SPECIAL_CTRL_ALT_DEL_TARGET] = "ctrl-alt-del.target" -}; - static int manager_setup_signals(Manager *m) { sigset_t mask; struct epoll_event ev; @@ -58,21 +50,6 @@ static int manager_setup_signals(Manager *m) { return 0; } -static int manager_load_special_units(Manager *m) { - SpecialUnit c; - int r; - - assert(m); - - /* Loads all 'special' units, so that we have easy access to them later */ - - for (c = 0; c < _SPECIAL_UNIT_MAX; c++) - if ((r = manager_load_unit(m, special_table[c], m->special_units+c)) < 0) - return r; - - return 0; -}; - Manager* manager_new(void) { Manager *m; @@ -99,9 +76,6 @@ Manager* manager_new(void) { if (manager_setup_signals(m) < 0) goto fail; - if (manager_load_special_units(m) < 0) - goto fail; - return m; fail: @@ -110,6 +84,7 @@ fail: } void manager_free(Manager *m) { + UnitType c; Unit *u; Job *j; @@ -121,6 +96,10 @@ void manager_free(Manager *m) { while ((u = hashmap_first(m->units))) unit_free(u); + for (c = 0; c < _UNIT_TYPE_MAX; c++) + if (unit_vtable[c]->shutdown) + unit_vtable[c]->shutdown(m); + hashmap_free(m->units); hashmap_free(m->jobs); hashmap_free(m->transaction_jobs); @@ -134,6 +113,39 @@ void manager_free(Manager *m) { free(m); } +int manager_coldplug(Manager *m) { + int r; + UnitType c; + Iterator i; + Unit *u; + char *k; + + assert(m); + + /* First, let's ask every type to load all units from + * disk/kernel that it might know */ + for (c = 0; c < _UNIT_TYPE_MAX; c++) + if (unit_vtable[c]->enumerate) + if ((r = unit_vtable[c]->enumerate(m)) < 0) + return r; + + manager_dispatch_load_queue(m); + + /* Then, let's set up their initial state. */ + HASHMAP_FOREACH_KEY(u, k, m->units, i) { + + /* ignore aliases */ + if (unit_id(u) != k) + continue; + + if (UNIT_VTABLE(u)->coldplug) + if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0) + return r; + } + + return 0; +} + static void transaction_delete_job(Manager *m, Job *j) { assert(m); assert(j); @@ -852,6 +864,8 @@ int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool for if ((r = transaction_activate(m, mode)) < 0) return r; + log_debug("Enqueued job %s/%s", unit_id(unit), job_type_to_string(type)); + if (_ret) *_ret = ret; @@ -871,7 +885,7 @@ Unit *manager_get_unit(Manager *m, const char *name) { return hashmap_get(m->units, name); } -static void dispatch_load_queue(Manager *m) { +void manager_dispatch_load_queue(Manager *m) { Meta *meta; assert(m); @@ -929,7 +943,7 @@ int manager_load_unit(Manager *m, const char *path, Unit **_ret) { } unit_add_to_load_queue(ret); - dispatch_load_queue(m); + manager_dispatch_load_queue(m); *_ret = ret; return 0;