diff options
-rw-r--r-- | initctl.c | 48 | ||||
-rw-r--r-- | manager.h | 6 | ||||
-rw-r--r-- | service.c | 29 |
3 files changed, 47 insertions, 36 deletions
@@ -39,6 +39,7 @@ #include "log.h" #include "list.h" #include "initreq.h" +#include "manager.h" #define SERVER_FD_START 3 #define SERVER_FD_MAX 16 @@ -67,42 +68,35 @@ struct Fifo { }; static const char *translate_runlevel(int runlevel) { + static const struct { + const int runlevel; + const char *special; + } table[] = { + { '0', SPECIAL_RUNLEVEL0_TARGET }, + { '1', SPECIAL_RUNLEVEL1_TARGET }, + { 's', SPECIAL_RUNLEVEL1_TARGET }, + { 'S', SPECIAL_RUNLEVEL1_TARGET }, + { '2', SPECIAL_RUNLEVEL2_TARGET }, + { '3', SPECIAL_RUNLEVEL3_TARGET }, + { '4', SPECIAL_RUNLEVEL4_TARGET }, + { '5', SPECIAL_RUNLEVEL5_TARGET }, + { '6', SPECIAL_RUNLEVEL6_TARGET }, + }; - switch (runlevel) { - - case '0': - return "halt.target"; - - case '1': - case 's': - case 'S': - return "rescue.target"; - - case '2': - return "runlevel2.target"; - - case '3': - return "runlevel3.target"; - - case '4': - return "runlevel4.target"; - - case '5': - return "runlevel5.target"; + unsigned i; - case '6': - return "reboot.target"; + for (i = 0; i < ELEMENTSOF(table); i++) + if (table[i].runlevel == runlevel) + return table[i].special; - default: - return NULL; - } + return NULL; } static void change_runlevel(Server *s, int runlevel) { const char *target; DBusMessage *m = NULL, *reply = NULL; DBusError error; - const char *path, *replace = "replace"; + const char *path, *replace = "isolate"; assert(s); @@ -85,6 +85,12 @@ struct Watch { #define SPECIAL_DEFAULT_TARGET "default.target" +/* This is not really intended to be started by directly. This is + * mostly so that other targets (reboot/halt/poweroff) can depend on + * it to bring all services down that want to be brought down on + * system shutdown. */ +#define SPECIAL_SHUTDOWN_TARGET "shutdown.target" + #define SPECIAL_LOGGER_SOCKET "systemd-logger.socket" #define SPECIAL_KBREQUEST_TARGET "kbrequest.target" @@ -2197,7 +2197,7 @@ static int service_enumerate(Manager *m) { } while ((de = readdir(d))) { - Unit *runlevel, *service; + Unit *service; if (ignore_file(de->d_name)) continue; @@ -2233,31 +2233,42 @@ static int service_enumerate(Manager *m) { if ((r = manager_load_unit(m, name, NULL, &service)) < 0) goto finish; - if ((r = manager_load_unit(m, rcnd_table[i+1], NULL, &runlevel)) < 0) - goto finish; - if (de->d_name[0] == 'S') { - if ((r = unit_add_dependency(runlevel, UNIT_WANTS, service, true)) < 0) + Unit *runlevel_target; + + if ((r = manager_load_unit(m, rcnd_table[i+1], NULL, &runlevel_target)) < 0) + goto finish; + + if ((r = unit_add_dependency(runlevel_target, UNIT_WANTS, service, true)) < 0) goto finish; - if ((r = unit_add_dependency(runlevel, UNIT_AFTER, service, true)) < 0) + if ((r = unit_add_dependency(runlevel_target, UNIT_AFTER, service, true)) < 0) goto finish; } else if (de->d_name[0] == 'K' && (streq(rcnd_table[i+1], SPECIAL_RUNLEVEL0_TARGET) || streq(rcnd_table[i+1], SPECIAL_RUNLEVEL6_TARGET))) { + Unit *shutdown_target; + /* We honour K links only for * halt/reboot. For the normal * runlevels we assume the * stop jobs will be * implicitly added by the - * core logic. */ + * core logic. Also, we don't + * really distuingish here + * between the runlevels 0 and + * 6 and just add them to the + * special shutdown target. */ + + if ((r = manager_load_unit(m, SPECIAL_SHUTDOWN_TARGET, NULL, &shutdown_target)) < 0) + goto finish; - if ((r = unit_add_dependency(runlevel, UNIT_CONFLICTS, service, true)) < 0) + if ((r = unit_add_dependency(shutdown_target, UNIT_CONFLICTS, service, true)) < 0) goto finish; - if ((r = unit_add_dependency(runlevel, UNIT_BEFORE, service, true)) < 0) + if ((r = unit_add_dependency(shutdown_target, UNIT_BEFORE, service, true)) < 0) goto finish; } } |