diff options
author | Lennart Poettering <lennart@poettering.net> | 2023-02-15 10:25:51 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2023-02-17 09:55:35 +0100 |
commit | a721cd0016fb662fc5888cef959eec19f96b4040 (patch) | |
tree | c78c36637dfa1f4f2c923ea1de57693110be5eb1 | |
parent | d51e31ac4197d971a468ff41f15593bb6fdb29f3 (diff) | |
download | systemd-a721cd0016fb662fc5888cef959eec19f96b4040.tar.gz |
pid1: add a new D-Bus method for enquing POSIX signals with values to unit processes
This augments the existing KillUnit() + Kill() methods with
QueueSignalUnit() + QueueSignal(), which are what sigqueue() is to
kill().
This is useful for sending our new SIGRTMIN+18 control signals to system
services.
-rw-r--r-- | man/org.freedesktop.systemd1.xml | 31 | ||||
-rw-r--r-- | src/core/dbus-manager.c | 5 | ||||
-rw-r--r-- | src/core/dbus-unit.c | 25 | ||||
-rw-r--r-- | src/core/mount.c | 4 | ||||
-rw-r--r-- | src/core/org.freedesktop.systemd1.conf | 8 | ||||
-rw-r--r-- | src/core/scope.c | 4 | ||||
-rw-r--r-- | src/core/service.c | 4 | ||||
-rw-r--r-- | src/core/slice.c | 4 | ||||
-rw-r--r-- | src/core/socket.c | 4 | ||||
-rw-r--r-- | src/core/swap.c | 4 | ||||
-rw-r--r-- | src/core/unit.c | 142 | ||||
-rw-r--r-- | src/core/unit.h | 6 | ||||
-rw-r--r-- | src/test/test-execute.c | 2 |
13 files changed, 168 insertions, 75 deletions
diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml index 1592d046ad..5bae473856 100644 --- a/man/org.freedesktop.systemd1.xml +++ b/man/org.freedesktop.systemd1.xml @@ -112,6 +112,10 @@ node /org/freedesktop/systemd1 { KillUnit(in s name, in s whom, in i signal); + QueueSignalUnit(in s name, + in s whom, + in i signal, + in i value); CleanUnit(in s name, in as mask); FreezeUnit(in s name); @@ -826,6 +830,8 @@ node /org/freedesktop/systemd1 { <variablelist class="dbus-method" generated="True" extra-ref="KillUnit()"/> + <variablelist class="dbus-method" generated="True" extra-ref="QueueSignalUnit()"/> + <variablelist class="dbus-method" generated="True" extra-ref="CleanUnit()"/> <variablelist class="dbus-method" generated="True" extra-ref="FreezeUnit()"/> @@ -1286,6 +1292,13 @@ node /org/freedesktop/systemd1 { <varname>ExecStop=</varname> and is spawned in parallel to the main daemon process in order to shut it down.</para> + <para><function>QueueSignalUnit()</function> is similar to <function>KillUnit()</function> but may be + used to enqueue a POSIX Realtime Signal (i.e. <constant>SIGRTMIN+…</constant> and + <constant>SIGRTMAX-…</constant>) to the selected process(es). Takes the same paramaters as + <function>KillUnit()</function> with one additional argument: an integer that is passed in the + <varname>sival_int</varname> value accompanying the queued signal. See <citerefentry project="man-pages"><refentrytitle>sigqueue</refentrytitle><manvolnum>3</manvolnum></citerefentry> for + details.</para> + <para><function>GetJob()</function> returns the job object path for a specific job, identified by its id.</para> @@ -1731,7 +1744,8 @@ node /org/freedesktop/systemd1 { <para>Read access is generally granted to all clients. Additionally, for unprivileged clients, some operations are allowed through the polkit privilege system. Operations which modify unit state (<function>StartUnit()</function>, <function>StopUnit()</function>, <function>KillUnit()</function>, - <function>RestartUnit()</function> and similar, <function>SetProperty()</function>) require + <function>QueueSignalUnit()</function>, <function>RestartUnit()</function> and similar, + <function>SetProperty()</function>) require <interfacename>org.freedesktop.systemd1.manage-units</interfacename>. Operations which modify unit file enablement state (<function>EnableUnitFiles()</function>, <function>DisableUnitFiles()</function>, <function>EnableUnitFilesWithFlags()</function>, <function>DisableUnitFilesWithFlags()</function>, @@ -1778,6 +1792,9 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { out a(uosos) affected_jobs); Kill(in s whom, in i signal); + QueueSignal(in s whom, + in i signal, + in i value); ResetFailed(); SetProperties(in b runtime, in a(sv) properties); @@ -2084,6 +2101,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { <variablelist class="dbus-method" generated="True" extra-ref="Kill()"/> + <variablelist class="dbus-method" generated="True" extra-ref="QueueSignal()"/> + <variablelist class="dbus-method" generated="True" extra-ref="ResetFailed()"/> <variablelist class="dbus-method" generated="True" extra-ref="SetProperties()"/> @@ -2302,12 +2321,12 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { <para><function>Start()</function>, <function>Stop()</function>, <function>Reload()</function>, <function>Restart()</function>, <function>TryRestart()</function>, <function>ReloadOrRestart()</function>, <function>ReloadOrTryRestart()</function>, - <function>Kill()</function>, <function>ResetFailed()</function>, and - <function>SetProperties()</function> implement the same operation as the respective methods on the + <function>Kill()</function>, <function>QueueSignal()</function>, <function>ResetFailed()</function>, + and <function>SetProperties()</function> implement the same operation as the respective methods on the <interfacename>Manager</interfacename> object (see above). However, these methods operate on the unit - object and hence do not take a unit name parameter. Invoking the methods directly on the Manager - object has the advantage of not requiring a <function>GetUnit()</function> call to get the unit object - for a specific unit name. Calling the methods on the Manager object is hence a round trip + object and hence do not take a unit name parameter. Invoking the methods directly on the Manager object + has the advantage of not requiring a <function>GetUnit()</function> call to get the unit object for a + specific unit name. Calling the methods on the Manager object is hence a round trip optimization.</para> </refsect2> diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index c4f205bc42..7d6f6bfc0f 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -3034,6 +3034,11 @@ const sd_bus_vtable bus_manager_vtable[] = { SD_BUS_NO_RESULT, method_kill_unit, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_ARGS("QueueSignalUnit", + SD_BUS_ARGS("s", name, "s", whom, "i", signal, "i", value), + SD_BUS_NO_RESULT, + method_kill_unit, + SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD_WITH_ARGS("CleanUnit", SD_BUS_ARGS("s", name, "as", mask), SD_BUS_NO_RESULT, diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index 1ef98da6fd..8f851cbceb 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -513,10 +513,11 @@ int bus_unit_method_enqueue_job(sd_bus_message *message, void *userdata, sd_bus_ int bus_unit_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *error) { Unit *u = ASSERT_PTR(userdata); + int32_t value = 0; const char *swho; int32_t signo; KillWho who; - int r; + int r, code; assert(message); @@ -528,17 +529,30 @@ int bus_unit_method_kill(sd_bus_message *message, void *userdata, sd_bus_error * if (r < 0) return r; + if (startswith(sd_bus_message_get_member(message), "QueueSignal")) { + r = sd_bus_message_read(message, "i", &value); + if (r < 0) + return r; + + code = SI_QUEUE; + } else + code = SI_USER; + if (isempty(swho)) who = KILL_ALL; else { who = kill_who_from_string(swho); if (who < 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid who argument %s", swho); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid who argument: %s", swho); } if (!SIGNAL_VALID(signo)) return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Signal number out of range."); + if (code == SI_QUEUE && !((signo >= SIGRTMIN) && (signo <= SIGRTMAX))) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, + "Value parameter only accepted for realtime signals (SIGRTMIN…SIGRTMAX), refusing for signal SIG%s.", signal_to_string(signo)); + r = bus_verify_manage_units_async_full( u, "kill", @@ -552,7 +566,7 @@ int bus_unit_method_kill(sd_bus_message *message, void *userdata, sd_bus_error * if (r == 0) return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ - r = unit_kill(u, who, signo, error); + r = unit_kill(u, who, signo, code, value, error); if (r < 0) return r; @@ -984,6 +998,11 @@ const sd_bus_vtable bus_unit_vtable[] = { SD_BUS_NO_RESULT, bus_unit_method_kill, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_ARGS("QueueSignal", + SD_BUS_ARGS("s", whom, "i", signal, "i", value), + SD_BUS_NO_RESULT, + bus_unit_method_kill, + SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("ResetFailed", NULL, NULL, diff --git a/src/core/mount.c b/src/core/mount.c index 993dce5118..95bd04f6e9 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -2158,12 +2158,12 @@ static void mount_reset_failed(Unit *u) { m->clean_result = MOUNT_SUCCESS; } -static int mount_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) { +static int mount_kill(Unit *u, KillWho who, int signo, int code, int value, sd_bus_error *error) { Mount *m = MOUNT(u); assert(m); - return unit_kill_common(u, who, signo, -1, m->control_pid, error); + return unit_kill_common(u, who, signo, code, value, -1, m->control_pid, error); } static int mount_control_pid(Unit *u) { diff --git a/src/core/org.freedesktop.systemd1.conf b/src/core/org.freedesktop.systemd1.conf index 1cef421db8..7f44c32b83 100644 --- a/src/core/org.freedesktop.systemd1.conf +++ b/src/core/org.freedesktop.systemd1.conf @@ -248,6 +248,10 @@ <allow send_destination="org.freedesktop.systemd1" send_interface="org.freedesktop.systemd1.Manager" + send_member="QueueSignalUnit"/> + + <allow send_destination="org.freedesktop.systemd1" + send_interface="org.freedesktop.systemd1.Manager" send_member="ResetFailedUnit"/> <allow send_destination="org.freedesktop.systemd1" @@ -392,6 +396,10 @@ <allow send_destination="org.freedesktop.systemd1" send_interface="org.freedesktop.systemd1.Unit" + send_member="QueueSignal"/> + + <allow send_destination="org.freedesktop.systemd1" + send_interface="org.freedesktop.systemd1.Unit" send_member="ResetFailed"/> <allow send_destination="org.freedesktop.systemd1" diff --git a/src/core/scope.c b/src/core/scope.c index 914d1cc744..62f23a9e1e 100644 --- a/src/core/scope.c +++ b/src/core/scope.c @@ -530,8 +530,8 @@ static void scope_reset_failed(Unit *u) { s->result = SCOPE_SUCCESS; } -static int scope_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) { - return unit_kill_common(u, who, signo, -1, -1, error); +static int scope_kill(Unit *u, KillWho who, int signo, int code, int value, sd_bus_error *error) { + return unit_kill_common(u, who, signo, code, value, -1, -1, error); } static int scope_get_timeout(Unit *u, usec_t *timeout) { diff --git a/src/core/service.c b/src/core/service.c index 9ad3c3d995..dc5ccfd239 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -4596,12 +4596,12 @@ static void service_reset_failed(Unit *u) { s->flush_n_restarts = false; } -static int service_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) { +static int service_kill(Unit *u, KillWho who, int signo, int code, int value, sd_bus_error *error) { Service *s = SERVICE(u); assert(s); - return unit_kill_common(u, who, signo, s->main_pid, s->control_pid, error); + return unit_kill_common(u, who, signo, code, value, s->main_pid, s->control_pid, error); } static int service_main_pid(Unit *u) { diff --git a/src/core/slice.c b/src/core/slice.c index 4824a300d0..eb0ba5e763 100644 --- a/src/core/slice.c +++ b/src/core/slice.c @@ -247,8 +247,8 @@ static int slice_stop(Unit *u) { return 1; } -static int slice_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) { - return unit_kill_common(u, who, signo, -1, -1, error); +static int slice_kill(Unit *u, KillWho who, int signo, int code, int value, sd_bus_error *error) { + return unit_kill_common(u, who, signo, code, value, -1, -1, error); } static int slice_serialize(Unit *u, FILE *f, FDSet *fds) { diff --git a/src/core/socket.c b/src/core/socket.c index 409d415d8d..8241ba050b 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -3299,8 +3299,8 @@ static void socket_trigger_notify(Unit *u, Unit *other) { socket_set_state(s, SOCKET_RUNNING); } -static int socket_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) { - return unit_kill_common(u, who, signo, -1, SOCKET(u)->control_pid, error); +static int socket_kill(Unit *u, KillWho who, int signo, int code, int value, sd_bus_error *error) { + return unit_kill_common(u, who, signo, code, value, -1, SOCKET(u)->control_pid, error); } static int socket_get_timeout(Unit *u, usec_t *timeout) { diff --git a/src/core/swap.c b/src/core/swap.c index 2d25014e5f..ab901a2cd1 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -1480,8 +1480,8 @@ static void swap_reset_failed(Unit *u) { s->clean_result = SWAP_SUCCESS; } -static int swap_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) { - return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error); +static int swap_kill(Unit *u, KillWho who, int signo, int code, int value, sd_bus_error *error) { + return unit_kill_common(u, who, signo, code, value, -1, SWAP(u)->control_pid, error); } static int swap_get_timeout(Unit *u, usec_t *timeout) { diff --git a/src/core/unit.c b/src/core/unit.c index 78a1f72f7f..be7b19877f 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -3785,15 +3785,16 @@ bool unit_will_restart(Unit *u) { return UNIT_VTABLE(u)->will_restart(u); } -int unit_kill(Unit *u, KillWho w, int signo, sd_bus_error *error) { +int unit_kill(Unit *u, KillWho w, int signo, int code, int value, sd_bus_error *error) { assert(u); assert(w >= 0 && w < _KILL_WHO_MAX); assert(SIGNAL_VALID(signo)); + assert(IN_SET(code, SI_USER, SI_QUEUE)); if (!UNIT_VTABLE(u)->kill) return -EOPNOTSUPP; - return UNIT_VTABLE(u)->kill(u, w, signo, error); + return UNIT_VTABLE(u)->kill(u, w, signo, code, value, error); } void unit_notify_cgroup_oom(Unit *u, bool managed_oom) { @@ -3838,21 +3839,48 @@ static int kill_common_log(pid_t pid, int signo, void *userdata) { return 1; } +static int kill_or_sigqueue(pid_t pid, int signo, int code, int value) { + assert(pid > 0); + assert(SIGNAL_VALID(signo)); + + switch (code) { + + case SI_USER: + log_debug("Killing " PID_FMT " with signal SIG%s.", pid, signal_to_string(signo)); + return RET_NERRNO(kill(pid, signo)); + + case SI_QUEUE: + log_debug("Enqueuing value %i to " PID_FMT " on signal SIG%s.", value, pid, signal_to_string(signo)); + return RET_NERRNO(sigqueue(pid, signo, (const union sigval) { .sival_int = value })); + + default: + assert_not_reached(); + } +} + int unit_kill_common( Unit *u, KillWho who, int signo, + int code, + int value, pid_t main_pid, pid_t control_pid, sd_bus_error *error) { - int r = 0; bool killed = false; + int ret = 0, r; /* This is the common implementation for explicit user-requested killing of unit processes, shared by * various unit types. Do not confuse with unit_kill_context(), which is what we use when we want to * stop a service ourselves. */ + assert(u); + assert(who >= 0); + assert(who < _KILL_WHO_MAX); + assert(SIGNAL_VALID(signo)); + assert(IN_SET(code, SI_USER, SI_QUEUE)); + 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)); @@ -3867,71 +3895,85 @@ int unit_kill_common( return sd_bus_error_set_const(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill"); } - if (IN_SET(who, KILL_CONTROL, KILL_CONTROL_FAIL, KILL_ALL, KILL_ALL_FAIL)) - if (control_pid > 0) { - _cleanup_free_ char *comm = NULL; - (void) get_process_comm(control_pid, &comm); + if (control_pid > 0 && + IN_SET(who, KILL_CONTROL, KILL_CONTROL_FAIL, KILL_ALL, KILL_ALL_FAIL)) { + _cleanup_free_ char *comm = NULL; + (void) get_process_comm(control_pid, &comm); - if (kill(control_pid, signo) < 0) { - /* Report this failure both to the logs and to the client */ - sd_bus_error_set_errnof( - error, errno, - "Failed to send signal SIG%s to control process " PID_FMT " (%s): %m", - signal_to_string(signo), control_pid, strna(comm)); - r = log_unit_warning_errno( - u, errno, - "Failed to send signal SIG%s to control process " PID_FMT " (%s) on client request: %m", - signal_to_string(signo), control_pid, strna(comm)); - } else { - log_unit_info(u, "Sent signal SIG%s to control process " PID_FMT " (%s) on client request.", - signal_to_string(signo), control_pid, strna(comm)); - killed = true; - } + r = kill_or_sigqueue(control_pid, signo, code, value); + if (r < 0) { + ret = r; + + /* Report this failure both to the logs and to the client */ + sd_bus_error_set_errnof( + error, r, + "Failed to send signal SIG%s to control process " PID_FMT " (%s): %m", + signal_to_string(signo), control_pid, strna(comm)); + log_unit_warning_errno( + u, r, + "Failed to send signal SIG%s to control process " PID_FMT " (%s) on client request: %m", + signal_to_string(signo), control_pid, strna(comm)); + } else { + log_unit_info(u, "Sent signal SIG%s to control process " PID_FMT " (%s) on client request.", + signal_to_string(signo), control_pid, strna(comm)); + killed = true; } + } - if (IN_SET(who, KILL_MAIN, KILL_MAIN_FAIL, KILL_ALL, KILL_ALL_FAIL)) - if (main_pid > 0) { - _cleanup_free_ char *comm = NULL; - (void) get_process_comm(main_pid, &comm); + if (main_pid > 0 && + IN_SET(who, KILL_MAIN, KILL_MAIN_FAIL, KILL_ALL, KILL_ALL_FAIL)) { - if (kill(main_pid, signo) < 0) { - if (r == 0) - sd_bus_error_set_errnof( - error, errno, - "Failed to send signal SIG%s to main process " PID_FMT " (%s): %m", - signal_to_string(signo), main_pid, strna(comm)); + _cleanup_free_ char *comm = NULL; + (void) get_process_comm(main_pid, &comm); + + r = kill_or_sigqueue(main_pid, signo, code, value); + if (r < 0) { + if (ret == 0) { + ret = r; - r = log_unit_warning_errno( - u, errno, - "Failed to send signal SIG%s to main process " PID_FMT " (%s) on client request: %m", + sd_bus_error_set_errnof( + error, r, + "Failed to send signal SIG%s to main process " PID_FMT " (%s): %m", signal_to_string(signo), main_pid, strna(comm)); - } else { - log_unit_info(u, "Sent signal SIG%s to main process " PID_FMT " (%s) on client request.", - signal_to_string(signo), main_pid, strna(comm)); - killed = true; } + + log_unit_warning_errno( + u, r, + "Failed to send signal SIG%s to main process " PID_FMT " (%s) on client request: %m", + signal_to_string(signo), main_pid, strna(comm)); + + } else { + log_unit_info(u, "Sent signal SIG%s to main process " PID_FMT " (%s) on client request.", + signal_to_string(signo), main_pid, strna(comm)); + killed = true; } + } - if (IN_SET(who, KILL_ALL, KILL_ALL_FAIL) && u->cgroup_path) { + /* Note: if we shall enqueue rather than kill we won't do this via the cgroup mechanism, since it + * doesn't really make much sense (and given that enqueued values are a relatively expensive + * resource, and we shouldn't allow us to be subjects for such allocation sprees) */ + if (IN_SET(who, KILL_ALL, KILL_ALL_FAIL) && u->cgroup_path && code == SI_USER) { _cleanup_set_free_ Set *pid_set = NULL; - int q; /* Exclude the main/control pids from being killed via the cgroup */ pid_set = unit_pid_set(main_pid, control_pid); if (!pid_set) return log_oom(); - q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, 0, pid_set, kill_common_log, u); - if (q < 0) { - if (!IN_SET(q, -ESRCH, -ENOENT)) { - if (r == 0) + r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, 0, pid_set, kill_common_log, u); + if (r < 0) { + if (!IN_SET(r, -ESRCH, -ENOENT)) { + if (ret == 0) { + ret = r; + sd_bus_error_set_errnof( - error, q, + error, r, "Failed to send signal SIG%s to auxiliary processes: %m", signal_to_string(signo)); + } - r = log_unit_warning_errno( - u, q, + log_unit_warning_errno( + u, r, "Failed to send signal SIG%s to auxiliary processes on client request: %m", signal_to_string(signo)); } @@ -3940,10 +3982,10 @@ int unit_kill_common( } /* If the "fail" versions of the operation are requested, then complain if the set of processes we killed is empty */ - if (r == 0 && !killed && IN_SET(who, KILL_ALL_FAIL, KILL_CONTROL_FAIL, KILL_MAIN_FAIL)) + if (ret == 0 && !killed && IN_SET(who, KILL_ALL_FAIL, KILL_CONTROL_FAIL, KILL_MAIN_FAIL)) return sd_bus_error_set_const(error, BUS_ERROR_NO_SUCH_PROCESS, "No matching processes to kill"); - return r; + return ret; } int unit_following_set(Unit *u, Set **s) { diff --git a/src/core/unit.h b/src/core/unit.h index 58417ebd0e..3f8377fbf6 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -619,7 +619,7 @@ typedef struct UnitVTable { int (*stop)(Unit *u); int (*reload)(Unit *u); - int (*kill)(Unit *u, KillWho w, int signo, sd_bus_error *error); + int (*kill)(Unit *u, KillWho w, int signo, int code, int value, sd_bus_error *error); /* Clear out the various runtime/state/cache/logs/configuration data */ int (*clean)(Unit *u, ExecCleanMask m); @@ -889,8 +889,8 @@ int unit_start(Unit *u, ActivationDetails *details); int unit_stop(Unit *u); int unit_reload(Unit *u); -int unit_kill(Unit *u, KillWho w, int signo, sd_bus_error *error); -int unit_kill_common(Unit *u, KillWho who, int signo, pid_t main_pid, pid_t control_pid, sd_bus_error *error); +int unit_kill(Unit *u, KillWho w, int signo, int code, int value, sd_bus_error *error); +int unit_kill_common(Unit *u, KillWho who, int signo, int code, int value, pid_t main_pid, pid_t control_pid, sd_bus_error *error); void unit_notify_cgroup_oom(Unit *u, bool managed_oom); diff --git a/src/test/test-execute.c b/src/test/test-execute.c index f8c64b6042..f6d05afc1b 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -73,7 +73,7 @@ static void wait_for_service_finish(Manager *m, Unit *unit) { n = now(CLOCK_MONOTONIC); if (ts + timeout < n) { log_error("Test timeout when testing %s", unit->id); - r = unit_kill(unit, KILL_ALL, SIGKILL, NULL); + r = unit_kill(unit, KILL_ALL, SIGKILL, SI_USER, 0, NULL); if (r < 0) log_error_errno(r, "Failed to kill %s: %m", unit->id); exit(EXIT_FAILURE); |