Ubuntu – Ubuntu 15.04 Suspend doesn’t run `pm-suspend`

15.04backlightpm-utilssuspendsystemd

After upgrading to Ubuntu GNOME 15.04 (from 14.10), I noticed my pm-utils hooks in /etc/pm/sleep.d aren't running anymore on suspend/resume.

I have a custom script which saves the brightness before suspend and restores it after resume. If I manually run sudo pm-suspend the hooks execute but if I close the laptop's lid (which suspends Ubuntu) the scripts aren't executed. Am I missing something?

The brightness script in /etc/pm/sleep.d is (worked on 14.04 and 14.10):

#!/bin/bash

case "$1" in
    suspend|suspend_hybrid|hibernate)
        cat /sys/class/backlight/acpi_video0/brightness > /tmp/.brightness_level
        # modprobe -r nvidiabl
        ;;
    resume|thaw)
        # modprobe nvidiabl
        cat /tmp/.brightness_level > /sys/class/backlight/acpi_video0/brightness
        rm /tmp/.brightness_level
        ;;
esac

Best Answer

Update: Found a nicer solution using systemd with no external scripts. Create and enable the following service:

[Unit]
Description=Save brightness on suspend
DefaultDependencies=no
RequiresMountsFor=/var/lib/systemd/backlight
Before=sleep.target
StopWhenUnneeded=yes

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/lib/systemd/systemd-backlight save acpi_video0
ExecStop=/lib/systemd/systemd-backlight load acpi_video0
TimeoutSec=90s

[Install]
WantedBy=sleep.target

Ubuntu 16.04 Note: The target backlight device name should be prefixed with "backlight:" (e.g. backlight:acpi_video0).

Enable by executing: systemctl enable suspend-save-backlight.service (or whatever you call it). Note that acpi_video0 is the name of the backlight symlink in /sys/class/backlight which is used to control the display brightness, might vary on different systems.

The above uses systemd's systemd-backlight executable to save and load the brightness before suspend and after resume respectively (inspired from /lib/systemd/system/systemd-backlight@.service which saves/loads brightness on restart/boot).


Old Solution (links a systemd service to my pm-utils suspend hook)

Found the problem. According to this ArchWiki article:

systemd does not use pm-utils to put the machine to sleep when using systemctl suspend, systemctl hibernate or systemctl hybrid-sleep; pm-utils hooks, including any custom hooks, will not be run. However, systemd provides two similar mechanisms to run custom scripts on these events.

So the right way to do it with systemd (which is used by default in 15.04) is to create the following service files which execute my brightness control script in /etc/pm/sleep.d/ as follows:

  1. /etc/systemd/system/root-suspend.service:

    [Unit]
    Description=Local system suspend actions
    Before=sleep.target
    
    [Service]
    Type=simple
    ExecStart=-/etc/pm/sleep.d/nvidiabl_brightness suspend
    
    [Install]
    WantedBy=sleep.target
    
  2. /etc/systemd/system/root-resume.service:

    [Unit]
    Description=Local system resume actions
    After=suspend.target
    
    [Service]
    Type=simple
    ExecStart=-/etc/pm/sleep.d/nvidiabl_brightness resume
    
    [Install]
    WantedBy=suspend.target
    

Then run the following to enable these services:

systemctl enable root-suspend.service
systemctl enable root-resume.service

Refer to the linked article for more details.

Related Question