genode/repos/gems/src/app/depot_deploy/main.cc

178 lines
4.5 KiB
C++
Raw Normal View History

2017-07-05 10:40:29 +02:00
/*
* \brief Tool for turning a subsystem blueprint into an init configuration
* \author Norman Feske
* \date 2017-07-07
*/
/*
* Copyright (C) 2017 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.
*/
/* Genode includes */
#include <base/component.h>
#include <base/attached_rom_dataspace.h>
#include <os/reporter.h>
namespace Depot_deploy {
using namespace Genode;
struct Main;
}
struct Depot_deploy::Main
{
Env &_env;
Attached_rom_dataspace _config { _env, "config" };
Attached_rom_dataspace _blueprint { _env, "blueprint" };
2018-01-19 19:23:39 +01:00
Reporter _init_config_reporter { _env, "config", "init.config", 16*1024 };
2017-07-05 10:40:29 +02:00
Signal_handler<Main> _config_handler {
_env.ep(), *this, &Main::_handle_config };
typedef String<128> Name;
typedef String<80> Binary;
typedef String<80> Config;
2017-07-05 10:40:29 +02:00
/**
* Generate start node of init configuration
*
* \param pkg pkg node of the subsystem blueprint
* \param common session routes to be added in addition to the ones
* found in the pkg blueprint
*/
static void _gen_start_node(Xml_generator &, Xml_node pkg, Xml_node common);
void _handle_config()
{
_config.update();
_blueprint.update();
Xml_node const config = _config.xml();
Xml_node const blueprint = _blueprint.xml();
Reporter::Xml_generator xml(_init_config_reporter, [&] () {
Xml_node static_config = config.sub_node("static");
xml.append(static_config.content_base(), static_config.content_size());
blueprint.for_each_sub_node("pkg", [&] (Xml_node pkg) {
/*
* Check preconditions for generating a '<start>' node.
*/
Name const name = pkg.attribute_value("name", Name());
if (!pkg.has_sub_node("runtime")) {
warning("<pkg> node for '", name, "' lacks <runtime> node");
return;
}
Xml_node const runtime = pkg.sub_node("runtime");
if (!runtime.has_attribute("binary")) {
warning("<runtime> node for '", name, "' lacks 'binary' attribute");
2017-07-05 10:40:29 +02:00
return;
}
xml.node("start", [&] () {
_gen_start_node(xml, pkg, config.sub_node("common_routes"));
});
});
});
}
Main(Env &env) : _env(env)
{
_init_config_reporter.enabled(true);
_config .sigh(_config_handler);
_blueprint.sigh(_config_handler);
_handle_config();
}
};
void Depot_deploy::Main::_gen_start_node(Xml_generator &xml, Xml_node pkg, Xml_node common)
{
typedef String<80> Name;
Name const name = pkg.attribute_value("name", Name());
Xml_node const runtime = pkg.sub_node("runtime");
size_t const caps = runtime.attribute_value("caps", 0UL);
Number_of_bytes const ram = runtime.attribute_value("ram", Number_of_bytes());
Binary const binary = runtime.attribute_value("binary", Binary());
Config const config = runtime.attribute_value("config", Config());
2017-07-05 10:40:29 +02:00
xml.attribute("name", name);
xml.attribute("caps", caps);
xml.node("binary", [&] () { xml.attribute("name", binary); });
xml.node("resource", [&] () {
xml.attribute("name", "RAM");
xml.attribute("quantum", String<32>(ram));
});
/*
* Insert inline '<config>' node if provided by the blueprint.
*/
if (runtime.has_sub_node("config")) {
Xml_node config = runtime.sub_node("config");
xml.node("config", [&] () {
xml.append(config.content_base(), config.content_size()); });
2017-07-05 10:40:29 +02:00
};
xml.node("route", [&] () {
/*
* Redirect config ROM request to label given in the 'config'
* attribute.
*/
if (config.valid()) {
xml.node("service", [&] () {
xml.attribute("name", "ROM");
xml.attribute("label", "config");
xml.node("parent", [&] () {
xml.attribute("label", config); });
});
}
2018-01-19 19:23:39 +01:00
/*
* Add common routes as defined in our config.
*/
xml.append(common.content_base(), common.content_size());
2017-07-05 10:40:29 +02:00
/*
* Add ROM routing rule with the label rewritten to
* the path within the depot.
*/
pkg.for_each_sub_node("rom", [&] (Xml_node rom) {
if (!rom.has_attribute("path"))
return;
typedef String<160> Path;
typedef Name Label;
Path const path = rom.attribute_value("path", Path());
Label const label = rom.attribute_value("label", Label());
xml.node("service", [&] () {
xml.attribute("name", "ROM");
2018-01-19 19:23:39 +01:00
xml.attribute("label_last", label);
2017-07-05 10:40:29 +02:00
xml.node("parent", [&] () {
xml.attribute("label", path); });
2017-07-05 10:40:29 +02:00
});
});
});
}
void Component::construct(Genode::Env &env) { static Depot_deploy::Main main(env); }