From: Lennart Poettering Date: Tue, 20 Jun 2023 10:31:10 +0000 (+0200) Subject: sleep-config: replace SwapEntry's .type field with a proper enum X-Git-Tag: v254-rc1~164^2~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1296b427a7516f56752163c7f52b76a36408e36d;p=thirdparty%2Fsystemd.git sleep-config: replace SwapEntry's .type field with a proper enum Following our usual rule: let's parse this early into internal representation, and stick to that. don't pass unparsed strings around needlessly. --- diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c index 0db02fae87b..88e907422b9 100644 --- a/src/shared/sleep-config.c +++ b/src/shared/sleep-config.c @@ -597,7 +597,6 @@ SwapEntry* swap_entry_free(SwapEntry *se) { return NULL; free(se->device); - free(se->type); return mfree(se); } @@ -623,7 +622,7 @@ static int swap_device_to_device_id(const SwapEntry *swap, dev_t *ret_dev) { if (r < 0) return -errno; - if (streq(swap->type, "partition")) { + if (swap->type == SWAP_BLOCK) { if (!S_ISBLK(sb.st_mode)) return -ENOTBLK; @@ -649,7 +648,8 @@ static int calculate_swap_file_offset(const SwapEntry *swap, uint64_t *ret_offse assert(swap); assert(swap->device); - assert(streq(swap->type, "file")); + assert(swap->type == SWAP_FILE); + assert(ret_offset); fd = open(swap->device, O_RDONLY|O_CLOEXEC|O_NOCTTY); if (fd < 0) @@ -678,10 +678,13 @@ static int calculate_swap_file_offset(const SwapEntry *swap, uint64_t *ret_offse static int read_resume_files(dev_t *ret_resume, uint64_t *ret_resume_offset) { _cleanup_free_ char *resume_str = NULL, *resume_offset_str = NULL; - uint64_t resume_offset = 0; + uint64_t resume_offset; dev_t resume; int r; + assert(ret_resume); + assert(ret_resume_offset); + r = read_one_line_file("/sys/power/resume", &resume_str); if (r < 0) return log_debug_errno(r, "Error reading /sys/power/resume: %m"); @@ -691,9 +694,10 @@ static int read_resume_files(dev_t *ret_resume, uint64_t *ret_resume_offset) { 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) + if (r == -ENOENT) { log_debug_errno(r, "Kernel does not support resume_offset; swap file offset detection will be skipped."); - else if (r < 0) + resume_offset = 0; + } else if (r < 0) return log_debug_errno(r, "Error reading /sys/power/resume_offset: %m"); else { r = safe_atou64(resume_offset_str, &resume_offset); @@ -707,7 +711,6 @@ static int read_resume_files(dev_t *ret_resume, uint64_t *ret_resume_offset) { *ret_resume = resume; *ret_resume_offset = resume_offset; - return 0; } @@ -766,20 +769,25 @@ int find_hibernate_location(HibernateLocation **ret_hibernate_location) { (void) fscanf(f, "%*s %*s %*s %*s %*s\n"); for (unsigned i = 1;; i++) { _cleanup_(swap_entry_freep) SwapEntry *swap = NULL; + _cleanup_free_ char *type = NULL; uint64_t swap_offset = 0; int k; - swap = new0(SwapEntry, 1); + swap = new(SwapEntry, 1); if (!swap) return -ENOMEM; + *swap = (SwapEntry) { + .type = _SWAP_TYPE_INVALID, + }; + k = fscanf(f, "%ms " /* device/file */ "%ms " /* type of swap */ "%" PRIu64 /* swap size */ "%" PRIu64 /* used */ "%i\n", /* priority */ - &swap->device, &swap->type, &swap->size, &swap->used, &swap->priority); + &swap->device, &type, &swap->size, &swap->used, &swap->priority); if (k == EOF) break; if (k != 5) { @@ -787,17 +795,20 @@ int find_hibernate_location(HibernateLocation **ret_hibernate_location) { continue; } - if (streq(swap->type, "file")) { + if (streq(type, "file")) { + if (endswith(swap->device, "\\040(deleted)")) { log_debug("Ignoring deleted swap file '%s'.", swap->device); continue; } + swap->type = SWAP_FILE; + r = calculate_swap_file_offset(swap, &swap_offset); if (r < 0) return r; - } else if (streq(swap->type, "partition")) { + } else if (streq(type, "partition")) { const char *fn; fn = path_startswith(swap->device, "/dev/"); @@ -806,8 +817,10 @@ int find_hibernate_location(HibernateLocation **ret_hibernate_location) { continue; } + swap->type = SWAP_BLOCK; + } else { - log_debug("%s: swap type %s is unsupported for hibernation, ignoring", swap->device, swap->type); + log_debug("%s: swap type %s is unsupported for hibernation, ignoring", swap->device, type); continue; } diff --git a/src/shared/sleep-config.h b/src/shared/sleep-config.h index b8245b129f0..126377bcfd4 100644 --- a/src/shared/sleep-config.h +++ b/src/shared/sleep-config.h @@ -28,10 +28,17 @@ typedef struct SleepConfig { SleepConfig* free_sleep_config(SleepConfig *sc); DEFINE_TRIVIAL_CLEANUP_FUNC(SleepConfig*, free_sleep_config); +typedef enum SwapType { + SWAP_BLOCK, + SWAP_FILE, + _SWAP_TYPE_MAX, + _SWAP_TYPE_INVALID = -EINVAL, +} SwapType; + /* entry in /proc/swaps */ typedef struct SwapEntry { char *device; - char *type; + SwapType type; uint64_t size; uint64_t used; int priority; diff --git a/src/sleep/sleep.c b/src/sleep/sleep.c index 0dc3ad35586..685339e9421 100644 --- a/src/sleep/sleep.c +++ b/src/sleep/sleep.c @@ -63,12 +63,10 @@ static int write_hibernate_location_info(const HibernateLocation *hibernate_loca 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")) - return r; + if (hibernate_location->swap->type == SWAP_BLOCK) + return 0; - if (!streq(hibernate_location->swap->type, "file")) - return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), - "Invalid hibernate type: %s", hibernate_location->swap->type); + assert(hibernate_location->swap->type == SWAP_FILE); /* Only available in 4.17+ */ if (hibernate_location->offset > 0 && access("/sys/power/resume_offset", W_OK) < 0) {