Commit 814cc562 authored by Michal Schmidt's avatar Michal Schmidt
Browse files

core: single unit_kill implementation for all unit types

There are very few differences in the implementations of the kill method in the
unit types that have one. Let's unify them.

This does not yet unify unit_kill() with unit_kill_context().
parent 6282c859
......@@ -1781,53 +1781,7 @@ static void mount_reset_failed(Unit *u) {
}
static int mount_kill(Unit *u, KillWho who, int signo, DBusError *error) {
Mount *m = MOUNT(u);
int r = 0;
Set *pid_set = NULL;
assert(m);
if (who == KILL_MAIN) {
dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Mount units have no main processes");
return -ESRCH;
}
if (m->control_pid <= 0 && who == KILL_CONTROL) {
dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
return -ESRCH;
}
if (who == KILL_CONTROL || who == KILL_ALL)
if (m->control_pid > 0)
if (kill(m->control_pid, signo) < 0)
r = -errno;
if (who == KILL_ALL) {
int q;
pid_set = set_new(trivial_hash_func, trivial_compare_func);
if (!pid_set)
return -ENOMEM;
/* Exclude the control pid from being killed via the cgroup */
if (m->control_pid > 0) {
q = set_put(pid_set, LONG_TO_PTR(m->control_pid));
if (q < 0) {
r = q;
goto finish;
}
}
q = cgroup_bonding_kill_list(UNIT(m)->cgroup_bondings, signo, false, false, pid_set, NULL);
if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
r = q;
}
finish:
if (pid_set)
set_free(pid_set);
return r;
return unit_kill_common(u, who, signo, -1, MOUNT(u)->control_pid, error);
}
static const char* const mount_state_table[_MOUNT_STATE_MAX] = {
......
......@@ -3711,65 +3711,7 @@ static void service_reset_failed(Unit *u) {
static int service_kill(Unit *u, KillWho who, int signo, DBusError *error) {
Service *s = SERVICE(u);
int r = 0;
Set *pid_set = NULL;
assert(s);
if (s->main_pid <= 0 && who == KILL_MAIN) {
dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill");
return -ESRCH;
}
if (s->control_pid <= 0 && who == KILL_CONTROL) {
dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
return -ESRCH;
}
if (who == KILL_CONTROL || who == KILL_ALL)
if (s->control_pid > 0)
if (kill(s->control_pid, signo) < 0)
r = -errno;
if (who == KILL_MAIN || who == KILL_ALL)
if (s->main_pid > 0)
if (kill(s->main_pid, signo) < 0)
r = -errno;
if (who == KILL_ALL) {
int q;
pid_set = set_new(trivial_hash_func, trivial_compare_func);
if (!pid_set)
return -ENOMEM;
/* Exclude the control/main pid from being killed via the cgroup */
if (s->control_pid > 0) {
q = set_put(pid_set, LONG_TO_PTR(s->control_pid));
if (q < 0) {
r = q;
goto finish;
}
}
if (s->main_pid > 0) {
q = set_put(pid_set, LONG_TO_PTR(s->main_pid));
if (q < 0) {
r = q;
goto finish;
}
}
q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, false, pid_set, NULL);
if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
r = q;
}
finish:
if (pid_set)
set_free(pid_set);
return r;
return unit_kill_common(u, who, signo, s->main_pid, s->control_pid, error);
}
static const char* const service_state_table[_SERVICE_STATE_MAX] = {
......
......@@ -2265,53 +2265,7 @@ static void socket_reset_failed(Unit *u) {
}
static int socket_kill(Unit *u, KillWho who, int signo, DBusError *error) {
Socket *s = SOCKET(u);
int r = 0;
Set *pid_set = NULL;
assert(s);
if (who == KILL_MAIN) {
dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Socket units have no main processes");
return -ESRCH;
}
if (s->control_pid <= 0 && who == KILL_CONTROL) {
dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
return -ESRCH;
}
if (who == KILL_CONTROL || who == KILL_ALL)
if (s->control_pid > 0)
if (kill(s->control_pid, signo) < 0)
r = -errno;
if (who == KILL_ALL) {
int q;
pid_set = set_new(trivial_hash_func, trivial_compare_func);
if (!pid_set)
return -ENOMEM;
/* Exclude the control pid from being killed via the cgroup */
if (s->control_pid > 0) {
q = set_put(pid_set, LONG_TO_PTR(s->control_pid));
if (q < 0) {
r = q;
goto finish;
}
}
q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, false, pid_set, NULL);
if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
r = q;
}
finish:
if (pid_set)
set_free(pid_set);
return r;
return unit_kill_common(u, who, signo, -1, SOCKET(u)->control_pid, error);
}
static const char* const socket_state_table[_SOCKET_STATE_MAX] = {
......
......@@ -1262,53 +1262,7 @@ static void swap_reset_failed(Unit *u) {
}
static int swap_kill(Unit *u, KillWho who, int signo, DBusError *error) {
Swap *s = SWAP(u);
int r = 0;
Set *pid_set = NULL;
assert(s);
if (who == KILL_MAIN) {
dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Swap units have no main processes");
return -ESRCH;
}
if (s->control_pid <= 0 && who == KILL_CONTROL) {
dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
return -ESRCH;
}
if (who == KILL_CONTROL || who == KILL_ALL)
if (s->control_pid > 0)
if (kill(s->control_pid, signo) < 0)
r = -errno;
if (who == KILL_ALL) {
int q;
pid_set = set_new(trivial_hash_func, trivial_compare_func);
if (!pid_set)
return -ENOMEM;
/* Exclude the control pid from being killed via the cgroup */
if (s->control_pid > 0) {
q = set_put(pid_set, LONG_TO_PTR(s->control_pid));
if (q < 0) {
r = q;
goto finish;
}
}
q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, false, pid_set, NULL);
if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
r = q;
}
finish:
if (pid_set)
set_free(pid_set);
return r;
return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
}
static const char* const swap_state_table[_SWAP_STATE_MAX] = {
......
......@@ -48,6 +48,7 @@
#include "mkdir.h"
#include "label.h"
#include "fileio-label.h"
#include "bus-errors.h"
const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
[UNIT_SERVICE] = &service_vtable,
......@@ -2644,6 +2645,64 @@ int unit_kill(Unit *u, KillWho w, int signo, DBusError *error) {
return UNIT_VTABLE(u)->kill(u, w, signo, error);
}
int unit_kill_common(Unit *u, KillWho who, int signo, pid_t main_pid, pid_t control_pid, DBusError *error) {
int r = 0;
if (who == KILL_MAIN && main_pid <= 0) {
if (main_pid < 0)
dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no main processes", unit_type_to_string(u->type));
else
dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill");
return -ESRCH;
}
if (who == KILL_CONTROL && control_pid <= 0) {
if (control_pid < 0)
dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no control processes", unit_type_to_string(u->type));
else
dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
return -ESRCH;
}
if (who == KILL_CONTROL || who == KILL_ALL)
if (control_pid > 0)
if (kill(control_pid, signo) < 0)
r = -errno;
if (who == KILL_MAIN || who == KILL_ALL)
if (main_pid > 0)
if (kill(main_pid, signo) < 0)
r = -errno;
if (who == KILL_ALL) {
_cleanup_set_free_ Set *pid_set = NULL;
int q;
pid_set = set_new(trivial_hash_func, trivial_compare_func);
if (!pid_set)
return -ENOMEM;
/* Exclude the control/main pid from being killed via the cgroup */
if (control_pid > 0) {
q = set_put(pid_set, LONG_TO_PTR(control_pid));
if (q < 0)
return q;
}
if (main_pid > 0) {
q = set_put(pid_set, LONG_TO_PTR(main_pid));
if (q < 0)
return q;
}
q = cgroup_bonding_kill_list(u->cgroup_bondings, signo, false, false, pid_set, NULL);
if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
r = q;
}
return r;
}
int unit_following_set(Unit *u, Set **s) {
assert(u);
assert(s);
......
......@@ -486,6 +486,7 @@ int unit_stop(Unit *u);
int unit_reload(Unit *u);
int unit_kill(Unit *u, KillWho w, int signo, DBusError *error);
int unit_kill_common(Unit *u, KillWho who, int signo, pid_t main_pid, pid_t control_pid, DBusError *error);
void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment