Propagate session diag flag to core

This commit restores the diag feature for selecting diagnostic output of
services provided by core. This feature became unavailable with commit
"base: remove dependency from deprecated APIs", which hard-wired the
diag flag for core services to false.

To control this feature, three possible policies can be expressed in a
routing target of init's configuration:

* Forcing silence by specifying 'diag="no"'
* Enabling diagnostics by specifying 'diag="yes"'
* Forwarding the preference of the client by omitting the 'diag'
  attribute

Fixes #3962
This commit is contained in:
Norman Feske 2020-12-02 10:30:22 +01:00
parent 36eeab6df2
commit a0fb944721
19 changed files with 63 additions and 41 deletions

View File

@ -83,7 +83,8 @@ struct Genode::Child_policy
* \throw Service_denied
*/
virtual Route resolve_session_request(Service::Name const &,
Session_label const &) = 0;
Session_label const &,
Session::Diag) = 0;
/**
* Apply transformations to session arguments
@ -575,7 +576,8 @@ class Genode::Child : protected Rpc_object<Parent>,
try {
Child_policy::Route const route =
_child._policy.resolve_session_request(_service_name(),
label_from_args(_args.string()));
label_from_args(_args.string()),
session_diag_from_args(_args.string()));
_env_service.construct(_child, route.service);
_connection.construct(*_env_service, _child._id_space, _client_id,
_args, _child._policy.filter_session_affinity(Affinity()),

View File

@ -68,7 +68,7 @@ struct Genode::Local_connection_base : Noncopyable
{
enum { NUM_ATTEMPTS = 10 };
for (unsigned i = 0; i < NUM_ATTEMPTS; i++) {
_session_state.construct(service, id_space, id, label,
_session_state.construct(service, id_space, id, label, diag,
_init_args(args, resources, diag),
affinity);

View File

@ -65,6 +65,7 @@ class Genode::Session_state : public Parent::Client, public Parent::Server
Reconstructible<Id_space<Parent::Client>::Element> _id_at_client;
Session::Label const _label;
Session::Diag const _diag;
Args _args;
Affinity _affinity;
@ -138,6 +139,7 @@ class Genode::Session_state : public Parent::Client, public Parent::Server
Id_space<Parent::Client> &client_id_space,
Parent::Client::Id client_id,
Session::Label const &label,
Session::Diag diag,
Args const &args,
Affinity const &affinity);
@ -179,6 +181,8 @@ class Genode::Session_state : public Parent::Client, public Parent::Server
Args const &args() const { return _args; }
Session::Diag diag() const { return _diag; }
Affinity const &affinity() const { return _affinity; }
void generate_session_request(Xml_generator &) const;

View File

@ -92,8 +92,8 @@ _ZN6Genode13Registry_base7_insertERNS0_7ElementE T
_ZN6Genode13Registry_base7_removeERNS0_7ElementE T
_ZN6Genode13Registry_base9_for_eachERNS0_15Untyped_functorE T
_ZN6Genode13Session_state7destroyEv T
_ZN6Genode13Session_stateC1ERNS_7ServiceERNS_8Id_spaceINS_6Parent6ClientEEENS6_2IdERKNS_13Session_labelERKNS_6StringILm256EEERKNS_8AffinityE T
_ZN6Genode13Session_stateC2ERNS_7ServiceERNS_8Id_spaceINS_6Parent6ClientEEENS6_2IdERKNS_13Session_labelERKNS_6StringILm256EEERKNS_8AffinityE T
_ZN6Genode13Session_stateC1ERNS_7ServiceERNS_8Id_spaceINS_6Parent6ClientEEENS6_2IdERKNS_13Session_labelENS_7Session4DiagERKNS_6StringILm256EEERKNS_8AffinityE T
_ZN6Genode13Session_stateC2ERNS_7ServiceERNS_8Id_spaceINS_6Parent6ClientEEENS6_2IdERKNS_13Session_labelENS_7Session4DiagERKNS_6StringILm256EEERKNS_8AffinityE T
_ZN6Genode13Shared_objectC1ERNS_3EnvERNS_9AllocatorEPKcNS0_4BindENS0_4KeepE T
_ZN6Genode13Shared_objectC2ERNS_3EnvERNS_9AllocatorEPKcNS0_4BindENS0_4KeepE T
_ZN6Genode13Shared_objectD1Ev T

View File

@ -146,7 +146,8 @@ class Core_child : public Child_policy
Name name() const override { return "init"; }
Route resolve_session_request(Service::Name const &name,
Session_label const &label) override
Session_label const &label,
Session::Diag const diag) override
{
Service *service = nullptr;
_services.for_each([&] (Service &s) {
@ -158,7 +159,7 @@ class Core_child : public Child_policy
return Route { .service = *service,
.label = label,
.diag = Session::Diag() };
.diag = diag };
}
void init(Pd_session &session, Capability<Pd_session> cap) override

View File

@ -100,13 +100,13 @@ void Child::session_sigh(Signal_context_capability sigh)
*/
Session_state &
create_session(Child_policy::Name const &child_name, Service &service,
Session_label const &label,
Session_label const &label, Session::Diag diag,
Session_state::Factory &factory, Id_space<Parent::Client> &id_space,
Parent::Client::Id id, Session_state::Args const &args,
Affinity const &affinity)
{
try {
return service.create_session(factory, id_space, id, label, args, affinity); }
return service.create_session(factory, id_space, id, label, diag, args, affinity); }
catch (Insufficient_ram_quota) {
error(child_name, " requested session with insufficient RAM quota");
@ -174,7 +174,9 @@ Session_capability Child::session(Parent::Client::Id id,
Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", forward_ram_quota.value);
/* may throw a 'Service_denied' exception */
Child_policy::Route route = _policy.resolve_session_request(name.string(), label);
Child_policy::Route route =
_policy.resolve_session_request(name.string(), label,
session_diag_from_args(argbuf));
Service &service = route.service;
@ -182,7 +184,7 @@ Session_capability Child::session(Parent::Client::Id id,
Arg_string::set_arg(argbuf, sizeof(argbuf), "diag", route.diag.enabled);
Session_state &session =
create_session(_policy.name(), service, route.label,
create_session(_policy.name(), service, route.label, route.diag,
_session_factory, _id_space, id, argbuf, filtered_affinity);
_policy.session_state_changed();

View File

@ -172,6 +172,7 @@ Session_state::Session_state(Service &service,
Id_space<Parent::Client> &client_id_space,
Parent::Client::Id client_id,
Session::Label const &label,
Session::Diag const diag,
Args const &args,
Affinity const &affinity)
:
@ -179,5 +180,5 @@ Session_state::Session_state(Service &service,
_donated_ram_quota(ram_quota_from_args(args.string())),
_donated_cap_quota(cap_quota_from_args(args.string())),
_id_at_client(*this, client_id_space, client_id),
_label(label), _args(args), _affinity(affinity)
_label(label), _diag(diag), _args(args), _affinity(affinity)
{ }

View File

@ -230,11 +230,12 @@ class Test_child_policy : public Child_policy
}
Route resolve_session_request(Service::Name const &name,
Session_label const &label) override
Session_label const &label,
Session::Diag const diag) override
{
return Route { .service = _matching_service(name),
.label = label,
.diag = Session::Diag() };
.diag = diag };
}
};

View File

@ -153,12 +153,13 @@ class Launchpad_child : public Genode::Child_policy,
Genode::Child_policy::Route
resolve_session_request(Genode::Service::Name const &service_name,
Genode::Session_label const &label) override
Genode::Session_label const &label,
Genode::Session::Diag const diag) override
{
auto route = [&] (Genode::Service &service) {
return Genode::Child_policy::Route { .service = service,
.label = label,
.diag = Genode::Session::Diag() }; };
.diag = diag }; };
Genode::Service *service = nullptr;

View File

@ -474,7 +474,8 @@ struct Libc::Forked_child : Child_policy, Child_ready
}
Route resolve_session_request(Service::Name const &name,
Session_label const &label) override
Session_label const &label,
Session::Diag const diag) override
{
Session_label rewritten_label = label;
@ -508,7 +509,7 @@ struct Libc::Forked_child : Child_policy, Child_ready
if (service_ptr)
return Route { .service = *service_ptr,
.label = rewritten_label,
.diag = Session::Diag() };
.diag = diag };
throw Service_denied();
}

View File

@ -164,11 +164,12 @@ class Genode::Slave::Policy : public Child_policy
}
Route resolve_session_request(Service::Name const &name,
Session_label const &label) override
Session_label const &label,
Session::Diag const diag) override
{
return Route { .service = _matching_service(name, label),
.label = label,
.diag = Session::Diag() };
.diag = diag };
}
Id_space<Parent::Server> &server_id_space() override {

View File

@ -114,12 +114,13 @@ struct Sequence::Child : Genode::Child_policy
* otherwise forward directly to the parent.
*/
Route resolve_session_request(Service::Name const &name,
Session_label const &label) override
Session_label const &label,
Session::Diag const diag) override
{
auto route = [&] (Service &service) {
return Route { .service = service,
.label = label,
.diag = Session::Diag() }; };
.diag = diag }; };
if (_have_config) {
Service *s =

View File

@ -446,7 +446,8 @@ void Sandbox::Child::init(Cpu_session &session, Cpu_session_capability cap)
Sandbox::Child::Route
Sandbox::Child::resolve_session_request(Service::Name const &service_name,
Session_label const &label)
Session_label const &label,
Session::Diag const diag)
{
/* check for "config" ROM request */
if (service_name == Rom_session::service_name() &&
@ -474,17 +475,16 @@ Sandbox::Child::resolve_session_request(Service::Name const &service_name,
*/
if (service_name == Rom_session::service_name() &&
label == _unique_name && _unique_name != _binary_name)
return resolve_session_request(service_name, _binary_name);
return resolve_session_request(service_name, _binary_name, diag);
/* supply binary as dynamic linker if '<start ld="no">' */
if (!_use_ld && service_name == Rom_session::service_name() && label == "ld.lib.so")
return resolve_session_request(service_name, _binary_name);
return resolve_session_request(service_name, _binary_name, diag);
/* check for "session_requests" ROM request */
if (service_name == Rom_session::service_name()
&& label.last_element() == Session_requester::rom_name())
return Route { _session_requester.service(),
Session::Label(), Session::Diag{false} };
return Route { _session_requester.service(), Session::Label(), diag };
try {
Xml_node route_node = _default_route_accessor.default_route();
@ -517,7 +517,7 @@ Sandbox::Child::resolve_session_request(Service::Name const &service_name,
target.attribute_value("label", Label(label.string()));
Session::Diag const
target_diag { target.attribute_value("diag", false) };
target_diag { target.attribute_value("diag", diag.enabled) };
auto no_filter = [] (Service &) -> bool { return false; };

View File

@ -385,7 +385,8 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
try {
Route const route =
resolve_session_request(session.service().name(),
session.client_label());
session.client_label(),
session.diag());
return (session.service() == route.service)
&& (route.label == session.label());
@ -599,7 +600,7 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
return _session_requester.id_space(); }
Route resolve_session_request(Service::Name const &,
Session_label const &) override;
Session_label const &, Session::Diag) override;
void filter_session_args(Service::Name const &, char *, size_t) override;
Affinity filter_session_affinity(Affinity const &) override;

View File

@ -226,10 +226,12 @@ void Sandbox::Server::_handle_create_session_request(Xml_node request,
Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", forward_ram_quota.value);
Session::Diag const diag = session_diag_from_args(args.string());
Session_state &session =
route.service.create_session(route.service.factory(),
_client_id_space, id, route.label,
argbuf, Affinity::from_xml(request));
_client_id_space, id, route.label,
diag, argbuf, Affinity::from_xml(request));
/* transfer session quota */
try {
@ -401,7 +403,7 @@ void Sandbox::Server::apply_config(Xml_node config)
session.client_label());
bool const route_unchanged = (route.service == session.service())
&& (route.label == session.label());
&& (route.label == session.label());
if (!route_unchanged)
throw Service_denied();
}

View File

@ -126,11 +126,12 @@ class Loader::Child : public Child_policy
}
Route resolve_session_request(Service::Name const &name,
Session_label const &label) override
Session_label const &label,
Session::Diag const diag) override
{
return Route { .service = _matching_service(name),
.label = label,
.diag = Session::Diag() };
.diag = diag };
}
};

View File

@ -101,11 +101,12 @@ class Bomb_child : public Child_policy
}
Route resolve_session_request(Service::Name const &service_name,
Session_label const &label) override
Session_label const &label,
Session::Diag const diag) override
{
return Route { .service = _matching_service(service_name, label),
.label = label,
.diag = Session::Diag() };
.diag = diag };
}
};

View File

@ -120,12 +120,13 @@ class Test_child : public Genode::Child_policy
}
Route resolve_session_request(Service::Name const &service,
Session_label const &label) override
Session_label const &label,
Session::Diag const diag) override
{
auto route = [&] (Service &service) {
return Route { .service = service,
.label = label,
.diag = Session::Diag() }; };
.diag = diag }; };
if (service == Cpu_session::service_name()) return route(_cpu_service);
if (service == Pd_session::service_name()) return route( _pd_service);

View File

@ -306,11 +306,12 @@ class Gdb_monitor::App_child : public Child_policy,
}
Route resolve_session_request(Service::Name const &service_name,
Session_label const &label) override
Session_label const &label,
Session::Diag const diag) override
{
return Route { .service = _matching_service(service_name, label),
.label = label,
.diag = Session::Diag() };
.diag = diag };
}
void announce_service(Service::Name const &service_name) override