core: extend KillUnit() to return error when no unit was killed

This commit is contained in:
Jan Synacek 2015-09-18 11:56:53 +02:00
parent 8c710f3ce6
commit ac5e3a505e
5 changed files with 43 additions and 10 deletions

View file

@ -294,6 +294,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>

View file

@ -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);

View file

@ -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;

View file

@ -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;
}

View file

@ -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)