summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2010-08-19 03:18:49 +0200
committerLennart Poettering <lennart@poettering.net>2010-08-20 02:31:54 +0200
commitd06dacd0020af7e31ff6089deff339b00ed979e3 (patch)
tree40d3db2c57f53955645e95df805b43913c6e3dde
parent8a2b3c097b5ebd53348700f591e50530a82b5cea (diff)
service/systemctl: don't consider LSB exit codes 5 and 6 as failure, and decode exit codes in systemctl
-rw-r--r--Makefile.am4
-rw-r--r--fixme6
-rw-r--r--src/execute.c112
-rw-r--r--src/execute.h46
-rw-r--r--src/manager.c5
-rw-r--r--src/service.c5
-rw-r--r--src/systemctl.c29
-rw-r--r--src/util.c11
-rw-r--r--src/util.h1
9 files changed, 47 insertions, 172 deletions
diff --git a/Makefile.am b/Makefile.am
index bf329e5083..1a7142158d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -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 a8a0dadc34..855f9d6c97 100644
--- a/fixme
+++ b/fixme
@@ -58,11 +58,7 @@
* 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
diff --git a/src/execute.c b/src/execute.c
index b4ddf8961f..f35e916e4c 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -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",
diff --git a/src/execute.h b/src/execute.h
index 381893587b..0dc5a1d252 100644
--- a/src/execute.h
+++ b/src/execute.h
@@ -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
diff --git a/src/manager.c b/src/manager.c
index c8fdbb5dee..900a00a6f5 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -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;
diff --git a/src/service.c b/src/service.c
index 80cd6ad9c6..66e233a669 100644
--- a/src/service.c
+++ b/src/service.c
@@ -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) {
diff --git a/src/systemctl.c b/src/systemctl.c
index 4f39cac07b..5bf5e9f38f 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -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;
diff --git a/src/util.c b/src/util.c
index 0b0063ee0e..7903ca07b9 100644
--- a/src/util.c
+++ b/src/util.c
@@ -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
diff --git a/src/util.h b/src/util.h
index 97e1b1ba41..e8d9b3e74b 100644
--- a/src/util.h
+++ b/src/util.h
@@ -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);