2012-01-25 20:04:42 +01:00
|
|
|
/*
|
|
|
|
* \brief Convenience helper for running a service as child process
|
|
|
|
* \author Norman Feske
|
|
|
|
* \author Christian Helmuth
|
|
|
|
* \date 2012-01-25
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-02-20 13:23:52 +01:00
|
|
|
* Copyright (C) 2012-2017 Genode Labs GmbH
|
2012-01-25 20:04:42 +01:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
2017-02-20 13:23:52 +01:00
|
|
|
* under the terms of the GNU Affero General Public License version 3.
|
2012-01-25 20:04:42 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _INCLUDE__OS__SLAVE_H_
|
|
|
|
#define _INCLUDE__OS__SLAVE_H_
|
|
|
|
|
|
|
|
/* Genode includes */
|
|
|
|
#include <base/rpc_server.h>
|
2016-11-06 14:26:34 +01:00
|
|
|
#include <base/local_connection.h>
|
2012-01-25 20:04:42 +01:00
|
|
|
#include <base/child.h>
|
|
|
|
#include <init/child_policy.h>
|
Support for dynamic ROM sessions, fix #170
This patch introduces support for ROM sessions that update their
provided data during the lifetime of the session. The 'Rom_session'
interface had been extended with the new 'release()' and 'sigh()'
functions, which are needed to support the new protocol. All ROM
services have been updated to the new interface.
Furthermore, the patch changes the child policy of init
with regard to the handling of configuration files. The 'Init::Child'
used to always provide the ROM dataspace with the child's config file
via a locally implemented ROM service. However, for dynamic ROM
sessions, we need to establish a session to the real supplier of the ROM
data. This is achieved by using a new 'Child_policy_redirect_rom_file'
policy to handle the 'configfile' rather than handling the 'configfile'
case entirely within 'Child_config'.
To see the new facility in action, the new 'os/run/dynamic_config.run'
script provides a simple scenario. The config file of the test program
is provided by a service, which generates and updates the config data
at regular intervals.
In addition, new support has been added to let slaves use dynamic
reconfiguration. By using the new 'Child_policy_dynamic_rom_file', the
configuration of a slave can be changed dynamically at runtime via the
new 'configure()' function.
The config is provided as plain null-terminated string (instead of a
dataspace capability) because we need to buffer the config data anyway.
So there is no benefit of using a dataspace. For buffering configuration
data, a 'Ram_session' must be supplied. If no 'Ram_session' is specified
at construction time of a 'Slave_policy', no config is supplied to the
slave (which is still a common case).
An example for dynamically reconfiguring a slave is provided by
'os/run/dynamic_config_slave.run'.
2012-04-04 17:07:19 +02:00
|
|
|
#include <os/child_policy_dynamic_rom.h>
|
2016-11-06 14:26:34 +01:00
|
|
|
#include <os/session_requester.h>
|
2012-01-25 20:04:42 +01:00
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
namespace Genode { struct Slave; }
|
2012-01-25 20:04:42 +01:00
|
|
|
|
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
struct Genode::Slave
|
|
|
|
{
|
|
|
|
typedef Session_state::Args Args;
|
2012-01-25 20:04:42 +01:00
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
class Policy;
|
|
|
|
|
|
|
|
template <typename>
|
|
|
|
class Connection_base;
|
|
|
|
|
|
|
|
template <typename>
|
|
|
|
struct Connection;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class Genode::Slave::Policy : public Child_policy
|
2015-03-04 21:12:14 +01:00
|
|
|
{
|
2016-11-06 14:26:34 +01:00
|
|
|
public:
|
|
|
|
|
|
|
|
typedef Child_policy::Name Name;
|
|
|
|
typedef Session_label Label;
|
|
|
|
|
|
|
|
typedef Registered<Genode::Parent_service> Parent_service;
|
|
|
|
typedef Registry<Parent_service> Parent_services;
|
|
|
|
|
2015-03-04 21:12:14 +01:00
|
|
|
private:
|
|
|
|
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 21:35:43 +02:00
|
|
|
Label const _label;
|
|
|
|
Binary_name const _binary_name;
|
|
|
|
Pd_session &_ref_pd;
|
|
|
|
Pd_session_capability _ref_pd_cap;
|
|
|
|
Genode::Parent_service _binary_service;
|
|
|
|
Cap_quota const _cap_quota;
|
|
|
|
Ram_quota const _ram_quota;
|
|
|
|
Parent_services &_parent_services;
|
|
|
|
Rpc_entrypoint &_ep;
|
|
|
|
Child_policy_dynamic_rom_file _config_policy;
|
|
|
|
Session_requester _session_requester;
|
2016-11-06 14:26:34 +01:00
|
|
|
|
2019-01-21 15:46:48 +01:00
|
|
|
Service &_matching_service(Service::Name const &service_name,
|
|
|
|
Session_label const &label)
|
|
|
|
{
|
|
|
|
/* check for config file request */
|
|
|
|
if (Service *s = _config_policy.resolve_session_request(service_name, label))
|
|
|
|
return *s;
|
|
|
|
|
|
|
|
if (service_name == "ROM") {
|
|
|
|
Session_label const rom_name(label.last_element());
|
|
|
|
if (rom_name == _binary_name) return _binary_service;
|
|
|
|
if (rom_name == "session_requests") return _session_requester.service();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* fill parent service registry on demand */
|
|
|
|
Parent_service *service = nullptr;
|
|
|
|
_parent_services.for_each([&] (Parent_service &s) {
|
|
|
|
if (!service && s.name() == service_name)
|
|
|
|
service = &s; });
|
|
|
|
|
|
|
|
if (!service) {
|
|
|
|
error(name(), ": illegal session request of "
|
|
|
|
"service \"", service_name, "\" (", label, ")");
|
|
|
|
throw Service_denied();
|
|
|
|
}
|
|
|
|
|
|
|
|
return *service;
|
|
|
|
}
|
|
|
|
|
2015-03-04 21:12:14 +01:00
|
|
|
public:
|
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
class Connection;
|
|
|
|
|
2015-03-04 21:12:14 +01:00
|
|
|
/**
|
|
|
|
* Slave-policy constructor
|
|
|
|
*
|
2016-11-06 14:26:34 +01:00
|
|
|
* \param ep entrypoint used to provide local services
|
|
|
|
* such as the config ROM service
|
2015-03-04 21:12:14 +01:00
|
|
|
*
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 22:03:22 +02:00
|
|
|
* \throw Out_of_ram by 'Child_policy_dynamic_rom_file'
|
|
|
|
* \throw Out_of_caps by 'Child_policy_dynamic_rom_file'
|
2015-03-04 21:12:14 +01:00
|
|
|
*/
|
2019-01-21 15:46:48 +01:00
|
|
|
Policy(Env &env,
|
|
|
|
Label const &label,
|
|
|
|
Name const &binary_name,
|
|
|
|
Parent_services &parent_services,
|
|
|
|
Rpc_entrypoint &ep,
|
|
|
|
Cap_quota cap_quota,
|
|
|
|
Ram_quota ram_quota)
|
2015-03-04 21:12:14 +01:00
|
|
|
:
|
2017-05-08 16:49:00 +02:00
|
|
|
_label(label), _binary_name(binary_name),
|
2019-01-21 15:46:48 +01:00
|
|
|
_ref_pd(env.pd()), _ref_pd_cap(env.pd_session_cap()),
|
|
|
|
_binary_service(env, Rom_session::service_name()),
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 21:35:43 +02:00
|
|
|
_cap_quota(cap_quota), _ram_quota(ram_quota),
|
2017-05-08 16:49:00 +02:00
|
|
|
_parent_services(parent_services), _ep(ep),
|
2019-01-21 15:46:48 +01:00
|
|
|
_config_policy(env.rm(), "config", _ep, &env.pd()),
|
|
|
|
_session_requester(ep, env.pd(), env.rm())
|
2016-11-06 14:26:34 +01:00
|
|
|
{
|
|
|
|
configure("<config/>");
|
|
|
|
}
|
2015-03-04 21:12:14 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Assign new configuration to slave
|
2016-11-06 14:26:34 +01:00
|
|
|
*
|
|
|
|
* \param config new configuration as null-terminated string
|
2015-03-04 21:12:14 +01:00
|
|
|
*/
|
|
|
|
void configure(char const *config)
|
|
|
|
{
|
2016-11-06 14:26:34 +01:00
|
|
|
_config_policy.load(config, strlen(config) + 1);
|
2015-03-04 21:12:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void configure(char const *config, size_t len)
|
|
|
|
{
|
|
|
|
_config_policy.load(config, len);
|
|
|
|
}
|
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
void trigger_session_requests()
|
|
|
|
{
|
|
|
|
_session_requester.trigger_update();
|
|
|
|
}
|
|
|
|
|
2015-03-04 21:12:14 +01:00
|
|
|
|
|
|
|
/****************************
|
|
|
|
** Child_policy interface **
|
|
|
|
****************************/
|
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
Name name() const override { return _label; }
|
2015-03-04 21:12:14 +01:00
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
Binary_name binary_name() const override { return _binary_name; }
|
|
|
|
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 21:35:43 +02:00
|
|
|
Pd_session &ref_pd() override { return _ref_pd; }
|
|
|
|
Pd_session_capability ref_pd_cap() const override { return _ref_pd_cap; }
|
|
|
|
|
|
|
|
void init(Pd_session &session, Pd_session_capability cap) override
|
|
|
|
{
|
|
|
|
session.ref_account(_ref_pd_cap);
|
|
|
|
_ref_pd.transfer_quota(cap, _cap_quota);
|
2017-05-11 20:03:28 +02:00
|
|
|
_ref_pd.transfer_quota(cap, _ram_quota);
|
2016-11-06 14:26:34 +01:00
|
|
|
}
|
2015-03-04 21:12:14 +01:00
|
|
|
|
2019-01-21 15:46:48 +01:00
|
|
|
Route resolve_session_request(Service::Name const &name,
|
|
|
|
Session_label const &label) override
|
2016-11-06 14:26:34 +01:00
|
|
|
{
|
2019-01-21 15:46:48 +01:00
|
|
|
return Route { .service = _matching_service(name, label),
|
|
|
|
.label = label,
|
|
|
|
.diag = Session::Diag() };
|
2015-03-04 21:12:14 +01:00
|
|
|
}
|
2012-01-25 20:04:42 +01:00
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
Id_space<Parent::Server> &server_id_space() override {
|
|
|
|
return _session_requester.id_space(); }
|
2015-03-04 21:12:14 +01:00
|
|
|
};
|
2012-01-25 20:04:42 +01:00
|
|
|
|
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
template <typename CONNECTION>
|
|
|
|
class Genode::Slave::Connection_base
|
2015-03-04 21:12:14 +01:00
|
|
|
{
|
2016-11-06 14:26:34 +01:00
|
|
|
protected:
|
2015-03-04 21:12:14 +01:00
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
/* each connection appears as a separate client */
|
|
|
|
Id_space<Parent::Client> _id_space;
|
|
|
|
|
|
|
|
Policy &_policy;
|
|
|
|
|
|
|
|
struct Service : Genode::Service, Session_state::Ready_callback,
|
|
|
|
Session_state::Closed_callback
|
2015-03-04 21:12:14 +01:00
|
|
|
{
|
2017-05-08 16:49:00 +02:00
|
|
|
Policy &_policy;
|
|
|
|
Lock _lock { Lock::LOCKED };
|
|
|
|
bool _alive = false;
|
2012-01-25 20:04:42 +01:00
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
Service(Policy &policy)
|
|
|
|
:
|
2017-05-08 16:49:00 +02:00
|
|
|
Genode::Service(CONNECTION::service_name()), _policy(policy)
|
2016-11-06 14:26:34 +01:00
|
|
|
{ }
|
2015-03-04 21:12:14 +01:00
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
void initiate_request(Session_state &session) override
|
2012-01-25 20:04:42 +01:00
|
|
|
{
|
2016-11-06 14:26:34 +01:00
|
|
|
switch (session.phase) {
|
|
|
|
|
|
|
|
case Session_state::CREATE_REQUESTED:
|
|
|
|
|
|
|
|
if (!session.id_at_server.constructed())
|
2017-05-08 16:49:00 +02:00
|
|
|
session.id_at_server.construct(session,
|
|
|
|
_policy.server_id_space());
|
2016-11-06 14:26:34 +01:00
|
|
|
|
|
|
|
session.ready_callback = this;
|
|
|
|
session.async_client_notify = true;
|
|
|
|
break;
|
2015-11-16 10:51:03 +01:00
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
case Session_state::UPGRADE_REQUESTED:
|
|
|
|
warning("upgrading slaves is not implemented");
|
|
|
|
session.phase = Session_state::CAP_HANDED_OUT;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Session_state::CLOSE_REQUESTED:
|
|
|
|
warning("closing slave connections is not implemented");
|
|
|
|
session.phase = Session_state::CLOSED;
|
|
|
|
break;
|
|
|
|
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 22:03:22 +02:00
|
|
|
case Session_state::SERVICE_DENIED:
|
2017-05-08 14:32:03 +02:00
|
|
|
case Session_state::INSUFFICIENT_RAM_QUOTA:
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 21:35:43 +02:00
|
|
|
case Session_state::INSUFFICIENT_CAP_QUOTA:
|
2016-11-06 14:26:34 +01:00
|
|
|
case Session_state::AVAILABLE:
|
|
|
|
case Session_state::CAP_HANDED_OUT:
|
|
|
|
case Session_state::CLOSED:
|
|
|
|
break;
|
|
|
|
}
|
2012-01-25 20:04:42 +01:00
|
|
|
}
|
2016-05-10 18:05:38 +02:00
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
void wakeup() override { }
|
2012-01-25 20:04:42 +01:00
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
/**
|
|
|
|
* Session_state::Ready_callback
|
|
|
|
*/
|
|
|
|
void session_ready(Session_state &session) override
|
|
|
|
{
|
|
|
|
_alive = session.alive();
|
|
|
|
_lock.unlock();
|
|
|
|
}
|
2012-01-25 20:04:42 +01:00
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
/**
|
|
|
|
* Session_state::Closed_callback
|
|
|
|
*/
|
|
|
|
void session_closed(Session_state &s) override { _lock.unlock(); }
|
|
|
|
|
2017-05-08 16:49:00 +02:00
|
|
|
/**
|
|
|
|
* Service ('Ram_transfer::Account') interface
|
|
|
|
*/
|
2019-01-21 15:46:48 +01:00
|
|
|
void transfer(Pd_session_capability to, Ram_quota amount) override
|
2017-05-08 16:49:00 +02:00
|
|
|
{
|
2017-05-11 20:03:28 +02:00
|
|
|
if (to.valid()) _policy.ref_pd().transfer_quota(to, amount);
|
2017-05-08 16:49:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Service ('Ram_transfer::Account') interface
|
|
|
|
*/
|
2017-05-11 20:03:28 +02:00
|
|
|
Pd_session_capability cap(Ram_quota) const override
|
2017-05-08 16:49:00 +02:00
|
|
|
{
|
2017-05-11 20:03:28 +02:00
|
|
|
return _policy.ref_pd_cap();
|
2017-05-08 16:49:00 +02:00
|
|
|
}
|
|
|
|
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 21:35:43 +02:00
|
|
|
/**
|
|
|
|
* Service ('Cap_transfer::Account') interface
|
|
|
|
*/
|
|
|
|
void transfer(Pd_session_capability to, Cap_quota amount) override
|
|
|
|
{
|
|
|
|
if (to.valid()) _policy.ref_pd().transfer_quota(to, amount);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Service ('Cap_transfer::Account') interface
|
|
|
|
*/
|
|
|
|
Pd_session_capability cap(Cap_quota) const override
|
|
|
|
{
|
|
|
|
return _policy.ref_pd_cap();
|
|
|
|
}
|
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
} _service;
|
|
|
|
|
|
|
|
Local_connection<CONNECTION> _connection;
|
2012-01-25 20:04:42 +01:00
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
Connection_base(Policy &policy, Args const &args, Affinity const &affinity)
|
2015-03-04 21:12:14 +01:00
|
|
|
:
|
2016-11-06 14:26:34 +01:00
|
|
|
_policy(policy), _service(_policy),
|
|
|
|
_connection(_service, _id_space, { 1 }, args, affinity)
|
|
|
|
{
|
|
|
|
_policy.trigger_session_requests();
|
|
|
|
_service._lock.lock();
|
|
|
|
if (!_service._alive)
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 22:03:22 +02:00
|
|
|
throw Service_denied();
|
2016-11-06 14:26:34 +01:00
|
|
|
}
|
2015-03-04 21:12:14 +01:00
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
~Connection_base()
|
|
|
|
{
|
|
|
|
_policy.trigger_session_requests();
|
|
|
|
_service._lock.lock();
|
|
|
|
}
|
2015-03-04 21:12:14 +01:00
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
typedef typename CONNECTION::Session_type SESSION;
|
2015-03-04 21:12:14 +01:00
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
Capability<SESSION> _cap() const { return _connection.cap(); }
|
|
|
|
};
|
2015-03-04 21:12:14 +01:00
|
|
|
|
|
|
|
|
2016-11-06 14:26:34 +01:00
|
|
|
template <typename CONNECTION>
|
|
|
|
struct Genode::Slave::Connection : private Connection_base<CONNECTION>,
|
|
|
|
public CONNECTION::Client
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 22:03:22 +02:00
|
|
|
* \throw Service_denied parent denies session request
|
|
|
|
* \throw Out_of_ram our own quota does not suffice for
|
|
|
|
* the creation of the new session
|
|
|
|
* \throw Out_of_caps
|
2016-11-06 14:26:34 +01:00
|
|
|
*/
|
|
|
|
Connection(Slave::Policy &policy, Args const &args,
|
|
|
|
Affinity const &affinity = Affinity())
|
|
|
|
:
|
|
|
|
Connection_base<CONNECTION>(policy, args, affinity),
|
|
|
|
CONNECTION::Client(Connection_base<CONNECTION>::_cap())
|
|
|
|
{ }
|
2017-02-13 17:29:27 +01:00
|
|
|
|
|
|
|
Connection(Region_map &rm, Slave::Policy &policy, Args const &args,
|
|
|
|
Affinity const &affinity = Affinity())
|
|
|
|
:
|
|
|
|
Connection_base<CONNECTION>(policy, args, affinity),
|
|
|
|
CONNECTION::Client(rm, Connection_base<CONNECTION>::_cap())
|
|
|
|
{ }
|
2015-03-04 21:12:14 +01:00
|
|
|
};
|
2012-01-25 20:04:42 +01:00
|
|
|
|
|
|
|
#endif /* _INCLUDE__OS__SLAVE_H_ */
|