Dear Genode developers,
Following Martijn's mail at the end of last year, which stated:
>> As a way to support detachment / reattachment of USB storage I’m
>> thinking about placing the rump_fs and part_blk components in a child
>> subtree of the CLI component that is spawned on demand and cleaned-up
>> after use. But this seems a bit like overkill.
> That's exactly the right solution. I don't think that it's overkill
> either. Spawning up rump_fs and part_blk dynamically is certainly quick
> enough. Memory-wise, it does not take more resources that a static
> scenario either. By letting your CLI component implement the protocol
> outlined above, you have full control over chain of events. Also the
> aborting rump_fs is nothing fatal anymore but can be gracefully handled
> by the CLI component. As another benefit, the solution does not need us
> to supplement the notion of hot-plugging to the file-system and block
> session interfaces, which would otherwise inflate the complexity of
> these interfaces (and thereby all the clients that rely on them).
Martijn and I have been thinking of a way to implement this, and came to
the conclusion that instead of spawning the stack as children of the CLI
component, it might be better to use a new management component
in-between. As Josef said earlier:
> A custom runtime/management component could monitor the
> usb_drv device report and spawn the whole stack if it detects a USB
> storage device. The usb_drv's device report does not contain the device
> class so far though but adding that to the report is easy.
This is exactly what we're trying to do now. We want to create a custom
component called "media" that monitors usb devices by reading the
report. It provides a service to other components through which they can
request a filesystem session in order to read-write from/to the usb-stick. For
this, it spawns the part_blk and rump_fs components as children if the
usb is plugged in, and kills them once the usb is plugged out. It
roughly looks like this:
rump_fs part_blk
| |
CLI media USB_drv
| | |
init
But this raises a few questions. First, the filesystem interface needs
to be presented to the client somehow. To avoid adding another layer of
indirection into media, essentially duplicating rump_fs's entire API, we
would like the client (in this case CLI) to be directly connected to
rump_fs. The client can then ask media if the USB is connected before
calling a function from rump_fs.
However, this means that rump_fs provides a service, announces it to its
parent (media), and media has to decide what to do with that announce.
It can implement rump_fs as a slave, but that way the entire API needs
to be copied into media so media can present it as its own service to the client.
So we would like media to announce the filesystem service to its parent
(in this case init), so any client can use this service. In the same
way, any session request will be passed from CLI to its parent (init),
init has to pass it to media, and media passes it to rump_fs. However,
the current implementation and specification of genode does not allow
services of any server to exist in any level above the server's parent.
Services can only be provided to direct parents, and to other components
in the parent's subtree. Therefore, copying the API from the child to
the parent seems unavoidable.
Another problem that pops up is that media has to spawn all these
subcomponents as children. In order to route block session requests from
rump-fs to part-blk, media needs to implement some routing policy and
effectively serves the same role for these two components as init serves
for the system. So we could:
1. Copy all necessary code for routing from init to media (which is
almost all code if we want to be generic).
2. Let media spawn another init child component (let's call it sub-init
for now) which in turn spawns rump-fs and part-blk and does the routing.
To us, the second option seems much more clean as it involves no
code-copying. However, services announced by rump-fs can not be used by
other components that are not children of the new init, and are kind of
useless. Their announcements can not be passed on to the parents,
leaving us with the same problem as we had with rump_fs but with the
additional problem that even if there would be a custom way to forward
service announces and requests to the parent/child respectively,
sub-init has no such policy, and this functionality has to be included
in sub-init's code as well, adding a lot of complexity.
Eventually both cases bottle down to the same problem: service
announcements to a parent cannot automatically be forwarded to that
parent's parent, and likewise, service requests need to be able to be
delegated to children of children without a lot of hassle. The only option if I'm correct is implementing this functionality manually, but this does not work if the parent is an existing component that does not support it.
Is there a reason this is never done? For init it is clear that it would
never pass an announce to its parent (usually core) or receive session
requests from it. But how about the general case?
And how should we solve cases such as the above scenario?
kind regards,
Boris Mulder
Cyber Security Labs B.V. | Gooimeer 6-31 | 1411 DD Naarden | The Netherlands
+31 35 631 3253 (office)