Noux: 'empty' ROM service for initial ROMs

The initial ROMs (program and linker) are already attached to the region
map of a forked process and don't need to be obtained again from an
external ROM service when the 'Child' class asks for them. For the program
image, the local Noux ROM service already returned an invalid dataspace
capability, but not for the linker.

Instead of adding another 'magic' ROM name for the local ROM service,
this commit implements an 'empty' ROM service, which returns an
invalid dataspace for the initial ROMs.

Fixes #2272
This commit is contained in:
Christian Prochaska 2017-01-31 18:03:11 +01:00 committed by Christian Helmuth
parent 2ac845281d
commit 3ac3236a28
5 changed files with 141 additions and 27 deletions

View File

@ -33,6 +33,7 @@
#include <interrupt_handler.h>
#include <kill_broadcaster.h>
#include <parent_execve.h>
#include <empty_rom_service.h>
#include <local_rom_service.h>
#include <verbose.h>
#include <user_info.h>
@ -187,6 +188,8 @@ class Noux::Child : public Rpc_object<Session>,
/*
* Locally-provided ROM service
*/
Empty_rom_factory _empty_rom_factory { _heap, _ep };
Empty_rom_service _empty_rom_service { _empty_rom_factory };
Local_rom_factory _rom_factory { _heap, _env, _ep, _root_dir, _ds_registry };
Local_rom_service _rom_service { _rom_factory };
@ -359,12 +362,11 @@ class Noux::Child : public Rpc_object<Session>,
_args_ds_info(_ds_registry, _args.cap()),
_sysio_env_ds_info(_ds_registry, _sysio_env.cap()),
_config_ds_info(_ds_registry, _config.cap()),
_child_policy(name,
forked ? Rom_session_component::forked_magic_binary_name()
: name,
_child_policy(name, forked,
_args.cap(), _sysio_env.cap(), _config.cap(),
_ep, _pd_service, _ram_service, _cpu_service,
_noux_service, _rom_service, _parent_services,
_noux_service, _empty_rom_service,
_rom_service, _parent_services,
*this, parent_exit, *this, _destruct_handler,
ref_ram, ref_ram_cap, _verbose.enabled()),
_child(_env.rm(), _ep, _child_policy)

View File

@ -21,6 +21,7 @@
#include <family_member.h>
#include <parent_exit.h>
#include <file_descriptor_registry.h>
#include <empty_rom_service.h>
#include <local_rom_service.h>
namespace Noux {
@ -42,7 +43,7 @@ class Noux::Child_policy : public Genode::Child_policy
private:
Name const _name;
Binary_name const _binary_name;
bool _forked;
Init::Child_policy_provide_rom_file _args_policy;
Init::Child_policy_provide_rom_file _env_policy;
Init::Child_policy_provide_rom_file _config_policy;
@ -50,6 +51,7 @@ class Noux::Child_policy : public Genode::Child_policy
Ram_service &_ram_service;
Cpu_service &_cpu_service;
Noux_service &_noux_service;
Empty_rom_service &_empty_rom_service;
Local_rom_service &_rom_service;
Parent_services &_parent_services;
Family_member &_family_member;
@ -75,7 +77,7 @@ class Noux::Child_policy : public Genode::Child_policy
public:
Child_policy(Name const &name,
Binary_name const &binary_name,
bool forked,
Dataspace_capability args_ds,
Dataspace_capability env_ds,
Dataspace_capability config_ds,
@ -84,6 +86,7 @@ class Noux::Child_policy : public Genode::Child_policy
Ram_service &ram_service,
Cpu_service &cpu_service,
Noux_service &noux_service,
Empty_rom_service &empty_rom_service,
Local_rom_service &rom_service,
Parent_services &parent_services,
Family_member &family_member,
@ -94,13 +97,13 @@ class Noux::Child_policy : public Genode::Child_policy
Ram_session_capability ref_ram_cap,
bool verbose)
:
_name(name),
_binary_name(binary_name),
_name(name), _forked(forked),
_args_policy( "args", args_ds, &entrypoint),
_env_policy( "env", env_ds, &entrypoint),
_config_policy("config", config_ds, &entrypoint),
_pd_service(pd_service), _ram_service(ram_service),
_cpu_service(cpu_service), _noux_service(noux_service),
_empty_rom_service(empty_rom_service),
_rom_service(rom_service), _parent_services(parent_services),
_family_member(family_member),
_parent_exit(parent_exit),
@ -117,8 +120,7 @@ class Noux::Child_policy : public Genode::Child_policy
** Child policy interface **
****************************/
Name name() const override { return _name; }
Binary_name binary_name() const override { return _binary_name; }
Name name() const override { return _name; }
Ram_session &ref_ram() override { return _ref_ram; }
@ -134,10 +136,14 @@ class Noux::Child_policy : public Genode::Child_policy
{
Session_label const label(Genode::label_from_args(args.string()));
/* route initial ROM requests (binary and linker) to the parent */
if (service_name == Genode::Rom_session::service_name()) {
if (label.last_element() == binary_name()) return _rom_service;
if (label.last_element() == linker_name()) return _rom_service;
/*
* Route initial ROM requests (binary and linker) of a forked child
* to the empty ROM service, since the ROMs are already attached in
* the replayed region map.
*/
if (_forked && (service_name == Genode::Rom_session::service_name())) {
if (label.last_element() == name()) return _empty_rom_service;
if (label.last_element() == linker_name()) return _empty_rom_service;
}
Genode::Service *service = nullptr;

View File

@ -0,0 +1,61 @@
/*
* \brief ROM service provided to Noux processes for initial ROMs
* \author Christian Prochaska
* \date 2017-01-31
*
* The initial ROMs (binary and linker) are already attached in a forked
* child and don't need a new ROM dataspace.
*/
/*
* Copyright (C) 2017 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 _NOUX__EMPTY_ROM_SERVICE_H_
#define _NOUX__EMPTY_ROM_SERVICE_H_
/* Genode includes */
#include <base/service.h>
/* Noux includes */
#include <empty_rom_session_component.h>
namespace Noux {
typedef Local_service<Empty_rom_session_component> Empty_rom_service;
class Empty_rom_factory;
}
class Noux::Empty_rom_factory : public Empty_rom_service::Factory
{
private:
Allocator &_alloc;
Rpc_entrypoint &_ep;
public:
Empty_rom_factory(Allocator &alloc, Rpc_entrypoint &ep)
: _alloc(alloc), _ep(ep) { }
Empty_rom_session_component &create(Args const &args, Affinity) override
{
try {
return *new (_alloc) Empty_rom_session_component(_ep);
}
catch (Rom_connection::Rom_connection_failed) { throw Denied(); }
}
void upgrade(Empty_rom_session_component &, Args const &) override { }
void destroy(Empty_rom_session_component &session) override
{
Genode::destroy(_alloc, &session);
}
};
#endif /* _NOUX__EMPTY_ROM_SERVICE_H_ */

View File

@ -0,0 +1,58 @@
/*
* \brief ROM session implementation used by Noux processes for initial ROMs
* \author Christian Prochaska
* \date 2017-01-31
*
* The initial ROMs (binary and linker) are already attached in a forked
* child and don't need a new ROM dataspace. The invalid dataspace returned
* by this component is handled in 'Child::Process'.
*/
/*
* Copyright (C) 2017 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 _NOUX__EMPTY_ROM_SESSION_COMPONENT_H_
#define _NOUX__EMPTY_ROM_SESSION_COMPONENT_H_
/* Genode includes */
#include <base/rpc_server.h>
namespace Noux { class Empty_rom_session_component; }
class Noux::Empty_rom_session_component : public Rpc_object<Rom_session>
{
private:
Rpc_entrypoint &_ep;
public:
Empty_rom_session_component(Rpc_entrypoint &ep)
: _ep(ep)
{
_ep.manage(this);
}
~Empty_rom_session_component()
{
_ep.dissolve(this);
}
/***************************
** ROM session interface **
***************************/
Rom_dataspace_capability dataspace()
{
return Rom_dataspace_capability();
}
void sigh(Signal_context_capability) { }
};
#endif /* _NOUX__EMPTY_ROM_SESSION_COMPONENT_H_ */

View File

@ -62,16 +62,6 @@ class Noux::Rom_session_component : public Rpc_object<Rom_session>
typedef Child_policy::Name Name;
/**
* Label of ROM session requested for the binary of a forked process
*
* In this case, the loading of the binary must be omitted because the
* address space is replayed by the fork operation. Hence, requests for
* such ROM modules are answered by an invalid dataspace, which is
* handled in 'Child::Process'.
*/
static Name forked_magic_binary_name() { return "(forked)"; }
private:
Allocator &_alloc;
@ -111,9 +101,6 @@ class Noux::Rom_session_component : public Rpc_object<Rom_session>
return _rom_from_vfs->ds;
}
if (name == forked_magic_binary_name())
return Dataspace_capability();
_rom_from_parent.construct(env, name.string());
Dataspace_capability ds = _rom_from_parent->dataspace();
return ds;