Procd respawn trigger?

Sometimes services need post-initialization and thus, simply respawning crashed program is not enough.
For instance, program creates tun interface and after that, in service_started(), some route rules/tables are added. When program crashed, interface disappeared (together with corresponding routing entries), procd detects crashed process and respawns it… but seems there is no way to recreate routing entries.

Is there a trigger for the respawn event? I found nothing relevant in procd.sh.

I'm looking for a way to implement something like procd_add_reload_respawn_trigger and procd_add_restart_respawn_trigger but I'm in doubts if procd supports respawn trigger.

investigating the issue I've noticed that procd emits ubus event on respawn:

ubus monitor
…
<- fbc72cb4 #d438d55e         notify: {"objid":-734472866,"method":"instance.respawn","data":{"service":"SERVICE","instance":"INSTANCE"},"no_reply":true}
…

procd triggers internals aren't documented, and even after some investigation I'm not understanding how (for instance) procd_add_reload_interface_trigger works (in fact, I've got no reloads creating and destroying dummy network interface), but I've noticed something interesting:

/etc/init.d/sysntpd: procd_add_raw_trigger "interface.*" 1000 /etc/init.d/$name reload
/etc/init.d/uhttpd:  procd_add_raw_trigger acme.renew 5000 /etc/init.d/uhttpd reload

seems like something able to respond to ubus events by mask. But I have no idea how to bind respawn event using this raw trigger properly.

2 Likes

At the moment I've ended up with a separate script (running as a separate service):

#!/bin/sh  

ubus subscribe service | while read -r line; do
    svc=$(jsonfilter -s "$line" -e '@["instance.respawn"].service') || continue   
    delay= ... # getting service delay
    ( sleep $delay; /etc/init.d/$svc respawned; ) &
done

Script reads service events from ubus and retrieves service name from instance.respawn event. After that, it calls extra respawned service command. Target service must define this command:

#!/bin/sh /etc/rc.common 
USE_PROCD=1              

…
EXTRA_COMMANDS="respawned" 
respawned() {    
    # do something
}
1 Like