summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO2
-rw-r--r--man/systemctl.xml13
-rw-r--r--shell-completion/systemd-bash-completion.sh2
-rw-r--r--shell-completion/systemd-zsh-completion.zsh3
-rw-r--r--src/systemctl/systemctl.c41
5 files changed, 50 insertions, 11 deletions
diff --git a/TODO b/TODO
index 6cc673eb27..8ebb951c21 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 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 },