chiark / gitweb /
service/systemctl: don't consider LSB exit codes 5 and 6 as failure, and decode exit...
authorLennart Poettering <lennart@poettering.net>
Thu, 19 Aug 2010 01:18:49 +0000 (03:18 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 20 Aug 2010 00:31:54 +0000 (02:31 +0200)
Makefile.am
fixme
src/execute.c
src/execute.h
src/manager.c
src/service.c
src/systemctl.c
src/util.c
src/util.h

index bf329e5083d20d32864687200cf60f7e5ce3e859..1a7142158dd9fe61c9ab01e6a552c34e8eebc03d 100644 (file)
@@ -299,6 +299,7 @@ libsystemd_core_la_SOURCES = \
        src/path.c \
         src/load-dropin.c \
         src/execute.c \
+       src/exit-status.c \
         src/dbus.c \
         src/dbus-manager.c \
         src/dbus-unit.c \
@@ -604,7 +605,8 @@ systemctl_SOURCES = \
        src/path-lookup.c \
        src/sd-daemon.c \
        src/cgroup-show.c \
-       src/cgroup-util.c
+       src/cgroup-util.c \
+       src/exit-status.c
 
 systemctl_CFLAGS = \
        $(AM_CFLAGS) \
diff --git a/fixme b/fixme
index a8a0dadc345e6087c8f12ee298eb69f3bdc508ae..855f9d6c97a1a237eefca79cdbd4af6c6a5b3f1b 100644 (file)
--- a/fixme
+++ b/fixme
 
 * if a service fails too often, make the service enter maintenance mode, and the socket, too.
 
-* exit code 5, 6 von sysv diensten ignorieren
-
-* decode exit codes in systemctl status
-
-* systemctl: ln -s output muss abschaltbar sein, und warning wenn [Install] leer ist.
+* systemctl: warning wenn [Install] leer ist bei enable
 
 * bash completion a la gdbus
 
index b4ddf8961f390071f690be5c588e01cb8d247917..f35e916e4cbedca7892531917715b090ef1c82b6 100644 (file)
@@ -51,6 +51,7 @@
 #include "cgroup.h"
 #include "namespace.h"
 #include "tcpwrap.h"
+#include "exit-status.h"
 
 /* This assumes there is a 'tty' group */
 #define TTY_MODE 0620
@@ -1757,117 +1758,6 @@ int exec_command_set(ExecCommand *c, const char *path, ...) {
         return 0;
 }
 
-const char* exit_status_to_string(ExitStatus status) {
-
-        /* We cast to int here, so that -Wenum doesn't complain that
-         * EXIT_SUCCESS/EXIT_FAILURE aren't in the enum */
-
-        switch ((int) status) {
-
-        case EXIT_SUCCESS:
-                return "SUCCESS";
-
-        case EXIT_FAILURE:
-                return "FAILURE";
-
-        case EXIT_INVALIDARGUMENT:
-                return "INVALIDARGUMENT";
-
-        case EXIT_NOTIMPLEMENTED:
-                return "NOTIMPLEMENTED";
-
-        case EXIT_NOPERMISSION:
-                return "NOPERMISSION";
-
-        case EXIT_NOTINSTALLED:
-                return "NOTINSSTALLED";
-
-        case EXIT_NOTCONFIGURED:
-                return "NOTCONFIGURED";
-
-        case EXIT_NOTRUNNING:
-                return "NOTRUNNING";
-
-        case EXIT_CHDIR:
-                return "CHDIR";
-
-        case EXIT_NICE:
-                return "NICE";
-
-        case EXIT_FDS:
-                return "FDS";
-
-        case EXIT_EXEC:
-                return "EXEC";
-
-        case EXIT_MEMORY:
-                return "MEMORY";
-
-        case EXIT_LIMITS:
-                return "LIMITS";
-
-        case EXIT_OOM_ADJUST:
-                return "OOM_ADJUST";
-
-        case EXIT_SIGNAL_MASK:
-                return "SIGNAL_MASK";
-
-        case EXIT_STDIN:
-                return "STDIN";
-
-        case EXIT_STDOUT:
-                return "STDOUT";
-
-        case EXIT_CHROOT:
-                return "CHROOT";
-
-        case EXIT_IOPRIO:
-                return "IOPRIO";
-
-        case EXIT_TIMERSLACK:
-                return "TIMERSLACK";
-
-        case EXIT_SECUREBITS:
-                return "SECUREBITS";
-
-        case EXIT_SETSCHEDULER:
-                return "SETSCHEDULER";
-
-        case EXIT_CPUAFFINITY:
-                return "CPUAFFINITY";
-
-        case EXIT_GROUP:
-                return "GROUP";
-
-        case EXIT_USER:
-                return "USER";
-
-        case EXIT_CAPABILITIES:
-                return "CAPABILITIES";
-
-        case EXIT_CGROUP:
-                return "CGROUP";
-
-        case EXIT_SETSID:
-                return "SETSID";
-
-        case EXIT_CONFIRM:
-                return "CONFIRM";
-
-        case EXIT_STDERR:
-                return "STDERR";
-
-        case EXIT_TCPWRAP:
-                return "TCPWRAP";
-
-        case EXIT_PAM:
-                return "PAM";
-
-        default:
-                return NULL;
-        }
-}
-
 static const char* const exec_input_table[_EXEC_INPUT_MAX] = {
         [EXEC_INPUT_NULL] = "null",
         [EXEC_INPUT_TTY] = "tty",
index 381893587b81ee73f6505704968aeb9f263b77fe..0dc5a1d252a14a0a5fb75bd3f0a9cee07cefd02d 100644 (file)
@@ -160,50 +160,6 @@ struct ExecContext {
         bool timer_slack_nsec_set:1;
 };
 
-typedef enum ExitStatus {
-        /* EXIT_SUCCESS defined by libc */
-        /* EXIT_FAILURE defined by libc */
-        EXIT_INVALIDARGUMENT = 2,
-        EXIT_NOTIMPLEMENTED = 3,
-        EXIT_NOPERMISSION = 4,
-        EXIT_NOTINSTALLED = 5,
-        EXIT_NOTCONFIGURED = 6,
-        EXIT_NOTRUNNING = 7,
-
-        /* The LSB suggests that error codes >= 200 are "reserved". We
-         * use them here under the assumption that they hence are
-         * unused by init scripts.
-         *
-         * http://refspecs.freestandards.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html */
-
-        EXIT_CHDIR = 200,
-        EXIT_NICE,
-        EXIT_FDS,
-        EXIT_EXEC,
-        EXIT_MEMORY,
-        EXIT_LIMITS,
-        EXIT_OOM_ADJUST,
-        EXIT_SIGNAL_MASK,
-        EXIT_STDIN,
-        EXIT_STDOUT,
-        EXIT_CHROOT,   /* 210 */
-        EXIT_IOPRIO,
-        EXIT_TIMERSLACK,
-        EXIT_SECUREBITS,
-        EXIT_SETSCHEDULER,
-        EXIT_CPUAFFINITY,
-        EXIT_GROUP,
-        EXIT_USER,
-        EXIT_CAPABILITIES,
-        EXIT_CGROUP,
-        EXIT_SETSID,   /* 220 */
-        EXIT_CONFIRM,
-        EXIT_STDERR,
-        EXIT_TCPWRAP,
-        EXIT_PAM
-
-} ExitStatus;
-
 int exec_spawn(ExecCommand *command,
                char **argv,
                const ExecContext *context,
@@ -243,6 +199,4 @@ int exec_output_from_string(const char *s);
 const char* exec_input_to_string(ExecInput i);
 int exec_input_from_string(const char *s);
 
-const char* exit_status_to_string(ExitStatus status);
-
 #endif
index c8fdbb5dee33993e60c0853bdc0cfb100482952b..900a00a6f56eb8b8470a2dfd90bb3dfef9c2656c 100644 (file)
@@ -57,6 +57,7 @@
 #include "path-lookup.h"
 #include "special.h"
 #include "bus-errors.h"
+#include "exit-status.h"
 
 /* As soon as 16 units are in our GC queue, make sure to run a gc sweep */
 #define GC_QUEUE_ENTRIES_MAX 16
@@ -1885,7 +1886,9 @@ static int manager_dispatch_sigchld(Manager *m) {
                           (long unsigned) si.si_pid,
                           sigchld_code_to_string(si.si_code),
                           si.si_status,
-                          strna(si.si_code == CLD_EXITED ? exit_status_to_string(si.si_status) : signal_to_string(si.si_status)));
+                          strna(si.si_code == CLD_EXITED
+                                ? exit_status_to_string(si.si_status, EXIT_STATUS_FULL)
+                                : signal_to_string(si.si_status)));
 
                 if (!u)
                         continue;
index 80cd6ad9c65eddb43a2d4b15986d5588b52f4594..66e233a66927f4be6bfd75180facb289b2674049 100644 (file)
@@ -2263,7 +2263,10 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
         assert(s);
         assert(pid >= 0);
 
-        success = is_clean_exit(code, status);
+        if (s->sysv_path)
+                success = is_clean_exit_lsb(code, status);
+        else
+                success = is_clean_exit(code, status);
 
         if (s->main_pid == pid) {
 
index 4f39cac07b8a20f08030ae7d4b0088b84e3affa4..5bf5e9f38ff61ba05c39ea0b4471d7828e12322d 100644 (file)
@@ -50,6 +50,7 @@
 #include "conf-parser.h"
 #include "sd-daemon.h"
 #include "shutdownd.h"
+#include "exit-status.h"
 
 static const char *arg_type = NULL;
 static char **arg_property = NULL;
@@ -1489,7 +1490,8 @@ typedef struct UnitStatusInfo {
         pid_t main_pid;
         pid_t control_pid;
         const char *status_text;
-        bool running;
+        bool running:1;
+        bool is_sysv:1;
 
         usec_t start_timestamp;
         usec_t exit_timestamp;
@@ -1584,9 +1586,15 @@ static void print_status_info(UnitStatusInfo *i) {
                 printf("\t  Exited: %u (%s, code=%s, ", p->pid, strna(t), sigchld_code_to_string(p->code));
                 free(t);
 
-                if (p->code == CLD_EXITED)
+                if (p->code == CLD_EXITED) {
+                        const char *c;
+
                         printf("status=%i", p->status);
-                else
+
+                        if ((c = exit_status_to_string(p->status, i->is_sysv ? EXIT_STATUS_LSB : EXIT_STATUS_SYSTEMD)))
+                                printf("/%s", c);
+
+                } else
                         printf("signal=%s", signal_to_string(p->status));
                 printf(")\n");
 
@@ -1616,9 +1624,15 @@ static void print_status_info(UnitStatusInfo *i) {
                         } else if (i->exit_code > 0) {
                                 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
 
-                                if (i->exit_code == CLD_EXITED)
+                                if (i->exit_code == CLD_EXITED) {
+                                        const char *c;
+
                                         printf("status=%i", i->exit_status);
-                                else
+
+                                        if ((c = exit_status_to_string(i->exit_status, i->is_sysv ? EXIT_STATUS_LSB : EXIT_STATUS_SYSTEMD)))
+                                                printf("/%s", c);
+
+                                } else
                                         printf("signal=%s", signal_to_string(i->exit_status));
                                 printf(")");
                         }
@@ -1687,9 +1701,10 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn
                                 i->description = s;
                         else if (streq(name, "FragmentPath"))
                                 i->path = s;
-                        else if (streq(name, "SysVPath"))
+                        else if (streq(name, "SysVPath")) {
+                                i->is_sysv = true;
                                 i->path = s;
-                        else if (streq(name, "DefaultControlGroup"))
+                        else if (streq(name, "DefaultControlGroup"))
                                 i->default_control_group = s;
                         else if (streq(name, "StatusText"))
                                 i->status_text = s;
index 0b0063ee0e6078a48cdec42f053be97c42a7742a..7903ca07b99fe64d493948f579eb9e34f3adbd31 100644 (file)
@@ -57,6 +57,7 @@
 #include "log.h"
 #include "strv.h"
 #include "label.h"
+#include "exit-status.h"
 
 bool streq_ptr(const char *a, const char *b) {
 
@@ -2398,6 +2399,16 @@ bool is_clean_exit(int code, int status) {
         return false;
 }
 
+bool is_clean_exit_lsb(int code, int status) {
+
+        if (is_clean_exit(code, status))
+                return true;
+
+        return
+                code == CLD_EXITED &&
+                (status == EXIT_NOTINSTALLED || status == EXIT_NOTCONFIGURED);
+}
+
 bool is_device_path(const char *path) {
 
         /* Returns true on paths that refer to a device, either in
index 97e1b1ba41d5ced38b93bbc13227930da447900c..e8d9b3e74bb496503db44ece59973719047d1d33 100644 (file)
@@ -253,6 +253,7 @@ char *format_timespan(char *buf, size_t l, usec_t t);
 int make_stdio(int fd);
 
 bool is_clean_exit(int code, int status);
+bool is_clean_exit_lsb(int code, int status);
 
 unsigned long long random_ull(void);