Ubuntu 18.04 can't resume after hibernate

Hibernate worked correctly when I had been using Ubuntu 17.04. After upgrade to 17.10 I couldn't resume because of black screen after resume (this bug).

After upgrade to 18.04 if I try to start my computer after hibernation it boots as if there was no hibernation done.


Solution 1:

There are changes done to default settings when compared to previous LTS (16.04). In my case hibernation didn't work until I've done several steps, among them increased the size of swap file, turned it on, made sure policies allowed it, etc.

This may easily be my lengthiest answer on entire StackExchange so I tried to make headers descriptive.

Boots as there was no hibernation

Would be prudent to take a look at your logs (dmesg might help) and see if anything's there. There are reasons when despite you telling the system to hibernate, it actually won't, or it will suspend-to-RAM instead (sleep).

Taking a look at kern.log and syslog looking for any hibernate-related messages wouldn't hurt as well. Sections starting with "problem" may help you with specific issues.

Swap file or swap partition

One of crucial changes is that now you DO NOT HAVE a swap partition, but you have a swap FILE.

Swap file may not work for your blend of hardware/drivers/OS and hibernation.

Hibernation turned off

Policies may also turn off or disallow hibernation.

Jargon

Suspend to RAM - RAM keeps the data, computer goes to sleep faster, uses more energy when suspended, wakes up faster. Some call this sleep.

Suspend to disk - aka hibernation. RAM is saved to swap (partition or file), computer goes to sleep slower, uses less energy while hibernating, wakes up slower.

Suspend-to-RAM in Linux by Rafael J. Wysocki and A. Leonard Brown

Prerequisites - do you have enough space?

To hibernate, you need to (simplification here) save your entire RAM to your hard drive. So, you need to set aside enough space to do so. If you don't, this will fail and you won't hibernate.

  1. free -m will tell you how much memory you have, use and how much is in your swap.
  2. df -h will tell you how much disk space you have on each mount point and how much is used, free, etc. This is important since you may want to later specify where your swap file will be located, or which partition to "trim" to have enough space for your swap.
  3. cat /etc/fstab should give you information if you have a swap partition or file. According to Ubuntu Hibernation FAQ swapfile may not always work with some combinations of hardware/drivers.

If you don't have enough space, follow Ubuntu swap FAQ. It tells you how to increase swap file, add another, check if it's used etc. With commands and explanations. Really nice resource.

I don't have enough space to fit my RAM!

Kernel docs say:

/sys/power/image_size controls the size of the image created by the suspend-to-disk mechanism. It can be written a string representing a non-negative integer that will be used as an upper limit of the image size, in bytes. The suspend-to-disk mechanism will do its best to ensure the image size will not exceed that number. However, if this turns out to be impossible, it will try to suspend anyway using the smallest image possible. In particular, if "0" is written to this file, the suspend image will be as small as possible. Reading from this file will display the current image size limit, which is set to 2/5 of available RAM by default.

So, try tweaking your image size. How - ask another question please.

Prerequisites - does your kernel support suspend-to-disk?

Kernel supports whatever is listed in /sys/power/state, so:

cat /sys/power/state

Allowed (to my knowledge) entries there include: mem, standby, freeze, disk. Explanation:

  • mem - has several meanings, which one exactly on your system you'll find out via cat /sys/power/mem_sleep. I have: s2idle [deep]
  • standby - Power-On Suspend (if supported)
  • freeze - Suspend To Idle (STI)
  • disk - Suspend To Disk (STD), hibernation. This - you want.

Then we need to check cat /sys/power/disk. If you have there disabled then dive in your BIOS looking for Secure Boot - that's the only idea I can offer and only thing I know may interfere and turn off hibernation. While I know only of SecureBoot, there may be other interferences, so taking a look at your BIOS is a good idea even if you don't have there any "secure boot".

Reading here:

  1. Kernel docs
  2. Debian Wiki on hibernation

TBH, even if your kernel does NOT support hibernation, you can try it in another way, scroll down to section Interfaces.

Read this - warnings and problems - no BTRFS

In no particular order:

  1. Not all chipsets will work (don't have sources that I can cite here so let's say this is hearsay)
  2. VAIO has problems, supposedly there's a flag to counter them
  3. SecureBoot is often cited as interfering or turning off hibernation
  4. Wake-on-LAN consumes power even with hibernation
  5. Number of modules (graphics especially) may be initialized BEFORE your system properly resumes from hibernation - this is usually the cause for black screen when resuming. Look at ArchLinux Wiki for tips on how to debug issues. I'd also suggest Ubuntu FAQ on hibernate issues. Browsing through Launchpad bugs may also yield results. IIRC, there's a kernel parameter specifying in seconds a delay before resume.
  6. Allowing hibernation procedure differs for different Polkit versions

Don't use BTRFS and hibernate: corrupted data will be the result.

I want to hibernate - swap partition

There are cases, when people forego swap file and go back to swap partition. After all, it worked on previous LTS. I did not try, so won't offer pointers.

I want to hibernate - with swap file

  1. Make sure you have enough space there. Ubuntu swap FAQ tells you how much you need, commands from above do so as well. If you need more info here, ask another question please, as this is a lengthy topic.
  2. Increase the swap file or create a new one with good enough size (preferred, I agree with @muru) and change in the /etc/fstab to new one. Reboot to see change is taken well (store backup of the fstab so you can easily revert just in case.
  3. Point your kernel at this with appropriate params, so it know where to resume from.
  4. Update/reconfigure your boot loader and reboot.

Kernel parameters? Scary!

Carefully read and decide if you wish to do that, but it's just a way to configure your kernel. It may be easier to hibernate via systemd and uswsusp (see Interfaces, below). It may be, that you - like me - will ultimately decide suspend-to-RAM is enough and you don't want to have 32GB on a swap file (not so great for folks with one SSD in their laptops, for instance). But!

  1. hibernate to swap file requires resume= to know which partition your swap file is on and resume_offset= to know where in swap file to start resuming from.
  2. hibernate to partition requires resume= to point to swap partition.
  3. resolving black screen issues may well require resumedelay=.

Kernel docs on delaying resuming from Hibernation:

resumedelay= [HIBERNATION] Delay (in seconds) to pause before attempting to read the resume files

Required parameters for swap-file and hibernation:

resume= [SWSUSP]

      Specify the partition device for software suspend
      Format:
      {/dev/<dev> | PARTUUID=<uuid> | <int>:<int> | <hex>}

resume_offset= [SWSUSP]

      Specify the offset from the beginning of the partition
      given by "resume=" at which the swap header is located,
      in <PAGE_SIZE> units (needed only for swap files).
      See Documentation/power/swsusp-and-swap-files.txt

For the resume= choose the same style as root element has in fstab. So, either /dev/sdaX or UUID or LVM. For hibernating to file - provide partition where your file can be found.

Reading:

  1. https://www.kernel.org/doc/Documentation/admin-guide/kernel-parameters.txt
  2. https://wiki.archlinux.org/index.php/Kernel_parameters

Problem - swap header not found

Swap file needs to be formatted properly. If your logs tell you this, you either are trying to hibernate to a file, or your resume parameter is not right.

Switch to partition or fix the file or change interface used for hibernation.

See: https://unix.stackexchange.com/questions/43508/debian-hibernate-problem-pm-swap-header-not-found

mkswap is used to format file, read more on it here

Problem! Hibernation not allowed!

Test: pm-hibernate (if pm-utils package is installed) or systemctl hibernate tell you you are not allowed. Default setting in Ubuntu since IIRC 12.04.

Solution(s): depends on your Polkit version, your Ubuntu version and flavour... See this question. Also, ArchWiki on Polkit may help.

For Mint, see: https://forums.linuxmint.com/viewtopic.php?t=259912

Problem! Hibernation disabled by something in BIOS!

Test: cat /sys/power/disk has disabled. Logs show "Failed to hibernate system via logind: Sleep verb not supported".

Solution: search your BIOS and find the problematic thing. Turn it off.

Solution 2: try another hibernate interface.

See: How to activate hibernation in 16.04.1 ? (systemd).

Interfaces

  1. swsusp - low level kernel interface. See Prerequisites - kernel for which files. Writing to files directly may cause suspend (to RAM, to disk and hybrid). According to SwapFAQ problematic with hibernating to file.
  2. uswsusp - ArchWiki and Debian Wiki and nice AskUbuntu question with a write-up how to use it.
  3. systemd - ArchWiki on it
  4. pm-utils - AFAIK that's a collection of scripts originally from Debian - I'll gladly welcome more info myself.

Closing remarks

For me it was a matter of almost two days of work to compile that. Hopefully this will help you (and others) solve your issue faster. There are still points I missed but it's 2 AM and I don't feel like writing more now. I'm of course open to anybody's pointers to make this better, so comment away. I'll reply once I sleep, work etc. :-)

I'm not certain hibernating to disk is that great. I went with sleeping in the end. But for me issue was with having a 32GB file just to be able to do hibernation, since I'm usually avoiding swapping at all. My initial swap-file was at 2GB and it was mostly empty. YMMV. Nevertheless, good luck! And start with the logs!

Solution 2:

Use the swap partition's UUID instead of it's mounting point in the RESUME parameter resume=UUID=<#> in both /etc/default/grub and /etc/initramfs-tools/conf.d/resume

Create an entry for the swap partition in /etc/fstab without a mounting point something like this

# Entry for Swap : 
UUID=# none  swap    sw              0       0

In /etc/default/grub I've used a separate entry for resuming hibernation

# FOR HIBERNATION 
GRUB_CMDLINE_LINUX="resume=UUID=..."

Create a policykit in local authority (pkla)

sudo gedit /etc/polkit-1/localauthority/50-local.d/com.ubuntu.enable-hibernate.pkla

And insert there

[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

[Enable hibernate to be run via cron]
Identity=unix-user:*
Action=org.freedesktop.login1.hibernate;org.freedesktop.login1.hibernate-multiple-sessions
ResultAny=yes

After that update initramfs and GRUB

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

Reboot , open some apps and use systemctl hibernate (without sudo) to see if it works

Solution 3:

For me it has always worked until 18.04 and after 18.04 I enabled it as is in many articles, but it suddenly stopped working just yesterday (working fine for 4-5 months),

and here is the ... ONE THING that got it working again ...

Tell grub2 where the swap partition is:

First find out which partition it is on using the below command:

cat /etc/fstab

Mine is on sda7 as is the following output:

swap was on /dev/sda7 during installation

Then, add in Grub2 the following addition to the following line, using the following command:

sudo gedit /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT="intel_pstate=disable resume=/dev/sda7"

The important part is resume=/dev/sda7

/dev/sda7 in my case

Then Update Grub with the following command, and after this it started working perfectly again:

sudo update-grub

After many attempts this was the one thing worked, perhaps it was just because of an update to the kernel that screwed it up, never the less this worked.