dhcp4 client: start controlled service when lease acquired
it is problematic to have dhcp signal readiness when a lease is acquired, because it holds the s6 service lock while it's waiting and that can lead to deadlock. Instead, start the dhcp client "daemon" process and monitor its outputs, bringing up and down a controlled "dhcp lease acquired" service that other services (e.g. ntp, or resolvconf, or ...) can declare as a dependency
This commit is contained in:
@@ -2,6 +2,11 @@
|
||||
liminix,
|
||||
writeAshScript,
|
||||
serviceFns,
|
||||
writeFennel,
|
||||
anoia,
|
||||
linotify,
|
||||
lualinux,
|
||||
s6-rc-up-tree,
|
||||
lib,
|
||||
}:
|
||||
{ interface }:
|
||||
@@ -29,7 +34,6 @@ let
|
||||
bound)
|
||||
# this doesn't actually replace, it adds a new address.
|
||||
set_address
|
||||
# echo >/proc/self/fd/10
|
||||
;;
|
||||
renew)
|
||||
set_address
|
||||
@@ -39,9 +43,36 @@ let
|
||||
;;
|
||||
esac
|
||||
'';
|
||||
in
|
||||
longrun {
|
||||
inherit name;
|
||||
run = "exec /bin/udhcpc -n -A 15 -f -i $(output ${interface} ifname) -x hostname:$(cat /proc/sys/kernel/hostname) -s ${script}";
|
||||
dependencies = [ interface ];
|
||||
service = longrun {
|
||||
inherit name;
|
||||
run = "exec /bin/udhcpc -n -A 15 -f -i $(output ${interface} ifname) -x hostname:$(cat /proc/sys/kernel/hostname) -s ${script}";
|
||||
dependencies = [ interface ];
|
||||
};
|
||||
controlled-name = "${name}-lease-acquired";
|
||||
watcher = longrun {
|
||||
name = "${name}-watcher";
|
||||
dependencies = [ service ];
|
||||
run =
|
||||
let
|
||||
script = writeFennel "dhcp-lease-watcher" {
|
||||
packages = [ anoia linotify lualinux ];
|
||||
mainFunction = "run";
|
||||
}
|
||||
./lease-watcher.fnl;
|
||||
in ''
|
||||
export PATH=${s6-rc-up-tree}/bin/:$PATH
|
||||
${script} ${service} ${controlled-name}
|
||||
'';
|
||||
};
|
||||
in longrun {
|
||||
name = controlled-name;
|
||||
run = ''
|
||||
set -e
|
||||
echo dhcp lease acquired $(output ${service} ip)
|
||||
(in_outputs ${controlled-name}
|
||||
cp $(output_path ${service})/* .
|
||||
)
|
||||
while sleep 86400 ; do true ; done
|
||||
'';
|
||||
controller = watcher;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
(local { : %% : system } (require :anoia))
|
||||
(local svc (require :anoia.svc))
|
||||
|
||||
(fn up-service [name]
|
||||
(system (%% "s6-rc-up-tree %q" name)))
|
||||
|
||||
(fn down-service [name]
|
||||
(system (%% "s6-rc -b -d change %q" name)))
|
||||
|
||||
(fn react [s controlled]
|
||||
(let [ip (s:output "ip")]
|
||||
(print "event" "ip=" ip)
|
||||
(if ip
|
||||
(up-service controlled)
|
||||
(down-service controlled))))
|
||||
|
||||
(fn run []
|
||||
(let [[watched controlled] arg
|
||||
s (assert (svc.open watched))]
|
||||
(print :service s)
|
||||
(react s controlled)
|
||||
(each [e (s:events)]
|
||||
(print :event e)
|
||||
(react s controlled))))
|
||||
|
||||
{ : run }
|
||||
@@ -44,6 +44,7 @@ in
|
||||
../network
|
||||
../hostapd
|
||||
../bridge
|
||||
../dhcp4c
|
||||
{ config.services = hostaps; }
|
||||
];
|
||||
|
||||
@@ -57,7 +58,6 @@ in
|
||||
};
|
||||
};
|
||||
config = {
|
||||
|
||||
services.int = svc.bridge.primary.build {
|
||||
ifname = "int";
|
||||
};
|
||||
@@ -67,7 +67,7 @@ in
|
||||
members = cfg.interfaces;
|
||||
};
|
||||
|
||||
services.dhcpc = svc.network.dhcp.client.build {
|
||||
services.dhcpc = svc.dhcp4c.client.build {
|
||||
interface = config.services.int;
|
||||
dependencies = [ config.services.hostname ];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user