commit 28a5dec7dd31834394748c9b19411715eeddc43c
parent fad0a47b7547252330e4f0931c651ef63f3615dd
Author: Daniel Barlow <dan@telent.net>
Date: Sat, 16 Mar 2024 20:41:13 +0000
implement ifwait trigger service and use in bridge
should we convert all ifwait uses to this trigger too? seems
reasonable
Diffstat:
5 files changed, 91 insertions(+), 14 deletions(-)
diff --git a/modules/bridge/default.nix b/modules/bridge/default.nix
@@ -14,6 +14,8 @@ let
inherit (pkgs) liminix;
in
{
+ imports = [ ../ifwait ];
+
options = {
system.service.bridge = {
primary = mkOption { type = liminix.lib.types.serviceDefn; };
@@ -27,7 +29,7 @@ in
description = "bridge interface name to create";
};
};
- members = liminix.callService ./members.nix {
+ members = config.system.callService ./members.nix {
primary = mkOption {
type = liminix.lib.types.interface;
description = "primary bridge interface";
@@ -47,5 +49,5 @@ in
# a better way to test for the existence of vlan config:
# maybe the module should set an `enabled` attribute?
BRIDGE_VLAN_FILTERING = "y";
- };
+ };
}
diff --git a/modules/bridge/members.nix b/modules/bridge/members.nix
@@ -2,6 +2,7 @@
liminix
, ifwait
, lib
+, svc
}:
{ members, primary } :
@@ -10,14 +11,20 @@ let
inherit (liminix.services) bundle oneshot;
inherit (lib) mkOption types;
addif = member :
- oneshot {
- name = "${primary.name}.member.${member.name}";
- up = ''
- dev=$(output ${member} ifname)
- ${ifwait}/bin/ifwait $dev running && ip link set dev $dev master $(output ${primary} ifname)
- '';
- down = "ip link set dev $(output ${member} ifname) nomaster";
+ # how do we get sight of services from here? maybe we need to
+ # implement ifwait as a regualr derivation instead of a
+ # servicedefinition
+ svc.ifwait.build {
+ state = "running";
+ interface = member;
dependencies = [ primary member ];
+ service = oneshot {
+ name = "${primary.name}.member.${member.name}";
+ up = ''
+ ip link set dev $(output ${member} ifname) master $(output ${primary} ifname)
+ '';
+ down = "ip link set dev $(output ${member} ifname) nomaster";
+ };
};
in bundle {
name = "${primary.name}.members";
diff --git a/modules/ifwait/default.nix b/modules/ifwait/default.nix
@@ -0,0 +1,18 @@
+{ config, pkgs, lib, ... } :
+let
+ inherit (pkgs) liminix;
+ inherit (lib) mkOption types;
+in {
+ options.system.service.ifwait =
+ mkOption { type = liminix.lib.types.serviceDefn; };
+
+ config.system.service.ifwait = config.system.callService ./ifwait.nix {
+ state = mkOption { type = types.str; };
+ interface = mkOption {
+ type = liminix.lib.types.interface;
+ };
+ service = mkOption {
+ type = liminix.lib.types.service;
+ };
+ };
+}
diff --git a/modules/ifwait/ifwait.nix b/modules/ifwait/ifwait.nix
@@ -0,0 +1,15 @@
+{ ifwait, liminix } :
+{
+ state
+, interface
+, service
+}:
+let
+ inherit (liminix.services) longrun;
+in longrun {
+ name = "ifwait.${interface.name}";
+ buildInputs = [ service ];
+ run = ''
+ ${ifwait}/bin/ifwait -s ${service.name} $(output ${interface} ifname) ${state}
+ '';
+}
diff --git a/tests/updown/script.expect b/tests/updown/script.expect
@@ -13,9 +13,14 @@ spawn socat unix-connect:vm/console -
set console_id $spawn_id
expect "BusyBox"
-expect "#" { send "PS1=RE\\ADY_\\ \r" }
-expect "READY_" { send "sleep 3\r" }
-expect "READY_" { send "ip link\r" }
+expect "#" { send "PS1=RE\\ADY_\\ ; stty -echo \r" }
+expect "READY_" { send "s6-rc -b -a list\r" } ; # -b waits for s6-rc lock
+expect "READY_" { send "ls /sys/class/net/lan/master\r" }
+expect {
+ "No such file or directory" { }
+ timeout { exit 1 }
+}
+
expect "READY_" { send "cat /sys/class/net/lan/operstate\r" }
expect {
"down" { }
@@ -24,6 +29,36 @@ expect {
expect "READY_" { send "s6-rc -a -u change\r" }
expect {
"unable to take locks" { exit 1 }
- "READY_" { send "hostname\r" }
+ "READY_" { send "\r" }
}
-expect "updown"
+
+set spawn_id $monitor_id
+send "\r"
+expect "(qemu)"
+send "set_link virtio-net-pci.1 on\n"
+expect "(qemu)"
+send "set_link virtio-net-pci.0 on\n"
+expect "(qemu)"
+set spawn_id $console_id
+
+expect "entered forwarding state"
+send "\r"
+expect "READY_" { send "cat /sys/class/net/lan/operstate\r" }
+expect {
+ "down" { exit 1 }
+ "up" { }
+}
+
+expect "READY_" { send "cat /sys/class/net/lan/master/uevent\r" }
+expect {
+ "INTERFACE=int" { }
+ timeout { exit 1 }
+}
+
+expect "READY_" { send "s6-rc listall int.link.a.10.8.0.1.member.lan.link ; hostname\r" }
+
+expect {
+ "updown" {}
+ timeout { exit 1 }
+}
+