init: use buffered XML for config

This commit is contained in:
Norman Feske 2017-02-21 17:01:02 +01:00 committed by Christian Helmuth
parent e4fba26a85
commit a9795c93f9
2 changed files with 67 additions and 13 deletions

View File

@ -28,6 +28,7 @@
namespace Init { namespace Init {
class Buffered_xml;
class Routed_service; class Routed_service;
class Name_registry; class Name_registry;
class Child_registry; class Child_registry;
@ -252,6 +253,42 @@ namespace Init {
} }
class Init::Buffered_xml
{
private:
Allocator &_alloc;
char const * const _ptr; /* pointer to dynamically allocated buffer */
Xml_node const _xml; /* referring to buffer of '_ptr' */
/**
* \throw Allocator::Out_of_memory
*/
static char const *_init_ptr(Allocator &alloc, Xml_node node)
{
char *ptr = (char *)alloc.alloc(node.size());
Genode::memcpy(ptr, node.addr(), node.size());
return ptr;
}
public:
/**
* Constructor
*
* \throw Allocator::Out_of_memory
*/
Buffered_xml(Allocator &alloc, Xml_node node)
:
_alloc(alloc), _ptr(_init_ptr(alloc, node)), _xml(_ptr, node.size())
{ }
~Buffered_xml() { _alloc.free(const_cast<char *>(_ptr), _xml.size()); }
Xml_node xml() const { return _xml; }
};
/** /**
* Init-specific representation of a child service * Init-specific representation of a child service
*/ */
@ -333,6 +370,11 @@ class Init::Child : Child_policy, Child_service::Wakeup
*/ */
struct Id { unsigned value; }; struct Id { unsigned value; };
struct Default_route_accessor
{
virtual Xml_node default_route() = 0;
};
private: private:
friend class Child_registry; friend class Child_registry;
@ -349,9 +391,9 @@ class Init::Child : Child_policy, Child_service::Wakeup
List_element<Child> _list_element; List_element<Child> _list_element;
Xml_node _start_node; Reconstructible<Buffered_xml> _start_node;
Xml_node _default_route_node; Default_route_accessor &_default_route_accessor;
Name_registry &_name_registry; Name_registry &_name_registry;
@ -522,6 +564,7 @@ class Init::Child : Child_policy, Child_service::Wakeup
* \throw Region_map::Attach_failed failed to temporarily attach * \throw Region_map::Attach_failed failed to temporarily attach
* config dataspace to local address * config dataspace to local address
* space * space
* \throw Allocator::Out_of_memory could not buffer the XML start node
*/ */
Child(Env &env, Child(Env &env,
Allocator &alloc, Allocator &alloc,
@ -529,7 +572,7 @@ class Init::Child : Child_policy, Child_service::Wakeup
Id id, Id id,
Report_update_trigger &report_update_trigger, Report_update_trigger &report_update_trigger,
Xml_node start_node, Xml_node start_node,
Xml_node default_route_node, Default_route_accessor &default_route_accessor,
Name_registry &name_registry, Name_registry &name_registry,
long prio_levels, long prio_levels,
Affinity::Space const &affinity_space, Affinity::Space const &affinity_space,
@ -539,8 +582,8 @@ class Init::Child : Child_policy, Child_service::Wakeup
_env(env), _alloc(alloc), _verbose(verbose), _id(id), _env(env), _alloc(alloc), _verbose(verbose), _id(id),
_report_update_trigger(report_update_trigger), _report_update_trigger(report_update_trigger),
_list_element(this), _list_element(this),
_start_node(start_node), _start_node(_alloc, start_node),
_default_route_node(default_route_node), _default_route_accessor(default_route_accessor),
_name_registry(name_registry), _name_registry(name_registry),
_unique_name(start_node, name_registry), _unique_name(start_node, name_registry),
_binary_name(_binary_name_from_xml(start_node, _unique_name)), _binary_name(_binary_name_from_xml(start_node, _unique_name)),
@ -700,9 +743,9 @@ class Init::Child : Child_policy, Child_service::Wakeup
return Route { _session_requester.service() }; return Route { _session_requester.service() };
try { try {
Xml_node route_node = _default_route_node; Xml_node route_node = _default_route_accessor.default_route();
try { try {
route_node = _start_node.sub_node("route"); } route_node = _start_node->xml().sub_node("route"); }
catch (...) { } catch (...) { }
Xml_node service_node = route_node.sub_node(); Xml_node service_node = route_node.sub_node();
@ -862,7 +905,7 @@ class Init::Child : Child_policy, Child_service::Wakeup
void exit(int exit_value) override void exit(int exit_value) override
{ {
try { try {
if (_start_node.sub_node("exit").attribute_value("propagate", false)) { if (_start_node->xml().sub_node("exit").attribute_value("propagate", false)) {
_env.parent().exit(exit_value); _env.parent().exit(exit_value);
return; return;
} }

View File

@ -384,7 +384,7 @@ class Init::State_reporter : public Report_update_trigger
}; };
struct Init::Main : State_reporter::Producer struct Init::Main : State_reporter::Producer, Child::Default_route_accessor
{ {
Env &_env; Env &_env;
@ -398,6 +398,8 @@ struct Init::Main : State_reporter::Producer
Reconstructible<Verbose> _verbose { _config.xml() }; Reconstructible<Verbose> _verbose { _config.xml() };
Constructible<Buffered_xml> _default_route;
unsigned _child_cnt = 0; unsigned _child_cnt = 0;
void _handle_resource_avail() { } void _handle_resource_avail() { }
@ -411,6 +413,15 @@ struct Init::Main : State_reporter::Producer
_children.report_state(xml, detail); _children.report_state(xml, detail);
} }
/**
* Default_route_accessor interface
*/
Xml_node default_route() override
{
return _default_route.constructed() ? _default_route->xml()
: Xml_node("<empty/>");
}
State_reporter _state_reporter { _env, *this }; State_reporter _state_reporter { _env, *this };
Signal_handler<Main> _resource_avail_handler { Signal_handler<Main> _resource_avail_handler {
@ -463,10 +474,8 @@ void Init::Main::_handle_config()
catch (...) { } catch (...) { }
/* determine default route for resolving service requests */ /* determine default route for resolving service requests */
Xml_node default_route_node("<empty/>");
try { try {
default_route_node = _default_route.construct(_heap, _config.xml().sub_node("default-route")); }
_config.xml().sub_node("default-route"); }
catch (...) { } catch (...) { }
/* create aliases */ /* create aliases */
@ -489,7 +498,7 @@ void Init::Main::_handle_config()
Init::Child(_env, _heap, *_verbose, Init::Child(_env, _heap, *_verbose,
Init::Child::Id { ++_child_cnt }, Init::Child::Id { ++_child_cnt },
_state_reporter, _state_reporter,
start_node, default_route_node, start_node, *this,
_children, read_prio_levels(_config.xml()), _children, read_prio_levels(_config.xml()),
read_affinity_space(_config.xml()), read_affinity_space(_config.xml()),
_parent_services, _child_services)); _parent_services, _child_services));
@ -500,6 +509,8 @@ void Init::Main::_handle_config()
* by the Rom_connection constructor. * by the Rom_connection constructor.
*/ */
} }
catch (Allocator::Out_of_memory) {
warning("local memory exhausted during child creation"); }
catch (Ram_session::Alloc_failed) { catch (Ram_session::Alloc_failed) {
warning("failed to allocate memory during child construction"); } warning("failed to allocate memory during child construction"); }
catch (Child::Missing_name_attribute) { catch (Child::Missing_name_attribute) {