chiark / gitweb /
systemctl: add is-failed
authorThomas Hindoe Paaboel Andersen <phomes@gmail.com>
Thu, 27 Dec 2012 16:39:48 +0000 (17:39 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 3 Jan 2013 23:33:25 +0000 (00:33 +0100)
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.

TODO
man/systemctl.xml
shell-completion/systemd-bash-completion.sh
shell-completion/systemd-zsh-completion.zsh
src/systemctl/systemctl.c

diff --git a/TODO b/TODO
index 6cc673e..8ebb951 100644 (file)
--- 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
index 62446d7..f86952c 100644 (file)
                                 STDOUT in
                                 <command>snapshot</command>,
                                 <command>is-active</command>,
+                                <command>is-failed</command>,
                                 <command>enable</command> and
                                 <command>disable</command>.</para></listitem>
                         </varlistentry>
                                 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
index a5df3bf..52dc72b 100644 (file)
@@ -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'
index ee68ac7..d5fb850 100644 (file)
@@ -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
index 463c72f..086872c 100644 (file)
@@ -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              },