💾 Archived View for spam.works › users › emery › sigil-policy-routing.gmi captured on 2023-07-22 at 21:39:18. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-06-14)
-=-=-=-=-=-=-
In an effort to transisition from writing Genode configuration by hand to mechanical generation I have made some modifications to the Genode Init component. This article will describe these changes to Init and revisions made to the Dhall Init library.
If you aren't already familiar with how Init route services, this probably wont be of interest.
In mainline Genode the routing policy of Init is declared at two locations, as top-level <default-route> declarations and within the individual child configurations.
<config> <parent-provides> <service name="..."/> ... </parent-provides> <default-route> <any-service> <parent/> <any-child/> </any-service> </default-route> <start name="foo"> <route> <service name="ROM" label="info"> <child name="bar"/> </service> <any-service> <parent/> </any-service> </route> </start> <start name="bar"> <route> <service name="ROM" label="info"> <child name="foo"/> </service> <any-service> <parent/> </any-service> </route> </start> </config>
In this example we can see that there are two children that have ROM services routed to each other. Both children have <route> declarations. A declaration local to a child means that <default-route> will not be consulted, so in this example <default-route> is dead code. At both children the <any-service> element is used to route any service not explicitly configured to the parent, which is why the <parent-provides> section is necessary. Without <parent-provides> a child could discover what services a parent provides by probing with dishonest sessions requests.
I have modified init (with some backwards compatiblity) to take policy from a top-level <routes> section. The previous configuration would be translated as follows:
<config> <parent-provides> <service name="..."/> ... </parent-provides> <routes> <service name="ROM" label="bar -> info"> <child name="foo"/> </service> <service name="ROM" label="foo -> info"> <child name="bar"/> </service> <service name="CPU"> <parent/> </service> <service name="LOG"> <parent/> </service> <service name="PD"> <parent/> </service> <service name="RM"> <parent/> </service> <service name="ROM"> <parent/> </service> </routes> <start name="bar"> ... </start> <start name="foo"> ... </start> </config>
In this version all routes are explicitly expressed within the top-level <routes> and child-specific policies are selected by the label prefix applied by Init prior to request routing.
As there are no <any-service> nodes in this version, all services that will be routed to the parent are made explicit within routes, and the <parent-provides> is thus redundant and should be removed.
The Dhall configurating library for Genode has generated routing policy in this format for some time, the previous example could have been derived from this:
let Genode = https://git.sr.ht/~ehmry/dhall-genode/blob/1a6b3609a778f1644bc2831c366c65cce854ae42/package.dhall sha256:e90438be23b5100003cf018b783986df67bc6d0e3d35e800677d0d9109ff6aa9 let Init = Genode.Init let Child = Init.Child let example = Init::{ , children = toMap { foo = Child.flat Child.Attributes::{ , binary = "..." , routes = [ Init.ServiceRoute.childLabel "ROM" "bar" (Some "info") (None Text) ] } , bar = Child.flat Child.Attributes::{ , binary = "..." , routes = [ Init.ServiceRoute.childLabel "ROM" "foo" (Some "info") (None Text) ] } } } in Init.render example
Consider now a scenario where a service must have policies specific to a child. The server must be configured with these policies and Init must be configured with the routes from children to this services.
The Dhall library now handles this by formalizing policy declarations and generating routing information from this. The second XML example could also have been generated like this:
let Genode = https://git.sr.ht/~ehmry/dhall-genode/blob/1a6b3609a778f1644bc2831c366c65cce854ae42/package.dhall sha256:e90438be23b5100003cf018b783986df67bc6d0e3d35e800677d0d9109ff6aa9 let Init = Genode.Init let Child = Init.Child let example = Init::{ , children = toMap { foo = Child.flat Child.Attributes::{ , binary = "..." , config = Init.Config::{ , policies = [ Init.Config.Policy::{ , service = "ROM" , label = Init.LabelSelector.label "bar -> info" } ] } } , bar = Child.flat Child.Attributes::{ , binary = "..." , config = Init.Config::{ , policies = [ Init.Config.Policy::{ , service = "ROM" , label = Init.LabelSelector.label "foo -> info" } ] } } } } in Init.render example
By normalizing the declaration of server-side policy and client-side routing into the server-side, configuration failures are reduced. Many services do not feature session policies and do not suffer problems from mismatched labels, but placing policies within the service configurations aids in documentation.
An example of a service that requires session policy declarations would look like this:
let Genode = https://git.sr.ht/~ehmry/dhall-genode/blob/1a6b3609a778f1644bc2831c366c65cce854ae42/package.dhall sha256:e90438be23b5100003cf018b783986df67bc6d0e3d35e800677d0d9109ff6aa9 let Config = Genode.Init.Config let example = Config::{ , policies = [ Config.Policy::{ , service = "File_system" , label = Genode.Init.LabelSelector.prefix "media-player" , attributes = toMap { root = "/music", writeable = "no" } } ] } in Config.render example
Which would produce:
<config> <policy label_prefix="media-player" root="/music" writeable="no"/> </config>