From 52133271a7b3d76bed6d957f75371030193f5282 Mon Sep 17 00:00:00 2001 From: Zach Smith Date: Fri, 6 Dec 2019 16:37:22 -0800 Subject: [PATCH 1/4] systemd-sleep: always attempt hibernation if configured When calculation of swap file offset is unsupported, rely on the /sys/power/resume & /sys/power/resume_offset values if configured rather than requiring a matching swap entry to be identified. Refactor to use dev_t for comparison of resume= device instead of string. --- src/shared/sleep-config.c | 117 +++++++++++++++++++++++++++----------- src/shared/sleep-config.h | 4 +- src/sleep/sleep.c | 15 ++--- 3 files changed, 94 insertions(+), 42 deletions(-) diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c index 754a63c2d24..f92924bf737 100644 --- a/src/shared/sleep-config.c +++ b/src/shared/sleep-config.c @@ -15,6 +15,7 @@ #include #include "alloc-util.h" +#include "blockdev-util.h" #include "btrfs-util.h" #include "conf-parser.h" #include "def.h" @@ -180,13 +181,11 @@ HibernateLocation* hibernate_location_free(HibernateLocation *hl) { return NULL; swap_entry_free(hl->swap); - free(hl->resume); return mfree(hl); } -static int swap_device_to_major_minor(const SwapEntry *swap, char **ret) { - _cleanup_free_ char *major_minor = NULL; +static int swap_device_to_device_id(const SwapEntry *swap, dev_t *ret_dev) { _cleanup_close_ int fd = -1; struct stat sb; dev_t swap_dev; @@ -204,15 +203,25 @@ static int swap_device_to_major_minor(const SwapEntry *swap, char **ret) { if (r < 0) return log_debug_errno(errno, "Unable to stat %s: %m", swap->device); - swap_dev = streq(swap->type, "partition") ? sb.st_rdev : sb.st_dev; - if (asprintf(&major_minor, "%u:%u", major(swap_dev), minor(swap_dev)) < 0) - return log_oom(); + if (streq(swap->type, "partition")) { + if(!S_ISBLK(sb.st_mode)) + return -ENOTBLK; + swap_dev = sb.st_rdev; + } else { + r = get_block_device(swap->device, &swap_dev); + if (r < 0) + return r; + } - *ret = TAKE_PTR(major_minor); + *ret_dev = swap_dev; return 0; } +/* + * Attempt to calculate the swap file offset on supported filesystems. On unsuported + * filesystems, a debug message is logged and the ret_offset is set to 0. + */ static int calculate_swap_file_offset(const SwapEntry *swap, uint64_t *ret_offset) { _cleanup_close_ int fd = -1; _cleanup_free_ struct fiemap *fiemap = NULL; @@ -248,15 +257,20 @@ static int calculate_swap_file_offset(const SwapEntry *swap, uint64_t *ret_offse return 0; } -static int read_resume_files(char **ret_resume, uint64_t *ret_resume_offset) { - _cleanup_free_ char *resume = NULL, *resume_offset_str = NULL; +static int read_resume_files(dev_t *ret_resume, uint64_t *ret_resume_offset) { + _cleanup_free_ char *resume_str = NULL, *resume_offset_str = NULL; + dev_t resume; uint64_t resume_offset = 0; int r; - r = read_one_line_file("/sys/power/resume", &resume); + r = read_one_line_file("/sys/power/resume", &resume_str); if (r < 0) return log_debug_errno(r, "Error reading /sys/power/resume: %m"); + r = parse_dev(resume_str, &resume); + if (r < 0) + return log_debug_errno(r, "Error parsing /sys/power/resume device: %s: %m", resume_str); + r = read_one_line_file("/sys/power/resume_offset", &resume_offset_str); if (r == -ENOENT) log_debug("Kernel does not support resume_offset; swap file offset detection will be skipped."); @@ -268,24 +282,29 @@ static int read_resume_files(char **ret_resume, uint64_t *ret_resume_offset) { return log_error_errno(r, "Failed to parse value in /sys/power/resume_offset \"%s\": %m", resume_offset_str); } - if (resume_offset > 0 && streq(resume, "0:0")) { + if (resume_offset > 0 && resume == 0) { log_debug("Found offset in /sys/power/resume_offset: %" PRIu64 "; no device id found in /sys/power/resume; ignoring resume_offset", resume_offset); resume_offset = 0; } - *ret_resume = TAKE_PTR(resume); + *ret_resume = resume; *ret_resume_offset = resume_offset; return 0; } -static bool location_is_resume_device(const HibernateLocation *location, const char *sys_resume, const uint64_t sys_offset) { - assert(location); - assert(location->resume); - assert(sys_resume); +/* + * Determine if the HibernateLocation matches the resume= (device) and resume_offset= (file). + */ +static bool location_is_resume_device(const HibernateLocation *location, dev_t sys_resume, uint64_t sys_offset) { + if (!location) + return false; - return streq(sys_resume, location->resume) && sys_offset == location->resume_offset; + if (sys_resume > 0 && sys_resume == location->devno && sys_offset == location->offset) + return true; + + return false; } /* @@ -293,14 +312,18 @@ static bool location_is_resume_device(const HibernateLocation *location, const c * /sys/power/resume_offset. * * Returns: - * 1 - HibernateLocation matches values found in /sys/power/resume & /sys/power/resume_offset - * 0 - HibernateLocation is highest priority swap with most remaining space; no valid values exist in /sys/power/resume & /sys/power/resume_offset - * negative value in the case of error + * 1 - Values are set in /sys/power/resume and /sys/power/resume_offset. + * ret_hibernate_location will represent matching /proc/swap entry if identified or NULL if not. + * + * 0 - No values are set in /sys/power/resume and /sys/power/resume_offset. + ret_hibernate_location will represent the highest priority swap with most remaining space discovered in /proc/swaps. + * + * Negative value in the case of error. */ int find_hibernate_location(HibernateLocation **ret_hibernate_location) { _cleanup_fclose_ FILE *f = NULL; _cleanup_(hibernate_location_freep) HibernateLocation *hibernate_location = NULL; - _cleanup_free_ char *sys_resume = NULL; + dev_t sys_resume; uint64_t sys_offset = 0; unsigned i; int r; @@ -350,6 +373,10 @@ int find_hibernate_location(HibernateLocation **ret_hibernate_location) { r = calculate_swap_file_offset(swap, &swap_offset); if (r < 0) return r; + + /* if the offset was not calculated, continue without considering the swap file */ + if (swap_offset == 0) + continue; } else if (streq(swap->type, "partition")) { const char *fn; @@ -368,8 +395,8 @@ int find_hibernate_location(HibernateLocation **ret_hibernate_location) { || ((swap->priority == hibernate_location->swap->priority) && (swap->size - swap->used) > (hibernate_location->swap->size - hibernate_location->swap->used))) { - _cleanup_free_ char *swap_device_id = NULL; - r = swap_device_to_major_minor(swap, &swap_device_id); + dev_t swap_device; + r = swap_device_to_device_id(swap, &swap_device); if (r < 0) return r; @@ -379,8 +406,8 @@ int find_hibernate_location(HibernateLocation **ret_hibernate_location) { return log_oom(); *hibernate_location = (HibernateLocation) { - .resume = TAKE_PTR(swap_device_id), - .resume_offset = swap_offset, + .devno = swap_device, + .offset = swap_offset, .swap = TAKE_PTR(swap), }; @@ -390,19 +417,31 @@ int find_hibernate_location(HibernateLocation **ret_hibernate_location) { } } + bool resume_match = location_is_resume_device(hibernate_location, sys_resume, sys_offset); + + /* resume= is set, but a matching /proc/swaps entry was not found */ + if (!resume_match && sys_resume != 0) { + log_debug("/sys/power/resume appears to be configured but a matching swap in /proc/swaps could not be identified; hibernation may fail"); + *ret_hibernate_location = NULL; + + return 1; + } + if (!hibernate_location) - return log_debug_errno(SYNTHETIC_ERRNO(ENOSYS), "No swap partitions or files were found"); + return log_debug_errno(SYNTHETIC_ERRNO(ENOSYS), "No swap partitions or files suitable for hibernation were found in /proc/swaps"); - if (!streq(sys_resume, "0:0") && !location_is_resume_device(hibernate_location, sys_resume, sys_offset)) - return log_warning_errno(SYNTHETIC_ERRNO(ENOSYS), "/sys/power/resume and /sys/power/resume_offset has no matching entry in /proc/swaps; Hibernation will fail: resume=%s, resume_offset=%" PRIu64, - sys_resume, sys_offset); - - log_debug("Hibernation will attempt to use swap entry with path: %s, device: %s, offset: %" PRIu64 ", priority: %i", - hibernate_location->swap->device, hibernate_location->resume, hibernate_location->resume_offset, hibernate_location->swap->priority); + if (resume_match) + log_debug("Hibernation will attempt to use swap entry with path: %s, device: %u:%u, offset: %" PRIu64 ", priority: %i", + hibernate_location->swap->device, major(hibernate_location->devno), minor(hibernate_location->devno), + hibernate_location->offset, hibernate_location->swap->priority); + else + log_debug("/sys/power/resume and /sys/power/resume_offset are not configured; attempting to hibernate with path: %s, device: %u:%u, offset: %" PRIu64 ", priority: %i", + hibernate_location->swap->device, major(hibernate_location->devno), minor(hibernate_location->devno), + hibernate_location->offset, hibernate_location->swap->priority); *ret_hibernate_location = TAKE_PTR(hibernate_location); - if (location_is_resume_device(*ret_hibernate_location, sys_resume, sys_offset)) + if (resume_match) return 1; return 0; @@ -421,6 +460,18 @@ static bool enough_swap_for_hibernation(void) { if (r < 0) return false; + /* If /sys/power/{resume,resume_offset} is configured but a matching entry + * could not be identified in /proc/swaps, user is likely using Btrfs with a swapfile; + * return true and let the system attempt hibernation. + */ + if (r > 0 && !hibernate_location) { + log_debug("Unable to determine remaining swap space; hibernation may fail"); + return true; + } + + if (!hibernate_location) + return false; + r = get_proc_field("/proc/meminfo", "Active(anon)", WHITESPACE, &active); if (r < 0) { log_debug_errno(r, "Failed to retrieve Active(anon) from /proc/meminfo: %m"); diff --git a/src/shared/sleep-config.h b/src/shared/sleep-config.h index 3d82ee8e6c1..faa3c0519aa 100644 --- a/src/shared/sleep-config.h +++ b/src/shared/sleep-config.h @@ -40,8 +40,8 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(SwapEntry*, swap_entry_free); * and the matching /proc/swap entry. */ typedef struct HibernateLocation { - char *resume; - uint64_t resume_offset; + dev_t devno; + uint64_t offset; SwapEntry *swap; } HibernateLocation; diff --git a/src/sleep/sleep.c b/src/sleep/sleep.c index 89b80367f8f..cfd254ad556 100644 --- a/src/sleep/sleep.c +++ b/src/sleep/sleep.c @@ -39,18 +39,19 @@ STATIC_DESTRUCTOR_REGISTER(arg_verb, freep); static int write_hibernate_location_info(const HibernateLocation *hibernate_location) { char offset_str[DECIMAL_STR_MAX(uint64_t)]; + char resume_str[DECIMAL_STR_MAX(unsigned) * 2 + STRLEN(":")]; int r; assert(hibernate_location); assert(hibernate_location->swap); - assert(hibernate_location->resume); - r = write_string_file("/sys/power/resume", hibernate_location->resume, WRITE_STRING_FILE_DISABLE_BUFFER); + xsprintf(resume_str, "%u:%u", major(hibernate_location->devno), minor(hibernate_location->devno)); + r = write_string_file("/sys/power/resume", resume_str, WRITE_STRING_FILE_DISABLE_BUFFER); if (r < 0) return log_debug_errno(r, "Failed to write partition device to /sys/power/resume for '%s': '%s': %m", - hibernate_location->swap->device, hibernate_location->resume); + hibernate_location->swap->device, resume_str); - log_debug("Wrote resume= value for %s to /sys/power/resume: %s", hibernate_location->swap->device, hibernate_location->resume); + log_debug("Wrote resume= value for %s to /sys/power/resume: %s", hibernate_location->swap->device, resume_str); /* if it's a swap partition, we're done */ if (streq(hibernate_location->swap->type, "partition")) @@ -61,17 +62,17 @@ static int write_hibernate_location_info(const HibernateLocation *hibernate_loca "Invalid hibernate type: %s", hibernate_location->swap->type); /* Only available in 4.17+ */ - if (hibernate_location->resume_offset > 0 && access("/sys/power/resume_offset", W_OK) < 0) { + if (hibernate_location->offset > 0 && access("/sys/power/resume_offset", W_OK) < 0) { if (errno == ENOENT) { log_debug("Kernel too old, can't configure resume_offset for %s, ignoring: %" PRIu64, - hibernate_location->swap->device, hibernate_location->resume_offset); + hibernate_location->swap->device, hibernate_location->offset); return 0; } return log_debug_errno(errno, "/sys/power/resume_offset not writeable: %m"); } - xsprintf(offset_str, "%" PRIu64, hibernate_location->resume_offset); + xsprintf(offset_str, "%" PRIu64, hibernate_location->offset); r = write_string_file("/sys/power/resume_offset", offset_str, WRITE_STRING_FILE_DISABLE_BUFFER); if (r < 0) return log_debug_errno(r, "Failed to write swap file offset to /sys/power/resume_offset for '%s': '%s': %m", From e9f0c5d08c6590c37d92dbdcf402706613d6daeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 7 Jan 2020 16:20:35 +0100 Subject: [PATCH 2/4] shared/sleep: use stat() instead of open()+fstat() in one place No functional change. --- src/shared/sleep-config.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c index f92924bf737..f1f4d6dd00b 100644 --- a/src/shared/sleep-config.c +++ b/src/shared/sleep-config.c @@ -186,36 +186,25 @@ HibernateLocation* hibernate_location_free(HibernateLocation *hl) { } static int swap_device_to_device_id(const SwapEntry *swap, dev_t *ret_dev) { - _cleanup_close_ int fd = -1; struct stat sb; - dev_t swap_dev; int r; assert(swap); assert(swap->device); assert(swap->type); - fd = open(swap->device, O_RDONLY | O_CLOEXEC | O_NONBLOCK); - if (fd < 0) - return log_debug_errno(errno, "Unable to open '%s': %m", swap->device); - - r = fstat(fd, &sb); + r = stat(swap->device, &sb); if (r < 0) return log_debug_errno(errno, "Unable to stat %s: %m", swap->device); if (streq(swap->type, "partition")) { - if(!S_ISBLK(sb.st_mode)) + if (!S_ISBLK(sb.st_mode)) return -ENOTBLK; - swap_dev = sb.st_rdev; - } else { - r = get_block_device(swap->device, &swap_dev); - if (r < 0) - return r; - } + *ret_dev = sb.st_rdev; + return 0; - *ret_dev = swap_dev; - - return 0; + } else + return get_block_device(swap->device, ret_dev); } /* From 8efc2c1608afa5bf8d857d4ea335c88cf6b6192b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 7 Jan 2020 16:44:12 +0100 Subject: [PATCH 3/4] shared/sleep-config: make swap detection stricter again MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To make this easier to understand, let's always log (at debug level) when we accept or reject each device: /swapfile: detection of swap file offset on Btrfs is not supported /swapfile: is a candidate device. /dev/zram0: ignoring zram swap /dev/vdb: ignoring device with lower priority /dev/vdc: ignoring device with lower usable space ... If we know that hibernation will fail, refuse. This includes cases where /sys/power/resume is set and doesn't match any device, or /sys/power/resume_offset is set and we're not on btrfs and it doesn't match. If /sys/power/resume is not set at all, we still accept the device with the highest priority (see 6d176522f5480ea9e9a83de5ef5ea5e0d95b79cb and 88bc86fcf895da0d51ddaf93d17b4280f4e60d74) Tested cases: 1. no swap active → refuse 2. just zram swap active → refuse 3. swapfile on btrfs with /sys/power/resume{,_offset} set → OK 4. swapfile on btrfs with /sys/power/resume set, offset not set → refuse 5. swapfile on btrfs with /sys/power/resume set to nonexistent device, offset set → refuse 6. /sys/power/resume not set, offset set, candidate exists → OK (*) 7. /sys/power/resume not set, offset not set, candidate exists → OK (*) I think this should fail, but I'm leaving that for the next commit. --- src/shared/sleep-config.c | 112 +++++++++++++++++++++----------------- 1 file changed, 62 insertions(+), 50 deletions(-) diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c index f1f4d6dd00b..9ac7b98e966 100644 --- a/src/shared/sleep-config.c +++ b/src/shared/sleep-config.c @@ -195,7 +195,7 @@ static int swap_device_to_device_id(const SwapEntry *swap, dev_t *ret_dev) { r = stat(swap->device, &sb); if (r < 0) - return log_debug_errno(errno, "Unable to stat %s: %m", swap->device); + return r; if (streq(swap->type, "partition")) { if (!S_ISBLK(sb.st_mode)) @@ -209,7 +209,7 @@ static int swap_device_to_device_id(const SwapEntry *swap, dev_t *ret_dev) { /* * Attempt to calculate the swap file offset on supported filesystems. On unsuported - * filesystems, a debug message is logged and the ret_offset is set to 0. + * filesystems, a debug message is logged and ret_offset is set to UINT64_MAX. */ static int calculate_swap_file_offset(const SwapEntry *swap, uint64_t *ret_offset) { _cleanup_close_ int fd = -1; @@ -232,8 +232,8 @@ static int calculate_swap_file_offset(const SwapEntry *swap, uint64_t *ret_offse if (btrfs < 0) return log_error_errno(btrfs, "Error checking %s for Btrfs filesystem: %m", swap->device); else if (btrfs > 0) { - log_debug("Detection of swap file offset on Btrfs is not supported: %s; skipping", swap->device); - *ret_offset = 0; + log_debug("%s: detection of swap file offset on Btrfs is not supported", swap->device); + *ret_offset = UINT64_MAX; return 0; } @@ -290,10 +290,9 @@ static bool location_is_resume_device(const HibernateLocation *location, dev_t s if (!location) return false; - if (sys_resume > 0 && sys_resume == location->devno && sys_offset == location->offset) - return true; - - return false; + return sys_resume > 0 && + sys_resume == location->devno && + (sys_offset == location->offset || (sys_offset > 0 && location->offset == UINT64_MAX)); } /* @@ -314,7 +313,7 @@ int find_hibernate_location(HibernateLocation **ret_hibernate_location) { _cleanup_(hibernate_location_freep) HibernateLocation *hibernate_location = NULL; dev_t sys_resume; uint64_t sys_offset = 0; - unsigned i; + bool resume_match = false; int r; /* read the /sys/power/resume & /sys/power/resume_offset values */ @@ -330,7 +329,7 @@ int find_hibernate_location(HibernateLocation **ret_hibernate_location) { } (void) fscanf(f, "%*s %*s %*s %*s %*s\n"); - for (i = 1;; i++) { + for (unsigned i = 1;; i++) { _cleanup_(swap_entry_freep) SwapEntry *swap = NULL; uint64_t swap_offset = 0; int k; @@ -363,68 +362,81 @@ int find_hibernate_location(HibernateLocation **ret_hibernate_location) { if (r < 0) return r; - /* if the offset was not calculated, continue without considering the swap file */ - if (swap_offset == 0) - continue; } else if (streq(swap->type, "partition")) { const char *fn; fn = path_startswith(swap->device, "/dev/"); if (fn && startswith(fn, "zram")) { - log_debug("Ignoring compressed RAM swap device '%s'.", swap->device); + log_debug("%s: ignoring zram swap", swap->device); continue; } + } else { - log_debug("Swap type %s is unsupported for hibernation: %s; skipping", swap->type, swap->device); + log_debug("%s: swap type %s is unsupported for hibernation, ignoring", swap->device, swap->type); continue; } /* prefer resume device or highest priority swap with most remaining space */ - if (!hibernate_location || swap->priority > hibernate_location->swap->priority - || ((swap->priority == hibernate_location->swap->priority) - && (swap->size - swap->used) > (hibernate_location->swap->size - hibernate_location->swap->used))) { - - dev_t swap_device; - r = swap_device_to_device_id(swap, &swap_device); - if (r < 0) - return r; - - hibernate_location = hibernate_location_free(hibernate_location); - hibernate_location = new(HibernateLocation, 1); - if (!hibernate_location) - return log_oom(); - - *hibernate_location = (HibernateLocation) { - .devno = swap_device, - .offset = swap_offset, - .swap = TAKE_PTR(swap), - }; - - /* if the swap is the resume device, stop looping swaps */ - if (location_is_resume_device(hibernate_location, sys_resume, sys_offset)) - break; + if (hibernate_location && swap->priority < hibernate_location->swap->priority) { + log_debug("%s: ignoring device with lower priority", swap->device); + continue; } + if (hibernate_location && + (swap->priority == hibernate_location->swap->priority + && swap->size - swap->used < hibernate_location->swap->size - hibernate_location->swap->used)) { + log_debug("%s: ignoring device with lower usable space", swap->device); + continue; + } + + dev_t swap_device; + r = swap_device_to_device_id(swap, &swap_device); + if (r < 0) + return log_error_errno(r, "%s: failed to query device number: %m", swap->device); + + hibernate_location = hibernate_location_free(hibernate_location); + hibernate_location = new(HibernateLocation, 1); + if (!hibernate_location) + return log_oom(); + + *hibernate_location = (HibernateLocation) { + .devno = swap_device, + .offset = swap_offset, + .swap = TAKE_PTR(swap), + }; + + /* if the swap is the resume device, stop the loop */ + if (location_is_resume_device(hibernate_location, sys_resume, sys_offset)) { + log_debug("%s: device matches configured resume settings.", hibernate_location->swap->device); + resume_match = true; + break; + } + + log_debug("%s: is a candidate device.", hibernate_location->swap->device); } - bool resume_match = location_is_resume_device(hibernate_location, sys_resume, sys_offset); - - /* resume= is set, but a matching /proc/swaps entry was not found */ - if (!resume_match && sys_resume != 0) { - log_debug("/sys/power/resume appears to be configured but a matching swap in /proc/swaps could not be identified; hibernation may fail"); - *ret_hibernate_location = NULL; - - return 1; - } - + /* We found nothing at all */ if (!hibernate_location) - return log_debug_errno(SYNTHETIC_ERRNO(ENOSYS), "No swap partitions or files suitable for hibernation were found in /proc/swaps"); + return log_debug_errno(SYNTHETIC_ERRNO(ENOSYS), + "No possible swap partitions or files suitable for hibernation were found in /proc/swaps."); + + /* resume= is set but a matching /proc/swaps entry was not found */ + if (sys_resume != 0 && !resume_match) + return log_debug_errno(SYNTHETIC_ERRNO(ENOSYS), + "No swap partitions or files matching resume config were found in /proc/swaps."); + + if (hibernate_location->offset == UINT64_MAX) { + if (sys_offset == 0) + return log_debug_errno(SYNTHETIC_ERRNO(ENOSYS), "Offset detection failed and /sys/power/resume_offset is not set."); + + hibernate_location->offset = sys_offset; + } if (resume_match) log_debug("Hibernation will attempt to use swap entry with path: %s, device: %u:%u, offset: %" PRIu64 ", priority: %i", hibernate_location->swap->device, major(hibernate_location->devno), minor(hibernate_location->devno), hibernate_location->offset, hibernate_location->swap->priority); else - log_debug("/sys/power/resume and /sys/power/resume_offset are not configured; attempting to hibernate with path: %s, device: %u:%u, offset: %" PRIu64 ", priority: %i", + log_debug("/sys/power/resume is not configured; attempting to hibernate with path: %s, device: %u:%u, offset: %" PRIu64 ", priority: %i", hibernate_location->swap->device, major(hibernate_location->devno), minor(hibernate_location->devno), hibernate_location->offset, hibernate_location->swap->priority); From 8f817cb888ccdb7625b6c6b50bf0f6c6ff12507c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 7 Jan 2020 18:16:01 +0100 Subject: [PATCH 4/4] shared/sleep-config: do not ignore resume_offset when resume not set This is most likely a user error, let's make it easier to diagnose. --- src/shared/sleep-config.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c index 9ac7b98e966..e63ef0f261b 100644 --- a/src/shared/sleep-config.c +++ b/src/shared/sleep-config.c @@ -271,11 +271,9 @@ static int read_resume_files(dev_t *ret_resume, uint64_t *ret_resume_offset) { return log_error_errno(r, "Failed to parse value in /sys/power/resume_offset \"%s\": %m", resume_offset_str); } - if (resume_offset > 0 && resume == 0) { - log_debug("Found offset in /sys/power/resume_offset: %" PRIu64 "; no device id found in /sys/power/resume; ignoring resume_offset", + if (resume_offset > 0 && resume == 0) + log_debug("Warning: found /sys/power/resume_offset==%" PRIu64 ", but /sys/power/resume unset. Misconfiguration?", resume_offset); - resume_offset = 0; - } *ret_resume = resume; *ret_resume_offset = resume_offset;