diff options
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | man/systemctl.xml | 13 | ||||
-rw-r--r-- | shell-completion/systemd-bash-completion.sh | 2 | ||||
-rw-r--r-- | shell-completion/systemd-zsh-completion.zsh | 3 | ||||
-rw-r--r-- | src/systemctl/systemctl.c | 41 |
5 files changed, 50 insertions, 11 deletions
@@ -47,8 +47,6 @@ Features: * Add a verbose mode to "systemctl start" and friends that explains what is being done or not done -* "systemctl is-failed" to join "systemctl is-active" and "systemctl is-enabled". - * journal is not closed properly at shutdown when run in a container? * All log messages generated from socket.c, service.c, ... should diff --git a/man/systemctl.xml b/man/systemctl.xml index 62446d7a57..f86952c683 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -198,6 +198,7 @@ STDOUT in <command>snapshot</command>, <command>is-active</command>, + <command>is-failed</command>, <command>enable</command> and <command>disable</command>.</para></listitem> </varlistentry> @@ -601,6 +602,18 @@ state to STDOUT.</para></listitem> </varlistentry> <varlistentry> + <term><command>is-failed [NAME...]</command></term> + + <listitem><para>Check whether any of + the specified units are failed. + Returns an exit code + 0 if at least one is failed, non-zero + otherwise. Unless + <option>--quiet</option> is specified + this will also print the current unit + state to STDOUT.</para></listitem> + </varlistentry> + <varlistentry> <term><command>status [NAME...|PID...]</command></term> <listitem><para>Show terse runtime diff --git a/shell-completion/systemd-bash-completion.sh b/shell-completion/systemd-bash-completion.sh index a5df3bf985..52dc72b04f 100644 --- a/shell-completion/systemd-bash-completion.sh +++ b/shell-completion/systemd-bash-completion.sh @@ -100,7 +100,7 @@ _systemctl () { fi local -A VERBS=( - [ALL_UNITS]='is-active is-enabled status show mask preset' + [ALL_UNITS]='is-active is-failed is-enabled status show mask preset' [ENABLED_UNITS]='disable reenable' [DISABLED_UNITS]='enable' [FAILED_UNITS]='reset-failed' diff --git a/shell-completion/systemd-zsh-completion.zsh b/shell-completion/systemd-zsh-completion.zsh index ee68ac7576..d5fb850cdb 100644 --- a/shell-completion/systemd-zsh-completion.zsh +++ b/shell-completion/systemd-zsh-completion.zsh @@ -335,6 +335,7 @@ _outputmodes() { "isolate:Start one unit and stop all others" "kill:Send signal to processes of a unit" "is-active:Check whether units are active" + "is-failed:Check whether units are failed" "status:Show runtime status of one or more units" "show:Show properties of one or more units/jobs or the manager" "reset-failed:Reset failed state for all, one, or more units" @@ -457,7 +458,7 @@ _systemctl_disabled_units(){_sys_disabled_units=($(__systemctl list-unit-files _systemctl_masked_units() {_sys_masked_units=( $(__systemctl list-unit-files | { while read a b; do [[ $b == "masked" ]] && echo "$a"; done; }) )} # Completion functions for ALL_UNITS -for fun in is-active is-enabled status show mask preset ; do +for fun in is-active is-failed is-enabled status show mask preset ; do (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() { _systemctl_really_all_units diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 463c72f659..086872c696 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -1366,7 +1366,7 @@ static int wait_for_jobs(DBusConnection *bus, Set *s) { return r; } -static int check_one_unit(DBusConnection *bus, char *name, bool quiet) { +static int check_one_unit(DBusConnection *bus, char *name, char **check_states, bool quiet) { DBusMessage *reply = NULL; DBusMessageIter iter, sub; const char @@ -1440,7 +1440,7 @@ static int check_one_unit(DBusConnection *bus, char *name, bool quiet) { if (!quiet) puts(state); - if (streq(state, "active") || streq(state, "reloading")) + if (strv_find(check_states, state)) r = 0; else r = 3; /* According to LSB: "program is not running" */ @@ -1503,6 +1503,7 @@ static void check_triggering_units( sub = iter; while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + char **check_states = NULL; if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) { log_error("Failed to parse reply."); @@ -1511,7 +1512,9 @@ static void check_triggering_units( dbus_message_iter_get_basic(&sub, &service_trigger); - r = check_one_unit(bus, service_trigger, true); + check_states = strv_new("active", "reloading", NULL); + r = check_one_unit(bus, service_trigger, check_states, true); + strv_free(check_states); if (r < 0) return; if (r == 0) { @@ -1847,7 +1850,7 @@ static int start_special(DBusConnection *bus, char **args) { return r; } -static int check_unit(DBusConnection *bus, char **args) { +static int check_unit_active(DBusConnection *bus, char **args) { char **name; int r = 3; /* According to LSB: "program is not running" */ @@ -1855,7 +1858,29 @@ static int check_unit(DBusConnection *bus, char **args) { assert(args); STRV_FOREACH(name, args+1) { - int state = check_one_unit(bus, *name, arg_quiet); + char **check_states = strv_new("active", "reloading", NULL); + int state = check_one_unit(bus, *name, check_states, arg_quiet); + strv_free(check_states); + if (state < 0) + return state; + if (state == 0) + r = 0; + } + + return r; +} + +static int check_unit_failed(DBusConnection *bus, char **args) { + char **name; + int r = 1; + + assert(bus); + assert(args); + + STRV_FOREACH(name, args+1) { + char **check_states = strv_new("failed", NULL); + int state = check_one_unit(bus, *name, check_states, arg_quiet); + strv_free(check_states); if (state < 0) return state; if (state == 0) @@ -3967,6 +3992,7 @@ static int systemctl_help(void) { " isolate [NAME] Start one unit and stop all others\n" " kill [NAME...] Send signal to processes of a unit\n" " is-active [NAME...] Check whether units are active\n" + " is-failed [NAME...] Check whether units are failed\n" " status [NAME...|PID...] Show runtime status of one or more units\n" " show [NAME...|JOB...] Show properties of one or more\n" " units/jobs or the manager\n" @@ -4945,8 +4971,9 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */ { "isolate", EQUAL, 2, start_unit }, { "kill", MORE, 2, kill_unit }, - { "is-active", MORE, 2, check_unit }, - { "check", MORE, 2, check_unit }, + { "is-active", MORE, 2, check_unit_active }, + { "check", MORE, 2, check_unit_active }, + { "is-failed", MORE, 2, check_unit_failed }, { "show", MORE, 1, show }, { "status", MORE, 2, show }, { "help", MORE, 2, show }, |