@@ -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+
146177static 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