[systemd-devel] suspend/resume hooks, the right way

Łukasz Stelmach stlman at poczta.fm
Sat Sep 26 04:55:56 PDT 2015


Andrei Borzenkov <arvidjaar at gmail.com> writes:

> 25.09.2015 23:17, Łukasz Stelmach пишет:
>> Hi,
>>
>> systemd-sleep(8) states
>>
>>         Note that scripts or binaries dropped in /usr/lib/systemd/system-sleep/
>>         are intended for local use only and should be considered hacks. If
>>         applications want to be notified of system suspend/hibernation and
>>         resume, there are much nicer interfaces available.
>>
>> What is the right way to hook some oneshot services like battery status
>> monitor[1] into systemd so they get executed as pre-sleep and
>> post-resume (or more specifically (pre|post)-(suspend|hibernate|hybrid-sleep)
>> if possible) hooks?
>> I found some notes[2] on Arch wiki.
>
> This one looks pretty fine as system-sleep hook. What's wrong with it?

See right below.

>> Unfortunately the unit with both StopWhenUnneeded and RemainAfterExit
>> does not work well when triggered with timer because it executes both
>> ExecStart and ExecStop commands and puts duplicate entries in the
>> log.

I'd like to run a service (the script) on three different ocassions:

+ once every 15 fifteen minutes (via timer unit)
+ upon "power" state changes:
  + power on and off (that's easy and obvioius)
  + sleep and resume (of every kind)
+ DC jack pluged in and out

The service is definitely a "oneshot" type, programme is started does
its job end exits. According to systemd "tradition" as I perceive it,
the service file should look like this:

--8<---------------cut here---------------start------------->8---
[Unit]
Description=Record Battery Status

[Service]
Type=oneshot
ExecStart=/root/bin/battery-status.sh
--8<---------------cut here---------------end--------------->8---

I'd like to have *one* service file attached to different triggers.
I don't want to add stuff like "StopWhenUnneeded=yes",
"RemainAfterExit=yes" "ExecStop=..." because:

+ it does not work, it causes the script to be fired twice in a row with
  a timer

+ it looks a bit abusive (that's subjective of course), somthing like
  trying to make the unit Turing-complete.

Let's say that I consider the below unit still a valid non-abusive unit.

--8<---------------cut here---------------start------------->8---
[Unit]
Description=Record Battery Status
Before=sleep.target shutdown.target

[Service]
Type=oneshot
ExecStart=/root/bin/battery-status.sh

[Install]
WantedBy=sleep.target shutdown.target
--8<---------------cut here---------------end--------------->8---

Such service works as expected:

+ with the timer
+ upon suspend/shutdown.

It does not work upon resume. I know that there is no resume.target
and making services run upon resume isn't as streightforward as
"WantedBy=resume.target" or "WantedBy=post-hibernate.target". However, I
hoped (hope) it isn't as hacky as StopWhenUnneeded+ExecStop which,
although logically correct, isn't the way I would like to express my
intentions about running a service after resuming from sleep. And I hope
I don't need to write a separate long running service that detects
suspends/resumes/shutdown/reboots and acts accordingly.

>> Then, does any part of systemd (package) react to plugging and
>> unplugging DC jack into a laptop?
>>
>> [1] http://people.skolelinux.org/pere/blog/The_life_and_death_of_a_laptop_battery.html
>> [2] https://wiki.archlinux.org/index.php/Power_management#Sleep_hooks
>>
>

-- 
Było mi bardzo miło.                                  --- Rurku. --- ...
>Łukasz<                                --- To dobrze, że mnie słuchasz.


More information about the systemd-devel mailing list