User Tools

Site Tools


hibernate_from_a_non_activate_swapfile_from_btrfs

**This is an old revision of the document!**

Hibernate from a non activate swapfile from btrfs

Create swapfile

  • Create a separate swap volume (not necessary)

    sudo btrfs subvolume create /mnt/btrfsbase/swap

    • Add it to /etc/fstab

    UUID=8f9ede3a-912f-40d6-9335-90ed3186e3e4 /swap btrfs defaults,noautodefrag,nodatacow,nodiscard,noatime,subvol=swap 0 0

  • Be sure there is no discard nor autodefrag options activated for this subvolume
  • Create a swapfile

    cd /swap sudo truncate -s 0 swapfile sudo chattr +C swapfile btrfs property set swapfile compression none sudo chmod 600 swapfile sudo dd if=/dev/zero of=swapfile bs=1M count=24576 #reserve 24GB sudo mkswap /swap/swapfile

Find out resume device and offset

  • Find out resume device:

    sudo findmnt -no UUID -T /swap/swapfile

  • swapoffset command doesn't work correctly with btrfs. Download this https://github.com/osandov/osandov-linux/blob/master/scripts/btrfs_map_physical.c and compile it: gcc -O2 -o btrfsmapphysical btrfsmap_physical.c
  • Calculate offset
  • Write down the last number from the output of the following command:

    sudo btrfsmapphysical /swap/swapfile | head -n 2

  • Result:

    FILE OFFSET FILE SIZE EXTENT OFFSET EXTENT TYPE LOGICAL SIZE LOGICAL OFFSET PHYSICAL SIZE DEVID PHYSICAL OFFSET 0 134217728 0 regular 134217728 4594864128 134217728 1 4594864128

  • Write down the output of the following command:

    sudo getconf PAGESIZE

    Result: 4096

  • Calculate offset: Divide the first number under the PAGESIZE: offset = PHYSICAL_OFFSET/PAGESIZE

4594864128/4096=1121793

Configure system for hibernation

  • Create /etc/initramfs-tools/conf.d/resume and put the resume and offset data on it:

    RESUME=UUID=8f9ede3a-912f-40d6-9335-90ed3186e3e4 resume_offset=1121793

  • Modify /etc/default/grub with the corresponding resume and offset values:

    GRUBCMDLINELINUXDEFAULT=“resume=UUID=8f9ede3a-912f-40d6-9335-90ed3186e3e4 resumeoffset=1121793 quiet btusb.enable_autosuspend=n”

  • Activate the swap file

    sudo swapon /swap/swapfile

  • Install uswsusp package
  • Edit /etc/uswsusp.conf:

    resume device = /dev/disk/by-uuid/8f9ede3a-912f-40d6-9335-90ed3186e3e4 early writeout = y image size = 0 RSA key file = /etc/uswsusp.key shutdown method = platform resume offset = 1121793

  • Activate a systemd service:

    sudo systemctl edit systemd-hibernate.service

  • With:

    [Service] ExecStart= ExecStartPre=-/bin/run-parts -v -a pre /lib/systemd/system-sleep ExecStart=/usr/sbin/s2disk ExecStartPost=-/bin/run-parts -v –reverse -a post /lib/systemd/system-sleep

  • Update initramfs and grub

    sudo update-grub sudo update-initramfs -k all -u sudo update-grub

  • Test the hibernation:

    sudo s2disk

I have a system with encrypted swap, but I don't want to have encryption on the hibernation swap file. My idea is to use hibernation only when strictly necessary, because I don't want to need to put a password during booting. Then, this swap file should actually be always deactivated except before hibernation. When resuming, this swap space should be deactivated and then securely wiped! The script to do this would be this: myserverhibernate.sh:

!/bin/bash

echo "Activating swap from swapfile"
sudo swapon /swap/swapfile
sleep 1
echo "Hibernating"
sleep 0.2
xtrlock -b &
sudo s2disk
echo "Returning from Hibernate"
sleep 10
echo "Deactivating swapfile"
sudo swapoff /swap/swapfile
sleep 5
echo "Wiping swapfile"
sudo wipe -f -q -Q 1 /swap/swapfile
sync
sleep 1
echo "Making swapfs again"
sudo mkswap /swap/swapfile
echo "All done, ready to hiberante again"

References

hibernate_from_a_non_activate_swapfile_from_btrfs.1608128209.txt.gz · Last modified: 2021/02/01 05:55 (external edit)