DEV Community

Cover image for Ubuntu 22.04 Hibernate Using Swap File
Dan Steren
Dan Steren

Posted on

Ubuntu 22.04 Hibernate Using Swap File

If you're like me, you expect that in 2024 you can close the lid on your laptop and your computer won't be dead when you pick it up the next day. Unfortunately, that's not the case after a default install of Ubuntu. To get this behavior, you need to enable hibernation through a swap partition or file. I've always used a swap file, so this guide will be for a swap file, not a swap partition.

Because I always forget how to set this up, I'm writing a canonical reference for myself and hopefully it helps you as well.

TLDR;

Just follow this guide. If it's confusing then come back here as I might have some helpful insight.

Overview

The way hibernation basically works is that it takes a snapshot of your system and saves it to disk right before shutting down, and then restores your system from that snapshot when you start your computer up again. To do that you need a swap system. So, we need to set that up first.

Setup Swap Area

Check swap setup

Very first we need to see if we even have a swap area. You can check by running this:

swapon --show
Enter fullscreen mode Exit fullscreen mode

My output was:

NAME      TYPE SIZE USED PRIO
/swapfile file   2G   0B   -2
Enter fullscreen mode Exit fullscreen mode

This means we are using a swapfile because it says "/swapfile", not something like "/dev/sdax partition" which would indicate a swap partition. So that's good, but 2GB isn't going to be large enough because it needs to be as big as your memory. So, we need resize the swapfile, or rather, delete the old one and make a new one.

Resize your Swapfile

So to make a new swap file we first turn off swap for all processes (so we're not using it while we go through the process):

sudo swapoff -a
Enter fullscreen mode Exit fullscreen mode

We then remove the current swapfile:

sudo rm /swapfile
Enter fullscreen mode Exit fullscreen mode

We create a new swapfile that is the same size as our memory:

sudo dd if=/dev/zero of=/swapfile bs=1G count=32
Enter fullscreen mode Exit fullscreen mode

My memory is currently 32 GB, but whatever it is you pass it to the count flag.

Note: When looking at the guide in the ubuntu handbook they use a block size (bs) value of 1MiB. When I asked ChatGPT it said the difference only mattered when creating the swapfile and not afterwards. If you have a smaller/older system then using 1MB block size may be easier on your system. You'll just have to multiply your count by 1024 then. But for me the above worked fine so as long as it creates the swap file you're good.

You then need to adjust the permissions so that only the root user can use the swapfile:

sudo chmod 600 /swapfile
Enter fullscreen mode Exit fullscreen mode

Make the file useable as swap:

sudo mkswap /swapfile
Enter fullscreen mode Exit fullscreen mode

Then activate it:

sudo swapon /swapfile
Enter fullscreen mode Exit fullscreen mode

To ensure the swap file is activated on boot we need to have a line with this contents in the /etc/fstab file:

/swapfile none swap sw 0 0
Enter fullscreen mode Exit fullscreen mode

It should already be there though so check the file first. If it isn't there already you can add it with this command:

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
Enter fullscreen mode Exit fullscreen mode

Mine was already there so I just skipped this step.

Find the Physical Offset

We then need to find the physical location of the swapfile. We can do so with the following command:

sudo filefrag -v /swapfile | awk '{ if($1=="0:"){ print $4 } }'
Enter fullscreen mode Exit fullscreen mode

This will give a number like 226572288.., you don't want the final .. though, so you'll have to manually grab just the number.

Update the GRUB Configuration

You'll add the resume and resume_offset parameters to your GRUB configuration to tell the system where to resume from when coming out of hibernation.

You'll want to open the GRUB configuration file with an editor (vim, nano, vscode, etc.):

sudo vim /etc/default/grub
Enter fullscreen mode Exit fullscreen mode

We then update that with a line referencing the output of blkid ("/dev/nvme0n1p2") and the physical offset we just found (226572288).

Suspend then Hibernate

Ok, so the secret sauce to make it all come together is to use suspend-then-hibernate rather than suspend. You do this by editing /etc/systemd/logind.conf.

sudo nano /etc/systemd/logind.conf
Enter fullscreen mode Exit fullscreen mode

Find the lines starting with HandleLidSwitch and HandleLidSwitchExternalPower in the file. If they don't exist, you can add them. Change or add these lines to specify suspend-then-hibernate:

HandleLidSwitch=suspend-then-hibernate
HandleLidSwitchExternalPower=suspend-then-hibernate
Enter fullscreen mode Exit fullscreen mode

Next, you need to specify the delay before transitioning from suspend to hibernate. This is done by creating or editing a file in /etc/systemd/sleep.conf or overriding the default configuration by creating a file in /etc/systemd/sleep.conf.d/.

For example, to set a 30-minute delay, create or edit /etc/systemd/sleep.conf:

sudo nano /etc/systemd/sleep.conf
Enter fullscreen mode Exit fullscreen mode
[Sleep]
HibernateDelaySec=1800s
Enter fullscreen mode Exit fullscreen mode

Then, all you should need to do is restart your computer to restart the systemd-logind service.

Epilogue

Someone should really automate this whole process. I may get to it one day. Ideally it would be checked into my .dotfiles so I can just have it setup automatically when I get a new linux box. This may be a fun project for you if you're feeling ambitious. I'd love to see what you come up with!

Resources

Top comments (0)