commit 5df5c822ea625da7ef1acadc06fa4cb10133595e
parent 4795dd05b79c3bd18f2909faa8baf9cd559864d8
Author: Daniel Barlow <dan@telent.net>
Date: Wed, 3 Apr 2024 23:17:36 +0100
convert mount service to trigger
Good: this means it's not hanging holding the s6 dataase lock.
Bad: it's the ugliest implementation and doesn't deserve to be preserved
(tbf the ugliness is not new)
Diffstat:
5 files changed, 154 insertions(+), 6 deletions(-)
diff --git a/modules/mount/service.nix b/modules/mount/service.nix
@@ -4,15 +4,28 @@
}:
{ device, mountpoint, options, fstype }:
let
- inherit (liminix.services) oneshot;
-in oneshot {
- name = "mount.${lib.escapeURL mountpoint}";
- up = ''
+ inherit (liminix.services) longrun oneshot;
+ options_string =
+ if options == [] then "" else "-o ${lib.concatStringsSep "," options}";
+ mount_service = oneshot {
+ name = "mount.${lib.escapeURL mountpoint}";
+ timeout-up = 3600;
+ up = "mount -t ${fstype} ${options_string} ${device} ${mountpoint}";
+ down = "umount ${mountpoint}";
+ };
+in longrun {
+ name = "watch-mount.${lib.strings.sanitizeDerivationName mountpoint}";
+ isTrigger = true;
+ buildInputs = [ mount_service ];
+
+ # This accommodates bringing the service up when the device appears.
+ # It doesn't bring it down on unplug because unmount will probably
+ # fail anyway (so don't do that)
+ run = ''
while ! findfs ${device}; do
echo waiting for device ${device}
sleep 1
done
- mount -t ${fstype} -o ${lib.concatStringsSep "," options} ${device} ${mountpoint}
+ s6-rc -b -u change ${mount_service.name}
'';
- down = "umount ${mountpoint}";
}
diff --git a/tests/ci.nix b/tests/ci.nix
@@ -9,4 +9,5 @@
fennel = import ./fennel/test.nix;
tftpboot = import ./tftpboot/test.nix;
updown = import ./updown/test.nix;
+ inout = import ./inout/test.nix;
}
diff --git a/tests/inout/configuration.nix b/tests/inout/configuration.nix
@@ -0,0 +1,61 @@
+{ config, pkgs, lib, modulesPath, ... } :
+let
+ inherit (pkgs.liminix.services) bundle oneshot longrun;
+ inherit (pkgs.pseudofile) dir symlink;
+ inherit (pkgs) serviceFns;
+
+ svc = config.system.service;
+
+in rec {
+ imports = [
+ "${modulesPath}/dhcp6c"
+ "${modulesPath}/dnsmasq"
+ "${modulesPath}/firewall"
+ "${modulesPath}/hostapd"
+ "${modulesPath}/network"
+ "${modulesPath}/ssh"
+ "${modulesPath}/mount"
+ ];
+
+ filesystem = dir { srv = dir {}; };
+
+ kernel = {
+ config = {
+ USB = "y";
+ USB_EHCI_HCD = "y";
+ USB_EHCI_HCD_PLATFORM = "y";
+ USB_OHCI_HCD = "y";
+ USB_OHCI_HCD_PLATFORM = "y";
+ USB_SUPPORT = "y";
+ USB_COMMON = "y";
+ USB_STORAGE = "y";
+ USB_STORAGE_DEBUG = "n";
+ USB_UAS = "y";
+ USB_ANNOUNCE_NEW_DEVICES = "y";
+ SCSI = "y";
+ BLK_DEV_SD = "y";
+ USB_PRINTER = "y";
+ MSDOS_PARTITION = "y";
+ EFI_PARTITION = "y";
+ EXT4_FS = "y";
+ EXT4_USE_FOR_EXT2 = "y";
+ FS_ENCRYPTION = "y";
+ };
+ };
+
+ rootfsType = "jffs2";
+ hostname = "inout";
+
+ services.mount_external_disk = svc.mount.build {
+ device = "LABEL=backup-disk";
+ mountpoint = "/srv";
+ fstype = "ext4";
+ };
+
+ services.sshd = svc.ssh.build { };
+
+ defaultProfile.packages = with pkgs; [
+ min-collect-garbage
+ tcpdump
+ ];
+}
diff --git a/tests/inout/script.expect b/tests/inout/script.expect
@@ -0,0 +1,47 @@
+set timeout 10
+
+proc chat {instr outstr} {
+ expect {
+ $instr { send $outstr }
+ timeout { exit 1 }
+ }
+}
+spawn socat -,echo=0,icanon=1 unix-connect:vm/monitor
+set monitor_id $spawn_id
+
+# expect "(qemu)"
+# send "set_link virtio-net-pci.1 off\n"
+# expect "(qemu)"
+# send "set_link virtio-net-pci.0 off\n"
+# expect "(qemu)"
+# send "c\r\n"
+
+spawn socat unix-connect:vm/console -
+set console_id $spawn_id
+
+expect "BusyBox"
+chat "#" "PS1=RE\\ADY_\\ ; stty -echo \r"
+chat "READY_" "s6-rc -b -a list\r"
+
+chat "watch-mount" "\r"
+
+set spawn_id $monitor_id
+chat "QEMU" "device_add usb-storage,bus=xhci.0,drive=usbstick\n"
+chat "(qemu)" "version\r"
+
+set spawn_id $console_id
+
+expect {
+ "mounted filesystem" { }
+ timeout { exit 1 }
+}
+
+
+send "\r"
+chat "READY_" "s6-rc -b -a list\r"
+chat "READY_" "cat /proc/mounts\r"
+
+expect {
+ "/srv" { }
+ timeout { exit 1 }
+}
diff --git a/tests/inout/test.nix b/tests/inout/test.nix
@@ -0,0 +1,26 @@
+{
+ liminix
+, nixpkgs
+}:
+let img = (import liminix {
+ device = import "${liminix}/devices/qemu/";
+ liminix-config = ./configuration.nix;
+ }).outputs.vmroot;
+ pkgs = import <nixpkgs> { overlays = [(import ../../overlay.nix)]; };
+in pkgs.runCommand "check" {
+ nativeBuildInputs = with pkgs; [
+ expect
+ socat
+ e2fsprogs
+ util-linux # for sfdisk, fallocate
+ ] ;
+} ''
+mkdir vm
+dd if=/dev/zero of=./vm/stick.e2fs bs=1M count=32
+mkfs.ext2 -L backup-disk ./vm/stick.e2fs
+cat <(dd if=/dev/zero bs=512 count=4) ./vm/stick.e2fs > ./vm/stick.img
+echo '4,-,L,*' | sfdisk ./vm/stick.img
+
+${img}/run.sh --background ./vm --flag -device --flag usb-ehci,id=xhci --flag -drive --flag if=none,id=usbstick,format=raw,file=$(pwd)/vm/stick.img
+expect ${./script.expect} | tee $out
+''