summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/mount.c48
-rw-r--r--src/core/service.c60
-rw-r--r--src/core/socket.c48
-rw-r--r--src/core/swap.c48
-rw-r--r--src/core/unit.c59
-rw-r--r--src/core/unit.h1
6 files changed, 64 insertions, 200 deletions
diff --git a/src/core/mount.c b/src/core/mount.c
index 895aa25371..73a7832430 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 3fbb0a136d..fd90ceba05 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 2105369018..ee9de4e14c 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 61ce8316c2..a0e55a0c03 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 a6cc3b6102..a1249dc093 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 9029d6225b..3da6a50da9 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);