I'll just post and follow this thread for the moment
]]>What I've done is to add an option for DAEMONS in rc.conf, which allows starting a daemon after all the previous dependencies are actually done.
This is done by a creating a named pipe for a before it starts, and removing it after the daemon completes.
Daemons with dependencies are guaranteed to either be blocked by reading the named pipe or fail to find the named pipe (which means it already completed) by some tricks.
Here is the snippet from the rc.multi:
depsd="/var/lock/boot"
mkdir -p "$depsd"
rm -f "$depsd"/*
start_daemon_dep(){
local dep daemon="$1"
shift
for dep; do
cat "$depsd/$dep" 2>/dev/null
done
start_daemon "$daemon"
/etc/rc.d/daemon_complete "$depsd/$daemon"
}
make_dep(){
mkfifo "$depsd/$1"
(cat "$depsd/$1") 2>/dev/null &
stat_bkgd "Starting daemon $1"
}
# Start daemons
for daemon in "${DAEMONS[@]}"; do
d=(${daemon//:/ })
case ${d[0]:0:1} in
'!') continue;;
'@')
make_dep "${d[0]#@}"
(start_daemon_dep ${d[0]#@} ${d[1]//,/ }) 1>/dev/null &
;;
*)
make_dep "${d[0]}"
start_daemon_dep ${d[0]} ${d[1]//,/ } 1>/dev/null
;;
esac
done
/etc/rc.d/daemon_complete is the programing doing the atomic guarantee.
daemon_complete.c:
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
int main(int argc, char **argv){
int fd;
if((fd = open(argv[1], O_WRONLY))< 0)
return 1;
if(unlink(argv[1]) < 0)
return 1;
if(close(fd) < 0)
return 1;
return 0;
}
Then we can write something like the following in rc.conf:
DAEMONS=(hwclock
rsyslogd
@network
@ntpdate:network
@dnsmasq:network
dbus
kdm:dbus,network
crond)
This means that ntpdate is running in background, but it won't start until its dependency, network, completes in background.
Multiple dependencies can be applied like the one kdm does: it relies on both dbus and network.
However, changing DAEMONS array syntax breaks some functionalities in /etc/rc.d/functions, so we have to accordingly change the file.
The file is here.
edit: I shouldn't put the executable in /etc/rc.d/functions.d/, so now it's in /etc/rc.d/
]]>