Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

systemctl: Implement --wait for kill command #32591

Merged
merged 1 commit into from
May 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,9 @@ CHANGES WITH 256-rc1:
that configures what to do after the system manager (PID 1) crashes.
This can also be configured through CrashAction= in systemd.conf.

* "systemctl kill" now supports --wait which will make the command wait
until the signalled services terminate.

Journal:

* systemd-journald can now forward journal entries to a socket
Expand Down
18 changes: 10 additions & 8 deletions man/systemctl.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2377,14 +2377,16 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<term><option>--wait</option></term>

<listitem>
<para>Synchronously wait for started units to terminate again.
This option may not be combined with <option>--no-block</option>.
Note that this will wait forever if any given unit never terminates
(by itself or by getting stopped explicitly); particularly services
which use <literal>RemainAfterExit=yes</literal>.</para>

<para>When used with <command>is-system-running</command>, wait
until the boot process is completed before returning.</para>
<para>When used with <command>start</command> or <command>restart</command>, synchronously wait for
started units to terminate again. This option may not be combined with <option>--no-block</option>.
Note that this will wait forever if any given unit never terminates (by itself or by getting
stopped explicitly); particularly services which use <literal>RemainAfterExit=yes</literal>.</para>

<para>When used with <command>is-system-running</command>, wait until the boot process is completed
before returning.</para>

<para>When used with <command>kill</command>, wait until the signalled units terminate. Note that
this will wait forever if any given unit never terminates.</para>

<xi:include href="version-info.xml" xpointer="v232"/>
</listitem>
Expand Down
27 changes: 24 additions & 3 deletions src/systemctl/systemctl-kill.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

#include "bus-error.h"
#include "bus-locator.h"
#include "bus-wait-for-units.h"
#include "systemctl-kill.h"
#include "systemctl-util.h"
#include "systemctl.h"

int verb_kill(int argc, char *argv[], void *userdata) {
_cleanup_(bus_wait_for_units_freep) BusWaitForUnits *w = NULL;
_cleanup_strv_free_ char **names = NULL;
const char *kill_whom;
sd_bus *bus;
Expand All @@ -16,6 +18,12 @@ int verb_kill(int argc, char *argv[], void *userdata) {
if (r < 0)
return r;

if (arg_wait) {
r = bus_wait_for_units_new(bus, &w);
if (r < 0)
return log_error_errno(r, "Failed to allocate unit watch context: %m");
}

polkit_agent_open_maybe();

kill_whom = arg_kill_whom ?: "all";
Expand Down Expand Up @@ -48,11 +56,24 @@ int verb_kill(int argc, char *argv[], void *userdata) {
NULL,
"ssi", *name, kill_whom, arg_signal);
if (q < 0) {
log_error_errno(q, "Failed to kill unit %s: %s", *name, bus_error_message(&error, q));
if (r == 0)
r = q;
RET_GATHER(r, log_error_errno(q, "Failed to kill unit %s: %s", *name, bus_error_message(&error, q)));
continue;
}

if (w) {
q = bus_wait_for_units_add_unit(w, *name, BUS_WAIT_FOR_INACTIVE|BUS_WAIT_NO_JOB, NULL, NULL);
if (q < 0)
RET_GATHER(r, log_error_errno(q, "Failed to watch unit %s: %m", *name));
}
}

if (w) {
q = bus_wait_for_units_run(w);
if (q < 0)
return log_error_errno(q, "Failed to wait for units: %m");
if (q == BUS_WAIT_FAILURE)
RET_GATHER(r, -EIO);
}

return r;
}
1 change: 1 addition & 0 deletions src/systemctl/systemctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ static int systemctl_help(void) {
" --no-warn Suppress several warnings shown by default\n"
" --wait For (re)start, wait until service stopped again\n"
" For is-system-running, wait until startup is completed\n"
" For kill, wait until service stopped\n"
" --no-block Do not wait until operation finished\n"
" --no-wall Don't send wall message before halt/power-off/reboot\n"
" --message=MESSAGE Specify human readable reason for system shutdown\n"
Expand Down
2 changes: 1 addition & 1 deletion test/units/testsuite-26.sh
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ systemctl reload -T "$UNIT_NAME"
systemctl restart -T "$UNIT_NAME"
systemctl try-restart --show-transaction "$UNIT_NAME"
systemctl try-reload-or-restart --show-transaction "$UNIT_NAME"
systemctl kill "$UNIT_NAME"
timeout 10 systemctl kill --wait "$UNIT_NAME"
(! systemctl is-active "$UNIT_NAME")
systemctl restart "$UNIT_NAME"
systemctl is-active "$UNIT_NAME"
Expand Down