parent
725d16e18e
commit
9b0fbf000e
|
@ -32,6 +32,18 @@ class Genode::Sandbox : Noncopyable
|
||||||
template <typename>
|
template <typename>
|
||||||
class Local_service;
|
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:
|
private:
|
||||||
|
|
||||||
friend class Local_service_base;
|
friend class Local_service_base;
|
||||||
|
@ -46,9 +58,16 @@ class Genode::Sandbox : Noncopyable
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Sandbox(Env &env);
|
Sandbox(Env &, State_handler &);
|
||||||
|
|
||||||
void apply_config(Xml_node const &);
|
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/component.h>
|
||||||
#include <base/attached_rom_dataspace.h>
|
#include <base/attached_rom_dataspace.h>
|
||||||
#include <os/sandbox.h>
|
#include <os/sandbox.h>
|
||||||
|
#include <os/reporter.h>
|
||||||
|
|
||||||
namespace Init {
|
namespace Init {
|
||||||
|
|
||||||
|
@ -24,11 +25,11 @@ namespace Init {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct Init::Main
|
struct Init::Main : Sandbox::State_handler
|
||||||
{
|
{
|
||||||
Env &_env;
|
Env &_env;
|
||||||
|
|
||||||
Sandbox _sandbox { _env };
|
Sandbox _sandbox { _env, *this };
|
||||||
|
|
||||||
Attached_rom_dataspace _config { _env, "config" };
|
Attached_rom_dataspace _config { _env, "config" };
|
||||||
|
|
||||||
|
@ -37,15 +38,62 @@ struct Init::Main
|
||||||
Signal_handler<Main> _resource_avail_handler {
|
Signal_handler<Main> _resource_avail_handler {
|
||||||
_env.ep(), *this, &Main::_handle_resource_avail };
|
_env.ep(), *this, &Main::_handle_resource_avail };
|
||||||
|
|
||||||
|
Constructible<Reporter> _reporter { };
|
||||||
|
|
||||||
|
size_t _report_buffer_size = 0;
|
||||||
|
|
||||||
void _handle_config()
|
void _handle_config()
|
||||||
{
|
{
|
||||||
_config.update();
|
_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 {
|
Signal_handler<Main> _config_handler {
|
||||||
_env.ep(), *this, &Main::_handle_config };
|
_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)
|
Main(Env &env) : _env(env)
|
||||||
{
|
{
|
||||||
_config.sigh(_config_handler);
|
_config.sigh(_config_handler);
|
||||||
|
|
|
@ -145,7 +145,7 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
|
||||||
*/
|
*/
|
||||||
Cap_quota default_caps() override { return _default_caps; }
|
Cap_quota default_caps() override { return _default_caps; }
|
||||||
|
|
||||||
State_reporter _state_reporter { _env, *this };
|
State_reporter _state_reporter;
|
||||||
|
|
||||||
Heartbeat _heartbeat { _env, _children, _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 };
|
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 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()),
|
_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_
|
#define _LIB__SANDBOX__STATE_REPORTER_H_
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <os/reporter.h>
|
|
||||||
#include <timer_session/connection.h>
|
#include <timer_session/connection.h>
|
||||||
|
#include <os/sandbox.h>
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include "report.h"
|
#include "report.h"
|
||||||
|
|
||||||
namespace Sandbox { class State_reporter; }
|
namespace Sandbox { class State_reporter; }
|
||||||
|
|
||||||
|
|
||||||
class Sandbox::State_reporter : public Report_update_trigger
|
class Sandbox::State_reporter : public Report_update_trigger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -35,14 +36,12 @@ class Sandbox::State_reporter : public Report_update_trigger
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
using State_handler = Genode::Sandbox::State_handler;
|
||||||
|
|
||||||
Env &_env;
|
Env &_env;
|
||||||
|
|
||||||
Producer &_producer;
|
Producer &_producer;
|
||||||
|
|
||||||
Constructible<Reporter> _reporter { };
|
|
||||||
|
|
||||||
size_t _buffer_size = 0;
|
|
||||||
|
|
||||||
Reconstructible<Report_detail> _report_detail { };
|
Reconstructible<Report_detail> _report_detail { };
|
||||||
|
|
||||||
uint64_t _report_delay_ms = 0;
|
uint64_t _report_delay_ms = 0;
|
||||||
|
@ -68,62 +67,43 @@ class Sandbox::State_reporter : public Report_update_trigger
|
||||||
|
|
||||||
bool _scheduled = false;
|
bool _scheduled = false;
|
||||||
|
|
||||||
|
State_handler &_state_handler;
|
||||||
|
|
||||||
void _handle_timer()
|
void _handle_timer()
|
||||||
{
|
{
|
||||||
_scheduled = false;
|
_scheduled = false;
|
||||||
|
|
||||||
try {
|
_state_handler.handle_sandbox_state();
|
||||||
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 (...) { }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
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)
|
void apply_config(Xml_node config)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
Xml_node report = config.sub_node("report");
|
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_detail.construct(report);
|
||||||
_report_delay_ms = report.attribute_value("delay_ms", 100UL);
|
_report_delay_ms = report.attribute_value("delay_ms", 100UL);
|
||||||
_reporter->enabled(true);
|
|
||||||
}
|
}
|
||||||
catch (Xml_node::Nonexistent_sub_node) {
|
catch (Xml_node::Nonexistent_sub_node) {
|
||||||
_report_detail.construct();
|
_report_detail.construct();
|
||||||
_report_delay_ms = 0;
|
_report_delay_ms = 0;
|
||||||
if (_reporter.constructed())
|
|
||||||
_reporter->enabled(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool trigger_update = false;
|
bool trigger_update = false;
|
||||||
|
|
|
@ -48,7 +48,13 @@ struct Test::Main : Sandbox::Local_service_base::Wakeup
|
||||||
|
|
||||||
Heap _heap { _env.ram(), _env.rm() };
|
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;
|
typedef Sandbox::Local_service<Log_session_component> Log_service;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user