51

I have configured a new Ubuntu installation in a Notebook to use a swap file, instead of using a swap partition.

By default is not possible to get Ubuntu to hibernate using a swap file, so I tried this tutorial, but it is specific to grub1, and Ubuntu now uses grub2.

Does anybody know how to do this?

muru
  • 197,895
  • 55
  • 485
  • 740
tfmoraes
  • 534
  • IDK what's up with systemd, looking at the code it should support swapfile natively. Then I've been using it for years with one swap partition much smaller that RAM, and one swapfile to compensate. In more recent versions I had to play with the priorities to make it work (make swap part lower prio, though from what I recall I I needed to use the swap part - I was probably mistaken). But at the same time I helped someone else with the same issue, and removing the swap partition (which alone is too small) broke it. One small swap part pri=0, one large swap file pri=1, worked for both of us. – Thomas Guyot-Sionnest Dec 16 '20 at 09:09
  • NB: The swap priority change fixed the resume, suspend always worked but resume would fail in initrd to pick up the image on the swapfile. I assumed the working boots used the partition for the resume image... IMHO, either the swapfile allows the kernel to further reduce the image size (ex swap out application memory) or systemd supported swapfiles all along and a recent bug broke it partially. Also before I fixed systemd, swsusp s2disk (and iirc pm-hibernate too) worked fine without any change. – Thomas Guyot-Sionnest Dec 16 '20 at 09:20

6 Answers6

65

Here is what I did to make it work with Ubuntu 18.04.

  • Make your /swapfile have at least the size of your RAM
sudo swapoff /swapfile
sudo dd if=/dev/zero of=/swapfile bs=$(cat /proc/meminfo | awk '/MemTotal/ {print $2}') count=1024 conv=notrunc
sudo mkswap /swapfile
sudo swapon /swapfile
  • Note the UUID of the partition containing your /swapfile:
$ sudo findmnt -no UUID -T /swapfile
20562a02-cfa6-42e0-bb9f-5e936ea763d0
  • Reconfigure the package uswsusp in order to correctly use the swapfile:
sudo dpkg-reconfigure -pmedium uswsusp
# Answer "Yes" to continue without swap space
# Select "/dev/disk/by-uuid/20562a02-cfa6-42e0-bb9f-5e936ea763d0" replace the UUID with the result from the previous findmnt command
# Encrypt: "No"
  • Edit the SystemD hibernate service using sudo systemctl edit systemd-hibernate.service and fill it with the following content:
[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
  • Note the resume offset of your /swapfile:
$ sudo swap-offset /swapfile
resume offset = 34818
  • Configure Grub to resume from the swapfile by editing /etc/default/grub and modify the following line:
GRUB_CMDLINE_LINUX_DEFAULT="resume=UUID=20562a02-cfa6-42e0-bb9f-5e936ea763d0 resume_offset=34818 quiet splash"
  • Update Grub:
sudo update-grub
  • Create the following /etc/initramfs-tools/conf.d/resume:
RESUME=UUID=20562a02-cfa6-42e0-bb9e-5e936ea763d0 resume_offset=34816
    # Resume from /swapfile
  • Update initramfs:
sudo update-initramfs -u -k all

Now you can hibernate with sudo systemctl hibernate.

One can also create those scripts:

sudo tee /usr/local/bin/gotosleep <<EOF
dbus-send --type=method_call --dest=org.gnome.ScreenSaver /org/gnome/ScreenSaver org.gnome.ScreenSaver.Lock
sleep 2
sudo /usr/sbin/s2both
EOF
sudo chmod +x /usr/local/bin/gotosleep
sudo tee /usr/local/bin/gotohibernation <<EOF
dbus-send --type=method_call --dest=org.gnome.ScreenSaver /org/gnome/ScreenSaver org.gnome.ScreenSaver.Lock
sleep 2
sudo systemctl hibernate
EOF
sudo chmod +x /usr/local/bin/gotohibernation

So you can sleep with gotosleep or hibernate with gotohibernation.

You must be able to execute sudo s2both, sudo s2ram and sudo systemctl hibernatewithout having to enter your password for the previous scripts to work.

You could do that for example by creating a powerdev group, add your current user to it, and configure the following sudoers config (edit it with sudo visudo -f /etc/sudoers.d/powerdev):

%powerdev ALL=NOPASSWD: /usr/sbin/s2both, /usr/sbin/s2ram, /bin/systemctl hibernate

Documentation used:

Anthony O.
  • 2,539
  • 2
    Thank you for this! I've tried many methods, but only yours works for me on Ubuntu 18.04 :) – jirislav Apr 26 '19 at 07:44
  • This almost makes me feel like trying hibernation again - I had a problem with occasional corruption on my disks, which was apparently related to the hibernation process. Have you encountered anything like that? – Charles Green May 04 '19 at 17:23
  • Thanks for this guide. After following the steps then trying to hibernate using $ sudo systemctl hibernate, my laptop wakes up a couple seconds after trying to hibernate. /var/log/syslog shows many errors, but these seem the most relevant:
    • Failed to set power save mode for output eDP-1: Permission denied

    ...

    • Object .Gjs_AppIndicatorIconActor__1 (0x561c60a4d150), has been already finalized. Impossible to set any property to it.

    ...

    • s2disk: Could not use the resume device (try swapon -a). Reason: No such device
    • systemd-hibernate.service: Main process exited, code=exited, ...
    – Jelani Nelson Jul 11 '19 at 23:42
  • @JelaniNelson it seems that your swap is not correctly configured – Anthony O. Jul 12 '19 at 10:19
  • Thanks, indeed you are right. All fixed now! Had the wrong offset by accident in /etc/uswsusp.conf. – Jelani Nelson Jul 13 '19 at 17:18
  • I did it like described, but I get an error. I have an ecrypted / filesystem and there a 9GB swapfile. s: deferring update (trigger activated) Trigger für initramfs-tools (0.136ubuntu6) werden verarbeitet ... update-initramfs: Generating /boot/initrd.img-5.4.0-25-generic W: initramfs-tools configuration sets RESUME=UUID=8fb86658-3799-4204-94df-7cf37441baa3 W: but no matching swap device is available. //n// sudo findmnt -no SOURCE,UUID -T /swapfile /dev/mapper/sda6_crypt 8fb86658-3799-4204-94df-7cf37441baa3 – Arno Apr 20 '20 at 10:25
  • 1
    Thank you for this! It's the only solution that worked for me on Ubuntu 20.04! – junkystu Jul 29 '20 at 10:19
  • Thank you for this solution! Finally, the only solution that I found working. By the way, for a record, I am using Lubuntu 20.04 on a 12-years old Dell D620 laptop, and it works correctly as well.

    Been trying many solutions prior to finding this, but none of the resume works from swapfile. The "resume_offset" parameter is what missing in other solutions.

    Thank you again!

    – Lye Heng Foo Feb 13 '21 at 09:05
  • 1
    This works for Ubutu 21.04 as well! – Microtribute Jul 08 '21 at 02:29
  • swapoff: /swapfile: swapoff failed: No such file or directory. Any help? – Timo Aug 03 '21 at 20:14
  • bs=$(cat /proc/meminfo..) looks strange as the default is 512. Here it is up to millions of bytes. How is that? – Timo Aug 04 '21 at 18:42
  • Thanks, works in 20.04 indeed (on Thinkpad T14 Gen2). I faced one issue not described here, so posting it: after doing all of the above, the command sudo systemctl hibernate resulted in Failed to hibernate system via logind: Sleep verb not supported. Turns out, cat /sys/power/state must return freeze mem disk, but in my case the disk was missing. To fix it, I only had to disable Secure Boot in BIOS. Once that's done, cat /sys/power/state returns freeze mem disk, and sudo systemctl hibernate works. – Dmitry Frank Oct 10 '21 at 08:04
  • After I did all of that, here is the output of sudo systemctl hibernate : Failed to hibernate system via logind: Not enough swap space for hibernation. I tried increasing the swap space to no avail. I now have 100GB of swap for 32GB of RAM and the same happens. – pieroxy Oct 11 '21 at 19:21
  • Why did you not accept any answer? – vanadium Sep 17 '22 at 13:53
  • @vanadium because I did not had time to test all the solution in order to find the best one ;) – Anthony O. Sep 19 '22 at 07:36
31

Hibernate with Swap file using uswusp

Although it is possible to hibernate to swap file and it supposedly works with systemd hibernate by setting kernel parameters. However, I couldn't get it to resume so instead switched to using uswsusp (userspace software suspend). Here are the steps I used on Ubuntu 17.04/17.10.

Create the Swap File

The commands to create a formatted 4GiB swap file, mounted and added to /etc/fstab:

sudo fallocate -l 4g /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile swap swap defaults 0 0' | sudo tee -a /etc/fstab

Verify Swap File Partition

sudo findmnt -no SOURCE,UUID -T /swapfile
> /dev/sda1 11cc33ee-1234-abcd-1234-ddeeff112233

Install Userspace Software Suspend (uswsusp)

sudo apt install uswsusp

Configure uswsusp

To create /etc/uswsusp.conf and recreate initramfs:

sudo dpkg-reconfigure -pmedium uswsusp
  • Yes to 'Continue without a valid swap space?' (Wizard not set swap file yet.)
  • Select the partition that the swap-file resides on, cross-reference with details from findmnt above. (Note:not the swap-file itself)

Note: Any changes manually made to /etc/uswsusp.conf will require recreating initramfs afterwards with this command:

sudo update-initramfs -u

Test uswusp hibernate

sudo s2disk

There should be snapshot messages on the screen on hibernate and resume.

Use s2disk with systemd hibernate

By default systemd will use it's own hibernate commands so replace them with the uswusp commands by overriding the systemd-hibernate.service:

sudo systemctl edit systemd-hibernate.service

In the text editor that opens put the following text (the blank ExecStart is required). Then save and exit:

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

This will create /etc/systemd/system/systemd-hibernate.service.d/override.conf file with override details.

Test systemd hibernate :

systemctl hibernate 

Note: To check that the systemd override.conf has been created, loaded and no errors, run:

systemctl status systemd-hibernate.service

References:

Cas
  • 8,557
  • This instructions seems to work but the systemd hibernation is not working for me. Have you tested this your own? Should this ExceStart=run-parts -a post /lib/systemd/system-sleep be ExceStartPost=run-parts -a post /lib/systemd/system-sleep – Joaquín Aramendía Oct 02 '17 at 14:51
  • It was tested and working but perhaps that addition is needed. I have updated my answer. – Cas Oct 02 '17 at 15:33
  • This doesn't look quite right. The enable option of systemctl symlinks from /etc/systemd/system/ to /lib/systemd/system/. You should never be copying directly into /etc/systemd/system/ – Auspex Oct 29 '17 at 19:46
  • Yes you should put put service files in /etc/systemd/system, especially if you are overriding existing services: https://wiki.archlinux.org/index.php/systemd#Writing_unit_files – Cas Oct 29 '17 at 22:46
  • That said there is an alternative of using a conf file as specified at the bottom of the systemd.unit docs but still either way is recommended. – Cas Oct 29 '17 at 22:51
  • @Auspex You might be interested that I have simplified the instruction to use override conf files. – Cas Dec 07 '17 at 22:36
  • 2
    I didn't manage to make this work . I set up swapfile, installed and configured uswsusp, but sudo s2disk only logs Saving snapshot, than turns off the display, hangs for ~5 min and then it shuts down the computer. However after I turn it on, it boots normally like there's been no hibernation. – m93a Aug 20 '18 at 07:42
  • I also needed to add resume=/dev/sdaX to GRUB_CMDLINE_LINUX_DEFAULT="resume=/dev/sdaX quiet splash" in /etc/default/grub for this work (also run sudo update-grub after updating grub). Where sdaX is the partition with the swap file. Source: https://wiki.debian.org/Hibernation/Hibernate_Without_Swap_Partition – Martin Becker Oct 16 '18 at 06:35
  • Thank you so much this worked for me on Ubuntu 18.04. Also, I used this extension to get the hibernate button in power menu from this post, http://ubuntuhandbook.org/index.php/2018/05/add-hibernate-option-ubuntu-18-04/ and I also set my power button to hibernate by default on press of power button. It's a little slow on my 5400rpm disk but its fine. – Mr.Hunt Nov 11 '18 at 09:11
  • For some reason I get sudo s2disk s2disk: Could not use the resume device (try swapon -a). Reason: No such device altought I followed everything in this tutorial. – user1915011 Sep 10 '19 at 20:58
  • 1
    I think this line sudo findmnt -no SOURCE,UUID -T /mnt/4GiB.swap should be changed to sudo findmnt -no SOURCE,UUID -T /swapfile – user1915011 Sep 10 '19 at 20:59
  • Using fallocate to create a swapfile is not recommended, because it may lead to creation of a file with holes, dd is recommended instead. Read more about this. – ManSamVampire May 02 '20 at 13:27
12

Ubuntu 22.04

uswusp is deprecated. You can still use it for Ubuntu <= 20.04. To find swap offset on Ubuntu 22.04:

  • Run sudo filefrag -v /swapfile
  • In the "physical_offset" column, copy the first row number (without dots!). Value example: 1234567.

Source: How To Enable Hibernation On Ubuntu (When Using A Swap File)

All other steps remain the same for Ubuntu 22.04, so you can follow other answers except installing and using uswusp.

Nairum
  • 221
  • The procedure does not work me. I have both swapfile and swap partition. The system was originally configured to hibernate to the swap partition (and that worked). Now I try to make it hibernate to swapfile (as swap partition is not large enough). I have updated /etc/default/grub with UUID and offset of the swapfile, created appropriate /etc/initramfs-tools/conf.d/resume. Yet sudo update-initramfs -u -k all produces original "I: The initramfs will attempt to resume from /dev/sdb1 I: Set the RESUME variable to override this." Can't figure how to override this. – matteroffact Oct 04 '23 at 22:58
  • The source is well documented and easy to follow. I'd struggled with the screen remaining black. I've also set the power button to Hibernate instead of powering off. – Tinashe Chinyanga Mar 07 '24 at 19:48
9

I've given a quick read to the tutorial and, if I have understood correctly, you just need to specify the resume options to the Linux command line. With Grub2 is really simple, and your changes will be always preserved. You need to edit the /etc/default/grub file, specifically this line:

GRUB_CMDLINE_LINUX="resume=... resume_offset=..."

After that, run sudo update-grub for the changes to take effect.

Changing GRUB_CMDLINE_LINUX won't affect other Linux installations you have (because /etc/grub.d/30_os-prober does not use this variable).

About the problem you're having: is the partition of the swapfile encrypted? If so, hibernation won't work. If not, then the output of filefrag -v /swapfile may be helpful.

  • Thanks! I will try. But I think it config all linux entries in grub with this line. – tfmoraes Oct 13 '10 at 16:26
  • Don't forget: after changing /etc/default/grub you need to run update-grub. – JanC Oct 13 '10 at 16:44
  • @tfmoraes: why wouldn't you want this added to all linux entries? – JanC Oct 13 '10 at 16:45
  • @JanC: Because I may have other Linux distributions installed. – tfmoraes Oct 13 '10 at 17:21
  • If you look at /etc/grub.d/30_os-prober, you'll see that GRUB_CMDLINE_LINUX is not used, so changing it won't affect other Linux installations. – Andrea Corbellini Oct 13 '10 at 17:43
  • Hi Andrea. No, my partition with swapfile is not encrypted. Only to add: filefrag isn't work (at least here), a substitute is the command swap-offset. Thanks! – tfmoraes Oct 15 '10 at 00:19
  • My suspect is that your swapfile is fragmented, so during the startup from hibernation the system reads the wrong data. Unfortunately, only filefrag knows the answer. Why doesn't it work? – Andrea Corbellini Oct 15 '10 at 15:14
  • Andrea, I don't know why, but in filefrag output there is not a "First block". In the tutorial I indicated swap-offset is mentioned as a filefrag alternative. I don't think the swapfile is fragmented, it's created entirely, not acording to necessary. And I see when it hibernates a output about writing in the swapfile. – tfmoraes Oct 17 '10 at 01:28
  • I posted a bug in launchpad https://bugs.launchpad.net/ubuntu/+source/uswsusp/+bug/663200 – tfmoraes Oct 19 '10 at 11:07
  • "is the partition of the swapfile encrypted? If so, hibernation won't work."

    This seems not to be true. I've Kubuntu 18.04 running with a LUKS encrypted root partition. Yet hibernate works for me after adding "resume=... resume_offset=..."

    – didi_X8 Jul 09 '18 at 08:48
  • 1
    @didi_X8 that comment was written 8 years ago. It's possible that things have changed since then. Thanks for sharing. – Andrea Corbellini Jul 09 '18 at 16:04
1

Since no from the previous answers seems to me to cover all aspects fully, here all the steps which worked for me to get everything running smoothly on Debian Bullseye, so should be applicable for Ubuntu 22 and hopefully higher too with grub2 used without the usage of the no longer existing package uswsusp and the whole s2* facility. I expect this should be also applicable to lower versions:

  1. Lets suppose, we have prepared the swap file named /tmpdisk/system/swap.file. How to prepare it, consult for example this answer.
  2. Get the information about the swap offset by the determination of the first fragment of the swap file on the partition, where it is placed, for example:

# filefrag -v /tmpdisk/system/swap.file

obtaining the result where the offset is the first physical offset fragment number

Filesystem type is: ef53
File size of /tmpdisk/system/swap.file is 68719476736 (16777216 blocks of 4096 bytes)  
ext:     logical_offset:        physical_offset: length:   expected: flags:
  0:        0..   63487:      34816..     98303:  63488:             
  1:    63488..  126975:     100352..    163839:  63488:      98304:
  2:   126976..  190463:     165888..    229375:  63488:     163840:
 …  

Same information can be retrieved by the simple issuing of
# filefrag -v /tmpdisk/system/swap.file | awk '$1=="0:" {print substr($4, 1, length($4)-2)}'
obtaining the offset value directly:
34816

  1. Find the UUID of the partition with the swap file (in my case of file /tmpdisk/system/swap.file placed on partition, mounted on mount point /tmpdisk, so):

# findmnt -no UUID,SOURCE -T /tmpdisk
resulting in something like this
6b127402-e917-4ab0-9490-00faa74e88e5 /dev/sdb1

  1. Use the obtained UUID of the partition with the swap file and of the offset in /etc/default/grub:

GRUB_CMDLINE_LINUX_DEFAULT="resume=UUID=6b127402-e917-4ab0-9490-00faa74e88e5 resume_offset=34816"

  1. Use the obtained UUID of the partition with the swap file and of the offset in /etc/initramfs-tools/conf.d/resume:

in the following way

resume=UUID=6b127402-e917-4ab0-9490-00faa74e88e5
resume_offset=34816
  1. Update the ramdisks for all kernels used:

# update-initramfs -u -k all

  1. Update grub:

# update-grub

and that's it...


Remark: The values UUID=6b127402-e917-4ab0-9490-00faa74e88e5 and resume_offset=34816 will be individual on every system

0

I'd spent hours to get my KDE (neon) with hibernation option on shutdown menu, and since I'd solved, I've decided to share it here. If you're using KDE, you should create a file "/etc/polkit-1/localauthority/10-vendor.d/hibernate.pkla" with the content:

[Re-enable hibernate by default in upower]
Identity=unix-user:*
Action=org.freedesktop.upower.hibernate
ResultActive=yes

[Re-enable hibernate by default in logind] Identity=unix-user:* Action=org.freedesktop.login1.hibernate;org.freedesktop.login1.handle-hibernate-key;org.freedesktop.login1;org.freedesktop.login1.hibernate-multiple-sessions;org.freedesktop.login1.hibernate-ignore-inhibit ResultActive=yes

I've got it here: https://forum.kde.org/viewtopic.php?f=309&t=135294

  • Its been a couple of years, but FYI @user2275455 the link you posted for the source of your answer setting up hibernation option under polkit no longes exists. I receive a file not found message when clicked on. chow – Terence Golightly Aug 30 '23 at 20:12