my Dell laptop is subject to this bug with kernel 3.14. As a workaround I wrote a simple script
/usr/bin/brightness-fix:
#!/bin/bash echo 0 > /sys/class/backlight/intel_backlight/brightnes
(and made executable: chmod +x /usr/bin/brightness-fix)
and a systemd service calling it that is executed at startup:
/etc/systemd/system/brightness-fix.service
[Unit] Description=Fixes intel backlight control with Kernel 3.14 [Service] Type=forking ExecStart=/usr/bin/brightness-fix TimeoutSec=0 StandardOutput=syslog #RemainAfterExit=yes #SysVStartPriority=99 [Install] WantedBy=multi-user.target
and enabled: systemctl enable /etc/systemd/system/brightness-fix.service
That works like a charm and I can control my display brightness as wanted.
The problem comes when the laptop resumes after going to sleep mode (e.g. when closing the laptop lip): brightness control doesn’t work anymore unless I manually execute my fisrt script above: /usr/bin/brightness-fix
How can I create another systemd service like mine above to be executed at resume time?
EDIT:
According to comments below I have modified my brightness-fix.service like this:
[Unit] Description=Fixes intel backlight control with Kernel 3.14 [Service] Type=oneshot ExecStart=/usr/local/bin/brightness-fix TimeoutSec=0 StandardOutput=syslog [Install] WantedBy=multi-user.target sleep.target
also I have added echo "$1 $2" > /home/luca/br.log to my script to check whether it is actually executed.
The script it is actually executed also at resume (post suspend) but it has no effect (backlit is 100% and cannot be changed). I also tried logging $DISPLAY and $USER and, at resume time, they are empty. So my guess is that the script is executed too early when waking up from sleep. Any hint?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
I know this is an old question, but the following unit file worked for me to run a script upon resume from sleep:
[Unit] Description=<your description> After=suspend.target [Service] User=root Type=oneshot ExecStart=<your script here> TimeoutSec=0 StandardOutput=syslog [Install] WantedBy=suspend.target
I believe it is the After=suspend.target that makes it run on resume, rather than when the computer goes to sleep.
Method 2
As an alternative to writing and enabling a unit file, you can also put a shell script (or a symlink to your script) into /lib/systemd/system-sleep/.
It will be called before sleep/hibernate, and at resume time.
From man systemd-suspend.service :
Immediately before entering system suspend and/or hibernation
systemd-suspend.service (and the other mentioned units, respectively)
will run all executables in /usr/lib/systemd/system-sleep/ and pass
two arguments to them. The first argument will be “pre”, the second
either “suspend”, “hibernate”, or “hybrid-sleep” depending on the
chosen action. Immediately after leaving system suspend and/or
hibernation the same executables are run, but the first argument is
now “post”. All executables in this directory are executed in
parallel, and execution of the action is not continued until all
executables have finished.
Test it with this:
#!/bin/sh ## This file (or a link to it) must be in /lib/systemd/system-sleep/ logger -t "test" "$0=$0, $1=$1, $2=$2"
Method 3
Followup to mivk’s answer, in which I avoid mucking with a new unit file (see my question here How to react to laptop lid events?). Here’s my solution; it’s not 100% straightforward (sigh) because the system is not stable when it’s coming out of sleep:
On my Fedora 26 box I put a symlink here: /usr/lib/systemd/system-sleep/sleepyhead which points here: /root/bin/sleepyhead, which contains:
#!/bin/sh
## This file (or a link to it) must be in /lib/systemd/system-sleep/
# This is called when the lid is closed, as follows:
# $0=/usr/lib/systemd/system-sleep/sleepyhead, $1=pre, $2=suspend
# ...and when the lid is opened, as follows:
# $0=/usr/lib/systemd/system-sleep/sleepyhead, $1=post, $2=suspend
touch /tmp/sleepyrun
logger -t "sleepyhead" "Start: $1=$1, $2=$2"
if [ "$1" = "post" ] ; then
action="RUN trackpoint"
bash /root/bin/trackpoint >/tmp/trackpoint-run 2>&1
else
action="NO ACTION"
fi
logger -t "sleepyhead" "${action}: " "$1=$1, $2=$2"
The /root/bin/trackpoint script follows. Note that the first sleep is critical. The device is set up every time the lid is opened, so it doesn’t exist at first. If I try to do anything but sleep, the “sleepyhead” script takes a really long time to exit and my pointer will be frozen for at least 60 seconds. Furthermore, note that you cannot put the /root/bin/trackpoint script in the background in sleepyhead, above. If you do, the process will be killed when sleepyhead exits.
#!/bin/bash
# This is /root/bin/trackpoint
echo "Start $0"
date
found=false
dir=""
# dirlist can look like:
# /sys/devices/platform/i8042/serio1/serio25/speed
# /sys/devices/platform/i8042/serio1/serio24/speed
# ...the older one appears to get cleaned a little later.
sleep 1 # If I don't put this in here, my pointer locks up for a really long time...
for i in 1 2 3 4; do
speedfiles=$(find /sys/devices/platform/i8042 -name speed) # There may be multiple speed files at this point.
[ -z "$speedfiles" ] && { sleep 1; continue; }
dirlist=$(dirname $speedfiles)
printf "Speed file(s) at $(find /sys/devices/platform/i8042 -name speed | tail -1) n"
# All this remaking of the path is here because the filenames change with
# every resume, and what's bigger: 9 or 10? ...Depends if you're
# lexicographical or numerical. We need to always be numerical.
largest_number="$(echo $dirlist | tr ' ' 'n' | sed -e 's/.*serio//' | sort -n | tail -1)"
dir="$(echo $dirlist | tr ' ' 'n' | egrep serio${largest_number}$ )"
echo "Dir is $dir number is $largest_number"
[ -n "$dir" ] && found=true && break
done
$found || exit 1
date
echo -n 4 > $dir/inertia
echo -n 220 > $dir/sensitivity
echo -n 128 > $dir/speed
date
echo "Done $0"
Method 4
Here’s a more complete example. Files in /etc/ are prone to getting lost when setting new machines, so this variation stores the config file in your home directory, where you might keep track of it with a dotfile manager.
- Create a file named
~/.config/systemd/system/after-suspend.servicewith contents similar to the following. Adjust theExecStart=commands for your needs. The file will be run as root.
[Unit] Description=On Resume After=suspend.target [Service] Type=oneshot # The leading dash before the paths tells to systemd to tolerate these commands failing # --no-block makes the commands non-blocking ExecStart=-/usr/bin/systemctl --no-block restart iwd ExecStart=-/usr/bin/systemctl --no-block restart bluetooth.target [Install] WantedBy=suspend.target
- Link the file into systemd, restart systemd to load it, then enable it.
sudo systemctl link ~/.config/systemd/system/after-suspend.service sudo systemctl daemon-reload sudo systemctl enable after-suspend
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0