From: Thomas Hindoe Paaboel Andersen Date: Thu, 27 Dec 2012 16:39:48 +0000 (+0100) Subject: systemctl: add is-failed X-Git-Tag: v197~63 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=1a0fce458d3b45624c5817006735d59a5689ef83;hp=c8be47e81568629f8ae9135ab2219de0180c04ac systemctl: add is-failed Adds is-failed to join is-active and is-enabled. I grabbed this one from the todo list. Most of the functionality was already there for is-active. I just needed to make check_one_unit take the states to check for as an argument instead of the hardcoded "active" and "reloading". is-failed will return 1 if none of the units given are failed. This is different from is-active which will return 3 if none of the units given are active. It returns 3 with this comment: /* According to LSB: "program is not running" */ As that does not make sense when looking for failed units I simply chose 1 instead. --- diff --git a/TODO b/TODO index 6cc673eb2..8ebb951c2 100644 --- a/TODO +++ b/TODO @@ -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 62446d7a5..f86952c68 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -198,6 +198,7 @@ STDOUT in snapshot, is-active, + is-failed, enable and disable. @@ -600,6 +601,18 @@ this will also print the current unit state to STDOUT. + + is-failed [NAME...] + + Check whether any of + the specified units are failed. + Returns an exit code + 0 if at least one is failed, non-zero + otherwise. Unless + is specified + this will also print the current unit + state to STDOUT. + status [NAME...|PID...] diff --git a/shell-completion/systemd-bash-completion.sh b/shell-completion/systemd-bash-completion.sh index a5df3bf98..52dc72b04 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 ee68ac757..d5fb850cd 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 463c72f65..086872c69 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 },