0

I created a swap file as described here: https://wiki.archlinux.org/index.php/Swap#Swap_file_creation

When I try to hibernate I get the following error:

$ echo disk > /sys/power/state
echo: write error: no such device

Also in dmesg, I get:

[30721.352822] [drm] Reducing the compressed framebuffer size. This may lead to less power savings than a non-reduced-size. Try to increase stolen memory size if available in BIOS.
[30721.454735] acpi LNXPOWER:07: Turning OFF
[30721.454987] acpi LNXPOWER:02: Turning OFF
[30721.455365] acpi LNXPOWER:01: Turning OFF
[30721.455563] PM: Cannot find swap device, try swapon -a
[30721.455563] PM: Cannot get swap writer
[30721.553943] OOM killer enabled.
[30721.553944] Restarting tasks ... done.

As described in https://wiki.archlinux.org/index.php/Power_management/Suspend_and_hibernate#Hibernation_into_swap_file, I set the following kernel params:

resume=UUID=2bfb4ccd-6b80-4806-8a08-4f1e67ef035f
resume_offset=148378880

Here is how I get the resume_offset and resume parameter values:

$ filefrag -v /swapfile
Filesystem type is: 9123683e
File size of /swapfile is 536870912 (131072 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..       0:  148378880.. 148378880:      1:            
   1:        1..  131071:  148378881.. 148509951: 131071:             last,unwritten,eof
$ findmnt -no SOURCE,UUID -T /swapfile
/dev/mapper/nvme0n1p2[/root] 2bfb4ccd-6b80-4806-8a08-4f1e67ef035f

When I try to use swap_offset, I get the following issue:

$ swap-offset /swapfile 
ioctl(FIBMAP) failed: Invalid argument

So is it even possible to use a swapfile for hibernation when using BTRFS? It seems that the kernel is not aware of the correction location of the swap file.

1

u/hjoke (https://www.reddit.com/user/kjoke/) made my day:

filefrag calculates the offset incorrectly for BTRFS but there is a script that calculate the correct offset: https://github.com/osandov/osandov-linux/blob/master/scripts/btrfs_map_physical.c

Download and gcc btrfs_map_physical.c -o btrfs_map_physical then get the first physical offset for the swap file:

$ sudo ./btrfs-map-physical /swap | head -n2
FILE OFFSET EXTENT TYPE LOGICAL SIZE    LOGICAL OFFSET  PHYSICAL SIZE   DEVID   PHYSICAL OFFSET
0   regular 4096    607759892480    268435456   1   608833634304

Here: 608833634304. Divide this offset by the page size:

$ getconf PAGESIZE
4096

So the resume_offset is 608833634304 / 4096 = 148641024. Add this value with the resume parameter as kernel params and reboot. Afterwards systemd hibernate will still fail because systemd ignores kernel params and calculate the offset incorrectly but echo disk > /sys/power/state works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.