diff options
-rw-r--r-- | man/systemctl.xml | 11 | ||||
-rw-r--r-- | src/core/kill.c | 5 | ||||
-rw-r--r-- | src/core/kill.h | 3 | ||||
-rw-r--r-- | src/core/unit.c | 26 | ||||
-rw-r--r-- | src/systemctl/systemctl.c | 8 |
5 files changed, 43 insertions, 10 deletions
diff --git a/man/systemctl.xml b/man/systemctl.xml index 37ba4ab6de..d8d433e4d3 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -295,6 +295,17 @@ </varlistentry> <varlistentry> + <term><option>--fail</option></term> + + <listitem> + <para>Shorthand for <option>--job-mode=</option>fail.</para> + <para>When used with the <command>kill</command> command, + if no units were killed, the operation results in an error. + </para> + </listitem> + </varlistentry> + + <varlistentry> <term><option>-i</option></term> <term><option>--ignore-inhibitors</option></term> diff --git a/src/core/kill.c b/src/core/kill.c index 2de71c6bf9..bddfa4460f 100644 --- a/src/core/kill.c +++ b/src/core/kill.c @@ -60,7 +60,10 @@ DEFINE_STRING_TABLE_LOOKUP(kill_mode, KillMode); static const char* const kill_who_table[_KILL_WHO_MAX] = { [KILL_MAIN] = "main", [KILL_CONTROL] = "control", - [KILL_ALL] = "all" + [KILL_ALL] = "all", + [KILL_MAIN_FAIL] = "main-fail", + [KILL_CONTROL_FAIL] = "control-fail", + [KILL_ALL_FAIL] = "all-fail" }; DEFINE_STRING_TABLE_LOOKUP(kill_who, KillWho); diff --git a/src/core/kill.h b/src/core/kill.h index d5f125fa41..5d97abb104 100644 --- a/src/core/kill.h +++ b/src/core/kill.h @@ -50,6 +50,9 @@ typedef enum KillWho { KILL_MAIN, KILL_CONTROL, KILL_ALL, + KILL_MAIN_FAIL, + KILL_CONTROL_FAIL, + KILL_ALL_FAIL, _KILL_WHO_MAX, _KILL_WHO_INVALID = -1 } KillWho; diff --git a/src/core/unit.c b/src/core/unit.c index 3356b97522..3a6313e4a2 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -3064,32 +3064,39 @@ int unit_kill_common( sd_bus_error *error) { int r = 0; + bool killed = false; - if (who == KILL_MAIN) { + if (IN_SET(who, KILL_MAIN, KILL_MAIN_FAIL)) { if (main_pid < 0) return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no main processes", unit_type_to_string(u->type)); else if (main_pid == 0) return sd_bus_error_set_const(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill"); } - if (who == KILL_CONTROL) { + if (IN_SET(who, KILL_CONTROL, KILL_CONTROL_FAIL)) { if (control_pid < 0) return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no control processes", unit_type_to_string(u->type)); else if (control_pid == 0) return sd_bus_error_set_const(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill"); } - if (who == KILL_CONTROL || who == KILL_ALL) - if (control_pid > 0) + if (IN_SET(who, KILL_CONTROL, KILL_CONTROL_FAIL, KILL_ALL, KILL_ALL_FAIL)) + if (control_pid > 0) { if (kill(control_pid, signo) < 0) r = -errno; + else + killed = true; + } - if (who == KILL_MAIN || who == KILL_ALL) - if (main_pid > 0) + if (IN_SET(who, KILL_MAIN, KILL_MAIN_FAIL, KILL_ALL, KILL_ALL_FAIL)) + if (main_pid > 0) { if (kill(main_pid, signo) < 0) r = -errno; + else + killed = true; + } - if (who == KILL_ALL && u->cgroup_path) { + if (IN_SET(who, KILL_ALL, KILL_ALL_FAIL) && u->cgroup_path) { _cleanup_set_free_ Set *pid_set = NULL; int q; @@ -3101,8 +3108,13 @@ int unit_kill_common( q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, false, false, pid_set); if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT) r = q; + else + killed = true; } + if (r == 0 && !killed && IN_SET(who, KILL_ALL_FAIL, KILL_CONTROL_FAIL, KILL_ALL_FAIL)) + return -ESRCH; + return r; } diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index d21ba9a566..d1e443b8a6 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3107,7 +3107,7 @@ static int check_unit_failed(sd_bus *bus, char **args) { static int kill_unit(sd_bus *bus, char **args) { _cleanup_strv_free_ char **names = NULL; - char **name; + char *kill_who = NULL, **name; int r, q; assert(bus); @@ -3118,6 +3118,10 @@ static int kill_unit(sd_bus *bus, char **args) { if (!arg_kill_who) arg_kill_who = "all"; + /* --fail was specified */ + if (streq(arg_job_mode, "fail")) + kill_who = strjoina(arg_kill_who, "-fail", NULL); + r = expand_names(bus, args + 1, NULL, &names); if (r < 0) log_error_errno(r, "Failed to expand names: %m"); @@ -3133,7 +3137,7 @@ static int kill_unit(sd_bus *bus, char **args) { "KillUnit", &error, NULL, - "ssi", *names, arg_kill_who, arg_signal); + "ssi", *names, kill_who ? kill_who : arg_kill_who, arg_signal); if (q < 0) { log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q)); if (r == 0) |