genode/repos/os/include/init/child_config.h
Norman Feske 511acad507 Consolidate RM service into PD session
This patch integrates three region maps into each PD session to
reduce the session overhead and to simplify the PD creation procedure.
Please refer to the issue cited below for an elaborative discussion.

Note the API change:

With this patch, the semantics of core's RM service have changed. Now,
the service is merely a tool for creating and destroying managed
dataspaces, which are rarely needed. Regular components no longer need a
RM session. For this reason, the corresponding argument for the
'Process' and 'Child' constructors has been removed.

The former interface of the 'Rm_session' is not named 'Region_map'. As a
minor refinement, the 'Fault_type' enum values are now part of the
'Region_map::State' struct.

Issue #1938
2016-05-09 13:10:51 +02:00

141 lines
3.7 KiB
C++

/*
* \brief Utility for handling child configuration
* \author Norman Feske
* \date 2008-03-22
*/
/*
* Copyright (C) 2008-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__INIT__CHILD_CONFIG_H_
#define _INCLUDE__INIT__CHILD_CONFIG_H_
#include <base/env.h>
#include <base/printf.h>
#include <util/xml_node.h>
#include <rom_session/connection.h>
#include <ram_session/client.h>
namespace Init { class Child_config; }
class Init::Child_config
{
private:
enum { CONFIGFILE_NAME_LEN = 64 };
char _filename[CONFIGFILE_NAME_LEN];
Genode::Ram_session_capability _ram_session_cap;
Genode::Ram_dataspace_capability _config_ram_ds;
public:
/**
* Constructor
*
* The provided RAM session is used to obtain a dataspace for
* holding the copy of the child's configuration data unless the
* configuration is supplied via a config file. Normally, the
* child's RAM session should be used to account the consumed RAM
* quota to the child.
*/
Child_config(Genode::Ram_session_capability ram_session,
Genode::Xml_node start_node)
: _ram_session_cap(ram_session)
{
using namespace Genode;
/*
* If the start node contains a 'filename' entry, we only keep
* the information about the file name.
*/
_filename[0] = 0;
try {
Xml_node configfile_node = start_node.sub_node("configfile");
configfile_node.attribute("name")
.value(_filename, sizeof(_filename));
return;
} catch (...) { }
/*
* If the start node contains a 'config' entry, we copy this
* entry into a fresh dataspace to be provided to our child.
*/
Ram_session_client rsc(_ram_session_cap);
try {
Xml_node config_node = start_node.sub_node("config");
const char *config = config_node.addr();
Genode::size_t config_size = config_node.size();
if (!config || !config_size) return;
/*
* Allocate RAM dataspace that is big enough to
* hold the configuration and the null termination.
*/
_config_ram_ds = rsc.alloc(config_size + 1);
/*
* Make dataspace locally accessible, copy
* configuration into the dataspace, and append
* a string-terminating zero.
*/
void *addr = env()->rm_session()->attach(_config_ram_ds);
Genode::memcpy(addr, config, config_size);
static_cast<char *>(addr)[config_size] = 0;
env()->rm_session()->detach(addr);
} catch (Region_map::Attach_failed) {
rsc.free(_config_ram_ds);
return;
} catch (Ram_session::Alloc_failed) {
return;
} catch (Xml_node::Nonexistent_sub_node) { }
}
/**
* Destructor
*/
~Child_config()
{
using namespace Genode;
/*
* The configuration data is either provided as a ROM session
* (holding a complete configfile) or as a RAM dataspace
* holding a copy of the start node's config entry. In the
* latter case, the child's configuration resides in a
* shadow copy kept in '_config_ram_ds'.
*/
if (_config_ram_ds.valid())
Ram_session_client(_ram_session_cap).free(_config_ram_ds);
}
/**
* Return file name if configuration comes from a file
*
* If the configuration is provided inline, the method returns 0.
*/
char const *filename() const {
return _filename[0] != 0 ? _filename : 0; }
/**
* Request dataspace holding the start node's configuration data
*
* This method returns a valid dataspace only when using an
* inline configuration (if 'filename()' returns 0).
*/
Genode::Dataspace_capability dataspace() {
return Genode::Dataspace_capability(_config_ram_ds); }
};
#endif /* _INCLUDE__INIT__CHILD_CONFIG_H_ */