mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-24 15:56:41 +00:00
06943f413d
This patch improves init's dynamic reconfigurability with respect to adjustments of the RAM quota assigned to the children. If the RAM quota is decreased, init withdraws as much quota from the child's RAM session as possible. If the child's RAM session does not have enough available quota, a resource-yield request is issued to the child. Cooparative children may respond to such a request by releasing memory. If the RAM quota is increased, the child's RAM session is upgraded. If the configuration exceeds init's available RAM, init re-attempts the upgrade whenever new slack memory becomes available (e.g., by disappearing other children).
743 lines
23 KiB
Plaintext
743 lines
23 KiB
Plaintext
#
|
|
# Build
|
|
#
|
|
|
|
set build_components { core init drivers/timer app/dummy test/init }
|
|
|
|
build $build_components
|
|
|
|
create_boot_directory
|
|
|
|
#
|
|
# Generate config
|
|
#
|
|
|
|
append config {
|
|
<config>
|
|
<parent-provides>
|
|
<service name="ROM"/>
|
|
<service name="RAM"/>
|
|
<service name="CPU"/>
|
|
<service name="PD"/>
|
|
<service name="LOG"/>
|
|
<service name="IRQ"/>
|
|
<service name="IO_MEM"/>
|
|
<service name="IO_PORT"/>
|
|
</parent-provides>
|
|
|
|
<default-route>
|
|
<any-service> <parent/> <any-child/> </any-service>
|
|
</default-route>
|
|
|
|
<start name="timer">
|
|
<resource name="RAM" quantum="1M"/>
|
|
<provides><service name="Timer"/></provides>
|
|
</start>
|
|
|
|
<start name="report_rom">
|
|
<resource name="RAM" quantum="2M"/>
|
|
<provides> <service name="ROM"/> <service name="Report"/> </provides>
|
|
<config verbose="no">
|
|
<policy label="init -> init.config" report="test-init -> init.config"/>
|
|
<policy label="test-init -> state" report="init -> state"/>
|
|
</config>
|
|
</start>
|
|
|
|
<start name="test-init">
|
|
<resource name="RAM" quantum="4M"/>
|
|
<provides> <service name="LOG"/> </provides>
|
|
<config>
|
|
|
|
<!-- let init settle, processing the initially invalid config -->
|
|
<sleep ms="150"/>
|
|
|
|
|
|
<message string="test state reporting"/>
|
|
|
|
<init_config version="initial">
|
|
<report init_ram="yes" ids="yes" child_ram="yes" requested="yes"/>
|
|
<parent-provides>
|
|
<service name="ROM"/>
|
|
<service name="RAM"/>
|
|
<service name="CPU"/>
|
|
<service name="PD"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<start name="application">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="1G"/>
|
|
<config>
|
|
<log string="started"/>
|
|
</config>
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
</init_config>
|
|
<expect_log string="[init -> application] started"/>
|
|
<sleep ms="200"/>
|
|
<expect_init_state>
|
|
<attribute name="version" value="initial"/>
|
|
<node name="child">
|
|
<attribute name="name" value="application"/>
|
|
<attribute name="binary" value="dummy"/>
|
|
<node name="requested">
|
|
<node name="session">
|
|
<attribute name="service" value="PD"/>
|
|
<attribute name="label" value="application"/>
|
|
<attribute name="state" value="CAP_HANDED_OUT"/>
|
|
</node>
|
|
</node>
|
|
</node>
|
|
</expect_init_state>
|
|
|
|
|
|
<message string="routing to custom log service"/>
|
|
|
|
<init_config version="chained log services">
|
|
<report ids="yes" requested="yes" provided="yes"/>
|
|
<parent-provides>
|
|
<service name="ROM"/>
|
|
<service name="RAM"/>
|
|
<service name="CPU"/>
|
|
<service name="PD"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<start name="server">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="1M"/>
|
|
<provides> <service name="LOG"/> </provides>
|
|
<config> <log_service/> </config>
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
<start name="indirect_server">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="1M"/>
|
|
<provides> <service name="LOG"/> </provides>
|
|
<config> <log_service/> </config>
|
|
<route>
|
|
<service name="LOG"> <child name="server"/> </service>
|
|
<any-service> <parent/> </any-service>
|
|
</route>
|
|
</start>
|
|
<start name="client">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="1M"/>
|
|
<config> <log string="client started"/> </config>
|
|
<route>
|
|
<service name="LOG"> <child name="indirect_server"/> </service>
|
|
<any-service> <parent/> </any-service>
|
|
</route>
|
|
</start>
|
|
</init_config>
|
|
<expect_log string="[init -> server] [indirect_server] [client] client started"/>
|
|
<sleep ms="200"/>
|
|
<expect_init_state>
|
|
<node name="child">
|
|
<attribute name="name" value="server"/>
|
|
<attribute name="id" value="2"/>
|
|
</node>
|
|
<node name="child">
|
|
<attribute name="name" value="client"/>
|
|
<attribute name="id" value="4"/>
|
|
</node>
|
|
</expect_init_state>
|
|
<sleep ms="150"/>
|
|
|
|
|
|
<message string="changing route of indirect server"/>
|
|
|
|
<!-- Because the route to the LOG session of the 'indirect_server'
|
|
is re-directed to the parent, the 'indirect_server' must be
|
|
restarted. As the 'client' depends on the 'indirect_server'
|
|
for its LOG session, the client must implicitly be restarted
|
|
as well. -->
|
|
|
|
<init_config version="restarted indirect server">
|
|
<report ids="yes" requested="yes" provided="yes"/>
|
|
<parent-provides>
|
|
<service name="ROM"/>
|
|
<service name="RAM"/>
|
|
<service name="CPU"/>
|
|
<service name="PD"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<start name="server">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="1M"/>
|
|
<provides> <service name="LOG"/> </provides>
|
|
<config> <log_service/> </config>
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
<start name="indirect_server">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="1M"/>
|
|
<provides> <service name="LOG"/> </provides>
|
|
<config> <log_service/> </config>
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
<start name="client">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="1M"/>
|
|
<config> <log string="client started"/> </config>
|
|
<route>
|
|
<service name="LOG"> <child name="indirect_server"/> </service>
|
|
<any-service> <parent/> </any-service>
|
|
</route>
|
|
</start>
|
|
</init_config>
|
|
<!-- the output of the new 'client' does no longer go via 'server' -->
|
|
<expect_log string="[init -> indirect_server] [client] client started"/>
|
|
<sleep ms="150"/>
|
|
<expect_init_state>
|
|
<node name="child">
|
|
<attribute name="name" value="server"/>
|
|
<attribute name="id" value="2"/>
|
|
</node>
|
|
<node name="child">
|
|
<attribute name="name" value="client"/>
|
|
<attribute name="id" value="6"/> <!-- client was restarted -->
|
|
</node>
|
|
</expect_init_state>
|
|
<sleep ms="100"/>
|
|
|
|
|
|
<message string="test changing provided services"/>
|
|
|
|
<!-- Initially, the log service lacks the <provides> declaration.
|
|
Therefore the attempt to route the LOG session of the client
|
|
to the 'log' fails. The environment of 'dummy' will remain
|
|
incomplete. -->
|
|
|
|
<init_config>
|
|
<report requested="yes"/>
|
|
<parent-provides>
|
|
<service name="ROM"/> <service name="RAM"/>
|
|
<service name="CPU"/> <service name="PD"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<start name="log">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="1M"/>
|
|
<config/>
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
<start name="dummy">
|
|
<resource name="RAM" quantum="1M"/>
|
|
<config> <log string="started"/> </config>
|
|
<route>
|
|
<service name="LOG"> <child name="log"/> </service>
|
|
<any-service> <parent/> </any-service>
|
|
</route>
|
|
</start>
|
|
</init_config>
|
|
<sleep ms="200"/>
|
|
<expect_init_state>
|
|
<node name="child"> <attribute name="name" value="log"/> </node>
|
|
<node name="child">
|
|
<attribute name="name" value="dummy"/>
|
|
<attribute name="state" value="incomplete"/>
|
|
</node>
|
|
</expect_init_state>
|
|
|
|
<!-- We add the <provides> node to the log server and thereby
|
|
make the LOG route of the 'dummy' client available. The
|
|
server is expected to remain unaffected but the client should
|
|
be restarted to re-route its LOG session to the server -->
|
|
|
|
<init_config>
|
|
<parent-provides>
|
|
<service name="ROM"/> <service name="RAM"/>
|
|
<service name="CPU"/> <service name="PD"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<start name="log">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="1M"/>
|
|
<provides> <service name="LOG"/> </provides>
|
|
<config version="providing service"> <log_service/> </config>
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
<start name="dummy">
|
|
<resource name="RAM" quantum="1M"/>
|
|
<config> <log string="started"/> </config>
|
|
<route>
|
|
<service name="LOG"> <child name="log"/> </service>
|
|
<any-service> <parent/> </any-service>
|
|
</route>
|
|
</start>
|
|
</init_config>
|
|
<expect_log string="[init -> log] config 2: providing service"/>
|
|
<expect_log string="[init -> log] [dummy] started"/>
|
|
|
|
<!-- We remove <provides> node from 'log' service and thereby
|
|
make the LOG service unavailble for 'dummy'. Consequently,
|
|
'dummy' will be restarted but will ultimately remain
|
|
incomplete (as the LOG environment session cannot be routed).
|
|
The server stays alive and reports its third config. -->
|
|
|
|
<init_config>
|
|
<report requested="yes"/>
|
|
<parent-provides>
|
|
<service name="ROM"/> <service name="RAM"/>
|
|
<service name="CPU"/> <service name="PD"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<start name="log">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="1M"/>
|
|
<config version="became unavailable"/>
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
<start name="dummy">
|
|
<resource name="RAM" quantum="1M"/>
|
|
<config> <log string="started"/> </config>
|
|
<route>
|
|
<service name="LOG"> <child name="log"/> </service>
|
|
<any-service> <parent/> </any-service>
|
|
</route>
|
|
</start>
|
|
</init_config>
|
|
<sleep ms="150"/>
|
|
<expect_init_state>
|
|
<node name="child">
|
|
<attribute name="name" value="dummy"/>
|
|
<attribute name="state" value="incomplete"/>
|
|
</node>
|
|
</expect_init_state>
|
|
|
|
|
|
<message string="update child config"/>
|
|
|
|
<init_config>
|
|
<parent-provides>
|
|
<service name="ROM"/> <service name="RAM"/>
|
|
<service name="CPU"/> <service name="PD"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<start name="application">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="1M"/>
|
|
<config version="Version A"/>
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
</init_config>
|
|
<expect_log string="[init -> application] config 1: Version A"/>
|
|
<init_config>
|
|
<parent-provides>
|
|
<service name="ROM"/> <service name="RAM"/>
|
|
<service name="CPU"/> <service name="PD"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<start name="application">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="1M"/>
|
|
<config version="Version B"/>
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
</init_config>
|
|
<expect_log string="[init -> application] config 2: Version B"/>
|
|
|
|
<!-- Add 'version' attribute to start node, which should trigger
|
|
the restart of the child, printing a version count of 1.
|
|
We also validate that the version is reflected in the state
|
|
report. -->
|
|
|
|
<init_config>
|
|
<report/>
|
|
<parent-provides>
|
|
<service name="ROM"/> <service name="RAM"/>
|
|
<service name="CPU"/> <service name="PD"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<start name="application" version="X">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="1M"/>
|
|
<config version="Version B"/>
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
</init_config>
|
|
<expect_log string="[init -> application] config 1: Version B"/>
|
|
<sleep ms="150"/>
|
|
<expect_init_state>
|
|
<node name="child"> <attribute name="version" value="X"/> </node>
|
|
</expect_init_state>
|
|
<sleep ms="100"/>
|
|
|
|
|
|
<message string="test label rewritiong and binary-name update"/>
|
|
|
|
<init_config>
|
|
<parent-provides>
|
|
<service name="ROM"/> <service name="RAM"/>
|
|
<service name="CPU"/> <service name="PD"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<start name="test">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="1M"/>
|
|
<config version="binary-name test"/>
|
|
<route>
|
|
<any-service> <parent/> </any-service>
|
|
</route>
|
|
</start>
|
|
</init_config>
|
|
<expect_log string="[init -> test] config 1: binary-name test"/>
|
|
|
|
<!-- We change the binary name, but also use the label-rewriting
|
|
feature of init to produce the same route as the original
|
|
binary. Consequently, init does not need to restart the
|
|
child. Instead the original child merely prints a new
|
|
config version (count 2). -->
|
|
|
|
<init_config>
|
|
<report/>
|
|
<parent-provides>
|
|
<service name="ROM"/> <service name="RAM"/>
|
|
<service name="CPU"/> <service name="PD"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<start name="test">
|
|
<binary name="renamed_dummy"/>
|
|
<resource name="RAM" quantum="1M"/>
|
|
<config version="binary re-routed to same route"/>
|
|
<route>
|
|
<service name="ROM" unscoped_label="renamed_dummy">
|
|
<parent label="dummy"/> </service>
|
|
<any-service> <parent/> </any-service>
|
|
</route>
|
|
</start>
|
|
</init_config>
|
|
<expect_log string="[init -> test] config 2: binary re-routed to same route"/>
|
|
|
|
<!-- We change the binary name in a way that results in a
|
|
different route for the binary ROM request, which requires
|
|
restart of the child. The config version printed by the
|
|
new child will have a count of 1. -->
|
|
|
|
<init_config>
|
|
<parent-provides>
|
|
<service name="ROM"/> <service name="RAM"/>
|
|
<service name="CPU"/> <service name="PD"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<start name="test">
|
|
<binary name="another_dummy"/>
|
|
<resource name="RAM" quantum="1M"/>
|
|
<config version="binary re-routed to other route"/>
|
|
<route>
|
|
<service name="ROM" unscoped_label="renamed_dummy">
|
|
<parent label="dummy"/> </service>
|
|
<any-service> <parent/> </any-service>
|
|
</route>
|
|
</start>
|
|
</init_config>
|
|
<expect_log string="[init -> test] config 1: binary re-routed to other route"/>
|
|
|
|
|
|
<message string="test RAM preservation"/>
|
|
|
|
<init_config>
|
|
<report init_ram="yes"/>
|
|
<resource name="RAM" preserve="2M"/>
|
|
<parent-provides>
|
|
<service name="ROM"/> <service name="RAM"/>
|
|
<service name="CPU"/> <service name="PD"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<start name="regular">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="1M"/>
|
|
<config> <log string="regular component started"/> </config>
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
<start name="greedy">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="1G"/>
|
|
<config> <log string="greedy component started"/> </config>
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
</init_config>
|
|
<sleep ms="350"/>
|
|
<!-- wait until both children are started -->
|
|
<expect_init_state>
|
|
<node name="child"> <attribute name="name" value="regular"/> </node>
|
|
<node name="child"> <attribute name="name" value="greedy"/> </node>
|
|
</expect_init_state>
|
|
<expect_init_state>
|
|
<node name="ram"> <attribute name="avail" higher="2M"/> </node>
|
|
</expect_init_state>
|
|
<sleep ms="100"/>
|
|
|
|
|
|
<message string="test RAM-quota adjustments"/>
|
|
|
|
<init_config>
|
|
<report child_ram="yes"/>
|
|
<parent-provides>
|
|
<service name="ROM"/> <service name="RAM"/>
|
|
<service name="CPU"/> <service name="PD"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<start name="test">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="1M"/>
|
|
<config version="initial" />
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
</init_config>
|
|
<expect_log string="[init -> test] config 1: initial"/>
|
|
<sleep ms="150"/>
|
|
<expect_init_state>
|
|
<node name="child"> <attribute name="name" value="test"/>
|
|
<node name="ram">
|
|
<attribute name="assigned" value="1M"/>
|
|
<attribute name="quota" lower="1M"/>
|
|
</node>
|
|
</node>
|
|
</expect_init_state>
|
|
|
|
<!-- increase RAM quota of child by 3 MiB -->
|
|
<init_config>
|
|
<report init_ram="yes" child_ram="yes"/>
|
|
<parent-provides>
|
|
<service name="ROM"/> <service name="RAM"/>
|
|
<service name="CPU"/> <service name="PD"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<start name="test">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="4M"/>
|
|
<config version="upgraded" />
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
</init_config>
|
|
<expect_log string="[init -> test] config 2: upgraded"/>
|
|
<sleep ms="150"/>
|
|
<expect_init_state>
|
|
<node name="child"> <attribute name="name" value="test"/>
|
|
<node name="ram">
|
|
<attribute name="assigned" value="4M"/>
|
|
<attribute name="quota" higher="3M"/>
|
|
</node>
|
|
</node>
|
|
</expect_init_state>
|
|
|
|
<!-- start second child consuming all slack memory -->
|
|
<init_config>
|
|
<report init_ram="yes" child_ram="yes"/>
|
|
<parent-provides>
|
|
<service name="ROM"/> <service name="RAM"/>
|
|
<service name="CPU"/> <service name="PD"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<start name="test">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="4M"/>
|
|
<config/>
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
<start name="greedy">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="1G"/>
|
|
<config version="started"/>
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
</init_config>
|
|
<expect_log string="[init -> greedy] config 1: started"/>
|
|
<sleep ms="150"/>
|
|
<expect_init_state>
|
|
<node name="ram"> <attribute name="avail" lower="1M"/> </node>
|
|
</expect_init_state>
|
|
|
|
<!-- attempt to upgrade the 'test' child to 8 MiB, hitting the RAM limit -->
|
|
<init_config>
|
|
<report init_ram="yes" child_ram="yes"/>
|
|
<parent-provides>
|
|
<service name="ROM"/> <service name="RAM"/>
|
|
<service name="CPU"/> <service name="PD"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<start name="test">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="8M"/>
|
|
<config version="upgrade impossible"/>
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
<start name="greedy">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="1G"/>
|
|
<config version="started"/>
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
</init_config>
|
|
<expect_log string="[init -> test] config 4: upgrade impossible"/>
|
|
<sleep ms="150"/>
|
|
<expect_init_state>
|
|
<node name="child"> <attribute name="name" value="test"/>
|
|
<node name="ram">
|
|
<attribute name="assigned" lower="8M"/>
|
|
</node>
|
|
</node>
|
|
</expect_init_state>
|
|
|
|
<!-- kill greedy child, now the upgrade of 'test' can be completed -->
|
|
<init_config>
|
|
<report init_ram="yes" child_ram="yes"/>
|
|
<parent-provides>
|
|
<service name="ROM"/> <service name="RAM"/>
|
|
<service name="CPU"/> <service name="PD"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<start name="test">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="8M"/>
|
|
<config version="upgraded to 8 MiB"/>
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
</init_config>
|
|
<expect_log string="[init -> test] config 5: upgraded to 8 MiB"/>
|
|
<sleep ms="150"/>
|
|
<expect_init_state>
|
|
<node name="child"> <attribute name="name" value="test"/>
|
|
<node name="ram">
|
|
<attribute name="assigned" value="8M"/>
|
|
<attribute name="quota" higher="7M"/>
|
|
</node>
|
|
</node>
|
|
</expect_init_state>
|
|
|
|
<!-- reduce quota -->
|
|
<init_config>
|
|
<report init_ram="yes" child_ram="yes"/>
|
|
<parent-provides>
|
|
<service name="ROM"/> <service name="RAM"/>
|
|
<service name="CPU"/> <service name="PD"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<start name="test">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="4M"/>
|
|
<config version="downgraded to 4 MiB"/>
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
</init_config>
|
|
<expect_log string="[init -> test] config 6: downgraded to 4 MiB"/>
|
|
<sleep ms="150"/>
|
|
<expect_init_state>
|
|
<node name="child"> <attribute name="name" value="test"/>
|
|
<node name="ram">
|
|
<attribute name="assigned" value="4M"/>
|
|
<attribute name="quota" lower="4M"/>
|
|
</node>
|
|
</node>
|
|
</expect_init_state>
|
|
|
|
<!-- let child consume quota -->
|
|
<init_config>
|
|
<report init_ram="yes" child_ram="yes" delay_ms="250"/>
|
|
<parent-provides>
|
|
<service name="ROM"/> <service name="RAM"/>
|
|
<service name="CPU"/> <service name="PD"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<start name="test">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="4M"/>
|
|
<config version="consume 2 MiB">
|
|
<handle_yield_requests/>
|
|
<consume_ram amount="2M"/>
|
|
</config>
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
</init_config>
|
|
<expect_log string="[init -> test] config 7: consume 2 MiB"/>
|
|
<expect_log string="[init -> test] consume 2M bytes of memory"/>
|
|
<sleep ms="500"/>
|
|
<expect_init_state>
|
|
<node name="child"> <attribute name="name" value="test"/>
|
|
<node name="ram">
|
|
<attribute name="avail" lower="2M"/>
|
|
</node>
|
|
</node>
|
|
</expect_init_state>
|
|
|
|
<!-- reduce child quota by 2M, triggering a resource-yield request -->
|
|
<init_config>
|
|
<report init_ram="yes" child_ram="yes" delay_ms="250"/>
|
|
<parent-provides>
|
|
<service name="ROM"/> <service name="RAM"/>
|
|
<service name="CPU"/> <service name="PD"/>
|
|
<service name="LOG"/>
|
|
</parent-provides>
|
|
<start name="test">
|
|
<binary name="dummy"/>
|
|
<resource name="RAM" quantum="2M"/>
|
|
<config version="consume 2 MiB">
|
|
<handle_yield_requests/>
|
|
<consume_ram amount="2M"/>
|
|
</config>
|
|
<route> <any-service> <parent/> </any-service> </route>
|
|
</start>
|
|
</init_config>
|
|
<expect_log string="[init -> test] got yield request"/>
|
|
<expect_log string="[init -> test] release 2M bytes of memory"/>
|
|
<sleep ms="150"/>
|
|
<expect_init_state>
|
|
<node name="child"> <attribute name="name" value="test"/>
|
|
<node name="ram"> <attribute name="quota" lower="2M"/> </node>
|
|
</node>
|
|
</expect_init_state>
|
|
|
|
<sleep ms="500"/>
|
|
<expect_init_state>
|
|
<node name="child"> <attribute name="name" value="test"/>
|
|
<node name="ram">
|
|
<attribute name="assigned" value="2M"/>
|
|
<attribute name="quota" lower="2M"/>
|
|
</node>
|
|
</node>
|
|
</expect_init_state>
|
|
|
|
</config>
|
|
<route>
|
|
<service name="Report"> <child name="report_rom"/> </service>
|
|
<service name="ROM" label="state"> <child name="report_rom"/> </service>
|
|
<service name="Timer"> <child name="timer"/> </service>
|
|
<any-service> <parent/> </any-service>
|
|
</route>
|
|
</start>
|
|
|
|
<start name="init">
|
|
<binary name="init"/>
|
|
<resource name="RAM" quantum="16M"/>
|
|
<configfile name="init.config"/>
|
|
<route>
|
|
<service name="ROM" label="init.config"> <child name="report_rom"/> </service>
|
|
<service name="Report"> <child name="report_rom"/> </service>
|
|
<service name="LOG"> <child name="test-init"/> </service>
|
|
<service name="Timer"> <child name="timer"/> </service>
|
|
|
|
<!-- alias for the binary as requested by the binary-name update test -->
|
|
<service name="ROM" label="another_dummy">
|
|
<parent label="dummy"/> </service>
|
|
|
|
<any-service> <parent/> </any-service>
|
|
</route>
|
|
</start>
|
|
|
|
</config>}
|
|
|
|
install_config $config
|
|
|
|
#
|
|
# Boot modules
|
|
#
|
|
|
|
set boot_modules { core ld.lib.so init timer report_rom test-init dummy }
|
|
|
|
build_boot_image $boot_modules
|
|
|
|
append qemu_args " -nographic "
|
|
|
|
run_genode_until {.*child "test-init" exited with exit value 0.*} 60
|
|
|