chiark / gitweb /
manager: expose a few special units via SIGRTMIN+x signals
authorLennart Poettering <lennart@poettering.net>
Thu, 17 Jun 2010 21:22:56 +0000 (23:22 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 17 Jun 2010 21:22:56 +0000 (23:22 +0200)
fixme
src/manager.c
src/manager.h
src/util.c
src/util.h

diff --git a/fixme b/fixme
index db3dda8..055fac4 100644 (file)
--- a/fixme
+++ b/fixme
@@ -71,6 +71,8 @@
 
 * __attribute__ for sd_notifyf
 
+* convenience library
+
 Regularly:
 
 * look for close() vs. close_nointr() vs. close_nointr_nofail()
index 385b371..2ad6072 100644 (file)
@@ -157,14 +157,23 @@ static int manager_setup_signals(Manager *m) {
         assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
 
         assert_se(sigemptyset(&mask) == 0);
-        assert_se(sigaddset(&mask, SIGCHLD) == 0);
-        assert_se(sigaddset(&mask, SIGTERM) == 0);
-        assert_se(sigaddset(&mask, SIGHUP) == 0);
-        assert_se(sigaddset(&mask, SIGUSR1) == 0);
-        assert_se(sigaddset(&mask, SIGUSR2) == 0);
-        assert_se(sigaddset(&mask, SIGINT) == 0);   /* Kernel sends us this on control-alt-del */
-        assert_se(sigaddset(&mask, SIGWINCH) == 0); /* Kernel sends us this on kbrequest (alt-arrowup) */
-        assert_se(sigaddset(&mask, SIGPWR) == 0);   /* Some kernel drivers and upsd send us this on power failure */
+
+        sigset_add_many(&mask,
+                        SIGCHLD,     /* Child died */
+                        SIGTERM,     /* Reexecute daemon */
+                        SIGHUP,      /* Reload configuration */
+                        SIGUSR1,     /* systemd/upstart: reconnect to D-Bus */
+                        SIGUSR2,     /* systemd: dump status */
+                        SIGINT,      /* Kernel sends us this on control-alt-del */
+                        SIGWINCH,    /* Kernel sends us this on kbrequest (alt-arrowup) */
+                        SIGPWR,      /* Some kernel drivers and upsd send us this on power failure */
+                        SIGRTMIN+0,  /* systemd: start default.target */
+                        SIGRTMIN+1,  /* systemd: start rescue.target */
+                        SIGRTMIN+2,  /* systemd: isolate emergency.target */
+                        SIGRTMIN+3,  /* systemd: start halt.target */
+                        SIGRTMIN+4,  /* systemd: start poweroff.target */
+                        SIGRTMIN+5,  /* systemd: start reboot.target */
+                        -1);
         assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
 
         m->signal_watch.type = WATCH_SIGNAL;
@@ -1731,10 +1740,10 @@ static int manager_dispatch_sigchld(Manager *m) {
         return 0;
 }
 
-static int manager_start_target(Manager *m, const char *name) {
+static int manager_start_target(Manager *m, const char *name, JobMode mode) {
         int r;
 
-        if ((r = manager_add_job_by_name(m, JOB_START, name, JOB_REPLACE, true, NULL)) < 0)
+        if ((r = manager_add_job_by_name(m, JOB_START, name, mode, true, NULL)) < 0)
                 log_error("Failed to enqueue %s job: %s", name, strerror(-r));
 
         return r;
@@ -1777,12 +1786,12 @@ static int manager_process_signal_fd(Manager *m) {
 
                 case SIGINT:
                         if (m->running_as == MANAGER_INIT) {
-                                manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET);
+                                manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE);
                                 break;
                         }
 
                         /* Run the exit target if there is one, if not, just exit. */
-                        if (manager_start_target(m, SPECIAL_EXIT_SERVICE) < 0) {
+                        if (manager_start_target(m, SPECIAL_EXIT_SERVICE, JOB_REPLACE) < 0) {
                                 m->exit_code = MANAGER_EXIT;
                                 return 0;
                         }
@@ -1791,14 +1800,14 @@ static int manager_process_signal_fd(Manager *m) {
 
                 case SIGWINCH:
                         if (m->running_as == MANAGER_INIT)
-                                manager_start_target(m, SPECIAL_KBREQUEST_TARGET);
+                                manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE);
 
                         /* This is a nop on non-init */
                         break;
 
                 case SIGPWR:
                         if (m->running_as == MANAGER_INIT)
-                                manager_start_target(m, SPECIAL_SIGPWR_TARGET);
+                                manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE);
 
                         /* This is a nop on non-init */
                         break;
@@ -1816,7 +1825,7 @@ static int manager_process_signal_fd(Manager *m) {
 
                         if (!u || !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) {
                                 log_info("Loading D-Bus service...");
-                                manager_start_target(m, SPECIAL_DBUS_SERVICE);
+                                manager_start_target(m, SPECIAL_DBUS_SERVICE, JOB_REPLACE);
                         }
 
                         break;
@@ -1853,9 +1862,26 @@ static int manager_process_signal_fd(Manager *m) {
                         m->exit_code = MANAGER_RELOAD;
                         break;
 
-                default:
+                default: {
+                        static const char * const table[] = {
+                                [0] = SPECIAL_DEFAULT_TARGET,
+                                [1] = SPECIAL_RESCUE_TARGET,
+                                [2] = SPECIAL_EMERGENCY_SERVICE,
+                                [3] = SPECIAL_HALT_TARGET,
+                                [4] = SPECIAL_POWEROFF_TARGET,
+                                [5] = SPECIAL_REBOOT_TARGET
+                        };
+
+                        if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
+                            (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(table)) {
+                                manager_start_target(m, table[sfsi.ssi_signo - SIGRTMIN],
+                                                     sfsi.ssi_signo == 2 ? JOB_ISOLATE : JOB_REPLACE);
+                                break;
+                        }
+
                         log_info("Got unhandled signal <%s>.", strsignal(sfsi.ssi_signo));
                 }
+                }
         }
 
         if (sigchld)
index 070a27f..5ee75d5 100644 (file)
@@ -113,6 +113,10 @@ struct Watch {
 #define SPECIAL_SYSINIT_TARGET "sysinit.target"
 #define SPECIAL_RESCUE_TARGET "rescue.target"
 #define SPECIAL_EXIT_SERVICE "exit.service"
+#define SPECIAL_EMERGENCY_SERVICE "emergency.service"
+#define SPECIAL_HALT_TARGET "halt.target"
+#define SPECIAL_POWEROFF_TARGET "poweroff.target"
+#define SPECIAL_REBOOT_TARGET "reboot.target"
 
 #ifndef SPECIAL_DBUS_SERVICE
 #define SPECIAL_DBUS_SERVICE "dbus.service"
index 8f70c0f..4fdc8e5 100644 (file)
@@ -2205,6 +2205,18 @@ void rename_process(const char name[8]) {
                 strncpy(program_invocation_name, name, strlen(program_invocation_name));
 }
 
+void sigset_add_many(sigset_t *ss, ...) {
+        va_list ap;
+        int sig;
+
+        assert(ss);
+
+        va_start(ap, ss);
+        while ((sig = va_arg(ap, int)) > 0)
+                assert_se(sigaddset(ss, sig) == 0);
+        va_end(ap);
+}
+
 static const char *const ioprio_class_table[] = {
         [IOPRIO_CLASS_NONE] = "none",
         [IOPRIO_CLASS_RT] = "realtime",
index 1ca8f90..f3aec1d 100644 (file)
@@ -256,6 +256,8 @@ int dir_is_empty(const char *path);
 
 void rename_process(const char name[8]);
 
+void sigset_add_many(sigset_t *ss, ...);
+
 const char *ioprio_class_to_string(int i);
 int ioprio_class_from_string(const char *s);