commit 0000000000000000000000000000000000000000 Author: Zbigniew Jędrzejewski-Szmek Date: Tue Jan 26 20:23:12 2021 +0100 core: decrease unit start/stop timeouts to 10s in the user manager The timeouts for the user manager were "inherited" from the system manager. Longer timeouts make sense for system units (databases, potentially remote transactions, flushing of gigabytes of data to disk, etc.). But for user units, they make little sense. Users are *extremely* annoyed by latency, and expect their machine to react fairly quickly to any command. It makes no sense to give background user programs minutes to terminate. Thus, if we are waiting for the full 90s for a user unit to terminate, this is almost certainly due to a bug and not a legitimate need. This commit separates the user manager timeouts and sets them to 10s, with TimeoutStopSec=25s for the user manager. I think even 5s would be reasonable, since we should expect user units to terminate withing a second or two at most, but a slightly longer timeout is reasonable in case of disk hiccups or some other unexpected latency. It is possible that user run some slow system-style services under the user manager. This was never a good idea, and they'll just have to move them to be proper system services (or adjust the timeouts). Motivated by https://pagure.io/fedora-workstation/issue/163. Decreasing the timeouts should decrease user annoyance and the chances of the user hitting the power button when the shut down seems stuck. (cherry picked from commit c16c7b7bb54710f21499b39fd4e866ecf0e94110) Conflicts: src/core/manager.c src/core/manager.h diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml index ac21c31d9a..2c16b576a2 100644 --- a/man/systemd-system.conf.xml +++ b/man/systemd-system.conf.xml @@ -349,24 +349,19 @@ DefaultTimeoutAbortSec= DefaultRestartSec= - Configures the default timeouts for starting, - stopping and aborting of units, as well as the default time to sleep - between automatic restarts of units, as configured per-unit in - TimeoutStartSec=, - TimeoutStopSec=, - TimeoutAbortSec= and - RestartSec= (for services, see + Configures the default timeouts for starting, stopping and aborting of units, as well + as the default time to sleep between automatic restarts of units, as configured per-unit in + TimeoutStartSec=, TimeoutStopSec=, + TimeoutAbortSec= and RestartSec= (for services, see systemd.service5 - for details on the per-unit settings). Disabled by default, when - service with Type=oneshot is used. - For non-service units, - DefaultTimeoutStartSec= sets the default - TimeoutSec= - value. DefaultTimeoutStartSec= and - DefaultTimeoutStopSec= default to - 90s. DefaultTimeoutAbortSec= is not set by default - so that all units fall back to TimeoutStopSec=. - DefaultRestartSec= defaults to + for details on the per-unit settings). For non-service units, + DefaultTimeoutStartSec= sets the default TimeoutSec= value. + + + DefaultTimeoutStartSec= and DefaultTimeoutStopSec= + default to 90s in the system manager and 10s in the user manager. + DefaultTimeoutAbortSec= is not set by default so that all units fall back to + TimeoutStopSec=. DefaultRestartSec= defaults to 100ms. diff --git a/man/systemd.service.xml b/man/systemd.service.xml index 8d8dd77689..4963e8016e 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -596,11 +596,12 @@ TimeoutStartSec= - Configures the time to wait for start-up. If a daemon service does not signal start-up - completion within the configured time, the service will be considered failed and will be shut down again. The - precise action depends on the TimeoutStartFailureMode= option. Takes a unit-less value in - seconds, or a time span value such as "5min 20s". Pass infinity to disable the timeout logic. - Defaults to DefaultTimeoutStartSec= from the manager configuration file, except when + Configures the time to wait for start-up. If a daemon service does not signal + start-up completion within the configured time, the service will be considered failed and will be + shut down again. The precise action depends on the TimeoutStartFailureMode= + option. Takes a unit-less value in seconds, or a time span value such as "5min 20s". Pass + infinity to disable the timeout logic. Defaults to + DefaultTimeoutStartSec= set in the manager, except when Type=oneshot is used, in which case the timeout is disabled by default (see systemd-system.conf5). diff --git a/src/basic/def.h b/src/basic/def.h index 2b4de29021..e669c1d173 100644 --- a/src/basic/def.h +++ b/src/basic/def.h @@ -1,8 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#define DEFAULT_TIMEOUT_USEC (90*USEC_PER_SEC) -#define DEFAULT_RESTART_USEC (100*USEC_PER_MSEC) +#define DEFAULT_TIMEOUT_USEC (90*USEC_PER_SEC) /* Many different things, but also system unit start/stop */ +#define DEFAULT_USER_TIMEOUT_USEC (10*USEC_PER_SEC) /* User unit start/stop */ #define DEFAULT_CONFIRM_USEC (30*USEC_PER_SEC) /* We use an extra-long timeout for the reload. This is because a reload or reexec means generators are rerun diff --git a/src/core/main.c b/src/core/main.c index a3fdd1dfe1..c2a2edc88e 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -2402,10 +2402,10 @@ static void reset_arguments(void) { arg_service_watchdogs = true; arg_default_std_output = EXEC_OUTPUT_JOURNAL; arg_default_std_error = EXEC_OUTPUT_INHERIT; - arg_default_restart_usec = DEFAULT_RESTART_USEC; - arg_default_timeout_start_usec = DEFAULT_TIMEOUT_USEC; - arg_default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC; - arg_default_timeout_abort_usec = DEFAULT_TIMEOUT_USEC; + arg_default_timeout_start_usec = manager_default_timeout(arg_system); + arg_default_timeout_stop_usec = manager_default_timeout(arg_system); + arg_default_restart_usec = manager_default_timeout(arg_system) * 10 / 9; + arg_default_timeout_abort_usec = manager_default_timeout(arg_system); arg_default_timeout_abort_set = false; arg_default_device_timeout_usec = DEFAULT_TIMEOUT_USEC; arg_default_start_limit_interval = DEFAULT_START_LIMIT_INTERVAL; diff --git a/src/core/manager.c b/src/core/manager.c index a59afafb58..e01721686d 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -830,9 +830,9 @@ int manager_new(LookupScope scope, ManagerTestRunFlags test_run_flags, Manager * .default_memory_accounting = MEMORY_ACCOUNTING_DEFAULT, .default_tasks_accounting = true, .default_tasks_max = TASKS_MAX_UNSET, - .default_timeout_start_usec = DEFAULT_TIMEOUT_USEC, - .default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC, - .default_restart_usec = DEFAULT_RESTART_USEC, + .default_timeout_start_usec = manager_default_timeout(scope == LOOKUP_SCOPE_SYSTEM), + .default_timeout_stop_usec = manager_default_timeout(scope == LOOKUP_SCOPE_SYSTEM), + .default_restart_usec = manager_default_timeout(scope == LOOKUP_SCOPE_SYSTEM) * 10 / 9, .default_device_timeout_usec = DEFAULT_TIMEOUT_USEC, .original_log_level = -1, diff --git a/src/core/manager.h b/src/core/manager.h index 75c16d6e26..2844853fe4 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -482,6 +482,10 @@ static inline usec_t manager_default_timeout_abort_usec(Manager *m) { #define MANAGER_IS_TEST_RUN(m) ((m)->test_run_flags != 0) +static inline usec_t manager_default_timeout(bool is_system) { + return is_system ? DEFAULT_TIMEOUT_USEC : DEFAULT_USER_TIMEOUT_USEC; +} + int manager_new(LookupScope scope, ManagerTestRunFlags test_run_flags, Manager **m); Manager* manager_free(Manager *m); DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free); diff --git a/units/user@.service.in b/units/user@.service.in index 1660de0326..e79316618a 100644 --- a/units/user@.service.in +++ b/units/user@.service.in @@ -23,6 +23,6 @@ Slice=user-%i.slice KillMode=mixed Delegate=pids memory cpu TasksMax=infinity -TimeoutStopSec=120s +TimeoutStopSec=25s KeyringMode=inherit OOMScoreAdjust=100