Writing systemd unit file for suspend/resume

suspendsystemd

Every time i boot my system I enter

# su
Password:
# hciattach -s 152000 /dev/ttyS1 billionton

Thats needed for initializing my BT mouse
and
after resuming from suspend i have to enter following:

# su
Password:

Looking for hciattach PID and killing it

# pkill hciattach
# hciattach -s 152000 /dev/ttyS1 billionton

Now i have composed two scripts

# cat bt-mouse-suspend.service 
[Unit]
Description=BT Mouse suspend helper
Before=sleep.target

[Service]
Type=simple
ExecStart=-/usr/bin/pkill hciattach

[Install]
WantedBy=sleep.target

# cat bt-mouse-resume.service 
[Unit]
Description=BT Mouse resume helper
After=suspend.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/hciattach -s 152000 /dev/ttyS1 billionton

[Install]
WantedBy=suspend.target
# systemctl status bt-mouse-resume
● bt-mouse-resume.service - BT Mouse resume helper
   Loaded: loaded (/etc/systemd/system/bt-mouse-resume.service; enabled; vendor preset: disabled)
   Active: active (exited) since Mon 2017-04-03 22:09:50 EEST; 12min ago
 Main PID: 6386 (code=exited, status=0/SUCCESS)
    Tasks: 0 (limit: 4915)
   CGroup: /system.slice/bt-mouse-resume.service

apr   03 22:09:50 Twinh systemd[1]: Started BT Mouse resume helper.
apr   03 22:09:51 Twinh hciattach[6386]: Device setup complete
# pgrep hciattach
#

Suspend script works well and kills what expected. But the resume hciattach once executed but becomes vanished after that.

Best Answer

You've confused what After is referring to, After will cause a service to wait for another unit before it starts. Your Wanted-By=suspend.target and After=suspend.target contradict each other.

The Wanted-By is stating that bt-mouse-resume.service is a part of suspend.target, but the After is stating that bt-mouse-resume.service should wait until suspend.target is done. Services should not be a part of a target and wait for that target before starting. This also means you're configuring your service to run when suspend.target is started, rather than when it is exited.

What you're really looking for is a way to run something when stopping suspend.target, so I'll point you to a pretty important part of systemd:

Note that when two units with an ordering dependency between them are shut down, the inverse of the start-up order is applied.

Reference

So you say your bt-mouse-suspend.service is working properly. Because of its Wanted-By=sleep.target, when sleep.target is started your service is run. Conversely, when sleep.target is stopped bt-mouse-suspend.service will be stopped as well. You should not require the Before field in this service, you are making your service an action of that target already.

So if you want to run /usr/bin/hciattach -s 152000 /dev/ttyS1 billionton when leaving sleep.target, make it the ExecStop for bt-mouse-suspend.service.

I'd also recommend some further reading on how systemd works, namely take a look at:

https://www.freedesktop.org/software/systemd/man/systemd.service.html#

https://www.freedesktop.org/software/systemd/man/systemd.unit.html#

https://www.freedesktop.org/software/systemd/man/systemd.target.html#

Also, your two services target suspend.target and sleep.target. You should obviously use whichever target you're actually concerned with, but you're probably only looking for suspend.target.