Skip to content

Commit 2002d8c

Browse files
committed
systemd-sleep: (bug) use resume_offset value if set
Use hibernation configuration as defined in /sys/power/resume and /sys/power/resume_offset if present before inspecting /proc/swaps and attempting to calculate swapfile offset
1 parent a7c5865 commit 2002d8c

File tree

3 files changed

+35
-6
lines changed

3 files changed

+35
-6
lines changed

TODO

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,6 @@ Features:
5656
with a nice speed-up on services that have many processes running in the same
5757
cgroup.
5858

59-
* clean up sleep.c:
60-
- Make sure resume= and resume_offset= on the kernel cmdline always take
61-
precedence
62-
6359
* make MAINPID= message reception checks even stricter: if service uses User=,
6460
then check sending UID and ignore message if it doesn't match the user or
6561
root.

src/shared/sleep-config.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ int find_hibernate_location(char **device, char **type, size_t *size, size_t *us
178178

179179
(void) fscanf(f, "%*s %*s %*s %*s %*s\n");
180180

181+
// TODO: sort swaps in priority order rather than using first successful option
181182
for (i = 1;; i++) {
182183
_cleanup_free_ char *dev_field = NULL, *type_field = NULL;
183184
size_t size_field, used_field;

src/sleep/sleep.c

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ static int write_hibernate_location_info(void) {
8080
if (r < 0)
8181
return log_debug_errno(errno, "Unable to stat %s: %m", device);
8282

83+
// TODO check for btrfs and fail if offset is not provided; calculation will fail
8384
r = read_fiemap(fd, &fiemap);
8485
if (r < 0)
8586
return log_debug_errno(r, "Unable to read extent map for '%s': %m", device);
@@ -93,11 +94,15 @@ static int write_hibernate_location_info(void) {
9394
if (r < 0)
9495
return log_debug_errno(r, "Failed to write offset '%s': %m", offset_str);
9596

97+
log_debug("Wrote calculated resume_offset value to /sys/power/resume_offset: %s", offset_str);
98+
9699
xsprintf(device_str, "%lx", (unsigned long)stb.st_dev);
97100
r = write_string_file("/sys/power/resume", device_str, WRITE_STRING_FILE_DISABLE_BUFFER);
98101
if (r < 0)
99102
return log_debug_errno(r, "Failed to write device '%s': %m", device_str);
100103

104+
log_debug("Wrote device id to /sys/power/resume: %s", device_str);
105+
101106
return 0;
102107
}
103108

@@ -143,6 +148,32 @@ static int write_state(FILE **f, char **states) {
143148
return r;
144149
}
145150

151+
static int configure_hibernation(void) {
152+
_cleanup_free_ char *resume = NULL, *resume_offset = NULL;
153+
int r;
154+
155+
/* check for proper hibernation configuration */
156+
r = read_one_line_file("/sys/power/resume", &resume);
157+
if (r < 0)
158+
return log_debug_errno(r, "Error reading from /sys/power/resume: %m");
159+
160+
r = read_one_line_file("/sys/power/resume_offset", &resume_offset);
161+
if (r < 0)
162+
return log_debug_errno(r, "Error reading from /sys/power/resume_offset: %m");
163+
164+
if (!streq(resume_offset, "0") && !streq(resume, "0:0")) {
165+
log_debug("Hibernating using device id and offset read from /sys/power/resume: %s and /sys/power/resume_offset: %s", resume, resume_offset);
166+
return 0;
167+
} else if (!streq(resume, "0:0")) {
168+
log_debug("Hibernating using device id read from /sys/power/resume: %s", resume);
169+
return 0;
170+
} else if (!streq(resume_offset, "0"))
171+
log_debug("Found offset in /sys/power/resume_offset: %s; no device id found in /sys/power/resume; ignoring offset", resume_offset);
172+
173+
/* if hibernation is not properly configured, attempt to calculate and write values */
174+
return write_hibernate_location_info();
175+
}
176+
146177
static int execute(char **modes, char **states) {
147178
char *arguments[] = {
148179
NULL,
@@ -168,9 +199,10 @@ static int execute(char **modes, char **states) {
168199

169200
/* Configure the hibernation mode */
170201
if (!strv_isempty(modes)) {
171-
r = write_hibernate_location_info();
202+
r = configure_hibernation();
172203
if (r < 0)
173-
return log_error_errno(r, "Failed to write hibernation disk offset: %m");
204+
return log_error_errno(r, "Failed to prepare for hibernation: %m");
205+
174206
r = write_mode(modes);
175207
if (r < 0)
176208
return log_error_errno(r, "Failed to write mode to /sys/power/disk: %m");;

0 commit comments

Comments
 (0)