mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 20:05:54 +00:00
parent
725d16e18e
commit
9b0fbf000e
@ -32,6 +32,18 @@ class Genode::Sandbox : Noncopyable
|
||||
template <typename>
|
||||
class Local_service;
|
||||
|
||||
/**
|
||||
* Interface invoked each time an interesting state change occurs
|
||||
*
|
||||
* The handler is supposed to inspect the state as provided by
|
||||
* the 'generate_state_report' method and respond by adjusting
|
||||
* the sandbox configuration via 'apply_config'.
|
||||
*/
|
||||
struct State_handler : Interface
|
||||
{
|
||||
virtual void handle_sandbox_state() = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
friend class Local_service_base;
|
||||
@ -46,9 +58,16 @@ class Genode::Sandbox : Noncopyable
|
||||
|
||||
public:
|
||||
|
||||
Sandbox(Env &env);
|
||||
Sandbox(Env &, State_handler &);
|
||||
|
||||
void apply_config(Xml_node const &);
|
||||
|
||||
/**
|
||||
* Generate state report as configured by the <report> config node
|
||||
*
|
||||
* \throw Xml_generator::Buffer_exceeded
|
||||
*/
|
||||
void generate_state_report(Xml_generator &) const;
|
||||
};
|
||||
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <base/component.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <os/sandbox.h>
|
||||
#include <os/reporter.h>
|
||||
|
||||
namespace Init {
|
||||
|
||||
@ -24,11 +25,11 @@ namespace Init {
|
||||
}
|
||||
|
||||
|
||||
struct Init::Main
|
||||
struct Init::Main : Sandbox::State_handler
|
||||
{
|
||||
Env &_env;
|
||||
|
||||
Sandbox _sandbox { _env };
|
||||
Sandbox _sandbox { _env, *this };
|
||||
|
||||
Attached_rom_dataspace _config { _env, "config" };
|
||||
|
||||
@ -37,15 +38,62 @@ struct Init::Main
|
||||
Signal_handler<Main> _resource_avail_handler {
|
||||
_env.ep(), *this, &Main::_handle_resource_avail };
|
||||
|
||||
Constructible<Reporter> _reporter { };
|
||||
|
||||
size_t _report_buffer_size = 0;
|
||||
|
||||
void _handle_config()
|
||||
{
|
||||
_config.update();
|
||||
_sandbox.apply_config(_config.xml());
|
||||
|
||||
Xml_node const config = _config.xml();
|
||||
|
||||
bool reporter_enabled = false;
|
||||
config.with_sub_node("report", [&] (Xml_node report) {
|
||||
|
||||
reporter_enabled = true;
|
||||
|
||||
/* (re-)construct reporter whenever the buffer size is changed */
|
||||
Number_of_bytes const buffer_size =
|
||||
report.attribute_value("buffer", Number_of_bytes(4096));
|
||||
|
||||
if (buffer_size != _report_buffer_size || !_reporter.constructed()) {
|
||||
_report_buffer_size = buffer_size;
|
||||
_reporter.construct(_env, "state", "state", _report_buffer_size);
|
||||
}
|
||||
});
|
||||
|
||||
if (_reporter.constructed())
|
||||
_reporter->enabled(reporter_enabled);
|
||||
|
||||
_sandbox.apply_config(config);
|
||||
}
|
||||
|
||||
Signal_handler<Main> _config_handler {
|
||||
_env.ep(), *this, &Main::_handle_config };
|
||||
|
||||
/**
|
||||
* Sandbox::State_handler interface
|
||||
*/
|
||||
void handle_sandbox_state() override
|
||||
{
|
||||
try {
|
||||
Reporter::Xml_generator xml(*_reporter, [&] () {
|
||||
_sandbox.generate_state_report(xml); });
|
||||
}
|
||||
catch (Xml_generator::Buffer_exceeded) {
|
||||
|
||||
error("state report exceeds maximum size");
|
||||
|
||||
/* try to reflect the error condition as state report */
|
||||
try {
|
||||
Reporter::Xml_generator xml(*_reporter, [&] () {
|
||||
xml.attribute("error", "report buffer exceeded"); });
|
||||
}
|
||||
catch (...) { }
|
||||
}
|
||||
}
|
||||
|
||||
Main(Env &env) : _env(env)
|
||||
{
|
||||
_config.sigh(_config_handler);
|
||||
|
@ -145,7 +145,7 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
|
||||
*/
|
||||
Cap_quota default_caps() override { return _default_caps; }
|
||||
|
||||
State_reporter _state_reporter { _env, *this };
|
||||
State_reporter _state_reporter;
|
||||
|
||||
Heartbeat _heartbeat { _env, _children, _state_reporter };
|
||||
|
||||
@ -157,12 +157,19 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
|
||||
|
||||
Server _server { _env, _heap, _child_services, _state_reporter };
|
||||
|
||||
Library(Env &env, Heap &heap, Registry<Local_service> &local_services)
|
||||
Library(Env &env, Heap &heap, Registry<Local_service> &local_services,
|
||||
State_handler &state_handler)
|
||||
:
|
||||
_env(env), _heap(heap), _local_services(local_services)
|
||||
_env(env), _heap(heap), _local_services(local_services),
|
||||
_state_reporter(_env, *this, state_handler)
|
||||
{ }
|
||||
|
||||
void apply_config(Xml_node const &);
|
||||
|
||||
void generate_state_report(Xml_generator &xml) const
|
||||
{
|
||||
_state_reporter.generate(xml);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -612,9 +619,15 @@ void Genode::Sandbox::apply_config(Xml_node const &config)
|
||||
}
|
||||
|
||||
|
||||
Genode::Sandbox::Sandbox(Env &env)
|
||||
void Genode::Sandbox::generate_state_report(Xml_generator &xml) const
|
||||
{
|
||||
_library.generate_state_report(xml);
|
||||
}
|
||||
|
||||
|
||||
Genode::Sandbox::Sandbox(Env &env, State_handler &state_handler)
|
||||
:
|
||||
_heap(env.ram(), env.rm()),
|
||||
_library(*new (_heap) Library(env, _heap, _local_services))
|
||||
_library(*new (_heap) Library(env, _heap, _local_services, state_handler))
|
||||
{ }
|
||||
|
||||
|
@ -15,14 +15,15 @@
|
||||
#define _LIB__SANDBOX__STATE_REPORTER_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <os/reporter.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <os/sandbox.h>
|
||||
|
||||
/* local includes */
|
||||
#include "report.h"
|
||||
|
||||
namespace Sandbox { class State_reporter; }
|
||||
|
||||
|
||||
class Sandbox::State_reporter : public Report_update_trigger
|
||||
{
|
||||
public:
|
||||
@ -35,14 +36,12 @@ class Sandbox::State_reporter : public Report_update_trigger
|
||||
|
||||
private:
|
||||
|
||||
using State_handler = Genode::Sandbox::State_handler;
|
||||
|
||||
Env &_env;
|
||||
|
||||
Producer &_producer;
|
||||
|
||||
Constructible<Reporter> _reporter { };
|
||||
|
||||
size_t _buffer_size = 0;
|
||||
|
||||
Reconstructible<Report_detail> _report_detail { };
|
||||
|
||||
uint64_t _report_delay_ms = 0;
|
||||
@ -68,62 +67,43 @@ class Sandbox::State_reporter : public Report_update_trigger
|
||||
|
||||
bool _scheduled = false;
|
||||
|
||||
State_handler &_state_handler;
|
||||
|
||||
void _handle_timer()
|
||||
{
|
||||
_scheduled = false;
|
||||
|
||||
try {
|
||||
Reporter::Xml_generator xml(*_reporter, [&] () {
|
||||
|
||||
if (_version.valid())
|
||||
xml.attribute("version", _version);
|
||||
|
||||
_producer.produce_state_report(xml, *_report_detail);
|
||||
});
|
||||
}
|
||||
catch(Xml_generator::Buffer_exceeded) {
|
||||
|
||||
error("state report exceeds maximum size");
|
||||
|
||||
/* try to reflect the error condition as state report */
|
||||
try {
|
||||
Reporter::Xml_generator xml(*_reporter, [&] () {
|
||||
xml.attribute("error", "report buffer exceeded"); });
|
||||
}
|
||||
catch (...) { }
|
||||
}
|
||||
_state_handler.handle_sandbox_state();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
State_reporter(Env &env, Producer &producer)
|
||||
State_reporter(Env &env, Producer &producer, State_handler &state_handler)
|
||||
:
|
||||
_env(env), _producer(producer)
|
||||
_env(env), _producer(producer),
|
||||
_state_handler(state_handler)
|
||||
{ }
|
||||
|
||||
void generate(Xml_generator &xml) const
|
||||
{
|
||||
if (_version.valid())
|
||||
xml.attribute("version", _version);
|
||||
|
||||
if (_report_detail.constructed())
|
||||
_producer.produce_state_report(xml, *_report_detail);
|
||||
}
|
||||
|
||||
void apply_config(Xml_node config)
|
||||
{
|
||||
try {
|
||||
Xml_node report = config.sub_node("report");
|
||||
|
||||
/* (re-)construct reporter whenever the buffer size is changed */
|
||||
Number_of_bytes const buffer_size =
|
||||
report.attribute_value("buffer", Number_of_bytes(4096));
|
||||
|
||||
if (buffer_size != _buffer_size || !_reporter.constructed()) {
|
||||
_buffer_size = buffer_size;
|
||||
_reporter.construct(_env, "state", "state", _buffer_size);
|
||||
}
|
||||
|
||||
_report_detail.construct(report);
|
||||
_report_delay_ms = report.attribute_value("delay_ms", 100UL);
|
||||
_reporter->enabled(true);
|
||||
}
|
||||
catch (Xml_node::Nonexistent_sub_node) {
|
||||
_report_detail.construct();
|
||||
_report_delay_ms = 0;
|
||||
if (_reporter.constructed())
|
||||
_reporter->enabled(false);
|
||||
}
|
||||
|
||||
bool trigger_update = false;
|
||||
|
@ -48,7 +48,13 @@ struct Test::Main : Sandbox::Local_service_base::Wakeup
|
||||
|
||||
Heap _heap { _env.ram(), _env.rm() };
|
||||
|
||||
Sandbox _sandbox { _env };
|
||||
struct State_handler : Sandbox::State_handler
|
||||
{
|
||||
void handle_sandbox_state() override { }
|
||||
|
||||
} _state_handler { };
|
||||
|
||||
Sandbox _sandbox { _env, _state_handler };
|
||||
|
||||
typedef Sandbox::Local_service<Log_session_component> Log_service;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user