Adapt resource-request test to changes of init

The test used to rely on init's formerly built-in policy of answering
resource requests with slack memory, if available. Since init no longer
responds to resource requests in an autonomous way, we use a dynamically
configured sub-init instance as runtime for the test. This instance, in
turn, is monitored and controlled such that resource requests are
result in quota upgrades. The monitoring component is implemented in
the same test-resource_request program as the test. Both roles are
distinguished by the "role" config attribute.

This is a follow-up to "init: explicit response to resource requests".
This commit is contained in:
Norman Feske 2017-03-16 16:12:25 +01:00 committed by Christian Helmuth
parent 8ab8e65fb5
commit 8d68d3d8ac
2 changed files with 120 additions and 5 deletions

View File

@ -1,4 +1,4 @@
build "core init test/resource_request drivers/timer"
build "core init server/report_rom test/resource_request drivers/timer"
create_boot_directory
@ -8,7 +8,6 @@ install_config {
<service name="ROM"/>
<service name="RAM"/>
<service name="CPU"/>
<service name="RM"/>
<service name="PD"/>
<service name="IRQ"/>
<service name="IO_PORT"/>
@ -22,14 +21,34 @@ install_config {
<resource name="RAM" quantum="1M"/>
<provides><service name="Timer"/></provides>
</start>
<start name="test-resource_request">
<start name="report_rom">
<resource name="RAM" quantum="2M"/>
<provides> <service name="ROM" /> </provides>
<provides> <service name="ROM"/> <service name="Report"/> </provides>
<config verbose="no">
<policy label="init -> config" report="init_monitor -> init.config"/>
<policy label="init_monitor -> state" report="init -> state"/>
</config>
</start>
<start name="init">
<resource name="RAM" quantum="10M"/>
<route>
<service name="ROM" label="config"> <child name="report_rom"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
<start name="init_monitor">
<binary name="test-resource_request"/>
<resource name="RAM" quantum="2M"/>
<config role="monitor"/>
<route>
<service name="ROM" label="state"> <child name="report_rom"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
</config>
}
build_boot_image "core ld.lib.so init timer test-resource_request"
build_boot_image "core ld.lib.so init timer report_rom test-resource_request"
append qemu_args "-nographic -m 128"

View File

@ -16,7 +16,14 @@
#include <base/component.h>
#include <base/log.h>
#include <base/attached_rom_dataspace.h>
#include <ram_session/connection.h>
#include <os/reporter.h>
namespace Test {
using namespace Genode;
struct Monitor;
}
static void print_quota_stats(Genode::Ram_session &ram)
@ -31,10 +38,99 @@ static void print_quota_stats(Genode::Ram_session &ram)
throw Error(); }
struct Test::Monitor
{
Env &_env;
Attached_rom_dataspace _init_state { _env, "state" };
Reporter _init_config { _env, "init.config" };
size_t _ram_quota = 2*1024*1024;
void _gen_service_xml(Xml_generator &xml, char const *name)
{
xml.node("service", [&] () { xml.attribute("name", name); });
};
void _generate_init_config()
{
Reporter::Xml_generator xml(_init_config, [&] () {
xml.node("report", [&] () { xml.attribute("child_ram", true); });
xml.node("parent-provides", [&] () {
_gen_service_xml(xml, "ROM");
_gen_service_xml(xml, "CPU");
_gen_service_xml(xml, "PD");
_gen_service_xml(xml, "RAM");
_gen_service_xml(xml, "LOG");
_gen_service_xml(xml, "Timer");
});
xml.node("start", [&] () {
xml.attribute("name", "test-resource_request");
xml.node("resource", [&] () {
xml.attribute("name", "RAM");
xml.attribute("quantum", _ram_quota);
});
xml.node("route", [&] () {
xml.node("any-service", [&] () {
xml.node("parent", [&] () { }); }); });
});
});
}
size_t _resource_request_from_init_state()
{
try {
return _init_state.xml().sub_node("child")
.sub_node("ram")
.attribute_value("requested", Number_of_bytes(0));
}
catch (...) { return 0; }
}
Signal_handler<Monitor> _init_state_handler {
_env.ep(), *this, &Monitor::_handle_init_state };
void _handle_init_state()
{
_init_state.update();
size_t const requested = _resource_request_from_init_state();
if (requested > 0) {
log("responding to resource request of ", Number_of_bytes(requested));
_ram_quota += requested;
_generate_init_config();
}
}
Monitor(Env &env) : _env(env)
{
_init_config.enabled(true);
_init_state.sigh(_init_state_handler);
_generate_init_config();
}
};
void Component::construct(Genode::Env &env)
{
using namespace Genode;
/*
* Distinguish the roles of the program. If configured as playing the
* monitor role, it manages the configuration of a sub init and monitors
* the init state for resource requests.
*/
Attached_rom_dataspace config { env, "config" };
if (config.xml().attribute_value("role", String<32>()) == "monitor") {
static Test::Monitor monitor(env);
return;
}
class Error : Exception { };
log("--- test-resource_request started ---");