]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sleep-config: minor cleanup for can_sleep_{state,disk}
authorMike Yuan <me@yhndnzj.com>
Wed, 27 Sep 2023 22:43:06 +0000 (06:43 +0800)
committerMike Yuan <me@yhndnzj.com>
Fri, 20 Oct 2023 15:22:28 +0000 (23:22 +0800)
* Rename to sleep_{state,mode}_supported
* Treat unreadable/unwriable sysfs files as error

src/shared/sleep-config.c
src/shared/sleep-config.h
src/test/test-sleep-config.c

index 764c29d2a94ec7e9b17175c0dc7419035456b3a4..736e38381fb020a2f7cf5e8c1ae1318b225a21bd 100644 (file)
@@ -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)
index 467502a7da6586704703b5ef610b80f1bcd1b34a..fc737bf94100158176aef57be00f8326ff0c2bc1 100644 (file)
@@ -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);
index 58d910d1d9d45da9cf19b0bb4b623b0b6df82d2c..c7aa0619b429c2522b0a6ff54d8408a1685fee56 100644 (file)
@@ -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);