]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
systemctl: is-failed: check if system is degraded when no unit given 29595/head
authorMike Yuan <me@yhndnzj.com>
Tue, 17 Oct 2023 12:47:54 +0000 (20:47 +0800)
committerMike Yuan <me@yhndnzj.com>
Wed, 18 Oct 2023 16:12:28 +0000 (00:12 +0800)
Closes #3335

man/systemctl.xml
src/systemctl/systemctl-is-active.c
src/systemctl/systemctl.c
test/units/testsuite-26.sh

index a673c18c0ee0bd55674e5d3f7e4fbc84d45b126a..419d4a82438f80dc465e0c3c9cb3c624e444c6e5 100644 (file)
@@ -219,15 +219,14 @@ Sun 2017-02-26 20:57:49 EST  2h 3min left  Sun 2017-02-26 11:56:36 EST  6h ago
         </varlistentry>
 
         <varlistentry>
-          <term><command>is-failed <replaceable>PATTERN</replaceable>…</command></term>
+          <term><command>is-failed <optional><replaceable>PATTERN</replaceable>…</optional></command></term>
 
           <listitem>
-            <para>Check whether any of the specified units are in a
-            "failed" state. Returns an exit code
-            <constant>0</constant> if at least one has failed,
-            non-zero otherwise. Unless <option>--quiet</option> is
-            specified, this will also print the current unit state to
-            standard output.</para>
+            <para>Check whether any of the specified units is in the "failed" state. If no unit is specified,
+            check whether there are any failed units, which corresponds to the <literal>degraded</literal> state
+            returned by <command>is-system-running</command>. Returns an exit code <constant>0</constant>
+            if at least one has failed, non-zero otherwise. Unless <option>--quiet</option> is specified, this
+            will also print the current unit or system state to standard output.</para>
 
             <xi:include href="version-info.xml" xpointer="v197"/>
           </listitem>
index 023869c9ac1d13af9062877dffc4530b94884668..596320a8c613d8297d753c3c1db1d8a6ad096bbb 100644 (file)
@@ -69,5 +69,28 @@ int verb_is_failed(int argc, char *argv[], void *userdata) {
                 UNIT_FAILED,
         };
 
-        return check_unit_generic(EXIT_PROGRAM_DEAD_AND_PID_EXISTS, states, ELEMENTSOF(states), strv_skip(argv, 1));
+        int r;
+
+        if (argc > 1)
+                return check_unit_generic(EXIT_PROGRAM_DEAD_AND_PID_EXISTS, states, ELEMENTSOF(states), strv_skip(argv, 1));
+
+        /* If no unit is provided, we check SystemState property of the manager, i.e. whether there're failed
+         * units. */
+
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        _cleanup_free_ char *state = NULL;
+        sd_bus *bus;
+
+        r = acquire_bus(BUS_MANAGER, &bus);
+        if (r < 0)
+                return r;
+
+        r = bus_get_property_string(bus, bus_systemd_mgr, "SystemState", &error, &state);
+        if (r < 0)
+                return log_error_errno(r, "Failed to query system state: %s", bus_error_message(&error, r));
+
+        if (!arg_quiet)
+                puts(state);
+
+        return streq(state, "degraded") ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index 989318360cf33c2e2e1fb7ff36ee33c8e627f878..dcd4dcc68aae29eb90cdf190d411b9843990e707 100644 (file)
@@ -162,7 +162,8 @@ static int systemctl_help(void) {
                "  list-timers [PATTERN...]            List timer units currently in memory,\n"
                "                                      ordered by next elapse\n"
                "  is-active PATTERN...                Check whether units are active\n"
-               "  is-failed PATTERN...                Check whether units are failed\n"
+               "  is-failed [PATTERN...]              Check whether units are failed or\n"
+               "                                      system is in degraded state\n"
                "  status [PATTERN...|PID...]          Show runtime status of one or more units\n"
                "  show [PATTERN...|JOB...]            Show properties of one or more\n"
                "                                      units/jobs or the manager\n"
@@ -1165,7 +1166,7 @@ static int systemctl_main(int argc, char *argv[]) {
                 { "thaw",                  2,        VERB_ANY, VERB_ONLINE_ONLY, verb_clean_or_freeze         },
                 { "is-active",             2,        VERB_ANY, VERB_ONLINE_ONLY, verb_is_active               },
                 { "check",                 2,        VERB_ANY, VERB_ONLINE_ONLY, verb_is_active               }, /* deprecated alias of is-active */
-                { "is-failed",             2,        VERB_ANY, VERB_ONLINE_ONLY, verb_is_failed               },
+                { "is-failed",             VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_is_failed               },
                 { "show",                  VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_show                    },
                 { "cat",                   2,        VERB_ANY, VERB_ONLINE_ONLY, verb_cat                     },
                 { "status",                VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_show                    },
index cce2a393db705b6e5a7aae05ede3e8e228e1e77a..1e11c420e1a3395a2abf2a2a3fe3957fe193311d 100755 (executable)
@@ -135,6 +135,8 @@ systemctl restart "$UNIT_NAME"
 systemctl stop "$UNIT_NAME"
 (! systemctl is-active "$UNIT_NAME")
 
+assert_eq "$(systemctl is-system-running)" "$(systemctl is-failed)"
+
 # enable/disable/preset
 test_enable_disable_preset() {
     (! systemctl is-enabled "$@" "$UNIT_NAME")