23

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?

20

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:

  • 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 2 '17 at 14:51
  • It was tested and working but perhaps that addition is needed. I have updated my answer. – Cas Oct 2 '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
  • 1
    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 7:42
  • 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 at 20:59
10

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 | grep MemTotal | grep -oh '[0-9]*') count=1024 conv=notrun
    sudo mkswap /swapfile
    sudo swapon /swapfile
    
  • Note the UUID of the partition containing your /swapfile:

    $ sudo findmnt -no SOURCE,UUID -T /swapfile
    /dev/nvme0n1p5 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:

  • Thank you for this! I've tried many methods, but only yours works for me on Ubuntu 18.04 :) – jirislav Apr 26 at 7: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 4 at 17:23
  • Thank you, @Anthony ! I tried so many things to get hibernate to work. Yours was the final solution which did. It seems very strange to me that this isn't set up correctly straight away. :( – Mike Williamson Jun 11 at 2:47
  • 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 at 23:42
  • 1
    This is the only solution that worked for me. Signed in just to upvote this answer. Thanks. – dpetrini Aug 20 at 11:34
8

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
  • 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 9 '18 at 16:04

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.