mirror of
https://github.com/systemd/systemd.git
synced 2024-11-07 09:56:51 +03:00
shutdown: make kill timeout configurable (#7835)
By default systemd-shutdown will wait for 90s after SIGTERM was sent for all processes to exit. This is way too long and effectively defeats an emergency watchdog reboot via "reboot-force" actions. Instead now use DefaultTimeoutStopSec which is configurable.
This commit is contained in:
parent
0a7eed95dd
commit
e73c54b838
@ -89,7 +89,7 @@ static bool ignore_proc(pid_t pid, bool warn_rootfs) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static void wait_for_children(Set *pids, sigset_t *mask) {
|
||||
static void wait_for_children(Set *pids, sigset_t *mask, usec_t timeout) {
|
||||
usec_t until;
|
||||
|
||||
assert(mask);
|
||||
@ -97,7 +97,7 @@ static void wait_for_children(Set *pids, sigset_t *mask) {
|
||||
if (set_isempty(pids))
|
||||
return;
|
||||
|
||||
until = now(CLOCK_MONOTONIC) + DEFAULT_TIMEOUT_USEC;
|
||||
until = now(CLOCK_MONOTONIC) + timeout;
|
||||
for (;;) {
|
||||
struct timespec ts;
|
||||
int k;
|
||||
@ -221,7 +221,7 @@ static int killall(int sig, Set *pids, bool send_sighup) {
|
||||
return set_size(pids);
|
||||
}
|
||||
|
||||
void broadcast_signal(int sig, bool wait_for_exit, bool send_sighup) {
|
||||
void broadcast_signal(int sig, bool wait_for_exit, bool send_sighup, usec_t timeout) {
|
||||
sigset_t mask, oldmask;
|
||||
_cleanup_set_free_ Set *pids = NULL;
|
||||
|
||||
@ -241,7 +241,7 @@ void broadcast_signal(int sig, bool wait_for_exit, bool send_sighup) {
|
||||
log_warning_errno(errno, "kill(-1, SIGCONT) failed: %m");
|
||||
|
||||
if (wait_for_exit)
|
||||
wait_for_children(pids, &mask);
|
||||
wait_for_children(pids, &mask, timeout);
|
||||
|
||||
assert_se(sigprocmask(SIG_SETMASK, &oldmask, NULL) == 0);
|
||||
}
|
||||
|
@ -20,4 +20,6 @@
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
void broadcast_signal(int sig, bool wait_for_exit, bool send_sighup);
|
||||
#include "time-util.h"
|
||||
|
||||
void broadcast_signal(int sig, bool wait_for_exit, bool send_sighup, usec_t timeout);
|
||||
|
@ -1467,17 +1467,19 @@ static int become_shutdown(
|
||||
int retval) {
|
||||
|
||||
char log_level[DECIMAL_STR_MAX(int) + 1],
|
||||
exit_code[DECIMAL_STR_MAX(uint8_t) + 1];
|
||||
exit_code[DECIMAL_STR_MAX(uint8_t) + 1],
|
||||
timeout[DECIMAL_STR_MAX(usec_t) + 1];
|
||||
|
||||
const char* command_line[11] = {
|
||||
const char* command_line[13] = {
|
||||
SYSTEMD_SHUTDOWN_BINARY_PATH,
|
||||
shutdown_verb,
|
||||
"--timeout", timeout,
|
||||
"--log-level", log_level,
|
||||
"--log-target",
|
||||
};
|
||||
|
||||
_cleanup_strv_free_ char **env_block = NULL;
|
||||
size_t pos = 5;
|
||||
size_t pos = 7;
|
||||
int r;
|
||||
|
||||
assert(shutdown_verb);
|
||||
@ -1485,6 +1487,7 @@ static int become_shutdown(
|
||||
env_block = strv_copy(environ);
|
||||
|
||||
xsprintf(log_level, "%d", log_get_max_level());
|
||||
xsprintf(timeout, "%" PRI_USEC "us", arg_default_timeout_stop_usec);
|
||||
|
||||
switch (log_get_target()) {
|
||||
|
||||
@ -1640,7 +1643,7 @@ static void do_reexecute(
|
||||
if (switch_root_dir) {
|
||||
/* Kill all remaining processes from the initrd, but don't wait for them, so that we can handle the
|
||||
* SIGCHLD for them after deserializing. */
|
||||
broadcast_signal(SIGTERM, false, true);
|
||||
broadcast_signal(SIGTERM, false, true, arg_default_timeout_stop_usec);
|
||||
|
||||
/* And switch root with MS_MOVE, because we remove the old directory afterwards and detach it. */
|
||||
r = switch_root(switch_root_dir, "/mnt", true, MS_MOVE);
|
||||
|
@ -58,6 +58,7 @@
|
||||
|
||||
static char* arg_verb;
|
||||
static uint8_t arg_exit_code;
|
||||
static usec_t arg_timeout = DEFAULT_TIMEOUT_USEC;
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
enum {
|
||||
@ -66,6 +67,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_LOG_COLOR,
|
||||
ARG_LOG_LOCATION,
|
||||
ARG_EXIT_CODE,
|
||||
ARG_TIMEOUT,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
@ -74,6 +76,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "log-color", optional_argument, NULL, ARG_LOG_COLOR },
|
||||
{ "log-location", optional_argument, NULL, ARG_LOG_LOCATION },
|
||||
{ "exit-code", required_argument, NULL, ARG_EXIT_CODE },
|
||||
{ "timeout", required_argument, NULL, ARG_TIMEOUT },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -129,6 +132,13 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
break;
|
||||
|
||||
case ARG_TIMEOUT:
|
||||
r = parse_sec(optarg, &arg_timeout);
|
||||
if (r < 0)
|
||||
log_error("Failed to parse shutdown timeout %s, ignoring", optarg);
|
||||
|
||||
break;
|
||||
|
||||
case '\001':
|
||||
if (!arg_verb)
|
||||
arg_verb = optarg;
|
||||
@ -327,10 +337,10 @@ int main(int argc, char *argv[]) {
|
||||
disable_core_dumps();
|
||||
|
||||
log_info("Sending SIGTERM to remaining processes...");
|
||||
broadcast_signal(SIGTERM, true, true);
|
||||
broadcast_signal(SIGTERM, true, true, arg_timeout);
|
||||
|
||||
log_info("Sending SIGKILL to remaining processes...");
|
||||
broadcast_signal(SIGKILL, true, false);
|
||||
broadcast_signal(SIGKILL, true, false, arg_timeout);
|
||||
|
||||
need_umount = !in_container;
|
||||
need_swapoff = !in_container;
|
||||
|
Loading…
Reference in New Issue
Block a user