From: Marc Reisner Date: Sun, 4 Aug 2024 23:01:34 +0000 (-0500) Subject: sleep: add HibernateOnACPower= option (#33846) X-Git-Tag: v257-rc1~739 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2d00f4c306b4a5c3edef44e17c9efcf10cfb5d9b;p=thirdparty%2Fsystemd.git sleep: add HibernateOnACPower= option (#33846) * Add HibernateOnACPower= systemd-sleep configuration option --- diff --git a/man/systemd-sleep.conf.xml b/man/systemd-sleep.conf.xml index 623e614b6ab..c02b44f3de6 100644 --- a/man/systemd-sleep.conf.xml +++ b/man/systemd-sleep.conf.xml @@ -227,6 +227,23 @@ + + HibernateOnACPower= + + + Whether to allow hibernation when the system has AC power. Only used by + systemd-suspend-then-hibernate.service8 + when HibernateDelaySec= is set. + + If this option is disabled, the countdown of HibernateDelaySec= starts only + after AC power is disconnected, keeping the system in the suspend state otherwise. + + This option is only effective on systems with a battery. + + + + + SuspendEstimationSec= diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c index 3d4d3317109..947ef582bd6 100644 --- a/src/shared/sleep-config.c +++ b/src/shared/sleep-config.c @@ -124,7 +124,8 @@ int parse_sleep_config(SleepConfig **ret) { return log_oom(); *sc = (SleepConfig) { - .hibernate_delay_usec = USEC_INFINITY, + .hibernate_delay_usec = USEC_INFINITY, + .hibernate_on_ac_power = true, }; const ConfigTableItem items[] = { @@ -145,6 +146,7 @@ int parse_sleep_config(SleepConfig **ret) { { "Sleep", "MemorySleepMode", config_parse_sleep_mode, 0, &sc->mem_modes }, { "Sleep", "HibernateDelaySec", config_parse_sec, 0, &sc->hibernate_delay_usec }, + { "Sleep", "HibernateOnACPower", config_parse_bool, 0, &sc->hibernate_on_ac_power }, { "Sleep", "SuspendEstimationSec", config_parse_sec, 0, &sc->suspend_estimation_usec }, {} }; diff --git a/src/shared/sleep-config.h b/src/shared/sleep-config.h index b59bce8fc4e..b05efaea95e 100644 --- a/src/shared/sleep-config.h +++ b/src/shared/sleep-config.h @@ -33,6 +33,7 @@ typedef struct SleepConfig { char **mem_modes; /* /sys/power/mem_sleep */ usec_t hibernate_delay_usec; + bool hibernate_on_ac_power; usec_t suspend_estimation_usec; } SleepConfig; diff --git a/src/sleep/sleep.c b/src/sleep/sleep.c index 15ef7ae9131..3f113fff744 100644 --- a/src/sleep/sleep.c +++ b/src/sleep/sleep.c @@ -390,7 +390,15 @@ static int custom_timer_suspend(const SleepConfig *sleep_config) { } } - /* Do not suspend more than HibernateDelaySec= */ + /* Do not suspend more than HibernateDelaySec= unless HibernateOnACPower=no and currently on AC power */ + if (!sleep_config->hibernate_on_ac_power) { + /* Do not allow "decay" to suspend if the system has no battery. */ + if (hashmap_isempty(last_capacity)) + log_once(LOG_WARNING, "HibernateOnACPower=no was ignored because the system does not have a battery."); + else if (on_ac_power() > 0) + hibernate_timestamp = usec_add(now(CLOCK_BOOTTIME), sleep_config->hibernate_delay_usec); + } + usec_t before_timestamp = now(CLOCK_BOOTTIME); suspend_interval = MIN(suspend_interval, usec_sub_unsigned(hibernate_timestamp, before_timestamp)); if (suspend_interval <= 0) diff --git a/src/sleep/sleep.conf b/src/sleep/sleep.conf index 98430348a7b..153f747342d 100644 --- a/src/sleep/sleep.conf +++ b/src/sleep/sleep.conf @@ -25,4 +25,5 @@ #HibernateMode=platform shutdown #MemorySleepMode= #HibernateDelaySec= +#HibernateOnACPower=yes #SuspendEstimationSec=60min