replace waitup with more generally useful ifwait

* wait for $interface present before ip link set up dev
* wait for wlan0 running before adding to bridge
This commit is contained in:
Daniel Barlow 2023-03-01 17:55:52 +00:00
parent 14dacb8056
commit 626a365f79
7 changed files with 75 additions and 21 deletions

View file

@ -87,7 +87,7 @@ final: prev: {
}; };
netlink-lua = final.callPackage ./pkgs/netlink-lua {}; netlink-lua = final.callPackage ./pkgs/netlink-lua {};
waitup = final.callPackage ./pkgs/waitup {}; ifwait = final.callPackage ./pkgs/ifwait {};
serviceFns = final.writeText "service-fns.sh" '' serviceFns = final.writeText "service-fns.sh" ''
output() { cat $1/.outputs/$2; } output() { cat $1/.outputs/$2; }

1
pkgs/ifwait/.#README Symbolic link
View file

@ -0,0 +1 @@
dan@noetbook.911352349782478447

View file

@ -9,21 +9,22 @@ let
netlink = netlink-lua.override {inherit lua;}; netlink = netlink-lua.override {inherit lua;};
fennel = lua.pkgs.fennel; fennel = lua.pkgs.fennel;
in stdenv.mkDerivation rec { in stdenv.mkDerivation rec {
pname = "waitup"; pname = "ifwait";
version = "1"; version = "1";
phases = [ "installPhase" ];
buildInputs = [ lua netlink-lua ]; buildInputs = [ lua netlink ];
nativeBuildInputs = [ makeWrapper fennel ]; nativeBuildInputs = [ makeWrapper fennel ];
src = ./.; LUA_CPATH = "${netlink}/lib/lua/${lua.luaversion}/\?.so"; # for nix-shell
installPhase = '' installPhase = ''
mkdir -p $out/bin $out/lib mkdir -p $out/bin $out/lib
fennel --compile ${./waitup.fnl} > $out/lib/waitup.lua fennel --compile ${./ifwait.fnl} > $out/lib/${pname}.lua
makeWrapper ${lua}/bin/lua $out/bin/${pname} \ makeWrapper ${lua}/bin/lua $out/bin/${pname} \
--prefix LUA_CPATH ";" ${netlink}/lib/lua/${lua.luaversion}/\?.so \ --prefix LUA_CPATH ";" ${netlink}/lib/lua/${lua.luaversion}/\?.so \
--add-flags $out/lib/waitup.lua --add-flags $out/lib/${pname}.lua
''; '';
} }

52
pkgs/ifwait/ifwait.fnl Normal file
View file

@ -0,0 +1,52 @@
(local netlink (require :netlink))
(local sock (netlink.socket))
; (local { : view} (require :fennel))
(fn assoc [tbl k v]
(tset tbl k v)
tbl)
(fn parse-args [args]
(match args
["-v" & rest] (assoc (parse-args rest) :verbose true)
["-t" timeout & rest] (assoc (parse-args rest) :timeout (tonumber timeout))
[linkname "up"] {:link linkname :expecting "up"}
[linkname "running"] {:link linkname :expecting "running"}
[linkname "present"] {:link linkname :expecting "present"}
[linkname nil] {:link linkname :expecting "present"}
_ nil))
(local parameters
(or
(parse-args arg)
(assert false (.. "Usage: " (. arg 0) " [-v] ifname [present|up|running]"))))
(fn run-events [evs]
(each [_ v (ipairs evs)]
(let [got
(match v
;; - up: Reflects the administrative state of the interface (IFF_UP)
;; - running: Reflects the operational state (IFF_RUNNING).
{:event "newlink" :name parameters.link :up :yes :running :yes}
{:present true :up true :running true}
{:event "newlink" :name parameters.link :up :yes}
{:present :true :up true}
{:event "newlink" :name parameters.link}
{:present true }
_
{})]
(when (. got parameters.expecting)
(os.exit 0)))))
(when parameters.verbose
(print (.. (. arg 0) ": waiting for "
parameters.link " to be " parameters.expecting)))
(run-events (sock:query {:link true}))
(while (sock:poll) (run-events (sock:event)))

View file

@ -10,9 +10,11 @@
(local stream (io.open (.. "/proc/self/fd/" fd) "w")) (local stream (io.open (.. "/proc/self/fd/" fd) "w"))
(fn notify-ready [] (fn notify-ready []
(when (= "file" (io.type stream))
(stream:write "\n") (stream:write "\n")
(print (.. (. arg 0) ": received netlink operstate up for " ifname))
(stream:close)) (stream:close))
(print (.. (. arg 0) ": received netlink operstate up for " ifname)))
(fn run-events [evs] (fn run-events [evs]
(each [_ v (ipairs evs)] (each [_ v (ipairs evs)]

View file

@ -1,6 +1,7 @@
{ {
callPackage callPackage
, liminix , liminix
, ifwait
, lib , lib
}: }:
let let
@ -12,6 +13,7 @@ in {
[] []
++ optional (type == "bridge") ++ optional (type == "bridge")
"ip link add name ${device} type bridge" "ip link add name ${device} type bridge"
++ ["${ifwait}/bin/ifwait -v ${device} present"]
++ ["ip link set up dev ${device}"] ++ ["ip link set up dev ${device}"]
++ optional (primary != null) ++ optional (primary != null)
"ip link set dev ${device} master ${primary.device}"; "ip link set dev ${device} master ${primary.device}";

View file

@ -19,7 +19,7 @@ let
route; route;
inherit (pkgs.liminix.services) oneshot longrun bundle target; inherit (pkgs.liminix.services) oneshot longrun bundle target;
inherit (pkgs) inherit (pkgs)
waitup ifwait
serviceFns serviceFns
iptables; iptables;
in rec { in rec {
@ -122,17 +122,13 @@ in rec {
}; };
services.bridgewlan = services.bridgewlan =
let waitup-wlan = longrun { let dev = services.wireless.device;
name = "waitup-wlan0";
run = "${waitup}/bin/waitup wlan0 10";
notification-fd = 10;
dependencies = [ services.wireless services.hostap ];
};
in oneshot { in oneshot {
name = "add-wlan-to-bridge"; name = "add-wlan2-to-bridge";
up = "ip link set dev ${services.wireless.device} master ${services.lan.device}"; up = "${ifwait}/bin/ifwait -v ${dev} running && ip link set dev ${dev} master ${services.lan.device}";
down = "ip link set dev ${services.wireless.device} nomaster"; down = "ip link set dev ${dev} nomaster";
dependencies = [ waitup-wlan ]; dependencies = [ services.wireless ];
};
}; };
users.dnsmasq = { users.dnsmasq = {