liminix

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 626a365f790f628dc8deff27b2296545f239d3fe
parent 14dacb80565c6e6d7080d2cd85abfbd19b875198
Author: Daniel Barlow <dan@telent.net>
Date:   Wed,  1 Mar 2023 17:55:52 +0000

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

Diffstat:
Moverlay.nix | 2+-
Apkgs/ifwait/.#README | 2++
Apkgs/ifwait/default.nix | 32++++++++++++++++++++++++++++++++
Apkgs/ifwait/ifwait.fnl | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Apkgs/ifwait/waitup.fnl | 38++++++++++++++++++++++++++++++++++++++
Mpkgs/liminix-tools/networking/default.nix | 2++
Dpkgs/waitup/default.nix | 31-------------------------------
Dpkgs/waitup/waitup.fnl | 36------------------------------------
Mrotuer.nix | 18+++++++-----------
9 files changed, 134 insertions(+), 79 deletions(-)

diff --git a/overlay.nix b/overlay.nix @@ -87,7 +87,7 @@ final: prev: { }; netlink-lua = final.callPackage ./pkgs/netlink-lua {}; - waitup = final.callPackage ./pkgs/waitup {}; + ifwait = final.callPackage ./pkgs/ifwait {}; serviceFns = final.writeText "service-fns.sh" '' output() { cat $1/.outputs/$2; } diff --git a/pkgs/ifwait/.#README b/pkgs/ifwait/.#README @@ -0,0 +1 @@ +dan@noetbook.911352349782478447 +\ No newline at end of file diff --git a/pkgs/ifwait/default.nix b/pkgs/ifwait/default.nix @@ -0,0 +1,32 @@ +{ + lua5_3 +, netlink-lua +, stdenv +, makeWrapper +}: +let + lua = lua5_3; + netlink = netlink-lua.override {inherit lua;}; + fennel = lua.pkgs.fennel; +in stdenv.mkDerivation rec { + pname = "ifwait"; + version = "1"; + phases = [ "installPhase" ]; + + buildInputs = [ lua netlink ]; + nativeBuildInputs = [ makeWrapper fennel ]; + + LUA_CPATH = "${netlink}/lib/lua/${lua.luaversion}/\?.so"; # for nix-shell + + installPhase = '' + mkdir -p $out/bin $out/lib + fennel --compile ${./ifwait.fnl} > $out/lib/${pname}.lua + + makeWrapper ${lua}/bin/lua $out/bin/${pname} \ + --prefix LUA_CPATH ";" ${netlink}/lib/lua/${lua.luaversion}/\?.so \ + --add-flags $out/lib/${pname}.lua + ''; +} + +# to use fennel.view, +# --prefix LUA_PATH ";" ${fennel}/share/lua/5.2/\?.lua \ diff --git a/pkgs/ifwait/ifwait.fnl b/pkgs/ifwait/ifwait.fnl @@ -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))) diff --git a/pkgs/ifwait/waitup.fnl b/pkgs/ifwait/waitup.fnl @@ -0,0 +1,38 @@ +(local netlink (require :netlink)) +(local sock (netlink.socket)) + +(when (< (# arg) 2) + (print "usage: waitup ifname fd") + (os.exit 1)) + +(local ifname (. arg 1)) +(local fd (tonumber (. arg 2))) +(local stream (io.open (.. "/proc/self/fd/" fd) "w")) + +(fn notify-ready [] + (when (= "file" (io.type stream)) + (stream:write "\n") + (stream:close)) + (print (.. (. arg 0) ": received netlink operstate up for " ifname))) + + +(fn run-events [evs] + (each [_ v (ipairs evs)] + (print :event v.event v.name) + + (match v + ;; - up: Reflects the administrative state of the interface (IFF_UP) + ;; - running: Reflects the operational state (IFF_RUNNING). + {:event "newlink" :name ifname :up :yes :running :yes} + (notify-ready) + + {:event "newlink" :name ifname :up :no} + (os.exit 0)))) + +(run-events (sock:query {:link true})) + +(print (.. (. arg 0) ": waiting for netlink NEWLINK " ifname)) + +(while (sock:poll) + (let [ev (sock:event)] + (run-events ev))) diff --git a/pkgs/liminix-tools/networking/default.nix b/pkgs/liminix-tools/networking/default.nix @@ -1,6 +1,7 @@ { callPackage , liminix +, ifwait , lib }: let @@ -12,6 +13,7 @@ in { [] ++ optional (type == "bridge") "ip link add name ${device} type bridge" + ++ ["${ifwait}/bin/ifwait -v ${device} present"] ++ ["ip link set up dev ${device}"] ++ optional (primary != null) "ip link set dev ${device} master ${primary.device}"; diff --git a/pkgs/waitup/default.nix b/pkgs/waitup/default.nix @@ -1,31 +0,0 @@ -{ - lua5_3 -, netlink-lua -, stdenv -, makeWrapper -}: -let - lua = lua5_3; - netlink = netlink-lua.override {inherit lua;}; - fennel = lua.pkgs.fennel; -in stdenv.mkDerivation rec { - pname = "waitup"; - version = "1"; - - buildInputs = [ lua netlink-lua ]; - nativeBuildInputs = [ makeWrapper fennel ]; - - src = ./.; - - installPhase = '' - mkdir -p $out/bin $out/lib - fennel --compile ${./waitup.fnl} > $out/lib/waitup.lua - - makeWrapper ${lua}/bin/lua $out/bin/${pname} \ - --prefix LUA_CPATH ";" ${netlink}/lib/lua/${lua.luaversion}/\?.so \ - --add-flags $out/lib/waitup.lua - ''; -} - -# to use fennel.view, -# --prefix LUA_PATH ";" ${fennel}/share/lua/5.2/\?.lua \ diff --git a/pkgs/waitup/waitup.fnl b/pkgs/waitup/waitup.fnl @@ -1,36 +0,0 @@ -(local netlink (require :netlink)) -(local sock (netlink.socket)) - -(when (< (# arg) 2) - (print "usage: waitup ifname fd") - (os.exit 1)) - -(local ifname (. arg 1)) -(local fd (tonumber (. arg 2))) -(local stream (io.open (.. "/proc/self/fd/" fd) "w")) - -(fn notify-ready [] - (stream:write "\n") - (print (.. (. arg 0) ": received netlink operstate up for " ifname)) - (stream:close)) - -(fn run-events [evs] - (each [_ v (ipairs evs)] - (print :event v.event v.name) - - (match v - ;; - up: Reflects the administrative state of the interface (IFF_UP) - ;; - running: Reflects the operational state (IFF_RUNNING). - {:event "newlink" :name ifname :up :yes :running :yes} - (notify-ready) - - {:event "newlink" :name ifname :up :no} - (os.exit 0)))) - -(run-events (sock:query {:link true})) - -(print (.. (. arg 0) ": waiting for netlink NEWLINK " ifname)) - -(while (sock:poll) - (let [ev (sock:event)] - (run-events ev))) diff --git a/rotuer.nix b/rotuer.nix @@ -19,7 +19,7 @@ let route; inherit (pkgs.liminix.services) oneshot longrun bundle target; inherit (pkgs) - waitup + ifwait serviceFns iptables; in rec { @@ -122,17 +122,13 @@ in rec { }; services.bridgewlan = - let waitup-wlan = longrun { - name = "waitup-wlan0"; - run = "${waitup}/bin/waitup wlan0 10"; - notification-fd = 10; - dependencies = [ services.wireless services.hostap ]; - }; + let dev = services.wireless.device; in oneshot { - name = "add-wlan-to-bridge"; - up = "ip link set dev ${services.wireless.device} master ${services.lan.device}"; - down = "ip link set dev ${services.wireless.device} nomaster"; - dependencies = [ waitup-wlan ]; + name = "add-wlan2-to-bridge"; + up = "${ifwait}/bin/ifwait -v ${dev} running && ip link set dev ${dev} master ${services.lan.device}"; + down = "ip link set dev ${dev} nomaster"; + dependencies = [ services.wireless ]; + }; }; users.dnsmasq = {