add s6-rc-up-tree: start reverse deps of controlled service
When s6-rc stops a service, it also stops everything that depends on it. but when it starts a service it starts only that service, so we have to go through the other services depending on it and figure out if they should be started too.
This commit is contained in:
parent
1d337588f9
commit
49d1703428
@ -8,7 +8,7 @@ let
|
||||
stdenvNoCC;
|
||||
inherit (lib.lists) unique concatMap;
|
||||
inherit (pkgs.pseudofile) dir symlink;
|
||||
inherit (pkgs.liminix.services) bundle;
|
||||
inherit (pkgs.liminix.services) oneshot bundle;
|
||||
|
||||
s6-rc-db =
|
||||
let
|
||||
@ -31,12 +31,25 @@ let
|
||||
isControlled s ||
|
||||
(lib.lists.any isDependentOnControlled s.dependencies);
|
||||
|
||||
# all controlled services depend on this oneshot, which
|
||||
# makes a list of them so we can identify them at runtime
|
||||
controlled = oneshot {
|
||||
name = "controlled";
|
||||
up = ''
|
||||
mkdir -p /run/services/controlled
|
||||
for s in $(s6-rc-db -d dependencies controlled); do
|
||||
touch /run/services/controlled/$s
|
||||
done
|
||||
'';
|
||||
down = "rm -r /run/services/controlled";
|
||||
};
|
||||
|
||||
defaultStart =
|
||||
builtins.filter
|
||||
(s: !(isDependentOnControlled s)) allServices;
|
||||
defaultDefaultTarget = bundle {
|
||||
name = "default";
|
||||
contents = defaultStart;
|
||||
contents = defaultStart ++ [controlled];
|
||||
};
|
||||
servicesAttrs = {
|
||||
default = defaultDefaultTarget;
|
||||
|
@ -98,6 +98,7 @@ in {
|
||||
run-liminix-vm = callPackage ./run-liminix-vm {};
|
||||
s6-init-bin = callPackage ./s6-init-bin {};
|
||||
s6-rc-database = callPackage ./s6-rc-database {};
|
||||
s6-rc-up-tree = callPackage ./s6-rc-up-tree {};
|
||||
|
||||
# schnapps is written by Turris and provides a high-level interface
|
||||
# to btrfs snapshots. It may be useful on the Turris Omnia to
|
||||
@ -112,6 +113,7 @@ in {
|
||||
uevent-watch = callPackage ./uevent-watch {};
|
||||
usb-modeswitch = callPackage ./usb-modeswitch {};
|
||||
writeAshScript = callPackage ./write-ash-script {};
|
||||
writeAshScriptBin = callPackage ./write-ash-script/bin.nix {};
|
||||
writeFennel = callPackage ./write-fennel {};
|
||||
writeFennelScript = callPackage ./write-fennel-script {};
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ done
|
||||
if test -n "$controller" ; then
|
||||
d=$(dirname $(cd ${controller} && ls -d */type))
|
||||
echo "$d)" > $out/${name}/controller
|
||||
# ^ why is there a closing paren here?
|
||||
touch $out/${name}/dependencies.d/controlled
|
||||
fi
|
||||
|
||||
for i in timeout-up timeout-down run notification-fd up down finish consumer-for producer-for pipeline-name restart-on-upgrade; do
|
||||
|
4
pkgs/s6-rc-up-tree/default.nix
Normal file
4
pkgs/s6-rc-up-tree/default.nix
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
writeAshScriptBin
|
||||
}:
|
||||
writeAshScriptBin "s6-rc-up-tree" {} (builtins.readFile ./s6-rc-up-tree.sh)
|
24
pkgs/s6-rc-up-tree/s6-rc-up-tree.sh
Normal file
24
pkgs/s6-rc-up-tree/s6-rc-up-tree.sh
Normal file
@ -0,0 +1,24 @@
|
||||
service=$1
|
||||
|
||||
blocks=""
|
||||
for controlled in $(cd /run/services/controlled/ && echo *); do
|
||||
down=$(s6-rc -un0 change $controlled)
|
||||
echo $controlled $down
|
||||
if test -n "$down"; then
|
||||
blocks="$blocks $controlled "
|
||||
fi
|
||||
done
|
||||
|
||||
for s in $(s6-rc-db -d all-dependencies $service); do
|
||||
for dep in $(s6-rc-db all-dependencies $s); do
|
||||
case "$blocks" in
|
||||
"* $dep *")
|
||||
echo "not starting $s, blocked by $dep"
|
||||
;;
|
||||
*)
|
||||
echo "starting $s because $service"
|
||||
s6-rc -u change $s
|
||||
;;
|
||||
esac
|
||||
done
|
||||
done
|
7
pkgs/s6-rc-up-tree/test-list
Normal file
7
pkgs/s6-rc-up-tree/test-list
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
the service starts
|
||||
uncontrolled descendants start
|
||||
controlled descendants don't start
|
||||
descendants which depend on a _different_ controlled service, which is down, don't start
|
||||
descendants which depend on a _different_ controlled service, which is up, do start
|
||||
|
@ -8,17 +8,21 @@
|
||||
, fennel
|
||||
, stdenv
|
||||
, fennelrepl
|
||||
, s6-rc-up-tree
|
||||
, makeWrapper
|
||||
}:
|
||||
stdenv.mkDerivation {
|
||||
name = "uevent-watch";
|
||||
src = ./.;
|
||||
nativeBuildInputs = [ fennelrepl ];
|
||||
nativeBuildInputs = [ fennelrepl makeWrapper ];
|
||||
propagatedBuildInputs = [ s6-rc-up-tree ];
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
cp -p ${writeFennel "uevent-watch" {
|
||||
packages = [fennel anoia nellie lualinux];
|
||||
mainFunction = "run";
|
||||
} ./watch.fnl} $out/bin/uevent-watch
|
||||
wrapProgram $out/bin/uevent-watch --prefix PATH : "${s6-rc-up-tree}/bin"
|
||||
'';
|
||||
checkPhase = ''
|
||||
fennelrepl ./test.fnl
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
(fn start-service [devname linkname service]
|
||||
(match (if linkname (symlink (.. "/dev/" devname) linkname) true)
|
||||
ok (pcall system (%% "s6-rc -b -u change %q" service))
|
||||
ok (pcall system (%% "s6-rc-up-tree %q" service))
|
||||
(nil err) false))
|
||||
|
||||
(fn stop-service [linkname service]
|
||||
|
Loading…
Reference in New Issue
Block a user