Compare commits
No commits in common. "a5f16dfa817f43c1ac65d2f64d279ba93d57005b" and "b231664a0672c55a26e885a6536b5bd021c34067" have entirely different histories.
a5f16dfa81
...
b231664a06
@ -19,7 +19,6 @@
|
|||||||
./kernel
|
./kernel
|
||||||
./outputs/kexecboot.nix
|
./outputs/kexecboot.nix
|
||||||
./mount
|
./mount
|
||||||
./mdevd.nix
|
|
||||||
./network
|
./network
|
||||||
./ntp
|
./ntp
|
||||||
./outputs.nix
|
./outputs.nix
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
{ config, pkgs, lib, ...} :
|
|
||||||
let inherit (pkgs.liminix.services) oneshot longrun bundle target;
|
|
||||||
in {
|
|
||||||
config = {
|
|
||||||
services = rec {
|
|
||||||
mdevd = longrun {
|
|
||||||
name = "mdevd";
|
|
||||||
notification-fd = 3;
|
|
||||||
run = "${pkgs.mdevd}/bin/mdevd -D 3 -b 200000 -O4";
|
|
||||||
};
|
|
||||||
mdevd-coldplug = oneshot {
|
|
||||||
name ="mdev-coldplug";
|
|
||||||
up = "${pkgs.mdevd}/bin/mdevd-coldplug";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
@ -33,5 +33,4 @@
|
|||||||
: mktree
|
: mktree
|
||||||
: rmtree
|
: rmtree
|
||||||
: directory?
|
: directory?
|
||||||
:symlink (fn [from to] (lfs.link from to true))
|
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,6 @@ in {
|
|||||||
zyxel-bootconfig = callPackage ./zyxel-bootconfig {};
|
zyxel-bootconfig = callPackage ./zyxel-bootconfig {};
|
||||||
min-collect-garbage = callPackage ./min-collect-garbage {};
|
min-collect-garbage = callPackage ./min-collect-garbage {};
|
||||||
min-copy-closure = callPackage ./min-copy-closure {};
|
min-copy-closure = callPackage ./min-copy-closure {};
|
||||||
nellie = callPackage ./nellie {};
|
|
||||||
netlink-lua = callPackage ./netlink-lua {};
|
netlink-lua = callPackage ./netlink-lua {};
|
||||||
odhcp-script = callPackage ./odhcp-script {};
|
odhcp-script = callPackage ./odhcp-script {};
|
||||||
odhcp6c = callPackage ./odhcp6c {};
|
odhcp6c = callPackage ./odhcp6c {};
|
||||||
@ -106,7 +105,6 @@ in {
|
|||||||
swconfig = callPackage ./swconfig {};
|
swconfig = callPackage ./swconfig {};
|
||||||
systemconfig = callPackage ./systemconfig {};
|
systemconfig = callPackage ./systemconfig {};
|
||||||
tufted = callPackage ./tufted {};
|
tufted = callPackage ./tufted {};
|
||||||
uevent-watch = callPackage ./uevent-watch {};
|
|
||||||
writeAshScript = callPackage ./write-ash-script {};
|
writeAshScript = callPackage ./write-ash-script {};
|
||||||
writeFennel = callPackage ./write-fennel {};
|
writeFennel = callPackage ./write-fennel {};
|
||||||
writeFennelScript = callPackage ./write-fennel-script {};
|
writeFennelScript = callPackage ./write-fennel-script {};
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
{ lua, lib, fetchpatch, fetchFromGitHub, stdenv }:
|
|
||||||
|
|
||||||
let pname = "nellie";
|
|
||||||
in lua.pkgs.buildLuaPackage {
|
|
||||||
inherit pname;
|
|
||||||
version = "0.1.1-1";
|
|
||||||
|
|
||||||
src = ./.;
|
|
||||||
|
|
||||||
buildPhase = "$CC -shared -l lua -o nellie.so nellie.c";
|
|
||||||
|
|
||||||
# for the checks to work you need to
|
|
||||||
# nix-build--option sandbox false
|
|
||||||
# otherwise the sandbox doesn't see any uevent messages
|
|
||||||
|
|
||||||
# doCheck = stdenv.hostPlatform == stdenv.buildPlatform;
|
|
||||||
|
|
||||||
checkPhase = ''
|
|
||||||
export LUA_CPATH=./?.so
|
|
||||||
lua test.lua
|
|
||||||
'';
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p "$out/lib/lua/${lua.luaversion}"
|
|
||||||
cp nellie.so "$out/lib/lua/${lua.luaversion}/"
|
|
||||||
'';
|
|
||||||
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
#include <lua.h>
|
|
||||||
#include <lualib.h>
|
|
||||||
#include <lauxlib.h>
|
|
||||||
|
|
||||||
#include <linux/netlink.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
static int l_close_socket(lua_State *L) {
|
|
||||||
lua_getfield(L, 1, "fileno");
|
|
||||||
int fd = (int) lua_tointeger(L, -1);
|
|
||||||
close(fd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int l_read_from_socket(lua_State *L) {
|
|
||||||
int length = 32;
|
|
||||||
|
|
||||||
if(lua_isnumber(L, 2))
|
|
||||||
length = lua_tointeger(L, 2);
|
|
||||||
|
|
||||||
lua_getfield(L, 1, "fileno");
|
|
||||||
int fd = (int) lua_tointeger(L, -1);
|
|
||||||
char *buf = (char *) malloc(length);
|
|
||||||
int bytes = recv(fd, buf, length, 0);
|
|
||||||
|
|
||||||
if(bytes > 0) {
|
|
||||||
lua_pushlstring(L, buf, bytes);
|
|
||||||
free(buf);
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
free(buf);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int l_open_socket(lua_State *L) {
|
|
||||||
int netlink_fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_KOBJECT_UEVENT);
|
|
||||||
|
|
||||||
struct sockaddr_nl sa;
|
|
||||||
memset(&sa, 0, sizeof(sa));
|
|
||||||
sa.nl_family = AF_NETLINK;
|
|
||||||
sa.nl_pid = getpid();
|
|
||||||
|
|
||||||
if(lua_isnumber(L, 1)) {
|
|
||||||
sa.nl_groups = lua_tointeger(L, 1);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sa.nl_groups = 4; /* group 4 is rebroadcasts from mdevd */
|
|
||||||
}
|
|
||||||
|
|
||||||
if(bind(netlink_fd, (struct sockaddr *) &sa, sizeof(sa))==0) {
|
|
||||||
lua_newtable(L);
|
|
||||||
|
|
||||||
lua_pushliteral(L, "fileno");
|
|
||||||
lua_pushinteger(L, netlink_fd);
|
|
||||||
lua_settable(L, 1);
|
|
||||||
|
|
||||||
lua_pushliteral(L, "read");
|
|
||||||
lua_pushcfunction(L, l_read_from_socket);
|
|
||||||
lua_settable(L, 1);
|
|
||||||
|
|
||||||
lua_pushliteral(L, "close");
|
|
||||||
lua_pushcfunction(L, l_close_socket);
|
|
||||||
lua_settable(L, 1);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static const struct luaL_Reg funcs [] = {
|
|
||||||
{"open", l_open_socket},
|
|
||||||
{NULL, NULL} /* sentinel */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* "luaopen_" prefix is magic and tells lua to run this function
|
|
||||||
* when it dlopens the library
|
|
||||||
*/
|
|
||||||
|
|
||||||
int luaopen_nellie (lua_State *L) {
|
|
||||||
luaL_newlib(L, funcs);
|
|
||||||
return 1;
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
local nellie = require('nellie')
|
|
||||||
print('dfg')
|
|
||||||
local f = nellie.open(2)
|
|
||||||
|
|
||||||
print(string.byte(f:read(1000), 0, 60))
|
|
||||||
print("CLOSED", f:close())
|
|
@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
lua
|
|
||||||
, nellie
|
|
||||||
, writeFennelScript
|
|
||||||
, runCommand
|
|
||||||
, anoia
|
|
||||||
, fennel
|
|
||||||
, stdenv
|
|
||||||
, fennelrepl
|
|
||||||
}:
|
|
||||||
stdenv.mkDerivation {
|
|
||||||
name = "uevent-watch";
|
|
||||||
src = ./.;
|
|
||||||
nativeBuildInputs = [ fennelrepl ];
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out/bin
|
|
||||||
cp -p ${writeFennelScript "uevent-watch" [fennel anoia nellie lua.pkgs.luafilesystem] ./watch.fnl} $out/bin/uevent-watch
|
|
||||||
'';
|
|
||||||
checkPhase = ''
|
|
||||||
fennelrepl ./test.fnl
|
|
||||||
'';
|
|
||||||
doCheck = true;
|
|
||||||
}
|
|
@ -1,154 +0,0 @@
|
|||||||
add@/devices/pci0000:00/0000:00:13.0/usb1/1-1
|
|
||||||
ACTION=add
|
|
||||||
DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1
|
|
||||||
SUBSYSTEM=usb
|
|
||||||
MAJOR=189
|
|
||||||
MINOR=1
|
|
||||||
DEVNAME=bus/usb/001/002
|
|
||||||
DEVTYPE=usb_device
|
|
||||||
PRODUCT=46f4/1/0
|
|
||||||
TYPE=0/0/0
|
|
||||||
BUSNUM=001
|
|
||||||
DEVNUM=002
|
|
||||||
SEQNUM=1513
|
|
||||||
|
|
||||||
add@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0
|
|
||||||
ACTION=add
|
|
||||||
DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0
|
|
||||||
SUBSYSTEM=usb
|
|
||||||
DEVTYPE=usb_interface
|
|
||||||
PRODUCT=46f4/1/0
|
|
||||||
TYPE=0/0/0
|
|
||||||
INTERFACE=8/6/80
|
|
||||||
MODALIAS=usb:v46F4p0001d0000dc00dsc00dp00ic08isc06ip50in00
|
|
||||||
SEQNUM=1514
|
|
||||||
|
|
||||||
add@/devices/virtual/workqueue/scsi_tmf_0
|
|
||||||
ACTION=add
|
|
||||||
DEVPATH=/devices/virtual/workqueue/scsi_tmf_0
|
|
||||||
SUBSYSTEM=workqueue
|
|
||||||
SEQNUM=1515
|
|
||||||
|
|
||||||
add@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0
|
|
||||||
ACTION=add
|
|
||||||
DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0
|
|
||||||
SUBSYSTEM=scsi
|
|
||||||
DEVTYPE=scsi_host
|
|
||||||
SEQNUM=1516
|
|
||||||
|
|
||||||
add@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/scsi_host/host0
|
|
||||||
ACTION=add
|
|
||||||
DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/scsi_host/host0
|
|
||||||
SUBSYSTEM=scsi_host
|
|
||||||
SEQNUM=1517
|
|
||||||
|
|
||||||
bind@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0
|
|
||||||
ACTION=bind
|
|
||||||
DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0
|
|
||||||
SUBSYSTEM=usb
|
|
||||||
DEVTYPE=usb_interface
|
|
||||||
DRIVER=usb-storage
|
|
||||||
PRODUCT=46f4/1/0
|
|
||||||
TYPE=0/0/0
|
|
||||||
INTERFACE=8/6/80
|
|
||||||
MODALIAS=usb:v46F4p0001d0000dc00dsc00dp00ic08isc06ip50in00
|
|
||||||
SEQNUM=1518
|
|
||||||
|
|
||||||
bind@/devices/pci0000:00/0000:00:13.0/usb1/1-1
|
|
||||||
ACTION=bind
|
|
||||||
DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1
|
|
||||||
SUBSYSTEM=usb
|
|
||||||
MAJOR=189
|
|
||||||
MINOR=1
|
|
||||||
DEVNAME=bus/usb/001/002
|
|
||||||
DEVTYPE=usb_device
|
|
||||||
DRIVER=usb
|
|
||||||
PRODUCT=46f4/1/0
|
|
||||||
TYPE=0/0/0
|
|
||||||
BUSNUM=001
|
|
||||||
DEVNUM=002
|
|
||||||
SEQNUM=1519
|
|
||||||
|
|
||||||
add@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0
|
|
||||||
ACTION=add
|
|
||||||
DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0
|
|
||||||
SUBSYSTEM=scsi
|
|
||||||
DEVTYPE=scsi_target
|
|
||||||
SEQNUM=1520
|
|
||||||
|
|
||||||
add@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0
|
|
||||||
ACTION=add
|
|
||||||
DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0
|
|
||||||
SUBSYSTEM=scsi
|
|
||||||
DEVTYPE=scsi_device
|
|
||||||
MODALIAS=scsi:t-0x00
|
|
||||||
SEQNUM=1521
|
|
||||||
|
|
||||||
add@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/scsi_device/0:0:0:0
|
|
||||||
ACTION=add
|
|
||||||
DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/scsi_device/0:0:0:0
|
|
||||||
SUBSYSTEM=scsi_device
|
|
||||||
SEQNUM=1522
|
|
||||||
|
|
||||||
add@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0
|
|
||||||
ACTION=add
|
|
||||||
DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0
|
|
||||||
SUBSYSTEM=scsi_disk
|
|
||||||
SEQNUM=1523
|
|
||||||
|
|
||||||
add@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0
|
|
||||||
ACTION=add
|
|
||||||
DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0
|
|
||||||
SUBSYSTEM=bsg
|
|
||||||
MAJOR=252
|
|
||||||
MINOR=0
|
|
||||||
DEVNAME=bsg/0:0:0:0
|
|
||||||
SEQNUM=1524
|
|
||||||
|
|
||||||
change@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0
|
|
||||||
ACTION=change
|
|
||||||
DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0
|
|
||||||
SUBSYSTEM=scsi
|
|
||||||
SDEV_UA=POWER_ON_RESET_OCCURRED
|
|
||||||
DEVTYPE=scsi_device
|
|
||||||
DRIVER=sd
|
|
||||||
MODALIAS=scsi:t-0x00
|
|
||||||
SEQNUM=1525
|
|
||||||
|
|
||||||
add@/devices/virtual/bdi/8:0
|
|
||||||
ACTION=add
|
|
||||||
DEVPATH=/devices/virtual/bdi/8:0
|
|
||||||
SUBSYSTEM=bdi
|
|
||||||
SEQNUM=1526
|
|
||||||
|
|
||||||
add@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/block/sda
|
|
||||||
ACTION=add
|
|
||||||
DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/block/sda
|
|
||||||
SUBSYSTEM=block
|
|
||||||
MAJOR=8
|
|
||||||
MINOR=0
|
|
||||||
DEVNAME=sda
|
|
||||||
DEVTYPE=disk
|
|
||||||
DISKSEQ=2
|
|
||||||
SEQNUM=1527
|
|
||||||
|
|
||||||
add@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/block/sda/sda1
|
|
||||||
ACTION=add
|
|
||||||
DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/block/sda/sda1
|
|
||||||
SUBSYSTEM=block
|
|
||||||
MAJOR=8
|
|
||||||
MINOR=1
|
|
||||||
DEVNAME=sda1
|
|
||||||
DEVTYPE=partition
|
|
||||||
DISKSEQ=2
|
|
||||||
PARTN=1
|
|
||||||
SEQNUM=1528
|
|
||||||
|
|
||||||
bind@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0
|
|
||||||
ACTION=bind
|
|
||||||
DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0
|
|
||||||
SUBSYSTEM=scsi
|
|
||||||
DEVTYPE=scsi_device
|
|
||||||
DRIVER=sd
|
|
||||||
MODALIAS=scsi:t-0x00
|
|
||||||
SEQNUM=1529
|
|
@ -1,48 +0,0 @@
|
|||||||
(local { : view} (require :fennel))
|
|
||||||
|
|
||||||
(set _G.arg (doto [] (tset 0 "test")))
|
|
||||||
(local subject (require :watch))
|
|
||||||
|
|
||||||
(macro expect= [actual expected]
|
|
||||||
`(let [ve# (view ,expected)
|
|
||||||
va# (view ,actual)]
|
|
||||||
(when (not (= ve# va#))
|
|
||||||
(assert false
|
|
||||||
(.. "\nexpected " ve# "\ngot " va#)
|
|
||||||
))))
|
|
||||||
|
|
||||||
(let [params
|
|
||||||
{:matches {:devname "foo" :partname "my-usbstick"}}]
|
|
||||||
(expect= (subject.event-matches? params {}) false)
|
|
||||||
(expect= (subject.event-matches? params {:devname "bill"}) false)
|
|
||||||
(expect= (subject.event-matches? params {:devname "foo" :partname "my-usbstick"}) true)
|
|
||||||
(expect= (subject.event-matches? params {:devname "foo" :otherthing "bar" :partname "my-usbstick"}) true)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
;; Events come from the netlink socket as an initial summary line
|
|
||||||
;; followed by a NUL character followed by newline-separated key=value
|
|
||||||
;; pairs. For ease of editing we don't have NULs in events.txt,
|
|
||||||
;; so we need to massage it into shape here
|
|
||||||
|
|
||||||
(local events
|
|
||||||
(with-open [f (io.open "./events.txt" :r)]
|
|
||||||
(let [text (string.gsub (f:read "*a") "\n\n" "\0") ]
|
|
||||||
(icollect [n (string.gmatch text "([^\0]+)")]
|
|
||||||
(string.gsub n "\n" "\0" 1)))))
|
|
||||||
|
|
||||||
|
|
||||||
(fn next-event []
|
|
||||||
(var i 0)
|
|
||||||
(fn []
|
|
||||||
(let [i_ (+ 1 i)
|
|
||||||
e (. events i_)]
|
|
||||||
(set i i_)
|
|
||||||
e)))
|
|
||||||
|
|
||||||
;; this tests event parsing but not whether anything
|
|
||||||
;; happens as a result of processing them
|
|
||||||
(subject.run
|
|
||||||
["-s" "foo" "-n" (os.getenv "TMPDIR") "partname=backup-disk" ]
|
|
||||||
{ :read (next-event) }
|
|
||||||
)
|
|
@ -1,70 +0,0 @@
|
|||||||
(local { : assoc : system : dirname } (require :anoia))
|
|
||||||
(local { : mktree : rmtree : symlink } (require :anoia.fs))
|
|
||||||
|
|
||||||
(fn parse-match [s] (string.match s "(.-)=(.+)"))
|
|
||||||
|
|
||||||
(fn parse-args [args]
|
|
||||||
(match args
|
|
||||||
["-s" service & rest] (assoc (parse-args rest) :service service)
|
|
||||||
["-n" path & rest] (assoc (parse-args rest) :linkname path)
|
|
||||||
matches { :matches (collect [_ m (ipairs matches)] (parse-match m)) }
|
|
||||||
_ nil))
|
|
||||||
|
|
||||||
(fn %% [fmt ...] (string.format fmt ...))
|
|
||||||
|
|
||||||
(fn event-matches? [params e]
|
|
||||||
(and
|
|
||||||
e
|
|
||||||
(accumulate [match? true
|
|
||||||
name value (pairs params.matches)]
|
|
||||||
(and match? (= value (. e name))))))
|
|
||||||
|
|
||||||
|
|
||||||
(var up :unknown)
|
|
||||||
|
|
||||||
(fn start-service [devname linkname service]
|
|
||||||
(match (symlink (.. "/dev/" devname ) linkname)
|
|
||||||
ok (pcall system (%% "s6-rc -b -u change %q" service))
|
|
||||||
(nil err) false))
|
|
||||||
|
|
||||||
(fn stop-service [linkname service]
|
|
||||||
(match (pcall system (%% "s6-rc -b -d change %q" linkname service))
|
|
||||||
ok (os.remove linkname)
|
|
||||||
(nil err) false))
|
|
||||||
|
|
||||||
(fn toggle-service [devname linkname service wanted?]
|
|
||||||
(when (not (= up wanted?))
|
|
||||||
(set up
|
|
||||||
(if wanted?
|
|
||||||
(start-service devname linkname service)
|
|
||||||
(not (stop-service linkname service))))))
|
|
||||||
|
|
||||||
(fn parse-uevent [s]
|
|
||||||
(when s
|
|
||||||
(let [(nl nxt) (string.find s "\0" 1 true)]
|
|
||||||
(collect [k v (string.gmatch
|
|
||||||
(string.sub s (+ 1 nxt))
|
|
||||||
"(%g-)=(%g+)")]
|
|
||||||
(k:lower) v))))
|
|
||||||
|
|
||||||
(fn run [args fh]
|
|
||||||
(set up :unknown)
|
|
||||||
(let [parameters
|
|
||||||
(assert (parse-args args) (.. "can't parse args: " (table.concat args " ")))]
|
|
||||||
(mktree (dirname parameters.linkname))
|
|
||||||
(var finished? false)
|
|
||||||
|
|
||||||
(while (not finished?)
|
|
||||||
(let [e (parse-uevent (fh:read 5000))]
|
|
||||||
(when (event-matches? parameters e)
|
|
||||||
(let [wanted? (. {:add true :change true} e.action)]
|
|
||||||
(toggle-service e.devname parameters.linkname parameters.service wanted?)))
|
|
||||||
(set finished? (= e nil))
|
|
||||||
))))
|
|
||||||
|
|
||||||
(when (not (= (. arg 0) "test"))
|
|
||||||
(let [nellie (require :nellie)
|
|
||||||
netlink (nellie.open 4)]
|
|
||||||
(run arg netlink)))
|
|
||||||
|
|
||||||
{ : run : event-matches? }
|
|
@ -15,7 +15,6 @@ in rec {
|
|||||||
"${modulesPath}/network"
|
"${modulesPath}/network"
|
||||||
"${modulesPath}/ssh"
|
"${modulesPath}/ssh"
|
||||||
"${modulesPath}/mount"
|
"${modulesPath}/mount"
|
||||||
"${modulesPath}/mdevd.nix"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
filesystem = dir { srv = dir {}; };
|
filesystem = dir { srv = dir {}; };
|
||||||
@ -47,20 +46,16 @@ in rec {
|
|||||||
rootfsType = "jffs2";
|
rootfsType = "jffs2";
|
||||||
hostname = "inout";
|
hostname = "inout";
|
||||||
|
|
||||||
services.watch_mount_srv =
|
services.mount_external_disk = svc.mount.build {
|
||||||
let
|
device = "LABEL=backup-disk";
|
||||||
node = "/dev/disk/by-partlabel/backup-disk";
|
mountpoint = "/srv";
|
||||||
mount = oneshot {
|
fstype = "ext4";
|
||||||
name = "mount-srv";
|
};
|
||||||
up = "mount -t ext2 ${node} /srv";
|
|
||||||
down = "umount /srv";
|
services.sshd = svc.ssh.build { };
|
||||||
};
|
|
||||||
in longrun {
|
defaultProfile.packages = with pkgs; [
|
||||||
name = "mount_srv";
|
min-collect-garbage
|
||||||
run = ''
|
tcpdump
|
||||||
${pkgs.uevent-watch}/bin/uevent-watch -s ${mount.name} -n ${node} partname=backup-disk devtype=partition
|
];
|
||||||
'';
|
|
||||||
dependencies = [ config.services.mdevd ];
|
|
||||||
buildInputs = [ mount ];
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
@ -9,14 +9,21 @@ proc chat {instr outstr} {
|
|||||||
spawn socat -,echo=0,icanon=1 unix-connect:vm/monitor
|
spawn socat -,echo=0,icanon=1 unix-connect:vm/monitor
|
||||||
set monitor_id $spawn_id
|
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 -
|
spawn socat unix-connect:vm/console -
|
||||||
set console_id $spawn_id
|
set console_id $spawn_id
|
||||||
|
|
||||||
expect "BusyBox"
|
expect "BusyBox"
|
||||||
chat "#" "PS1=RE\\ADY_\\ ; stty -echo \r"
|
chat "#" "PS1=RE\\ADY_\\ ; stty -echo \r"
|
||||||
chat "READY_" "tail -f /run/uncaught-logs/current & \rs6-rc -b -a list\r"
|
chat "READY_" "s6-rc -b -a list\r"
|
||||||
|
|
||||||
chat "mount" "\r"
|
chat "watch-mount" "\r"
|
||||||
|
|
||||||
set spawn_id $monitor_id
|
set spawn_id $monitor_id
|
||||||
chat "QEMU" "device_add usb-storage,bus=xhci.0,drive=usbstick\n"
|
chat "QEMU" "device_add usb-storage,bus=xhci.0,drive=usbstick\n"
|
||||||
@ -25,15 +32,16 @@ chat "(qemu)" "version\r"
|
|||||||
set spawn_id $console_id
|
set spawn_id $console_id
|
||||||
|
|
||||||
expect {
|
expect {
|
||||||
"sda: sda1" { }
|
"mounted filesystem" { }
|
||||||
timeout { exit 1 }
|
timeout { exit 1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
send "\r"
|
send "\r"
|
||||||
chat "READY_" "sleep 3; grep /srv /proc/mounts && hostname\r"
|
chat "READY_" "s6-rc -b -a list\r"
|
||||||
|
chat "READY_" "cat /proc/mounts\r"
|
||||||
|
|
||||||
expect {
|
expect {
|
||||||
"inout" { }
|
"/srv" { }
|
||||||
timeout { exit 1 }
|
timeout { exit 1 }
|
||||||
}
|
}
|
||||||
|
@ -13,15 +13,13 @@ in pkgs.runCommand "check" {
|
|||||||
socat
|
socat
|
||||||
e2fsprogs
|
e2fsprogs
|
||||||
util-linux # for sfdisk, fallocate
|
util-linux # for sfdisk, fallocate
|
||||||
parted
|
|
||||||
] ;
|
] ;
|
||||||
} ''
|
} ''
|
||||||
mkdir vm
|
mkdir vm
|
||||||
dd if=/dev/zero of=./vm/stick.e2fs bs=1M count=32
|
dd if=/dev/zero of=./vm/stick.e2fs bs=1M count=32
|
||||||
mkfs.ext2 -L backup-disk ./vm/stick.e2fs
|
mkfs.ext2 -L backup-disk ./vm/stick.e2fs
|
||||||
dd if=/dev/zero of=./vm/stick.img bs=1M count=38
|
cat <(dd if=/dev/zero bs=512 count=4) ./vm/stick.e2fs > ./vm/stick.img
|
||||||
dd if=./vm/stick.e2fs of=./vm/stick.img bs=512 seek=34 conv=notrunc
|
echo '4,-,L,*' | sfdisk ./vm/stick.img
|
||||||
parted -s ./vm/stick.img -- mklabel gpt mkpart backup-disk ext2 34s -0M
|
|
||||||
|
|
||||||
${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
|
${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
|
expect ${./script.expect} | tee $out
|
||||||
|
Loading…
Reference in New Issue
Block a user