You are not logged in.

#1 2015-04-27 21:12:18

Wild Penguin
Member
Registered: 2015-03-19
Posts: 399

Delaying a service until a kernel module has loaded and... [SOLVED]

Hi,

I have a problem: a certain program is started too soon before a kernel module has had time to settle down. That means that the program needs to be restarted manually after each reboot, otherwise it won't detect the hardware.

The service in question is tvheadend (from aur) and the module ddbridge, which I've installed from outside of the kernel tree (since the one in kernel is out of date). That is a beta driver so probably it should settle sooner, but it doesn't.

From the recent boot (and others) I can see this:

$ journalctl -b | grep -i ddbridge
                                             experimental: 1969cdc5388b711e2aef3d1747b5f7dd1cd965f3 experimental/ddbridge: Fix 'inlining failed in call to always_inline ...: recursive inlining'.
huhti 27 20:25:59 ArkkiVille kernel: ddbridge 0000:02:00.0: enabling device (0000 -> 0002)
huhti 27 20:25:59 ArkkiVille kernel: DDBridge driver detected: Digital Devices Octopus DVB adapter
huhti 27 20:25:59 ArkkiVille kernel: ddbridge 0000:02:00.0: irq 41 for MSI/MSI-X
huhti 27 20:25:59 ArkkiVille kernel: DDBridge using 1 MSI interrupt(s)
huhti 27 20:25:59 ArkkiVille kernel: DVB: registering new adapter (DDBridge)
huhti 27 20:25:59 ArkkiVille kernel: DVB: registering new adapter (DDBridge)
                                             experimental: 1969cdc5388b711e2aef3d1747b5f7dd1cd965f3 experimental/ddbridge: Fix 'inlining failed in call to always_inline ...: recursive inlining'.
huhti 27 20:26:01 ArkkiVille kernel: ddbridge 0000:02:00.0: DVB: registering adapter 0 frontend 0 (DRXK DVB-C DVB-T)...
huhti 27 20:26:03 ArkkiVille kernel: ddbridge 0000:02:00.0: DVB: registering adapter 0 frontend 1 (DRXK DVB-C DVB-T)...

But the tvheadend unit file is run right after the module is loaded at 20:26:00, which is too soon before the device nodes have actually populated:

huhti 27 20:26:00 ArkkiVille systemd[1]: Starting tvheadend...
huhti 27 20:26:00 ArkkiVille systemd[1]: Started tvheadend.
huhti 27 20:26:00 ArkkiVille tvheadend[502]: charset: 71 entries loaded
huhti 27 20:26:00 ArkkiVille tvheadend[502]: CSA: Using SSE2 128bit parallel descrambling
huhti 27 20:26:00 ArkkiVille tvheadend[502]: epggrab: module eit created
huhti 27 20:26:00 ArkkiVille tvheadend[502]: epggrab: module uk_freesat created
huhti 27 20:26:00 ArkkiVille tvheadend[502]: epggrab: module uk_freeview created
huhti 27 20:26:00 ArkkiVille tvheadend[502]: epggrab: module viasat_baltic created
huhti 27 20:26:00 ArkkiVille tvheadend[502]: epggrab: module opentv-skyuk created
huhti 27 20:26:00 ArkkiVille tvheadend[502]: epggrab: module opentv-skyit created
huhti 27 20:26:00 ArkkiVille tvheadend[502]: epggrab: module opentv-ausat created
huhti 27 20:26:00 ArkkiVille tvheadend[502]: epggrab: module pyepg created
huhti 27 20:26:00 ArkkiVille tvheadend[502]: epggrab: module xmltv created
huhti 27 20:26:00 ArkkiVille tvheadend[502]: epgdb: loaded v2
huhti 27 20:26:00 ArkkiVille tvheadend[502]: epgdb:   channels   0
huhti 27 20:26:00 ArkkiVille tvheadend[502]: epgdb:   brands     0
huhti 27 20:26:00 ArkkiVille tvheadend[502]: epgdb:   seasons    0
huhti 27 20:26:00 ArkkiVille tvheadend[502]: epgdb:   episodes   10870
huhti 27 20:26:00 ArkkiVille tvheadend[502]: epgdb:   broadcasts 10869
huhti 27 20:26:00 ArkkiVille tvheadend[502]: dvr: Creating new configuration ''
huhti 27 20:26:00 ArkkiVille tvheadend[502]: AVAHI: Service 'Tvheadend' successfully established.
huhti 27 20:26:00 ArkkiVille tvheadend[502]: START: HTS Tvheadend version  started, running as PID:502 UID:1337 GID:91, settings located in '/home/hts/.hts/tvheadend'

Restarting the service manually 'fixes' the issue:

huhti 27 20:27:16 ArkkiVille tvheadend[1311]: dvb: Found adapter /dev/dvb/adapter0 (DRXK DVB-C DVB-T) via PCI
huhti 27 20:27:16 ArkkiVille tvheadend[1311]: dvb: Found adapter /dev/dvb/adapter0 (DRXK DVB-C DVB-T) via PCI
huhti 27 20:27:16 ArkkiVille tvheadend[1311]: dvb: Found adapter /dev/dvb/adapter1 (DRXK DVB-C DVB-T) via PCI

Any ideas how to 'delay' the service? Is there a .target or service (or similar) in systemd which can see if the kernel modules have settled down?

Is my only option making a dirty script that will check that the device nodes are there, or hard-coding a delay in the unit file? How would one do that?

EDIT: Just wanted to add a thank you - but don't want to necrobump too much. Berbaes solution works!

Cheers!

Last edited by Wild Penguin (2015-11-22 12:02:08)

Offline

#2 2015-04-28 09:40:39

berbae
Member
From: France
Registered: 2007-02-12
Posts: 1,304

Re: Delaying a service until a kernel module has loaded and... [SOLVED]

A simple way to do that would be to use a systemd timer unit, named '/etc/systemd/system/tvheadend.timer':

[Unit]
Description=Delaying tvheadend start

[Timer]
OnStartupSec=20
AccuracySec=5

Then:

# cp /usr/lib/systemd/system/tvheadend.service /etc/systemd/system
# cd /etc/systemd/system
# vim tvheadend.service
# diff /usr/lib/systemd/system/tvheadend.service tvheadend.service
14c14
< WantedBy=multi-user.target
---
> #WantedBy=multi-user.target

Edit: The above part is superfluous, sorry, see the next posts

Finally:

# systemctl disable tvheadend.service
# systemctl add-wants multi-user.target tvheadend.timer
# systemctl daemon-reload

This timer will start the 'tvheadend.service' 20 seconds (+~5 seconds) after systemd start time.

To my opinion, this is the easiest way to do that (no udev rule to write with the systemd device unit features which is much more complicated).

Last edited by berbae (2015-04-28 15:13:47)

Offline

#3 2015-04-28 09:54:54

Raynman
Member
Registered: 2011-10-22
Posts: 1,539

Re: Delaying a service until a kernel module has loaded and... [SOLVED]

berbae wrote:

Then:

# cp /usr/lib/systemd/system/tvheadend.service /etc/systemd/system
# cd /etc/systemd/system
# vim tvheadend.service
# diff /usr/lib/systemd/system/tvheadend.service tvheadend.service
14c14
< WantedBy=multi-user.target
---
> #WantedBy=multi-user.target

That seems rather pointless; just don't enable the service.

Offline

#4 2015-04-28 15:10:47

berbae
Member
From: France
Registered: 2007-02-12
Posts: 1,304

Re: Delaying a service until a kernel module has loaded and... [SOLVED]

@Raynman
Yes you are right, this part is useless; my fault.
Just the following part is enough, not the above one:

# systemctl disable tvheadend.service
# systemctl add-wants multi-user.target tvheadend.timer
# systemctl daemon-reload

Thanks.

Last edited by berbae (2015-04-28 15:15:54)

Offline

Board footer

Powered by FluxBB