mirror of
https://github.com/AuxXxilium/eudev.git
synced 2024-11-23 23:10:57 +07:00
service/systemctl: don't consider LSB exit codes 5 and 6 as failure, and decode exit codes in systemctl
This commit is contained in:
parent
8a2b3c097b
commit
d06dacd002
@ -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) \
|
||||
|
6
fixme
6
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
|
||||
|
||||
|
112
src/execute.c
112
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",
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -2263,6 +2263,9 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||
assert(s);
|
||||
assert(pid >= 0);
|
||||
|
||||
if (s->sysv_path)
|
||||
success = is_clean_exit_lsb(code, status);
|
||||
else
|
||||
success = is_clean_exit(code, status);
|
||||
|
||||
if (s->main_pid == pid) {
|
||||
|
@ -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;
|
||||
|
11
src/util.c
11
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
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user