Dear Genodians,
I want to determine the total resources consumed within a deeply nested subsystem. The only apparent way to do this is to iterate through all the init state reports of the children and their ancestors down to the leaf and accumulate the respective `ram_used` and `caps_used` attributes of the `child` nodes. Is this the way?
Intuitively, the parent at the tree's root should be aware of this information. However, after digging through the documentation and the code, I found that this `total_ram_used`/`total_caps_used` information is not available out of the box within an init component/sandbox library. I assume the reason for this is that there is no (easy) way to communicate this information all the way back to the parent.
On the other hand, implementing a monitor component that goes through all these recursive init state reports, not knowing how deep the tree is, and assuming that all the sub-inits correctly report their state seems quite error-prone.
Is my assumption correct that the only way to determine a subsystem's resource consumption is to aggregate the init state reports down to the leaf?
Cheers, Sid
Hi Sid,
On 2025-05-27 08:24, Sid Hussmann via users wrote:
I want to determine the total resources consumed within a deeply nested subsystem. The only apparent way to do this is to iterate through all the init state reports of the children and their ancestors down to the leaf and accumulate the respective `ram_used` and `caps_used` attributes of the `child` nodes. Is this the way? > Intuitively, the parent at the tree's root should be aware of this information. However, after digging through the documentation and the code, I found that this `total_ram_used`/`total_caps_used` information is not available out of the box within an init component/sandbox library. I assume the reason for this is that there is no (easy) way to communicate this information all the way back to the parent.
your intuition is right. The top-level init instance has in principle all the strings in hand because it has created the PD sessions of all children, grandchildren, etc. in the first place. E.g., when enabling the reporting of the requested sessions via
<report requested="yes"/>
you can in fact observe all the PD sessions with their corresponding labels. You can try this live at home on Sculpt OS by editing /config/managed/runtime in the inspect view and then looking at the resulting /report/runtime/state.
The labels reveal the component topology. What's missing from the report is the live status of the 'ram' and 'caps' for the PD sessions. The reported amounts show merely the session quotas (the quota donated at session-creation time and via Parent::upgrade). But quota transferred from one PD to another via 'Pd_account::transfer_quota' is not covered because init is not involved in such transfers.
However, since init has all the PD capabilities at hand, it could in principle ask each PD for its live 'ram_quota' and 'used_ram' via the corresponding RPCs. E.g., as a quick hack you could add such details to the reporting at sandbox/child.cc [1] by inspecting the session.service().name() for "PD" and then, once you know that the session is a PD session, cast the corresponding 'Session_state::cap' to a 'Capability<Pd_session>' (via 'static_cap_cast') and issue the RPC call of interest.
Note, however, that those RPCs are not for free. Depending on the complexity of the scenario and the rate of reporting, the querying may induce unwelcome overhead.
[1] https://github.com/genodelabs/genode/blob/master/repos/os/src/lib/sandbox/ch...
An alternative way would be the wrapping of core's PD service as done by the monitor component (look out for 'Inferior_pd'). The monitor thereby sits in-between each monitored component and core's PD service. Hence, it can observe all interactions including 'transfer_quota' between PDs.
Is my assumption correct that the only way to determine a subsystem's resource consumption is to aggregate the init state reports down to the leaf?
The two approaches sketched above are preferable because one gets all the information at a central point instead of relying on the good will and the enabled reporting of all the nested init instances.
In your position, I would try implementing the feature using the sandbox API, taking inspiration from the monitor component. But your component will be _much_ simpler. Like the monitor, you can then use your component as a drop-in replacement of init.
Cheers Norman