depot_deploy: make child-state tracking reusable

This commit is contained in:
Norman Feske 2018-05-09 11:56:54 +02:00 committed by Christian Helmuth
parent 94db45036c
commit 2a9b0a163e
3 changed files with 133 additions and 88 deletions

View File

@ -34,6 +34,7 @@ class Depot_deploy::Child : public List_model<Child>::Element
typedef String<100> Name;
typedef String<80> Binary_name;
typedef String<80> Config_name;
typedef String<32> Depot_rom_server;
private:
@ -72,7 +73,7 @@ class Depot_deploy::Child : public List_model<Child>::Element
&& (_config_pkg_path() == _blueprint_pkg_path);
}
inline void _gen_routes(Xml_generator &, Xml_node common) const;
inline void _gen_routes(Xml_generator &, Xml_node, Depot_rom_server const &) const;
static void _gen_provides_sub_node(Xml_generator &xml, Xml_node service,
Xml_node::Type const &node_type,
@ -181,14 +182,19 @@ class Depot_deploy::Child : public List_model<Child>::Element
/**
* Generate start node of init configuration
*
* \param common session routes to be added in addition to the ones
* found in the pkg blueprint
* \param common session routes to be added in addition to the ones
* found in the pkg blueprint
* \param depot_rom name of the server that provides the depot content
* as ROM modules. If the string is invalid, ROM
* requests are routed to the parent.
*/
inline void gen_start_node(Xml_generator &, Xml_node common) const;
inline void gen_start_node(Xml_generator &, Xml_node common,
Depot_rom_server const &depot_rom) const;
};
void Depot_deploy::Child::gen_start_node(Xml_generator &xml, Xml_node common) const
void Depot_deploy::Child::gen_start_node(Xml_generator &xml, Xml_node common,
Depot_rom_server const &depot_rom) const
{
if (!_configured())
return;
@ -250,12 +256,13 @@ void Depot_deploy::Child::gen_start_node(Xml_generator &xml, Xml_node common) co
});
}
xml.node("route", [&] () { _gen_routes(xml, common); });
xml.node("route", [&] () { _gen_routes(xml, common, depot_rom); });
});
}
void Depot_deploy::Child::_gen_routes(Xml_generator &xml, Xml_node common) const
void Depot_deploy::Child::_gen_routes(Xml_generator &xml, Xml_node common,
Depot_rom_server const &depot_rom) const
{
if (!_pkg_xml.constructed())
return;
@ -289,10 +296,16 @@ void Depot_deploy::Child::_gen_routes(Xml_generator &xml, Xml_node common) const
xml.node("service", [&] () {
xml.attribute("name", "ROM");
xml.attribute("label", "config");
xml.node("parent", [&] () {
typedef String<160> Path;
xml.attribute("label", rom.attribute_value("path", Path()));
});
typedef String<160> Path;
Path const path = rom.attribute_value("path", Path());
if (depot_rom.valid())
xml.node("child", [&] () {
xml.attribute("name", depot_rom);
xml.attribute("label", path); });
else
xml.node("parent", [&] () {
xml.attribute("label", path); });
});
});
}
@ -318,8 +331,16 @@ void Depot_deploy::Child::_gen_routes(Xml_generator &xml, Xml_node common) const
xml.node("service", [&] () {
xml.attribute("name", "ROM");
xml.attribute("label_last", label);
xml.node("parent", [&] () {
xml.attribute("label", path); });
if (depot_rom.valid()) {
xml.node("child", [&] () {
xml.attribute("name", depot_rom);
xml.attribute("label", path);
});
} else {
xml.node("parent", [&] () {
xml.attribute("label", path); });
}
});
});
}

View File

@ -0,0 +1,95 @@
/*
* \brief State tracking of subsystems deployed from depot packages
* \author Norman Feske
* \date 2018-01-23
*/
/*
* Copyright (C) 2018 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _CHILDREN_H_
#define _CHILDREN_H_
/* Genode includes */
#include <util/list_model.h>
#include <util/xml_generator.h>
#include <base/service.h>
#include <depot/archive.h>
/* local includes */
#include "child.h"
namespace Depot_deploy { class Children; }
class Depot_deploy::Children
{
private:
Allocator &_alloc;
List_model<Child> _children { };
struct Model_update_policy : List_model<Child>::Update_policy
{
Allocator &_alloc;
Model_update_policy(Allocator &alloc) : _alloc(alloc) { }
void destroy_element(Child &c) { destroy(_alloc, &c); }
Child &create_element(Xml_node node)
{
return *new (_alloc) Child(_alloc, node);
}
void update_element(Child &c, Xml_node node) { c.apply_config(node); }
static bool element_matches_xml_node(Child const &child, Xml_node node)
{
return node.attribute_value("name", Child::Name()) == child.name();
}
static bool node_is_element(Xml_node node) { return node.has_type("start"); }
} _model_update_policy { _alloc };
public:
Children(Allocator &alloc) : _alloc(alloc) { }
void apply_config(Xml_node config)
{
_children.update_from_xml(_model_update_policy, config);
}
void apply_blueprint(Xml_node blueprint)
{
blueprint.for_each_sub_node("pkg", [&] (Xml_node pkg) {
_children.for_each([&] (Child &child) {
child.apply_blueprint(pkg); }); });
blueprint.for_each_sub_node("missing", [&] (Xml_node missing) {
_children.for_each([&] (Child &child) {
child.mark_as_incomplete(missing); }); });
}
void gen_start_nodes(Xml_generator &xml, Xml_node common,
Child::Depot_rom_server const &depot_rom) const
{
_children.for_each([&] (Child const &child) {
child.gen_start_node(xml, common, depot_rom); });
}
void gen_queries(Xml_generator &xml) const
{
_children.for_each([&] (Child const &child) {
child.gen_query(xml); });
}
};
#endif /* _CHILDREN_H_ */

View File

@ -19,78 +19,9 @@
#include <os/reporter.h>
/* local includes */
#include "child.h"
#include "children.h"
namespace Depot_deploy {
struct Children;
struct Main;
}
class Depot_deploy::Children
{
private:
Allocator &_alloc;
List_model<Child> _children { };
struct Model_update_policy : List_model<Child>::Update_policy
{
Allocator &_alloc;
Model_update_policy(Allocator &alloc) : _alloc(alloc) { }
void destroy_element(Child &c) { destroy(_alloc, &c); }
Child &create_element(Xml_node node)
{
return *new (_alloc) Child(_alloc, node);
}
void update_element(Child &c, Xml_node node) { c.apply_config(node); }
static bool element_matches_xml_node(Child const &child, Xml_node node)
{
return node.attribute_value("name", Child::Name()) == child.name();
}
static bool node_is_element(Xml_node node) { return node.has_type("start"); }
} _model_update_policy { _alloc };
public:
Children(Allocator &alloc) : _alloc(alloc) { }
void apply_config(Xml_node config)
{
_children.update_from_xml(_model_update_policy, config);
}
void apply_blueprint(Xml_node blueprint)
{
blueprint.for_each_sub_node("pkg", [&] (Xml_node pkg) {
_children.for_each([&] (Child &child) {
child.apply_blueprint(pkg); }); });
blueprint.for_each_sub_node("missing", [&] (Xml_node missing) {
_children.for_each([&] (Child &child) {
child.mark_as_incomplete(missing); }); });
}
void gen_start_nodes(Xml_generator &xml, Xml_node common)
{
_children.for_each([&] (Child const &child) {
child.gen_start_node(xml, common); });
}
void gen_queries(Xml_generator &xml)
{
_children.for_each([&] (Child const &child) {
child.gen_query(xml); });
}
};
namespace Depot_deploy { struct Main; }
struct Depot_deploy::Main
@ -103,9 +34,6 @@ struct Depot_deploy::Main
Expanding_reporter _query_reporter { _env, "query" , "query"};
Expanding_reporter _init_config_reporter { _env, "config", "init.config"};
size_t _query_buffer_size = 4096;
size_t _init_config_buffer_size = 4096;
Heap _heap { _env.ram(), _env.rm() };
Children _children { _heap };
@ -135,7 +63,8 @@ struct Depot_deploy::Main
_init_config_reporter.generate([&] (Xml_generator &xml) {
Xml_node static_config = config.sub_node("static");
xml.append(static_config.content_base(), static_config.content_size());
_children.gen_start_nodes(xml, config.sub_node("common_routes"));
Child::Depot_rom_server const parent { };
_children.gen_start_nodes(xml, config.sub_node("common_routes"), parent);
});
/* update query for blueprints of all unconfigured start nodes */