[systemd-devel] [PATCHv3] systemctl, man: option to list units by state

Maciej Wereski m.wereski at partner.samsung.com
Wed Jul 17 04:01:49 PDT 2013


This allows to show only units with specified SUB or ACTIVE state.

Signed-off-by: Maciej Wereski <m.wereski at partner.samsung.com>
---
 man/systemctl.xml         | 15 +++++++++++++--
 src/systemctl/systemctl.c | 43 +++++++++++++++++++++++++++++++++++++------
 2 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/man/systemctl.xml b/man/systemctl.xml
index f550215..2fb74c5 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -114,6 +114,16 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
       </varlistentry>
 
       <varlistentry>
+        <term><option>--state=</option></term>
+
+        <listitem>
+        <para>Argument should be a comma-separated list of unit
+        SUB or ACTIVE states. When listing units show only those
+        with specified SUB or ACTIVE state.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><option>-p</option></term>
         <term><option>--property=</option></term>
 
@@ -169,8 +179,9 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
         <term><option>--failed</option></term>
 
         <listitem>
-          <para>When listing units, show only failed units. Do not
-          confuse with <option>--fail</option>.</para>
+          <para>When listing units, show only failed units.
+          This is the same as <option>--state=</option>failed.
+          Do not confuse with <option>--fail</option>.</para>
         </listitem>
       </varlistentry>
 
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 9574ff2..61b4730 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -93,13 +93,13 @@ static bool arg_quiet = false;
 static bool arg_full = false;
 static int arg_force = 0;
 static bool arg_ask_password = true;
-static bool arg_failed = false;
 static bool arg_runtime = false;
 static char **arg_wall = NULL;
 static const char *arg_kill_who = NULL;
 static int arg_signal = SIGTERM;
 static const char *arg_root = NULL;
 static usec_t arg_when = 0;
+static char **arg_state = NULL;
 static enum action {
         ACTION_INVALID,
         ACTION_SYSTEMCTL,
@@ -301,8 +301,8 @@ static int compare_unit_info(const void *a, const void *b) {
 static bool output_show_unit(const struct unit_info *u) {
         const char *dot;
 
-        if (arg_failed)
-                return streq(u->active_state, "failed");
+        if (!strv_isempty(arg_state))
+                return strv_contains(arg_state, u->sub_state) || strv_contains(arg_state, u->active_state);
 
         return (!arg_types || ((dot = strrchr(u->id, '.')) &&
                                strv_find(arg_types, dot+1))) &&
@@ -4660,12 +4660,13 @@ static int systemctl_help(void) {
                "  -h --help           Show this help\n"
                "     --version        Show package version\n"
                "  -t --type=TYPE      List only units of a particular type\n"
+               "     --state=STATE    Show only units with particular SUB or ACTIVE state\n"
                "  -p --property=NAME  Show only properties by this name\n"
                "  -a --all            Show all loaded units/properties, including dead/empty\n"
                "                      ones. To list all units installed on the system, use\n"
                "                      the 'list-unit-files' command instead.\n"
                "     --reverse        Show reverse dependencies with 'list-dependencies'\n"
-               "     --failed         Show only failed units\n"
+               "     --failed         Show only failed units (the same as --state=failed)\n"
                "  -l --full           Don't ellipsize unit names on output\n"
                "     --fail           When queueing a new job, fail if conflicting jobs are\n"
                "                      pending\n"
@@ -4886,7 +4887,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                 ARG_FAILED,
                 ARG_RUNTIME,
                 ARG_FORCE,
-                ARG_PLAIN
+                ARG_PLAIN,
+                ARG_STATE
         };
 
         static const struct option options[] = {
@@ -4925,6 +4927,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                 { "lines",     required_argument, NULL, 'n'           },
                 { "output",    required_argument, NULL, 'o'           },
                 { "plain",     no_argument,       NULL, ARG_PLAIN     },
+                { "state",     required_argument, NULL, ARG_STATE     },
                 { NULL,        0,                 NULL, 0             }
         };
 
@@ -5086,7 +5089,14 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_FAILED:
-                        arg_failed = true;
+                        if (!strv_contains(arg_state, "failed")) {
+                                char **tmp = arg_state;
+                                arg_state = strv_append(arg_state, "failed");
+                                if (!arg_state) {
+                                        strv_free(tmp);
+                                        return -ENOMEM;
+                                }
+                        }
                         break;
 
                 case 'q':
@@ -5156,6 +5166,27 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                         arg_plain = true;
                         break;
 
+                case ARG_STATE: {
+                        char *word, *state;
+                        size_t size;
+                        FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
+                                char _cleanup_free_ *str;
+
+                                str = strndup(word, size);
+                                if (!str)
+                                        return -ENOMEM;
+                                 if (!strv_contains(arg_state, str)) {
+                                        char **tmp = arg_state;
+                                        arg_state = strv_append(arg_state, str);
+                                        if (!arg_state) {
+                                                strv_free(tmp);
+                                                return -ENOMEM;
+                                        }
+                                 }
+                        }
+                        break;
+                }
+
                 case '?':
                         return -EINVAL;
 
-- 
1.8.3.3



More information about the systemd-devel mailing list