Most modern devices are running large SSD's, so there's no reason not to set up hibernate on your linux system. It's really convenient to be able to snapshot your working state if you need to power off your machine or reboot into a different OS.
This is a comprehensive guide that shows how to set up Hibernation on Ubuntu 20.04. It is based heavily on this stackoverflow answer plus a whole plethora of reddit posts and linux man pages.
Some jargon to know before we dive in:
- Swap: Specially allocated disk space that extends RAM if it fills up. RAM can also be written to swap when suspending.
- Sleep: Also known as "Suspend to RAM". Writes all data to RAM, computer goes to sleep quickly and wakes up instantly. State lost on power loss, and this requires constant energy to DRAM.
- Hibernate: Also known as "Suspend to Disk". Writes all RAM contents on disk, and computer can turn off completely. Requires enough swap space (either file or partition) to store the entire contents of ram. Does not require any energy usage while off, and can survive power disruptions.
Check your available kernel sleep states with
cat /sys/power/state. You'll see something like
freeze mem disk. The
disk part is crucial: this is what we need to suspend to disk. Check
cat /sys/power/disk and make sure it's not disabled. If it is, check your Secure Boot settings.
Explanation of other options:
standbyis for Power-on-Suspend and
freezeis for suspend-to-idle
For more details, check this stackoverflow answer .
First, make sure you have enough disk space to store the contents of your RAM.
- Find out how much ram you have:
free -mh | grep "Mem"- the first column will be your total
- Check your disk space:
df -h- look for the line that is mounted on
- Check for existing swap:
cat /etc/fstab | grep swap
Your swap space can be either a disk file or a partition. I recommend going with the swap partition instead of a file for two reasons:
- You don't have to worry about file offsets and swap file fragmentation
- It's easier to do backups of your root partition, since you don't have to remember to set up excludes on your
/swapfile. It really sucks to back up 32gb of useless data.
If your results from step 3 above showed a swap file, check the size of it with
du -sh /swapfile. If it's less than your total RAM (from step 1) you'll need a bigger file.
/etc/fstab shows something like
UUID=2ae674d7-6b75-4680-93c5-6d11c7bfb9b3 none swap sw 0 0 , this means you have a swap partition. You can get more details about it with:
lsblk | grep SWAP. The 4th column will show the size in GB. Again, if it's smaller than your total RAM you're going to have to make a bigger partition. The details are out of scope for this guide - you can check the ubuntu wiki for more information. You will probably want to use gdisk or gparted to create a large enough swap partition.
Configure swap partition
Now that you've set up your swap partition, let's grab the UUID of it.
blkid | grep swap
You'll see something like:
/dev/sdb6: UUID="2ae674d7-6b75-4680-93c5-6d11c7bfb9b3" TYPE="swsuspend" PARTLABEL="swap" PARTUUID="ab9cf927-6daa-4b7a-a548-2c0a7de0dcec"
Our UUID is "2ae674d7-6b75-4680-93c5-6d11c7bfb9b3". Hang on to this, we're going to need this UUID a ton in the next few steps.
Optional: Add new swap to /etc/fstab.
If you had to create a swap partition, you'll need to add it to the
sudo vim /etc/fstab and add the line
UUID=2ae674d7-6b75-4680-93c5-6d11c7bfb9b3 none swap sw 0 0, where the UUID string is replaced with the value you got earlier in the
Turn on your swap and verify that it works with
sudo swapon --all --verbose and
cat /proc/swaps. If you run
free -mh now, you should see a
You can test this setup with
sudo systemctl hibernate. Your computer should turn off, but when you boot it back up it will not resume. This is expected, since we haven't configured the resume part yet.
Install the tools
We'll need the proper tools to enable hibernate:
sudo apt install pm-utils hibernate
Set up "resume" in grub and initramfs
Now that the swap space is created, we can inform the kernel where to resume from.
First, we need to update the grub config. Run
sudo vim /etc/default/grub and find the line
GRUB_CMDLINE_LINUX_DEFAULT. This is the list of parameters passed to the kernel on boot. it will probably be set to
quiet splash. You'll want to add the string
resume=UUID=2ae674d7-6b75-4680-93c5-6d11c7bfb9b32, replacing my UUID with yours.
Optional: remove the "quiet splash". I like to see the boot logs since it makes it easier to debug things when they inevitably break. Plus, it scares my friends so that's fun too.
Update grub to pick up these changes:
We're also going to need to regenerate the initramfs and provide it the resume parameter:
# write the resume UUID (make sure to replace this with your UUID) echo RESUME=UUID=2ae674d7-6b75-4680-93c5-6d11c7bfb9b2 | sudo tee /etc/initramfs-tools/conf.d/resume # regenerate initramfs sudo update-initramfs -c -k all
Let's try the
sudo systemctl hibernate command again. If all went well, this time your system should completely power off, and then resume successfully to your desktop. If something didn't work, remove the
quiet splash from
/etc/default/grub , run
sudo update-grub and read the logs to see what went wrong.
Again, check this stackoverflow answer for debugging tips as well as the ubuntu wiki.
If all went well, congratulations! You now have hibernate working on your ubuntu 20.04 installation. If you'd like to set up passwordless hibernation, read on.
Enable Hibernation without password
We've achieved our primary goal of setting up hibernation on Ubuntu 20.04. However, it's even more convenient to have a simple shortcut that can auto lock and hibernate our system.
First, let's allow our user to run the
systemctl hibernate command without having to provide
sudo update-alternatives --config editor # pick your editor sudo visudo /etc/sudoers
Add the following lines to this file, replacing
yourname with your username:
yourname ALL= NOPASSWD: /usr/bin/systemctl hibernate yourname ALL= NOPASSWD: /usr/bin/systemctl suspend
You should now be able to run
systemctl hibernate . If your system hibernates, you're done!
On my Ubuntu 20.04 system, the
visudo changes above were not enough to get a non-interactive hibernate working. I no longer needed to provide the sudo password, but I still saw an authentication dialog:
This dialog comes from polkit, which is an application level policy handler that allows or blocks access to privileged actions. In this case, we are attempting to use the privileged action of triggering a
If we expand the
Details tab, we can see what exact action is being triggered:
The "Action" is
org.freedesktop.systemd1.manage-units. We can pick an "Identity" and grant it access to this action. For this example, we'll use the unix group
users, so our Identity will be
Make sure that your user is part of that group by running
sudo usermod -aG users "$USER".
sudo su and go to the
/var/lib/polkit-1/localauthority/50-local.d directory. We'll add a file called
51-systemd-manage-units.pkla with the following contents:
[Allow users to manage systemd units] Identity=unix-group:users Action=org.freedesktop.systemd1.manage-units ResultAny=yes ResultInactive=yes ResultActive=yes
Note that the
Identity can be any group or user you pick (
If you're curious about the other keys, you can check the "Authorization Entry" header on [this](https://www.freedesktop.org/software/polkit/docs/0.105/pklocalauthority.8.html) page.
This change is picked up immediately - no logout/reboot required.
You can test this command by running
systemctl hibernate . Your system should immediately go into the hibernate mode we saw previously, without a password prompt.
After resuming, you'll notice that you're taken to the exact screen you had before you ran the hibernate command. This is of course expected, but you probably want to set up some password protection for best practices. There are two options that come to mind:
- Set up an encrypted swap partition
- Lock the screen before triggering hibernate.
I'm setting this up on my home desktop, so I don't have an encrypted root partition. As such, encrypting the swap is kinda pointless.
Instead, we can set up a command that will lock the desktop and then trigger hibernate.
You have many different options. Ultimately, all you need is your favorite lock screen program plus a way to trigger a shell script easily. In this example, we'll use xsecurelock.
# Install prerequisites sudo apt installapache2-utils autotools-dev binutils gcc libc6-dev libpam-dev libx11-dev libxcomposite-dev libxext-dev libxfixes-dev libxft-dev libxmuu-dev libxrandr-dev libxss-dev make pamtester # Clone the repo git clone https://github.com/google/xsecurelock.git # Generate config. cd xsecurelock sh autogen.sh # Configure with PAM from /etc/pam.d/ - we'll use "common-auth" ./configure --with-pam-service-name=common-auth # make and install make sudo make install
Test this by running
xsecurelock from your terminal. You should see a simple black screen, and if you start typing you'll see the password field. More options available at https://github.com/google/xsecurelock#options. You may want to set
Personally, I like to get additional signals in the form of colors or sound when my various devices are doing complex actions. I looked into it, but there doesn't seem to be a good way to hook into the hibernate process to signal progress. There's a beep utility in linux, but it relies on the blacklisted `pcspkr` module. If you have suggestions, please email me :)
Putting it all together
At this point we have working hibernate, proper authentication to hibernate non-interactively, and a screen lock. We can create a simple wrapper shell script at
~/bin/hibernate with the following contents:
#!/usr/bin/env bash xsecurelock && sleep 1 && systemctl hibernate
How your trigger this is up to you. You can run it manually in a terminal, trigger it with rofi, or if using i3wm add a keybind:
bindsym $MOD+Shift+h exec "xsecurelock && sleep 1 && systemctl hibernate"