From: Mike Yuan Date: Wed, 27 Sep 2023 22:43:06 +0000 (+0800) Subject: sleep-config: minor cleanup for can_sleep_{state,disk} X-Git-Tag: v255-rc1~170^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=23577f44623c108e4958d435cf95cf93199503ba;p=thirdparty%2Fsystemd.git sleep-config: minor cleanup for can_sleep_{state,disk} * Rename to sleep_{state,mode}_supported * Treat unreadable/unwriable sysfs files as error --- diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c index 764c29d2a94..736e38381fb 100644 --- a/src/shared/sleep-config.c +++ b/src/shared/sleep-config.c @@ -22,6 +22,8 @@ #include "strv.h" #include "time-util.h" +#define DEFAULT_SUSPEND_ESTIMATION_USEC (1 * USEC_PER_HOUR) + static const char* const sleep_operation_table[_SLEEP_OPERATION_MAX] = { [SLEEP_SUSPEND] = "suspend", [SLEEP_HIBERNATE] = "hibernate", @@ -110,59 +112,57 @@ int parse_sleep_config(SleepConfig **ret) { return 0; } -int can_sleep_state(char **requested_types) { - _cleanup_free_ char *text = NULL; +int sleep_state_supported(char **states) { + _cleanup_free_ char *supported_sysfs = NULL; + const char *found; int r; - if (strv_isempty(requested_types)) - return true; + if (strv_isempty(states)) + return log_debug_errno(SYNTHETIC_ERRNO(ENOMSG), "No sleep state configured."); - /* If /sys is read-only we cannot sleep */ - if (access("/sys/power/state", W_OK) < 0) { - log_debug_errno(errno, "/sys/power/state is not writable, cannot sleep: %m"); - return false; - } + if (access("/sys/power/state", W_OK) < 0) + return log_debug_errno(errno, "/sys/power/state is not writable: %m"); - r = read_one_line_file("/sys/power/state", &text); - if (r < 0) { - log_debug_errno(r, "Failed to read /sys/power/state, cannot sleep: %m"); - return false; - } + r = read_one_line_file("/sys/power/state", &supported_sysfs); + if (r < 0) + return log_debug_errno(r, "Failed to read /sys/power/state: %m"); - const char *found; - r = string_contains_word_strv(text, NULL, requested_types, &found); + r = string_contains_word_strv(supported_sysfs, NULL, states, &found); if (r < 0) return log_debug_errno(r, "Failed to parse /sys/power/state: %m"); - if (r > 0) - log_debug("Sleep mode \"%s\" is supported by the kernel.", found); - else if (DEBUG_LOGGING) { - _cleanup_free_ char *t = strv_join(requested_types, "/"); - log_debug("Sleep mode %s not supported by the kernel, sorry.", strnull(t)); + if (r > 0) { + log_debug("Sleep state '%s' is supported by kernel.", found); + return true; } - return r; + + if (DEBUG_LOGGING) { + _cleanup_free_ char *joined = strv_join(states, " "); + log_debug("None of the configured sleep states are supported by kernel: %s", strnull(joined)); + } + return false; } -int can_sleep_disk(char **types) { - _cleanup_free_ char *text = NULL; +int sleep_mode_supported(char **modes) { + _cleanup_free_ char *supported_sysfs = NULL; int r; - if (strv_isempty(types)) + /* Unlike state, kernel has its own default choice if not configured */ + if (strv_isempty(modes)) { + log_debug("No sleep mode configured, using kernel default."); return true; - - /* If /sys is read-only we cannot sleep */ - if (access("/sys/power/disk", W_OK) < 0) { - log_debug_errno(errno, "/sys/power/disk is not writable: %m"); - return false; } - r = read_one_line_file("/sys/power/disk", &text); - if (r < 0) { - log_debug_errno(r, "Couldn't read /sys/power/disk: %m"); - return false; - } + if (access("/sys/power/disk", W_OK) < 0) + return log_debug_errno(errno, "/sys/power/disk is not writable: %m"); - for (const char *p = text;;) { + r = read_one_line_file("/sys/power/disk", &supported_sysfs); + if (r < 0) + return log_debug_errno(r, "Failed to read /sys/power/disk: %m"); + + for (const char *p = supported_sysfs;;) { _cleanup_free_ char *word = NULL; + char *mode; + size_t l; r = extract_first_word(&p, &word, NULL, 0); if (r < 0) @@ -170,22 +170,23 @@ int can_sleep_disk(char **types) { if (r == 0) break; - char *s = word; - size_t l = strlen(s); - if (s[0] == '[' && s[l-1] == ']') { - s[l-1] = '\0'; - s++; + mode = word; + l = strlen(word); + + if (mode[0] == '[' && mode[l - 1] == ']') { + mode[l - 1] = '\0'; + mode++; } - if (strv_contains(types, s)) { - log_debug("Disk sleep mode \"%s\" is supported by the kernel.", s); + if (strv_contains(modes, mode)) { + log_debug("Disk sleep mode '%s' is supported by kernel.", mode); return true; } } if (DEBUG_LOGGING) { - _cleanup_free_ char *t = strv_join(types, "/"); - log_debug("Disk sleep mode %s not supported by the kernel, sorry.", strnull(t)); + _cleanup_free_ char *joined = strv_join(modes, " "); + log_debug("None of the configured hibernation power modes are supported by kernel: %s", strnull(joined)); } return false; } @@ -235,8 +236,8 @@ static int can_sleep_internal( if (operation == SLEEP_SUSPEND_THEN_HIBERNATE) return can_s2h(sleep_config); - if (can_sleep_state(sleep_config->states[operation]) <= 0 || - can_sleep_disk(sleep_config->modes[operation]) <= 0) + if (sleep_state_supported(sleep_config->states[operation]) <= 0 || + sleep_mode_supported(sleep_config->modes[operation]) <= 0) return false; if (operation == SLEEP_SUSPEND) diff --git a/src/shared/sleep-config.h b/src/shared/sleep-config.h index 467502a7da6..fc737bf9410 100644 --- a/src/shared/sleep-config.h +++ b/src/shared/sleep-config.h @@ -3,8 +3,6 @@ #include "time-util.h" -#define DEFAULT_SUSPEND_ESTIMATION_USEC (1 * USEC_PER_HOUR) - typedef enum SleepOperation { SLEEP_SUSPEND, SLEEP_HIBERNATE, @@ -38,5 +36,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(SleepConfig*, sleep_config_free); int parse_sleep_config(SleepConfig **sleep_config); int can_sleep(SleepOperation operation); -int can_sleep_disk(char **types); -int can_sleep_state(char **types); + +/* Only for test-sleep-config */ +int sleep_state_supported(char **states); +int sleep_mode_supported(char **modes); diff --git a/src/test/test-sleep-config.c b/src/test/test-sleep-config.c index 58d910d1d9d..c7aa0619b42 100644 --- a/src/test/test-sleep-config.c +++ b/src/test/test-sleep-config.c @@ -34,7 +34,7 @@ TEST(parse_sleep_config) { log_debug(" states: %s", hys); } -TEST(sleep) { +TEST(sleep_supported) { _cleanup_strv_free_ char **standby = strv_new("standby"), **mem = strv_new("mem"), @@ -49,14 +49,14 @@ TEST(sleep) { printf("Secure boot: %sd\n", enable_disable(is_efi_secure_boot())); log_info("/= individual sleep modes =/"); - log_info("Standby configured: %s", yes_no(can_sleep_state(standby) > 0)); - log_info("Suspend configured: %s", yes_no(can_sleep_state(mem) > 0)); - log_info("Hibernate configured: %s", yes_no(can_sleep_state(disk) > 0)); - log_info("Hibernate+Suspend (Hybrid-Sleep) configured: %s", yes_no(can_sleep_disk(suspend) > 0)); - log_info("Hibernate+Reboot configured: %s", yes_no(can_sleep_disk(reboot) > 0)); - log_info("Hibernate+Platform configured: %s", yes_no(can_sleep_disk(platform) > 0)); - log_info("Hibernate+Shutdown configured: %s", yes_no(can_sleep_disk(shutdown) > 0)); - log_info("Freeze configured: %s", yes_no(can_sleep_state(freeze) > 0)); + log_info("Standby configured: %s", yes_no(sleep_state_supported(standby) > 0)); + log_info("Suspend configured: %s", yes_no(sleep_state_supported(mem) > 0)); + log_info("Hibernate configured: %s", yes_no(sleep_state_supported(disk) > 0)); + log_info("Hibernate+Suspend (Hybrid-Sleep) configured: %s", yes_no(sleep_mode_supported(suspend) > 0)); + log_info("Hibernate+Reboot configured: %s", yes_no(sleep_mode_supported(reboot) > 0)); + log_info("Hibernate+Platform configured: %s", yes_no(sleep_mode_supported(platform) > 0)); + log_info("Hibernate+Shutdown configured: %s", yes_no(sleep_mode_supported(shutdown) > 0)); + log_info("Freeze configured: %s", yes_no(sleep_state_supported(freeze) > 0)); log_info("/= high-level sleep verbs =/"); r = can_sleep(SLEEP_SUSPEND);