Refactor routing
Patch init to simplify routing. Update Dhall library and NixOS modules accordingly.
This commit is contained in:
parent
8dd6e9c248
commit
ddc65a8087
|
@ -57,7 +57,6 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
config = let
|
config = let
|
||||||
initInputs = unique config.genode.init.inputs;
|
|
||||||
|
|
||||||
addManifest = drv:
|
addManifest = drv:
|
||||||
drv // {
|
drv // {
|
||||||
|
@ -91,6 +90,12 @@ in {
|
||||||
in (foldl' f "[" inputs) + "]";
|
in (foldl' f "[" inputs) + "]";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
romDirectories = mapAttrs (name: value:
|
||||||
|
pkgs.symlinkJoin {
|
||||||
|
name = "${name}-rom";
|
||||||
|
paths = value.inputs;
|
||||||
|
}) config.genode.init.children;
|
||||||
|
|
||||||
in {
|
in {
|
||||||
|
|
||||||
assertions = [{
|
assertions = [{
|
||||||
|
@ -104,38 +109,36 @@ in {
|
||||||
"${config.system.build.tarball}/tarball/${config.system.build.tarball.fileName}.tar";
|
"${config.system.build.tarball}/tarball/${config.system.build.tarball.fileName}.tar";
|
||||||
manifest = mergeManifests (map addManifest
|
manifest = mergeManifests (map addManifest
|
||||||
(config.genode.core.basePackages ++ [ config.system.build.tarball ]
|
(config.genode.core.basePackages ++ [ config.system.build.tarball ]
|
||||||
++ (with pkgs.genodePackages; [ init cached_fs_rom vfs ])));
|
++ (with pkgs.genodePackages; [
|
||||||
|
init
|
||||||
|
cached_fs_rom
|
||||||
|
report_rom
|
||||||
|
vfs
|
||||||
|
])));
|
||||||
|
storeRomPolicies = let
|
||||||
|
policies = mapAttrsToList
|
||||||
|
(name: value: '', { mapKey = "${name}", mapValue = "${value}" }'')
|
||||||
|
romDirectories;
|
||||||
|
in "[${toString policies}]";
|
||||||
in localPackages.runCommand "boot.dhall" { } ''
|
in localPackages.runCommand "boot.dhall" { } ''
|
||||||
cat > $out << EOF
|
cat > $out << EOF
|
||||||
${./store-wrapper.dhall}
|
${./store-wrapper.dhall}
|
||||||
(${config.genode.init.configFile})
|
(${config.genode.init.configFile})
|
||||||
"${config.system.build.tarball.fileName}.tar"
|
"${config.system.build.tarball.fileName}.tar"
|
||||||
$(stat --format '%s' ${tarball})
|
$(stat --format '%s' ${tarball})
|
||||||
${config.system.build.storeManifest} ${manifest}
|
${storeRomPolicies}
|
||||||
|
${manifest}
|
||||||
EOF
|
EOF
|
||||||
'';
|
'';
|
||||||
|
|
||||||
system.build.storeManifest = mergeManifests (map addManifest initInputs);
|
|
||||||
|
|
||||||
# Create the tarball of the store to live in core ROM
|
# Create the tarball of the store to live in core ROM
|
||||||
system.build.tarball =
|
system.build.tarball =
|
||||||
pkgs.callPackage "${modulesPath}/../lib/make-system-tarball.nix" {
|
pkgs.callPackage "${modulesPath}/../lib/make-system-tarball.nix" {
|
||||||
contents = [ ];
|
contents = [ ];
|
||||||
storeContents = [
|
storeContents = mapAttrsToList (name: object: {
|
||||||
{
|
symlink = "rom/${name}";
|
||||||
# assume that the init config will depend
|
inherit object;
|
||||||
# on every store path needed to boot
|
}) romDirectories;
|
||||||
object = config.genode.init.configFile;
|
|
||||||
symlink = "/config.dhall";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
object = pkgs.buildPackages.symlinkJoin {
|
|
||||||
name = config.system.name + ".rom";
|
|
||||||
paths = config.genode.init.inputs;
|
|
||||||
};
|
|
||||||
symlink = "/rom";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
compressCommand = "cat";
|
compressCommand = "cat";
|
||||||
compressionExtension = "";
|
compressionExtension = "";
|
||||||
};
|
};
|
||||||
|
@ -143,13 +146,12 @@ in {
|
||||||
system.build.initXml = pkgs.buildPackages.runCommand "init.xml" {
|
system.build.initXml = pkgs.buildPackages.runCommand "init.xml" {
|
||||||
nativeBuildInputs = with pkgs.buildPackages; [ dhall xorg.lndir libxml2 ];
|
nativeBuildInputs = with pkgs.buildPackages; [ dhall xorg.lndir libxml2 ];
|
||||||
DHALL_GENODE = "${pkgs.genodePackages.dhallGenode}/binary.dhall";
|
DHALL_GENODE = "${pkgs.genodePackages.dhallGenode}/binary.dhall";
|
||||||
BOOT_CONFIG = config.genode.boot.configFile;
|
|
||||||
} ''
|
} ''
|
||||||
export XDG_CACHE_HOME=$NIX_BUILD_TOP
|
export XDG_CACHE_HOME=$NIX_BUILD_TOP
|
||||||
lndir -silent \
|
lndir -silent \
|
||||||
${pkgs.genodePackages.dhallGenode}/.cache \
|
${pkgs.genodePackages.dhallGenode}/.cache \
|
||||||
$XDG_CACHE_HOME
|
$XDG_CACHE_HOME
|
||||||
dhall text <<< "(env:DHALL_GENODE).Init.render (env:BOOT_CONFIG).config" > $out
|
dhall text <<< "(env:DHALL_GENODE).Init.render (${config.genode.boot.configFile}).config" > $out
|
||||||
xmllint --noout $out
|
xmllint --noout $out
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,15 @@
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
|
cfg = config.genode.init;
|
||||||
inputs = mkOption {
|
inputs = mkOption {
|
||||||
description = "List of packages to build a ROM store with.";
|
description = "List of packages to build a ROM store with.";
|
||||||
|
default = [ ];
|
||||||
type = types.listOf types.package;
|
type = types.listOf types.package;
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
|
|
||||||
options.genode.init = {
|
options.genode.init = {
|
||||||
inherit inputs;
|
|
||||||
|
|
||||||
configFile = mkOption {
|
configFile = mkOption {
|
||||||
description = ''
|
description = ''
|
||||||
|
@ -56,53 +57,49 @@ in {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
subinits = mkOption {
|
subinits =
|
||||||
default = { };
|
# Subinits are just a different kind of children.
|
||||||
type = with types;
|
# Eventually this will be nested "genode.init" instances.
|
||||||
attrsOf (submodule {
|
mkOption {
|
||||||
options = {
|
default = { };
|
||||||
inherit inputs;
|
type = with types;
|
||||||
configFile = mkOption {
|
attrsOf (submodule {
|
||||||
type = types.path;
|
options = {
|
||||||
description = ''
|
inherit inputs;
|
||||||
Dhall configuration of child init.
|
configFile = mkOption {
|
||||||
See https://git.sr.ht/~ehmry/dhall-genode/tree/master/Init/Type
|
type = types.path;
|
||||||
'';
|
description = ''
|
||||||
|
Dhall configuration of child init.
|
||||||
|
See https://git.sr.ht/~ehmry/dhall-genode/tree/master/Init/Type
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
});
|
||||||
});
|
};
|
||||||
};
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config.genode.init = {
|
||||||
|
|
||||||
genode.init.inputs = with builtins;
|
|
||||||
[ pkgs.genodePackages.report_rom ] ++ concatLists (catAttrs "inputs"
|
|
||||||
((attrValues config.genode.init.children)
|
|
||||||
++ (attrValues config.genode.init.subinits)));
|
|
||||||
|
|
||||||
# TODO: convert the subinits to children
|
# TODO: convert the subinits to children
|
||||||
|
|
||||||
genode.init.configFile = pkgs.writeText "init.dhall" ''
|
children = mapAttrs (name: value: {
|
||||||
|
inherit (value) inputs;
|
||||||
|
configFile = pkgs.writeText "${name}.child.dhall" ''
|
||||||
|
let Genode = env:DHALL_GENODE
|
||||||
|
|
||||||
|
in Genode.Init.toChild ${value.configFile} Genode.Init.Attributes.default
|
||||||
|
'';
|
||||||
|
}) cfg.subinits;
|
||||||
|
|
||||||
|
configFile = pkgs.writeText "init.dhall" ''
|
||||||
let Genode = env:DHALL_GENODE
|
let Genode = env:DHALL_GENODE
|
||||||
let baseConfig = ${config.genode.init.baseConfig}
|
let baseConfig = ${cfg.baseConfig}
|
||||||
|
|
||||||
in baseConfig with children = baseConfig.children # toMap {${
|
in baseConfig with children = baseConfig.children # toMap {${
|
||||||
concatMapStrings (name:
|
concatMapStrings
|
||||||
", `${name}` = (${
|
(name: ", `${name}` = (${cfg.children.${name}.configFile}) ")
|
||||||
config.genode.init.children.${name}.configFile
|
(builtins.attrNames cfg.children)
|
||||||
} : Genode.Init.Child.Type)")
|
|
||||||
(builtins.attrNames config.genode.init.children)
|
|
||||||
} ${
|
|
||||||
concatMapStrings (name: ''
|
|
||||||
, `${name}` =
|
|
||||||
Genode.Init.toChild
|
|
||||||
(${
|
|
||||||
config.genode.init.subinits.${name}.configFile
|
|
||||||
} : Genode.Init.Type)
|
|
||||||
Genode.Init.Attributes.default
|
|
||||||
'') (builtins.attrNames config.genode.init.subinits)
|
|
||||||
} }
|
} }
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
let Genode =
|
let Genode = env:DHALL_GENODE
|
||||||
env:DHALL_GENODE sha256:e90438be23b5100003cf018b783986df67bc6d0e3d35e800677d0d9109ff6aa9
|
|
||||||
|
|
||||||
let Prelude = Genode.Prelude
|
let Prelude = Genode.Prelude
|
||||||
|
|
||||||
|
@ -13,75 +12,10 @@ let TextMapType = Prelude.Map.Type Text
|
||||||
|
|
||||||
let Manifest/Type = TextMapType (TextMapType Text)
|
let Manifest/Type = TextMapType (TextMapType Text)
|
||||||
|
|
||||||
let Manifest/toRoutes =
|
|
||||||
λ(manifest : Manifest/Type) →
|
|
||||||
Prelude.List.map
|
|
||||||
(Prelude.Map.Entry Text Text)
|
|
||||||
Init.ServiceRoute.Type
|
|
||||||
( λ(entry : Prelude.Map.Entry Text Text) →
|
|
||||||
{ service =
|
|
||||||
{ name = "ROM"
|
|
||||||
, label = Init.LabelSelector.Type.Last entry.mapKey
|
|
||||||
}
|
|
||||||
, route =
|
|
||||||
Init.Route.Type.Child
|
|
||||||
{ name = "store_rom"
|
|
||||||
, label = Some entry.mapValue
|
|
||||||
, diag = Some True
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
( Prelude.List.concat
|
|
||||||
(Prelude.Map.Entry Text Text)
|
|
||||||
(Prelude.Map.values Text (Prelude.Map.Type Text Text) manifest)
|
|
||||||
)
|
|
||||||
|
|
||||||
let parentROMs =
|
|
||||||
Prelude.List.map
|
|
||||||
Text
|
|
||||||
Init.ServiceRoute.Type
|
|
||||||
( λ(label : Text) →
|
|
||||||
{ service = { name = "ROM", label = Init.LabelSelector.last label }
|
|
||||||
, route =
|
|
||||||
Init.Route.Type.Parent { label = Some label, diag = None Bool }
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
let wrapStore
|
|
||||||
: Init.Type → Manifest/Type → Child.Type
|
|
||||||
= λ(init : Init.Type) →
|
|
||||||
λ(manifest : Manifest/Type) →
|
|
||||||
Init.toChild
|
|
||||||
init
|
|
||||||
Init.Attributes::{
|
|
||||||
, exitPropagate = True
|
|
||||||
, resources = Init.Resources::{ ram = Genode.units.MiB 4 }
|
|
||||||
, routes =
|
|
||||||
[ Init.ServiceRoute.parent "IO_MEM"
|
|
||||||
, Init.ServiceRoute.parent "IO_PORT"
|
|
||||||
, Init.ServiceRoute.parent "IRQ"
|
|
||||||
, Init.ServiceRoute.parent "VM"
|
|
||||||
, Init.ServiceRoute.child "Timer" "timer"
|
|
||||||
, Init.ServiceRoute.child "Rtc" "rtc"
|
|
||||||
]
|
|
||||||
# parentROMs
|
|
||||||
[ "ld.lib.so"
|
|
||||||
, "init"
|
|
||||||
, "platform_info"
|
|
||||||
, "core_log"
|
|
||||||
, "kernel_log"
|
|
||||||
, "vfs"
|
|
||||||
, "vfs.lib.so"
|
|
||||||
, "cached_fs_rom"
|
|
||||||
]
|
|
||||||
# Manifest/toRoutes manifest
|
|
||||||
# [ Init.ServiceRoute.child "ROM" "store_rom" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
in λ(subinit : Init.Type) →
|
in λ(subinit : Init.Type) →
|
||||||
λ(storeName : Text) →
|
λ(storeName : Text) →
|
||||||
λ(storeSize : Natural) →
|
λ(storeSize : Natural) →
|
||||||
λ(storeManifest : Manifest/Type) →
|
λ(storeRomPolicies : Prelude.Map.Type Text Text) →
|
||||||
λ(bootManifest : Manifest/Type) →
|
λ(bootManifest : Manifest/Type) →
|
||||||
Genode.Boot::{
|
Genode.Boot::{
|
||||||
, config = Init::{
|
, config = Init::{
|
||||||
|
@ -112,17 +46,14 @@ in λ(subinit : Init.Type) →
|
||||||
, binary = "vfs"
|
, binary = "vfs"
|
||||||
, config = Init.Config::{
|
, config = Init.Config::{
|
||||||
, content =
|
, content =
|
||||||
[ XML.element
|
let VFS = Genode.VFS
|
||||||
{ name = "vfs"
|
|
||||||
, attributes = XML.emptyAttributes
|
in [ VFS.vfs
|
||||||
, content =
|
[ VFS.leafAttrs
|
||||||
[ XML.leaf
|
"tar"
|
||||||
{ name = "tar"
|
(toMap { name = storeName })
|
||||||
, attributes = toMap { name = storeName }
|
]
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
|
||||||
]
|
|
||||||
, policies =
|
, policies =
|
||||||
[ Init.Config.Policy::{
|
[ Init.Config.Policy::{
|
||||||
, service = "File_system"
|
, service = "File_system"
|
||||||
|
@ -148,9 +79,107 @@ in λ(subinit : Init.Type) →
|
||||||
, resources = Init.Resources::{
|
, resources = Init.Resources::{
|
||||||
, ram = storeSize + Genode.units.MiB 1
|
, ram = storeSize + Genode.units.MiB 1
|
||||||
}
|
}
|
||||||
|
, config = Init.Config::{
|
||||||
|
, policies =
|
||||||
|
[ Init.Config.Policy::{
|
||||||
|
, service = "ROM"
|
||||||
|
, label =
|
||||||
|
Init.LabelSelector.prefix
|
||||||
|
"nixos -> /nix/store"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
# ( let Entry = Prelude.Map.Entry Text Text
|
||||||
|
|
||||||
|
in Prelude.List.concatMap
|
||||||
|
Entry
|
||||||
|
Init.Config.Policy.Type
|
||||||
|
( λ(e : Entry) →
|
||||||
|
[ Init.Config.Policy::{
|
||||||
|
, service = "ROM"
|
||||||
|
, label =
|
||||||
|
Init.LabelSelector.prefix
|
||||||
|
"nixos -> ${e.mapKey}"
|
||||||
|
, attributes = toMap
|
||||||
|
{ directory =
|
||||||
|
"${e.mapValue}/bin"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, Init.Config.Policy::{
|
||||||
|
, service = "ROM"
|
||||||
|
, label =
|
||||||
|
Init.LabelSelector.Type.Partial
|
||||||
|
{ prefix = Some
|
||||||
|
"nixos -> ${e.mapKey}"
|
||||||
|
, suffix = Some ".lib.so"
|
||||||
|
}
|
||||||
|
, attributes = toMap
|
||||||
|
{ directory =
|
||||||
|
"${e.mapValue}/lib"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
storeRomPolicies
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
, child
|
||||||
|
"nixos"
|
||||||
|
( Init.toChild
|
||||||
|
subinit
|
||||||
|
Init.Attributes::{
|
||||||
|
, exitPropagate = True
|
||||||
|
, resources = Init.Resources::{
|
||||||
|
, ram = Genode.units.MiB 4
|
||||||
|
}
|
||||||
|
, routes =
|
||||||
|
let parentROMs =
|
||||||
|
Prelude.List.concatMap
|
||||||
|
Text
|
||||||
|
Init.ServiceRoute.Type
|
||||||
|
( λ(suffix : Text) →
|
||||||
|
Prelude.List.map
|
||||||
|
Text
|
||||||
|
Init.ServiceRoute.Type
|
||||||
|
( λ(prefix : Text) →
|
||||||
|
{ service =
|
||||||
|
{ name = "ROM"
|
||||||
|
, label =
|
||||||
|
Init.LabelSelector.Type.Partial
|
||||||
|
{ prefix = Some prefix
|
||||||
|
, suffix = Some suffix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, route =
|
||||||
|
Init.Route.parent
|
||||||
|
(Some suffix)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
( Prelude.Map.keys
|
||||||
|
Text
|
||||||
|
Init.Child.Type
|
||||||
|
subinit.children
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
in parentROMs
|
||||||
|
[ "ld.lib.so"
|
||||||
|
, "vfs.lib.so"
|
||||||
|
, "init"
|
||||||
|
, "platform_info"
|
||||||
|
, "core_log"
|
||||||
|
, "kernel_log"
|
||||||
|
]
|
||||||
|
# [ Init.ServiceRoute.parent "IO_MEM"
|
||||||
|
, Init.ServiceRoute.parent "IO_PORT"
|
||||||
|
, Init.ServiceRoute.parent "IRQ"
|
||||||
|
, Init.ServiceRoute.parent "VM"
|
||||||
|
, Init.ServiceRoute.child "Timer" "timer"
|
||||||
|
, Init.ServiceRoute.child "Rtc" "rtc"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
, child "init" (wrapStore subinit storeManifest)
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
, rom =
|
, rom =
|
||||||
|
|
|
@ -4,6 +4,8 @@ let Prelude = Genode.Prelude
|
||||||
|
|
||||||
let XML = Prelude.XML
|
let XML = Prelude.XML
|
||||||
|
|
||||||
|
let VFS = Genode.VFS
|
||||||
|
|
||||||
let Init = Genode.Init
|
let Init = Genode.Init
|
||||||
|
|
||||||
let Child = Init.Child
|
let Child = Init.Child
|
||||||
|
@ -11,149 +13,156 @@ let Child = Init.Child
|
||||||
let parentRoutes =
|
let parentRoutes =
|
||||||
Prelude.List.map Text Init.ServiceRoute.Type Init.ServiceRoute.parent
|
Prelude.List.map Text Init.ServiceRoute.Type Init.ServiceRoute.parent
|
||||||
|
|
||||||
in λ(params : { coreutils : Text, execStart : Text }) →
|
in λ ( params
|
||||||
Init::{
|
: { name : Text
|
||||||
, verbose = True
|
, coreutils : Text
|
||||||
, routes = parentRoutes [ "Timer", "Rtc", "File_system" ]
|
, execStart : Text
|
||||||
, children = toMap
|
, interface : Optional Text
|
||||||
{ vfs =
|
}
|
||||||
Child.flat
|
) →
|
||||||
Child.Attributes::{
|
let socketsVfs =
|
||||||
, binary = "vfs"
|
merge
|
||||||
, exitPropagate = True
|
{ Some =
|
||||||
, provides = [ "File_system" ]
|
λ(interface : Text) →
|
||||||
, resources = Genode.Init.Resources::{
|
[ VFS.dir
|
||||||
, caps = 256
|
"sockets"
|
||||||
, ram = Genode.units.MiB 8
|
[ VFS.fs VFS.FS::{ label = "${interface}.sockets" } ]
|
||||||
}
|
]
|
||||||
, config = Init.Config::{
|
, None = [] : List XML.Type
|
||||||
, content =
|
}
|
||||||
[ XML.element
|
params.interface
|
||||||
{ name = "vfs"
|
|
||||||
, attributes = XML.emptyAttributes
|
|
||||||
, content =
|
|
||||||
let dir =
|
|
||||||
λ(name : Text) →
|
|
||||||
λ(content : List XML.Type) →
|
|
||||||
XML.element
|
|
||||||
{ name = "dir"
|
|
||||||
, content
|
|
||||||
, attributes = toMap { name }
|
|
||||||
}
|
|
||||||
|
|
||||||
let leaf =
|
let init =
|
||||||
λ(name : Text) →
|
Init::{
|
||||||
XML.leaf
|
, routes = parentRoutes [ "Timer", "Rtc", "File_system" ]
|
||||||
{ name, attributes = XML.emptyAttributes }
|
, children = toMap
|
||||||
|
{ vfs =
|
||||||
in [ dir
|
Child.flat
|
||||||
"dev"
|
Child.Attributes::{
|
||||||
[ dir "pipes" [ leaf "pipe" ]
|
, binary = "vfs"
|
||||||
, dir
|
, exitPropagate = True
|
||||||
"sockets"
|
, provides = [ "File_system" ]
|
||||||
[ XML.leaf
|
, resources = Genode.Init.Resources::{
|
||||||
{ name = "fs"
|
, caps = 256
|
||||||
, attributes = toMap
|
, ram = Genode.units.MiB 8
|
||||||
{ label = "sockets" }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
, leaf "log"
|
|
||||||
, leaf "null"
|
|
||||||
, leaf "rtc"
|
|
||||||
, leaf "zero"
|
|
||||||
]
|
|
||||||
, dir
|
|
||||||
"etc"
|
|
||||||
[ XML.element
|
|
||||||
{ name = "inline"
|
|
||||||
, attributes = toMap
|
|
||||||
{ name = "ExecStart" }
|
|
||||||
, content =
|
|
||||||
[ XML.text params.execStart ]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
, dir
|
|
||||||
"usr"
|
|
||||||
[ dir
|
|
||||||
"bin"
|
|
||||||
[ XML.leaf
|
|
||||||
{ name = "symlink"
|
|
||||||
, attributes = toMap
|
|
||||||
{ name = "env"
|
|
||||||
, target =
|
|
||||||
"${params.coreutils}/bin/env"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
|
||||||
, dir "tmp" [ leaf "ram" ]
|
|
||||||
, dir
|
|
||||||
"nix"
|
|
||||||
[ dir
|
|
||||||
"store"
|
|
||||||
[ XML.leaf
|
|
||||||
{ name = "fs"
|
|
||||||
, attributes = toMap
|
|
||||||
{ label = "nix-store" }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
, config = Init.Config::{
|
||||||
, policies =
|
, content =
|
||||||
[ Init.Config.Policy::{
|
[ VFS.vfs
|
||||||
, service = "File_system"
|
[ VFS.dir
|
||||||
, label = Init.LabelSelector.prefix "shell"
|
"dev"
|
||||||
, attributes = toMap { root = "/", writeable = "yes" }
|
( [ VFS.dir "pipes" [ VFS.leaf "pipe" ]
|
||||||
}
|
, VFS.leaf "log"
|
||||||
]
|
, VFS.leaf "null"
|
||||||
}
|
, VFS.leaf "rtc"
|
||||||
}
|
, VFS.leaf "zero"
|
||||||
, shell =
|
]
|
||||||
Child.flat
|
# socketsVfs
|
||||||
Child.Attributes::{
|
)
|
||||||
, binary = "bash"
|
, VFS.dir
|
||||||
, exitPropagate = True
|
"usr"
|
||||||
, resources = Genode.Init.Resources::{
|
[ VFS.dir
|
||||||
, caps = 256
|
"bin"
|
||||||
, ram = Genode.units.MiB 8
|
[ VFS.symlink
|
||||||
}
|
"env"
|
||||||
, config = Genode.Init.Config::{
|
"${params.coreutils}/bin/env"
|
||||||
, content =
|
]
|
||||||
[ XML.leaf
|
]
|
||||||
{ name = "libc"
|
, VFS.dir "tmp" [ VFS.leaf "ram" ]
|
||||||
, attributes = toMap
|
, VFS.dir
|
||||||
{ stdin = "/dev/null"
|
"nix"
|
||||||
, stdout = "/dev/log"
|
[ VFS.dir
|
||||||
, stderr = "/dev/log"
|
"store"
|
||||||
, pipe = "/dev/pipes"
|
[ VFS.fs VFS.FS::{ label = "nix-store" } ]
|
||||||
, rtc = "/dev/rtc"
|
]
|
||||||
, socket = "/dev/sockets"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
, XML.element
|
|
||||||
{ name = "vfs"
|
|
||||||
, attributes = XML.emptyAttributes
|
|
||||||
, content =
|
|
||||||
[ XML.leaf
|
|
||||||
{ name = "fs"
|
|
||||||
, attributes = XML.emptyAttributes
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
|
]
|
||||||
|
, policies =
|
||||||
|
[ Init.Config.Policy::{
|
||||||
|
, service = "File_system"
|
||||||
|
, label = Init.LabelSelector.prefix "shell"
|
||||||
|
, attributes = toMap
|
||||||
|
{ root = "/", writeable = "yes" }
|
||||||
}
|
}
|
||||||
]
|
, Init.Config.Policy::{
|
||||||
# Prelude.List.map
|
, service = "File_system"
|
||||||
Text
|
, label = Init.LabelSelector.prefix "vfs_rom"
|
||||||
XML.Type
|
, attributes = toMap
|
||||||
( λ(x : Text) →
|
{ root = "/", writeable = "yes" }
|
||||||
XML.leaf
|
}
|
||||||
{ name = "arg"
|
]
|
||||||
, attributes = toMap { value = x }
|
}
|
||||||
}
|
}
|
||||||
)
|
, vfs_rom =
|
||||||
[ "bash", "/etc/ExecStart" ]
|
Child.flat
|
||||||
}
|
Child.Attributes::{
|
||||||
|
, binary = "cached_fs_rom"
|
||||||
|
, provides = [ "ROM" ]
|
||||||
|
, resources = Genode.Init.Resources::{
|
||||||
|
, ram = Genode.units.MiB 16
|
||||||
|
}
|
||||||
|
, config = Init.Config::{
|
||||||
|
, policies =
|
||||||
|
[ Init.Config.Policy::{
|
||||||
|
, service = "ROM"
|
||||||
|
, diag = Some True
|
||||||
|
, label = Init.LabelSelector.prefix "shell"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, shell =
|
||||||
|
Child.flat
|
||||||
|
Child.Attributes::{
|
||||||
|
, binary = "bash"
|
||||||
|
, exitPropagate = True
|
||||||
|
, resources = Genode.Init.Resources::{
|
||||||
|
, caps = 256
|
||||||
|
, ram = Genode.units.MiB 8
|
||||||
|
}
|
||||||
|
, config = Init.Config::{
|
||||||
|
, content =
|
||||||
|
[ XML.leaf
|
||||||
|
{ name = "libc"
|
||||||
|
, attributes = toMap
|
||||||
|
{ stdin = "/dev/null"
|
||||||
|
, stdout = "/dev/log"
|
||||||
|
, stderr = "/dev/log"
|
||||||
|
, pipe = "/dev/pipes"
|
||||||
|
, rtc = "/dev/rtc"
|
||||||
|
, socket = "/dev/sockets"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, VFS.vfs [ VFS.leaf "fs" ]
|
||||||
|
]
|
||||||
|
# Prelude.List.map
|
||||||
|
Text
|
||||||
|
XML.Type
|
||||||
|
( λ(x : Text) →
|
||||||
|
XML.leaf
|
||||||
|
{ name = "arg"
|
||||||
|
, attributes = toMap { value = x }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
[ "bash", "-c", params.execStart ]
|
||||||
|
}
|
||||||
|
, routes =
|
||||||
|
Prelude.List.map
|
||||||
|
Text
|
||||||
|
Init.ServiceRoute.Type
|
||||||
|
( λ(label : Text) →
|
||||||
|
Init.ServiceRoute.parentLabel
|
||||||
|
"ROM"
|
||||||
|
(Some label)
|
||||||
|
(Some label)
|
||||||
|
)
|
||||||
|
[ "libc.lib.so"
|
||||||
|
, "libm.lib.so"
|
||||||
|
, "posix.lib.so"
|
||||||
|
, "vfs.lib.so"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
in Init.toChild init Init.Attributes::{=}
|
||||||
|
|
|
@ -3,31 +3,65 @@ with lib; {
|
||||||
|
|
||||||
options.systemd.services = lib.mkOption {
|
options.systemd.services = lib.mkOption {
|
||||||
type = types.attrsOf (types.submodule ({ name, config, ... }: {
|
type = types.attrsOf (types.submodule ({ name, config, ... }: {
|
||||||
options.genode.enable = lib.mkOption {
|
options.genode = {
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
enable = lib.mkOption {
|
||||||
description = "Translate this systemd unit to a Genode subsystem.";
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Translate this systemd unit to a Genode subsystem.";
|
||||||
|
};
|
||||||
|
|
||||||
|
interface = lib.mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
default = null;
|
||||||
|
example = "eth0";
|
||||||
|
description = ''
|
||||||
|
Grant access to an IP stack for this interface.
|
||||||
|
Only UDP and TCP are supported. No raw device access.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
config.services.klogd.enable = false;
|
config = {
|
||||||
# The default is determined by checking the Linux version
|
|
||||||
# which cannot be evaluated here.
|
services.klogd.enable = false;
|
||||||
|
# The default is determined by checking the Linux version
|
||||||
|
# which cannot be evaluated here.
|
||||||
|
|
||||||
|
genode.init.children = mapAttrs' (name: service:
|
||||||
|
let name' = "services." + name;
|
||||||
|
in {
|
||||||
|
name = name';
|
||||||
|
value = {
|
||||||
|
inputs = with pkgs;
|
||||||
|
with genodePackages; [
|
||||||
|
bash
|
||||||
|
cached_fs_rom
|
||||||
|
libc
|
||||||
|
posix
|
||||||
|
vfs
|
||||||
|
vfs_pipe
|
||||||
|
];
|
||||||
|
configFile = let
|
||||||
|
interface = if service.genode.interface == null then
|
||||||
|
"None Text"
|
||||||
|
else
|
||||||
|
''Some "${service.genode.interface}"'';
|
||||||
|
in pkgs.writeText "${name'}.dhall" ''
|
||||||
|
${./systemd-runner.dhall} {
|
||||||
|
, name = "${name'}"
|
||||||
|
, coreutils = "${pkgs.coreutils}"
|
||||||
|
, execStart = "${toString service.serviceConfig.ExecStart}"
|
||||||
|
, interface = ${interface}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}) (filterAttrs (name: service: service.genode.enable)
|
||||||
|
config.systemd.services);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
config.genode.init.subinits = mapAttrs' (name: service:
|
|
||||||
let name' = "services." + name;
|
|
||||||
in {
|
|
||||||
name = name';
|
|
||||||
value = {
|
|
||||||
inputs = with pkgs; with genodePackages; [ bash libc posix vfs_pipe ];
|
|
||||||
configFile = pkgs.writeText "${name'}.dhall" ''
|
|
||||||
${./systemd-runner.dhall} {
|
|
||||||
, coreutils = "${pkgs.coreutils}"
|
|
||||||
, execStart = "${toString service.serviceConfig.ExecStart}"
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}) (filterAttrs (name: service: service.genode.enable)
|
|
||||||
config.systemd.services);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,12 @@ dhallPackages.buildDhallPackage {
|
||||||
code = let
|
code = let
|
||||||
src = fetchgit {
|
src = fetchgit {
|
||||||
url = "https://git.sr.ht/~ehmry/dhall-genode";
|
url = "https://git.sr.ht/~ehmry/dhall-genode";
|
||||||
rev = "1a6b3609a778f1644bc2831c366c65cce854ae42";
|
rev = "882740d78425bb1a6c4b1b34b1b201ace9d71317";
|
||||||
sha256 = "1zcnja7wmjx8rlm38x0lkgdz7cfwnd4m6jkasczrf7jqr53j73kv";
|
sha256 = "0cqlrbjb6023x7yynnglv11755xiw0wy4g16r88nsflcw119czqm";
|
||||||
};
|
};
|
||||||
in src + "/package.dhall";
|
in src + "/package.dhall";
|
||||||
|
|
||||||
dependencies = [ dhallPackages.Prelude."13.0.0" ];
|
dependencies = [ dhallPackages.Prelude ];
|
||||||
|
|
||||||
source = true;
|
source = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,84 +1,37 @@
|
||||||
commit 20abcefd185d72ecc55e87ff78f8f784d927653d
|
From dc4594b0bb0effdd261c70147a47ff0f0b8ee1f3 Mon Sep 17 00:00:00 2001
|
||||||
Author: Emery Hemingway <ehmry@posteo.net>
|
From: Emery Hemingway <ehmry@posteo.net>
|
||||||
Date: Sat Apr 25 16:08:45 2020 +0530
|
Date: Sat, 25 Apr 2020 17:10:03 +0530
|
||||||
|
Subject: [PATCH 1/3] init/sandbox: <routes> support
|
||||||
|
|
||||||
Init/sandbox: always route "ld.lib.so" ROM to parent
|
Apply routing rules to a child from a <routes> node at the top-level of
|
||||||
|
a sandbox config, unless the corresponding start node has as <route>
|
||||||
A livelock may occur if init router the "ld.lib.so" ROM request of a
|
node. If neither are present routes are taken from <default-route> as a
|
||||||
child to another child, and the child providing the ROM interacts with
|
fallback.
|
||||||
Init during the creation of the session.
|
|
||||||
|
Unlike the <route> and <default-route> the <routes> rules are checked by
|
||||||
|
labels prefixed by child name, so <routes> may contain child-specific
|
||||||
|
rules.
|
||||||
|
---
|
||||||
|
repos/os/src/lib/sandbox/child.cc | 12 +++++++++++-
|
||||||
|
repos/os/src/lib/sandbox/child.h | 10 ++++++++++
|
||||||
|
repos/os/src/lib/sandbox/library.cc | 14 +++++++++++++-
|
||||||
|
repos/os/src/lib/sandbox/utils.h | 8 +++++---
|
||||||
|
4 files changed, 39 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
diff --git a/repos/os/src/lib/sandbox/child.cc b/repos/os/src/lib/sandbox/child.cc
|
diff --git a/repos/os/src/lib/sandbox/child.cc b/repos/os/src/lib/sandbox/child.cc
|
||||||
index 5361665eac..fa09cca31a 100644
|
index e321df61fd..d25e3d9683 100644
|
||||||
--- a/repos/os/src/lib/sandbox/child.cc
|
--- a/repos/os/src/lib/sandbox/child.cc
|
||||||
+++ b/repos/os/src/lib/sandbox/child.cc
|
+++ b/repos/os/src/lib/sandbox/child.cc
|
||||||
@@ -448,6 +448,8 @@ Sandbox::Child::Route
|
@@ -487,17 +487,25 @@ Sandbox::Child::resolve_session_request(Service::Name const &service_name,
|
||||||
Sandbox::Child::resolve_session_request(Service::Name const &service_name,
|
Session::Label(), Session::Diag{false} };
|
||||||
Session_label const &label)
|
|
||||||
{
|
|
||||||
+ auto no_filter = [] (Service &) -> bool { return false; };
|
|
||||||
+
|
|
||||||
/* check for "config" ROM request */
|
|
||||||
if (service_name == Rom_session::service_name() &&
|
|
||||||
label.last_element() == "config") {
|
|
||||||
@@ -498,9 +500,20 @@ Sandbox::Child::resolve_session_request(Service::Name const &service_name,
|
|
||||||
label == _unique_name && _unique_name != _binary_name)
|
|
||||||
return resolve_session_request(service_name, _binary_name);
|
|
||||||
|
|
||||||
- /* supply binary as dynamic linker if '<start ld="no">' */
|
|
||||||
- if (!_use_ld && service_name == Rom_session::service_name() && label == "ld.lib.so")
|
|
||||||
- return resolve_session_request(service_name, _binary_name);
|
|
||||||
+ /*
|
|
||||||
+ * Check for the "ld.lib.so" ROM request
|
|
||||||
+ */
|
|
||||||
+ if (service_name == Rom_session::service_name() && label == "ld.lib.so") {
|
|
||||||
+ if (_use_ld) {
|
|
||||||
+ /* forward request to parent */
|
|
||||||
+ return Route {
|
|
||||||
+ find_service(_parent_services, Rom_session::service_name(), no_filter),
|
|
||||||
+ Session_label("ld.lib.so"), Session::Diag { false} };
|
|
||||||
+ } else {
|
|
||||||
+ /* supply binary as dynamic linker if '<start ld="no">' */
|
|
||||||
+ return resolve_session_request(service_name, _binary_name);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
|
|
||||||
/* check for "session_requests" ROM request */
|
|
||||||
if (service_name == Rom_session::service_name()
|
|
||||||
@@ -541,8 +554,6 @@ Sandbox::Child::resolve_session_request(Service::Name const &service_name,
|
|
||||||
Session::Diag const
|
|
||||||
target_diag { target.attribute_value("diag", false) };
|
|
||||||
|
|
||||||
- auto no_filter = [] (Service &) -> bool { return false; };
|
|
||||||
-
|
|
||||||
if (target.has_type("parent")) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
commit ce74d9bb7740f14b362e72adcf8ac42e36693468
|
|
||||||
Author: Emery Hemingway <ehmry@posteo.net>
|
|
||||||
Date: Sat Apr 25 17:10:03 2020 +0530
|
|
||||||
|
|
||||||
init/sandbox: <routes> support
|
|
||||||
|
|
||||||
Apply routing rules to a child from a <routes> node at the top-level of
|
|
||||||
a sandbox config, unless the corresponding start node has as <route>
|
|
||||||
node. If neither are present routes are taken from <default-route> as a
|
|
||||||
fallback.
|
|
||||||
|
|
||||||
Unlike the <route> and <default-route> the <routes> rules are checked by
|
|
||||||
labels prefixed by child name, so <routes> may contain child-specific
|
|
||||||
rules.
|
|
||||||
|
|
||||||
diff --git a/repos/os/src/lib/sandbox/child.cc b/repos/os/src/lib/sandbox/child.cc
|
|
||||||
index fa09cca31a..85389474ef 100644
|
|
||||||
--- a/repos/os/src/lib/sandbox/child.cc
|
|
||||||
+++ b/repos/os/src/lib/sandbox/child.cc
|
|
||||||
@@ -523,16 +523,21 @@ Sandbox::Child::resolve_session_request(Service::Name const &service_name,
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
+ /* Lookup route in <default-route>… */
|
||||||
Xml_node route_node = _default_route_accessor.default_route();
|
Xml_node route_node = _default_route_accessor.default_route();
|
||||||
|
+ /* …unless <routes> is present… */
|
||||||
+ route_node = _routes_accessor.routes(route_node);
|
+ route_node = _routes_accessor.routes(route_node);
|
||||||
try {
|
try {
|
||||||
|
+ /* …otherwise use <child><route>. */
|
||||||
route_node = _start_node->xml().sub_node("route"); }
|
route_node = _start_node->xml().sub_node("route"); }
|
||||||
catch (...) { }
|
catch (...) { }
|
||||||
+
|
+
|
||||||
|
@ -96,7 +49,7 @@ index fa09cca31a..85389474ef 100644
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Xml_node target = service_node.sub_node();
|
Xml_node target = service_node.sub_node();
|
||||||
@@ -736,6 +741,7 @@ Sandbox::Child::Child(Env &env,
|
@@ -705,6 +713,7 @@ Sandbox::Child::Child(Env &env,
|
||||||
Report_update_trigger &report_update_trigger,
|
Report_update_trigger &report_update_trigger,
|
||||||
Xml_node start_node,
|
Xml_node start_node,
|
||||||
Default_route_accessor &default_route_accessor,
|
Default_route_accessor &default_route_accessor,
|
||||||
|
@ -104,7 +57,7 @@ index fa09cca31a..85389474ef 100644
|
||||||
Default_caps_accessor &default_caps_accessor,
|
Default_caps_accessor &default_caps_accessor,
|
||||||
Name_registry &name_registry,
|
Name_registry &name_registry,
|
||||||
Ram_quota ram_limit,
|
Ram_quota ram_limit,
|
||||||
@@ -753,6 +759,7 @@ Sandbox::Child::Child(Env &env,
|
@@ -722,6 +731,7 @@ Sandbox::Child::Child(Env &env,
|
||||||
_list_element(this),
|
_list_element(this),
|
||||||
_start_node(_alloc, start_node),
|
_start_node(_alloc, start_node),
|
||||||
_default_route_accessor(default_route_accessor),
|
_default_route_accessor(default_route_accessor),
|
||||||
|
@ -113,7 +66,7 @@ index fa09cca31a..85389474ef 100644
|
||||||
_ram_limit_accessor(ram_limit_accessor),
|
_ram_limit_accessor(ram_limit_accessor),
|
||||||
_cap_limit_accessor(cap_limit_accessor),
|
_cap_limit_accessor(cap_limit_accessor),
|
||||||
diff --git a/repos/os/src/lib/sandbox/child.h b/repos/os/src/lib/sandbox/child.h
|
diff --git a/repos/os/src/lib/sandbox/child.h b/repos/os/src/lib/sandbox/child.h
|
||||||
index 4dd2803417..8e84e9bf75 100644
|
index 2c213e662c..81836a2045 100644
|
||||||
--- a/repos/os/src/lib/sandbox/child.h
|
--- a/repos/os/src/lib/sandbox/child.h
|
||||||
+++ b/repos/os/src/lib/sandbox/child.h
|
+++ b/repos/os/src/lib/sandbox/child.h
|
||||||
@@ -52,6 +52,14 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
|
@@ -52,6 +52,14 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
|
||||||
|
@ -139,7 +92,7 @@ index 4dd2803417..8e84e9bf75 100644
|
||||||
Default_caps_accessor &_default_caps_accessor;
|
Default_caps_accessor &_default_caps_accessor;
|
||||||
Ram_limit_accessor &_ram_limit_accessor;
|
Ram_limit_accessor &_ram_limit_accessor;
|
||||||
Cap_limit_accessor &_cap_limit_accessor;
|
Cap_limit_accessor &_cap_limit_accessor;
|
||||||
@@ -475,6 +484,7 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
|
@@ -473,6 +482,7 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
|
||||||
Report_update_trigger &report_update_trigger,
|
Report_update_trigger &report_update_trigger,
|
||||||
Xml_node start_node,
|
Xml_node start_node,
|
||||||
Default_route_accessor &default_route_accessor,
|
Default_route_accessor &default_route_accessor,
|
||||||
|
@ -226,3 +179,523 @@ index 7afcaebf00..36aab737f2 100644
|
||||||
|
|
||||||
if (!scoped_label)
|
if (!scoped_label)
|
||||||
return false;
|
return false;
|
||||||
|
--
|
||||||
|
2.28.0
|
||||||
|
|
||||||
|
|
||||||
|
From 13f2b3357f0e366a61d8b440fb56a52e5d2dfaff Mon Sep 17 00:00:00 2001
|
||||||
|
From: Emery Hemingway <ehmry@posteo.net>
|
||||||
|
Date: Wed, 4 Nov 2020 11:03:49 +0100
|
||||||
|
Subject: [PATCH 2/3] init/sandbox: do not parse <parent-provides> if <routes>
|
||||||
|
is present
|
||||||
|
|
||||||
|
---
|
||||||
|
repos/os/src/lib/sandbox/library.cc | 124 +++++++++++++++++++---------
|
||||||
|
1 file changed, 85 insertions(+), 39 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/repos/os/src/lib/sandbox/library.cc b/repos/os/src/lib/sandbox/library.cc
|
||||||
|
index 30d0f2dfc1..caa9840ea6 100644
|
||||||
|
--- a/repos/os/src/lib/sandbox/library.cc
|
||||||
|
+++ b/repos/os/src/lib/sandbox/library.cc
|
||||||
|
@@ -184,47 +184,93 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
|
||||||
|
|
||||||
|
void Genode::Sandbox::Library::_update_parent_services_from_config(Xml_node const &config)
|
||||||
|
{
|
||||||
|
- Xml_node const node = config.has_sub_node("parent-provides")
|
||||||
|
- ? config.sub_node("parent-provides")
|
||||||
|
- : Xml_node("<empty/>");
|
||||||
|
-
|
||||||
|
- /* remove services that are no longer present in config */
|
||||||
|
- _parent_services.for_each([&] (Parent_service &service) {
|
||||||
|
-
|
||||||
|
- Service::Name const name = service.name();
|
||||||
|
-
|
||||||
|
- bool obsolete = true;
|
||||||
|
+ if (config.has_sub_node("routes")) {
|
||||||
|
+ if (config.has_sub_node("parent-provides"))
|
||||||
|
+ warning("ignoring <parent-provides> and parsing <routes> instead");
|
||||||
|
+
|
||||||
|
+ Xml_node const node = config.sub_node("routes");
|
||||||
|
+
|
||||||
|
+ /* remove services that are no longer present in config */
|
||||||
|
+ _parent_services.for_each([&] (Parent_service &service) {
|
||||||
|
+
|
||||||
|
+ Service::Name const name = service.name();
|
||||||
|
+
|
||||||
|
+ bool obsolete = true;
|
||||||
|
+ node.for_each_sub_node("service", [&] (Xml_node service) {
|
||||||
|
+ if (obsolete && name == service.attribute_value("name", Service::Name())) {
|
||||||
|
+ obsolete = !service.has_sub_node("parent"); }});
|
||||||
|
+
|
||||||
|
+ if (obsolete)
|
||||||
|
+ service.abandon();
|
||||||
|
+ });
|
||||||
|
+
|
||||||
|
+ /* used to prepend the list of new parent services with title */
|
||||||
|
+ bool first_log = true;
|
||||||
|
+
|
||||||
|
+ /* register new services */
|
||||||
|
node.for_each_sub_node("service", [&] (Xml_node service) {
|
||||||
|
- if (name == service.attribute_value("name", Service::Name())) {
|
||||||
|
- obsolete = false; }});
|
||||||
|
-
|
||||||
|
- if (obsolete)
|
||||||
|
- service.abandon();
|
||||||
|
- });
|
||||||
|
-
|
||||||
|
- /* used to prepend the list of new parent services with title */
|
||||||
|
- bool first_log = true;
|
||||||
|
-
|
||||||
|
- /* register new services */
|
||||||
|
- node.for_each_sub_node("service", [&] (Xml_node service) {
|
||||||
|
-
|
||||||
|
- Service::Name const name = service.attribute_value("name", Service::Name());
|
||||||
|
-
|
||||||
|
- bool registered = false;
|
||||||
|
- _parent_services.for_each([&] (Parent_service const &service) {
|
||||||
|
- if (service.name() == name)
|
||||||
|
- registered = true; });
|
||||||
|
-
|
||||||
|
- if (!registered) {
|
||||||
|
- new (_heap) ::Sandbox::Parent_service(_parent_services, _env, name);
|
||||||
|
- if (_verbose->enabled()) {
|
||||||
|
- if (first_log)
|
||||||
|
- log("parent provides");
|
||||||
|
- log(" service \"", name, "\"");
|
||||||
|
- first_log = false;
|
||||||
|
+ if (service.has_sub_node("child")) return;
|
||||||
|
+
|
||||||
|
+ Service::Name const name = service.attribute_value("name", Service::Name());
|
||||||
|
+
|
||||||
|
+ bool registered = false;
|
||||||
|
+ _parent_services.for_each([&] (Parent_service const &service) {
|
||||||
|
+ if (service.name() == name)
|
||||||
|
+ registered = true; });
|
||||||
|
+
|
||||||
|
+ if (!registered) {
|
||||||
|
+ new (_heap) ::Sandbox::Parent_service(_parent_services, _env, name);
|
||||||
|
+ if (_verbose->enabled()) {
|
||||||
|
+ if (first_log)
|
||||||
|
+ log("parent provides");
|
||||||
|
+ log(" service \"", name, "\"");
|
||||||
|
+ first_log = false;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
- }
|
||||||
|
- });
|
||||||
|
+ });
|
||||||
|
+ } else {
|
||||||
|
+ Xml_node const node = config.has_sub_node("parent-provides")
|
||||||
|
+ ? config.sub_node("parent-provides")
|
||||||
|
+ : Xml_node("<empty/>");
|
||||||
|
+
|
||||||
|
+ /* remove services that are no longer present in config */
|
||||||
|
+ _parent_services.for_each([&] (Parent_service &service) {
|
||||||
|
+
|
||||||
|
+ Service::Name const name = service.name();
|
||||||
|
+
|
||||||
|
+ bool obsolete = true;
|
||||||
|
+ node.for_each_sub_node("service", [&] (Xml_node service) {
|
||||||
|
+ if (name == service.attribute_value("name", Service::Name())) {
|
||||||
|
+ obsolete = false; }});
|
||||||
|
+
|
||||||
|
+ if (obsolete)
|
||||||
|
+ service.abandon();
|
||||||
|
+ });
|
||||||
|
+
|
||||||
|
+ /* used to prepend the list of new parent services with title */
|
||||||
|
+ bool first_log = true;
|
||||||
|
+
|
||||||
|
+ /* register new services */
|
||||||
|
+ node.for_each_sub_node("service", [&] (Xml_node service) {
|
||||||
|
+
|
||||||
|
+ Service::Name const name = service.attribute_value("name", Service::Name());
|
||||||
|
+
|
||||||
|
+ bool registered = false;
|
||||||
|
+ _parent_services.for_each([&] (Parent_service const &service) {
|
||||||
|
+ if (service.name() == name)
|
||||||
|
+ registered = true; });
|
||||||
|
+
|
||||||
|
+ if (!registered) {
|
||||||
|
+ new (_heap) ::Sandbox::Parent_service(_parent_services, _env, name);
|
||||||
|
+ if (_verbose->enabled()) {
|
||||||
|
+ if (first_log)
|
||||||
|
+ log("parent provides");
|
||||||
|
+ log(" service \"", name, "\"");
|
||||||
|
+ first_log = false;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ });
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
2.28.0
|
||||||
|
|
||||||
|
|
||||||
|
From f89d8cbc3aa5fe9f7162ad66819fd2cedd76ba02 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Emery Hemingway <ehmry@posteo.net>
|
||||||
|
Date: Wed, 4 Nov 2020 20:02:03 +0100
|
||||||
|
Subject: [PATCH 3/3] init/sandbox: simplify routing
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Remove <default-route>, <any-service>, and <any-child> configuration
|
||||||
|
options.
|
||||||
|
|
||||||
|
Allow label rewriting with <parent prefix="…" suffix="…">
|
||||||
|
and <child name="…" prefix="…" suffix="…">.
|
||||||
|
|
||||||
|
Routes are now selected by longest match rather than first match.
|
||||||
|
---
|
||||||
|
repos/os/src/lib/sandbox/child.cc | 131 ++++++++++------------------
|
||||||
|
repos/os/src/lib/sandbox/child.h | 3 -
|
||||||
|
repos/os/src/lib/sandbox/library.cc | 12 +--
|
||||||
|
repos/os/src/lib/sandbox/utils.h | 57 ++++++------
|
||||||
|
4 files changed, 76 insertions(+), 127 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/repos/os/src/lib/sandbox/child.cc b/repos/os/src/lib/sandbox/child.cc
|
||||||
|
index d25e3d9683..46aa22411c 100644
|
||||||
|
--- a/repos/os/src/lib/sandbox/child.cc
|
||||||
|
+++ b/repos/os/src/lib/sandbox/child.cc
|
||||||
|
@@ -11,6 +11,7 @@
|
||||||
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#include <os/session_policy.h>
|
||||||
|
#include <vm_session/vm_session.h>
|
||||||
|
|
||||||
|
/* local includes */
|
||||||
|
@@ -486,105 +487,65 @@ Sandbox::Child::resolve_session_request(Service::Name const &service_name,
|
||||||
|
return Route { _session_requester.service(),
|
||||||
|
Session::Label(), Session::Diag{false} };
|
||||||
|
|
||||||
|
- try {
|
||||||
|
- /* Lookup route in <default-route>… */
|
||||||
|
- Xml_node route_node = _default_route_accessor.default_route();
|
||||||
|
- /* …unless <routes> is present… */
|
||||||
|
- route_node = _routes_accessor.routes(route_node);
|
||||||
|
- try {
|
||||||
|
- /* …otherwise use <child><route>. */
|
||||||
|
- route_node = _start_node->xml().sub_node("route"); }
|
||||||
|
- catch (...) { }
|
||||||
|
-
|
||||||
|
- Xml_node service_node = route_node.sub_node();
|
||||||
|
-
|
||||||
|
- /* <routes> is processed with the "«child» -> " prefix */
|
||||||
|
- bool skip_prefix = route_node.type() != "routes";
|
||||||
|
-
|
||||||
|
- for (; ; service_node = service_node.next()) {
|
||||||
|
-
|
||||||
|
- bool service_wildcard = service_node.has_type("any-service");
|
||||||
|
-
|
||||||
|
- if (!service_node_matches(service_node, label, name(), service_name, skip_prefix))
|
||||||
|
- continue;
|
||||||
|
-
|
||||||
|
- Xml_node target = service_node.sub_node();
|
||||||
|
- for (; ; target = target.next()) {
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * Determine session label to be provided to the server
|
||||||
|
- *
|
||||||
|
- * By default, the client's identity (accompanied with the a
|
||||||
|
- * client-provided label) is presented as session label to the
|
||||||
|
- * server. However, the target node can explicitly override the
|
||||||
|
- * client's identity by a custom label via the 'label'
|
||||||
|
- * attribute.
|
||||||
|
- */
|
||||||
|
- typedef String<Session_label::capacity()> Label;
|
||||||
|
- Label const target_label =
|
||||||
|
- target.attribute_value("label", Label(label.string()));
|
||||||
|
-
|
||||||
|
- Session::Diag const
|
||||||
|
- target_diag { target.attribute_value("diag", false) };
|
||||||
|
-
|
||||||
|
- auto no_filter = [] (Service &) -> bool { return false; };
|
||||||
|
-
|
||||||
|
- if (target.has_type("parent")) {
|
||||||
|
-
|
||||||
|
- try {
|
||||||
|
- return Route { find_service(_parent_services, service_name, no_filter),
|
||||||
|
- target_label, target_diag };
|
||||||
|
- } catch (Service_denied) { }
|
||||||
|
+ {
|
||||||
|
+ Xml_node service_node("<deny/>");
|
||||||
|
+ Xml_node routes_node = _routes_accessor.routes(service_node);
|
||||||
|
+ Xml_node_label_score best_score;
|
||||||
|
+
|
||||||
|
+ routes_node.for_each_sub_node([&] (Xml_node const &node) {
|
||||||
|
+ if (service_node_matches(node, label, service_name)) {
|
||||||
|
+ Xml_node_label_score score(node, label);
|
||||||
|
+ if (score.stronger(best_score)
|
||||||
|
+ || service_node.has_type("deny")) {
|
||||||
|
+ best_score = score;
|
||||||
|
+ service_node = node;
|
||||||
|
}
|
||||||
|
+ }
|
||||||
|
+ });
|
||||||
|
|
||||||
|
- if (target.has_type("local")) {
|
||||||
|
+ if (service_node.has_type("deny")) {
|
||||||
|
+ warning(name(), ": no route to service \"", service_name, "\" (label=\"", label, "\")");
|
||||||
|
+ throw Service_denied();
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- try {
|
||||||
|
- return Route { find_service(_local_services, service_name, no_filter),
|
||||||
|
- target_label, target_diag };
|
||||||
|
- } catch (Service_denied) { }
|
||||||
|
- }
|
||||||
|
+ for (Xml_node target_node = service_node.sub_node(); ;
|
||||||
|
+ target_node = target_node.next()) {
|
||||||
|
|
||||||
|
- if (target.has_type("child")) {
|
||||||
|
+ Session_label the_label_part_of_label(skip_label_prefix(name().string(), label.string()));
|
||||||
|
+ if (the_label_part_of_label == "") the_label_part_of_label = label;
|
||||||
|
|
||||||
|
- typedef Name_registry::Name Name;
|
||||||
|
- Name server_name = target.attribute_value("name", Name());
|
||||||
|
- server_name = _name_registry.deref_alias(server_name);
|
||||||
|
+ auto target_label = Sandbox::target_label(
|
||||||
|
+ target_node, name(), the_label_part_of_label);
|
||||||
|
|
||||||
|
- auto filter_server_name = [&] (Routed_service &s) -> bool {
|
||||||
|
- return s.child_name() != server_name; };
|
||||||
|
+ Session::Diag const
|
||||||
|
+ target_diag { target_node.attribute_value("diag", false) };
|
||||||
|
|
||||||
|
- try {
|
||||||
|
- return Route { find_service(_child_services, service_name, filter_server_name),
|
||||||
|
- target_label, target_diag };
|
||||||
|
+ auto no_filter = [] (Service &) -> bool { return false; };
|
||||||
|
|
||||||
|
- } catch (Service_denied) { }
|
||||||
|
- }
|
||||||
|
+ if (target_node.has_type("parent"))
|
||||||
|
+ return Route { find_service(_parent_services, service_name, no_filter),
|
||||||
|
+ target_label, target_diag };
|
||||||
|
|
||||||
|
- if (target.has_type("any-child")) {
|
||||||
|
+ if (target_node.has_type("local"))
|
||||||
|
+ return Route { find_service(_local_services, service_name, no_filter),
|
||||||
|
+ target_label, target_diag };
|
||||||
|
|
||||||
|
- if (is_ambiguous(_child_services, service_name)) {
|
||||||
|
- error(name(), ": ambiguous routes to "
|
||||||
|
- "service \"", service_name, "\"");
|
||||||
|
- throw Service_denied();
|
||||||
|
- }
|
||||||
|
- try {
|
||||||
|
- return Route { find_service(_child_services, service_name, no_filter),
|
||||||
|
- target_label, target_diag };
|
||||||
|
+ if (target_node.has_type("child")) {
|
||||||
|
|
||||||
|
- } catch (Service_denied) { }
|
||||||
|
- }
|
||||||
|
+ typedef Name_registry::Name Name;
|
||||||
|
+ Name server_name = target_node.attribute_value("name", Name());
|
||||||
|
+ server_name = _name_registry.deref_alias(server_name);
|
||||||
|
|
||||||
|
- if (!service_wildcard) {
|
||||||
|
- warning(name(), ": lookup for service \"", service_name, "\" failed");
|
||||||
|
- throw Service_denied();
|
||||||
|
- }
|
||||||
|
+ auto filter_server_name = [&] (Routed_service &s) -> bool {
|
||||||
|
+ return s.child_name() != server_name; };
|
||||||
|
|
||||||
|
- if (target.last())
|
||||||
|
- break;
|
||||||
|
+ return Route { find_service(_child_services, service_name, filter_server_name),
|
||||||
|
+ target_label, target_diag };
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (target_node.last()) break;
|
||||||
|
}
|
||||||
|
- } catch (Xml_node::Nonexistent_sub_node) { }
|
||||||
|
+ }
|
||||||
|
|
||||||
|
warning(name(), ": no route to service \"", service_name, "\" (label=\"", label, "\")");
|
||||||
|
throw Service_denied();
|
||||||
|
@@ -712,7 +673,6 @@ Sandbox::Child::Child(Env &env,
|
||||||
|
Id id,
|
||||||
|
Report_update_trigger &report_update_trigger,
|
||||||
|
Xml_node start_node,
|
||||||
|
- Default_route_accessor &default_route_accessor,
|
||||||
|
Routes_accessor &routes_accessor,
|
||||||
|
Default_caps_accessor &default_caps_accessor,
|
||||||
|
Name_registry &name_registry,
|
||||||
|
@@ -730,7 +690,6 @@ Sandbox::Child::Child(Env &env,
|
||||||
|
_report_update_trigger(report_update_trigger),
|
||||||
|
_list_element(this),
|
||||||
|
_start_node(_alloc, start_node),
|
||||||
|
- _default_route_accessor(default_route_accessor),
|
||||||
|
_routes_accessor(routes_accessor),
|
||||||
|
_default_caps_accessor(default_caps_accessor),
|
||||||
|
_ram_limit_accessor(ram_limit_accessor),
|
||||||
|
diff --git a/repos/os/src/lib/sandbox/child.h b/repos/os/src/lib/sandbox/child.h
|
||||||
|
index 81836a2045..f9d04cfdaf 100644
|
||||||
|
--- a/repos/os/src/lib/sandbox/child.h
|
||||||
|
+++ b/repos/os/src/lib/sandbox/child.h
|
||||||
|
@@ -49,7 +49,6 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
|
||||||
|
*/
|
||||||
|
struct Id { unsigned value; };
|
||||||
|
|
||||||
|
- struct Default_route_accessor : Interface { virtual Xml_node default_route() = 0; };
|
||||||
|
struct Default_caps_accessor : Interface { virtual Cap_quota default_caps() = 0; };
|
||||||
|
|
||||||
|
struct Routes_accessor : Interface
|
||||||
|
@@ -105,7 +104,6 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
|
||||||
|
*/
|
||||||
|
bool const _use_ld = _start_node->xml().attribute_value("ld", true);
|
||||||
|
|
||||||
|
- Default_route_accessor &_default_route_accessor;
|
||||||
|
Routes_accessor &_routes_accessor;
|
||||||
|
Default_caps_accessor &_default_caps_accessor;
|
||||||
|
Ram_limit_accessor &_ram_limit_accessor;
|
||||||
|
@@ -481,7 +479,6 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
|
||||||
|
Id id,
|
||||||
|
Report_update_trigger &report_update_trigger,
|
||||||
|
Xml_node start_node,
|
||||||
|
- Default_route_accessor &default_route_accessor,
|
||||||
|
Routes_accessor &route_accessor,
|
||||||
|
Default_caps_accessor &default_caps_accessor,
|
||||||
|
Name_registry &name_registry,
|
||||||
|
diff --git a/repos/os/src/lib/sandbox/library.cc b/repos/os/src/lib/sandbox/library.cc
|
||||||
|
index caa9840ea6..7b4e72c60e 100644
|
||||||
|
--- a/repos/os/src/lib/sandbox/library.cc
|
||||||
|
+++ b/repos/os/src/lib/sandbox/library.cc
|
||||||
|
@@ -22,7 +22,6 @@
|
||||||
|
#include <heartbeat.h>
|
||||||
|
|
||||||
|
struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
|
||||||
|
- ::Sandbox::Child::Default_route_accessor,
|
||||||
|
::Sandbox::Child::Routes_accessor,
|
||||||
|
::Sandbox::Child::Default_caps_accessor,
|
||||||
|
::Sandbox::Child::Ram_limit_accessor,
|
||||||
|
@@ -134,15 +133,6 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
|
||||||
|
_children.report_state(xml, detail);
|
||||||
|
}
|
||||||
|
|
||||||
|
- /**
|
||||||
|
- * Default_route_accessor interface
|
||||||
|
- */
|
||||||
|
- Xml_node default_route() override
|
||||||
|
- {
|
||||||
|
- return _default_route.constructed() ? _default_route->xml()
|
||||||
|
- : Xml_node("<empty/>");
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
/**
|
||||||
|
* Routes_accessor interface
|
||||||
|
*/
|
||||||
|
@@ -462,7 +452,7 @@ void Genode::Sandbox::Library::apply_config(Xml_node const &config)
|
||||||
|
Child &child = *new (_heap)
|
||||||
|
Child(_env, _heap, *_verbose,
|
||||||
|
Child::Id { ++_child_cnt }, _state_reporter,
|
||||||
|
- start_node, *this, *this, *this, _children,
|
||||||
|
+ start_node, *this, *this, _children,
|
||||||
|
Ram_quota { avail_ram.value - used_ram.value },
|
||||||
|
Cap_quota { avail_caps.value - used_caps.value },
|
||||||
|
*this, *this, prio_levels, affinity_space,
|
||||||
|
diff --git a/repos/os/src/lib/sandbox/utils.h b/repos/os/src/lib/sandbox/utils.h
|
||||||
|
index 36aab737f2..639a4be4dd 100644
|
||||||
|
--- a/repos/os/src/lib/sandbox/utils.h
|
||||||
|
+++ b/repos/os/src/lib/sandbox/utils.h
|
||||||
|
@@ -58,12 +58,9 @@ namespace Sandbox {
|
||||||
|
*/
|
||||||
|
inline bool service_node_matches(Xml_node const service_node,
|
||||||
|
Session_label const &label,
|
||||||
|
- Child_policy::Name const &child_name,
|
||||||
|
- Service::Name const &service_name,
|
||||||
|
- bool skip_child_prefix = true)
|
||||||
|
+ Service::Name const &service_name)
|
||||||
|
{
|
||||||
|
bool const service_matches =
|
||||||
|
- service_node.has_type("any-service") ||
|
||||||
|
(service_node.has_type("service") &&
|
||||||
|
service_node.attribute_value("name", Service::Name()) == service_name);
|
||||||
|
|
||||||
|
@@ -72,7 +69,6 @@ namespace Sandbox {
|
||||||
|
|
||||||
|
typedef String<Session_label::capacity()> Label;
|
||||||
|
|
||||||
|
- char const *unscoped_attr = "unscoped_label";
|
||||||
|
char const *label_last_attr = "label_last";
|
||||||
|
|
||||||
|
bool const route_depends_on_child_provided_label =
|
||||||
|
@@ -81,34 +77,13 @@ namespace Sandbox {
|
||||||
|
service_node.has_attribute("label_suffix") ||
|
||||||
|
service_node.has_attribute(label_last_attr);
|
||||||
|
|
||||||
|
- if (service_node.has_attribute(unscoped_attr)) {
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * If an 'unscoped_label' attribute is provided, don't consider any
|
||||||
|
- * scoped label attribute.
|
||||||
|
- */
|
||||||
|
- if (route_depends_on_child_provided_label)
|
||||||
|
- warning("service node contains both scoped and unscoped label attributes");
|
||||||
|
-
|
||||||
|
- return label == service_node.attribute_value(unscoped_attr, Label());
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
if (service_node.has_attribute(label_last_attr))
|
||||||
|
return service_node.attribute_value(label_last_attr, Label()) == label.last_element();
|
||||||
|
|
||||||
|
if (!route_depends_on_child_provided_label)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
- char const * const scoped_label = skip_child_prefix
|
||||||
|
- ? skip_label_prefix(child_name.string(), label.string())
|
||||||
|
- : label.string();
|
||||||
|
-
|
||||||
|
- if (!scoped_label)
|
||||||
|
- return false;
|
||||||
|
-
|
||||||
|
- Session_label const session_label(scoped_label);
|
||||||
|
-
|
||||||
|
- return !Xml_node_label_score(service_node, session_label).conflict();
|
||||||
|
+ return !Xml_node_label_score(service_node, label).conflict();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -131,6 +106,34 @@ namespace Sandbox {
|
||||||
|
return cnt > 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Determine session label to be provided to the server
|
||||||
|
+ *
|
||||||
|
+ * By default, the client's identity (accompanied with the a
|
||||||
|
+ * client-provided label) is presented as session label to the
|
||||||
|
+ * server. However, the target node can explicitly override the
|
||||||
|
+ * client's identity by a custom label via the 'label' attribute or
|
||||||
|
+ * by specifying a 'prefix' and 'suffix attributes.
|
||||||
|
+ */
|
||||||
|
+ typedef String<Session_label::capacity()> Label;
|
||||||
|
+ inline Label target_label(Xml_node const node,
|
||||||
|
+ Child_policy::Name const &child_name,
|
||||||
|
+ Session_label const &label)
|
||||||
|
+ {
|
||||||
|
+ if (node.has_attribute("label"))
|
||||||
|
+ return Session_label(node.attribute_value("label", Label()).string());
|
||||||
|
+
|
||||||
|
+ Label head = node.attribute_value("prefix", Label(child_name.string()));
|
||||||
|
+ Label tail = node.attribute_value("suffix", Label(child_name == label ? "" : label));
|
||||||
|
+
|
||||||
|
+ if (head == "") return tail;
|
||||||
|
+ if (tail == "") return head;
|
||||||
|
+
|
||||||
|
+ return Label(prefixed_label(head, tail).string());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* Find service with certain values in given registry
|
||||||
|
*
|
||||||
|
--
|
||||||
|
2.28.0
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
in {
|
in {
|
||||||
genode.init.children.hello = {
|
genode.init.children.hello = {
|
||||||
configFile = ./hello.dhall;
|
configFile = ./hello.dhall;
|
||||||
inputs = [ hello ];
|
inputs = [ hello pkgs.genodePackages.vfs.lib ];
|
||||||
|
# TODO: libc.lib.so has only relative linking to vfs.lib.so
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
testScript = ''
|
testScript = ''
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
name = "lighttpd";
|
||||||
|
machine = { pkgs, ... }: {
|
||||||
|
imports = [ ../nixos-modules/systemd.nix ];
|
||||||
|
services.lighttpd = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
systemd.services.lighttpd.genode.enable = true;
|
||||||
|
};
|
||||||
|
}
|
|
@ -33,13 +33,13 @@ let init =
|
||||||
, service = "Nic"
|
, service = "Nic"
|
||||||
, attributes = toMap { ip_addr = "10.0.0.2" }
|
, attributes = toMap { ip_addr = "10.0.0.2" }
|
||||||
, label =
|
, label =
|
||||||
Init.LabelSelector.Type.Scoped "solo5 -> service0"
|
Init.LabelSelector.Type.Full "solo5 -> service0"
|
||||||
}
|
}
|
||||||
, Init.Config.Policy::{
|
, Init.Config.Policy::{
|
||||||
, service = "Nic"
|
, service = "Nic"
|
||||||
, attributes = toMap { ip_addr = "10.1.0.2" }
|
, attributes = toMap { ip_addr = "10.1.0.2" }
|
||||||
, label =
|
, label =
|
||||||
Init.LabelSelector.Type.Scoped "solo5 -> service1"
|
Init.LabelSelector.Type.Full "solo5 -> service1"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue