summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-07-29 15:44:39 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-07-29 15:54:53 +0200
commit76ed04d936f757763c32db5dbaaebd8b13785d7b (patch)
tree9a022c24978d3494e8409d66d080cf4fe741b3d4
parent716e6f4488d3ea7bb91c40577b588253cfe00216 (diff)
downloadsystemd-76ed04d936f757763c32db5dbaaebd8b13785d7b.tar.gz
analyze: add exit-codes verb
-rw-r--r--man/systemd-analyze.xml30
-rw-r--r--man/systemd.service.xml5
-rw-r--r--src/analyze/analyze.c45
3 files changed, 79 insertions, 1 deletions
diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml
index 7112362ac5..8e9f24caac 100644
--- a/man/systemd-analyze.xml
+++ b/man/systemd-analyze.xml
@@ -86,6 +86,12 @@
<cmdsynopsis>
<command>systemd-analyze</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
+ <arg choice="plain">exit-codes</arg>
+ <arg choice="opt" rep="repeat"><replaceable>CODE</replaceable></arg>
+ </cmdsynopsis>
+ <cmdsynopsis>
+ <command>systemd-analyze</command>
+ <arg choice="opt" rep="repeat">OPTIONS</arg>
<arg choice="plain">condition</arg>
<arg choice="plain"><replaceable>CONDITION</replaceable>…</arg>
</cmdsynopsis>
@@ -366,6 +372,30 @@ $ eog targets.svg</programlisting>
</refsect2>
<refsect2>
+ <title><command>systemd-analyze exit-codes <optional><replaceable>CODE</replaceable>...</optional></command></title>
+
+ <para>This command prints a list of exit codes along with their "class", i.e. the source of the
+ definition (one of <literal>glibc</literal>, <literal>systemd</literal>, <literal>LSB</literal>, or
+ <literal>BSD</literal>), see the Process Exit Codes section in
+ <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ If no additional arguments are specified, all known codes are are shown. Otherwise, only the
+ definitions for the specified codes are shown.</para>
+
+ <example>
+ <title><command>Show some example exit code names</command></title>
+
+ <programlisting>$ systemd-analyze exit-codes 0 1 {63..65}
+NAME CODE CLASS
+SUCCESS 0 glibc
+FAILURE 1 glibc
+- 63 -
+USAGE 64 BSD
+DATAERR 65 BSD
+</programlisting>
+ </example>
+ </refsect2>
+
+ <refsect2>
<title><command>systemd-analyze condition <replaceable>CONDITION</replaceable>...</command></title>
<para>This command will evaluate <varname noindex='true'>Condition*=...</varname> and
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index 06116df1b0..40ac052ba5 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -877,7 +877,10 @@
<para>Exit codes 75 (<constant>TEMPFAIL</constant>), 250, and the termination signal
<constant>SIGKILL</constant> are considered clean service terminations.</para>
- </example></listitem>
+ </example>
+
+ <para>Note: <command>systemd-analyze exit-codes</command> may be used to list exit
+ codes and translate between numerical code values and names.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c
index 92727974d6..c8767e88c8 100644
--- a/src/analyze/analyze.c
+++ b/src/analyze/analyze.c
@@ -24,6 +24,7 @@
#include "conf-files.h"
#include "copy.h"
#include "def.h"
+#include "exit-status.h"
#include "fd-util.h"
#include "fileio.h"
#include "format-table.h"
@@ -1637,6 +1638,48 @@ static void dump_syscall_filter(const SyscallFilterSet *set) {
printf(" %s%s%s\n", syscall[0] == '@' ? ansi_underline() : "", syscall, ansi_normal());
}
+static int dump_exit_codes(int argc, char *argv[], void *userdata) {
+ _cleanup_(table_unrefp) Table *table = NULL;
+ int r;
+
+ table = table_new("name", "code", "class");
+ if (!table)
+ return log_oom();
+
+ if (strv_isempty(strv_skip(argv, 1)))
+ for (size_t i = 0; i < ELEMENTSOF(exit_status_mappings); i++) {
+ if (!exit_status_mappings[i].name)
+ continue;
+
+ r = table_add_many(table,
+ TABLE_STRING, exit_status_mappings[i].name,
+ TABLE_UINT, i,
+ TABLE_STRING, exit_status_class(i));
+ if (r < 0)
+ return r;
+ }
+ else
+ for (int i = 1; i < argc; i++) {
+ int code;
+
+ code = exit_status_from_string(argv[i]);
+ if (code < 0)
+ return log_error_errno(r, "Invalid exit code \"%s\": %m", argv[i]);
+
+ assert(code >= 0 && (size_t) code < ELEMENTSOF(exit_status_mappings));
+ r = table_add_many(table,
+ TABLE_STRING, exit_status_mappings[code].name ?: "-",
+ TABLE_UINT, code,
+ TABLE_STRING, exit_status_class(code) ?: "-");
+ if (r < 0)
+ return r;
+ }
+
+ (void) pager_open(arg_pager_flags);
+
+ return table_print(table, NULL);
+}
+
static int dump_syscall_filters(int argc, char *argv[], void *userdata) {
bool first = true;
@@ -2165,6 +2208,7 @@ static int help(int argc, char *argv[], void *userdata) {
" dump Output state serialization of service manager\n"
" cat-config Show configuration file and drop-ins\n"
" unit-paths List load directories for units\n"
+ " exit-codes List exit code definitions\n"
" syscall-filter [NAME...] Print list of syscalls in seccomp filter\n"
" condition CONDITION... Evaluate conditions and asserts\n"
" verify FILE... Check unit files for correctness\n"
@@ -2368,6 +2412,7 @@ static int run(int argc, char *argv[]) {
{ "dump", VERB_ANY, 1, 0, dump },
{ "cat-config", 2, VERB_ANY, 0, cat_config },
{ "unit-paths", 1, 1, 0, dump_unit_paths },
+ { "exit-codes", VERB_ANY, VERB_ANY, 0, dump_exit_codes },
{ "syscall-filter", VERB_ANY, VERB_ANY, 0, dump_syscall_filters },
{ "condition", 2, VERB_ANY, 0, do_condition },
{ "verify", 2, VERB_ANY, 0, do_verify },