From 814cc562121270e2d5de0630b773792c74990a9c Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Sat, 2 Mar 2013 22:31:09 +0100 Subject: [PATCH] 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(). --- src/core/mount.c | 48 +------------------------------------ src/core/service.c | 60 +--------------------------------------------- src/core/socket.c | 48 +------------------------------------ src/core/swap.c | 48 +------------------------------------ src/core/unit.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ src/core/unit.h | 1 + 6 files changed, 64 insertions(+), 200 deletions(-) diff --git a/src/core/mount.c b/src/core/mount.c index 895aa2537..73a783243 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -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] = { diff --git a/src/core/service.c b/src/core/service.c index 3fbb0a136..fd90ceba0 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -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] = { diff --git a/src/core/socket.c b/src/core/socket.c index 210536901..ee9de4e14 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -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] = { diff --git a/src/core/swap.c b/src/core/swap.c index 61ce8316c..a0e55a0c0 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -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] = { diff --git a/src/core/unit.c b/src/core/unit.c index a6cc3b610..a1249dc09 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -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); diff --git a/src/core/unit.h b/src/core/unit.h index 9029d6225..3da6a50da 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -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); -- 2.30.2