diff --git a/ports/src/lib/libc_noux/plugin.cc b/ports/src/lib/libc_noux/plugin.cc index 5d109a7446..e3bc250ba8 100644 --- a/ports/src/lib/libc_noux/plugin.cc +++ b/ports/src/lib/libc_noux/plugin.cc @@ -38,6 +38,9 @@ #include +enum { verbose = false }; + + void *operator new (size_t, void *ptr) { return ptr; } @@ -166,13 +169,15 @@ static bool serialize_string_array(char const * const * array, char *dst, Genode extern "C" int execve(const char *filename, char *const argv[], char *const envp[]) { - PDBG("filename=%s", filename); + if (verbose) { + PDBG("filename=%s", filename); - for (int i = 0; argv[i]; i++) - PDBG("argv[%d]='%s'", i, argv[i]); + for (int i = 0; argv[i]; i++) + PDBG("argv[%d]='%s'", i, argv[i]); - for (int i = 0; envp[i]; i++) - PDBG("envp[%d]='%s'", i, envp[i]); + for (int i = 0; envp[i]; i++) + PDBG("envp[%d]='%s'", i, envp[i]); + } Genode::strncpy(sysio()->execve_in.filename, filename, sizeof(sysio()->execve_in.filename)); if (!serialize_string_array(argv, sysio()->execve_in.args, @@ -420,6 +425,33 @@ extern "C" int gettimeofday(struct timeval *tv, struct timezone *tz) } +/********************* + ** Signal handling ** + *********************/ + +extern "C" int sigprocmask(int how, const sigset_t *set, sigset_t *oldset) +{ + /* XXX todo */ + errno = ENOSYS; + return -1; +} + + +extern "C" int _sigprocmask(int how, const sigset_t *set, sigset_t *oldset) +{ + return sigprocmask(how, set, oldset); +} + + +extern "C" int sigaction(int signum, const struct sigaction *act, + struct sigaction *oldact) +{ + /* XXX todo */ + errno = ENOSYS; + return -1; +} + + /********************* ** File operations ** *********************/ diff --git a/ports/src/noux/child.h b/ports/src/noux/child.h index fff915994b..4b92cb9814 100644 --- a/ports/src/noux/child.h +++ b/ports/src/noux/child.h @@ -15,7 +15,6 @@ #define _NOUX__CHILD_H_ /* Genode includes */ -#include #include #include #include @@ -28,10 +27,9 @@ #include #include #include -#include #include #include - +#include namespace Noux { @@ -118,99 +116,9 @@ namespace Noux { }; - class Family_member : public List::Element - { - private: - - int const _pid; - Lock _lock; - List _list; - Family_member * const _parent; - bool _has_exited; - int _exit_status; - Semaphore _wait4_blocker; - - void _wakeup_wait4() - { - _wait4_blocker.up(); - } - - public: - - Family_member(int pid, Family_member *parent) - : _pid(pid), _parent(parent), _has_exited(false), _exit_status(0) - { } - - virtual ~Family_member() { } - - int pid() const { return _pid; } - - Family_member *parent() { return _parent; } - - int exit_status() const { return _exit_status; } - - /** - * Called by the parent at creation time of the process - */ - void insert(Family_member *member) - { - Lock::Guard guard(_lock); - _list.insert(member); - } - - /** - * Called by the parent from the return path of the wait4 syscall - */ - void remove(Family_member *member) - { - Lock::Guard guard(_lock); - _list.remove(member); - } - - /** - * Tell the parent that we exited - */ - void wakeup_parent(int exit_status) - { - _exit_status = exit_status; - _has_exited = true; - if (_parent) - _parent->_wakeup_wait4(); - } - - Family_member *poll4() - { - Lock::Guard guard(_lock); - - /* check if any of our children has exited */ - Family_member *curr = _list.first(); - for (; curr; curr = curr->next()) { - if (curr->_has_exited) - return curr; - } - return 0; - } - - /** - * Wait for the exit of any of our children - */ - Family_member *wait4() - { - for (;;) { - Family_member *result = poll4(); - if (result) - return result; - - _wait4_blocker.down(); - } - } - }; - - - class Child : private Child_policy, - public Rpc_object, - public File_descriptor_registry, - public Family_member + class Child : public Rpc_object, + public File_descriptor_registry, + public Family_member { private: @@ -221,9 +129,6 @@ namespace Noux { */ Semaphore _blocker; - enum { MAX_NAME_LEN = 64 }; - char _name[MAX_NAME_LEN]; - Child_exit_dispatcher _exit_dispatcher; Signal_context_capability _exit_context_cap; @@ -244,12 +149,12 @@ namespace Noux { * Entrypoint used to serve the RPC interfaces of the * locally-provided services */ - Rpc_entrypoint &ep; + Rpc_entrypoint &ep; /** * Registry of dataspaces owned by the Noux process */ - Dataspace_registry ds_registry; + Dataspace_registry ds_registry; /** * Locally-provided services for accessing platform resources @@ -293,15 +198,6 @@ namespace Noux { */ Dataspace_capability const _binary_ds; - Genode::Child _child; - - Service_registry * const _parent_services; - - Init::Child_policy_enforce_labeling _labeling_policy; - Init::Child_policy_provide_rom_file _binary_policy; - Init::Child_policy_provide_rom_file _args_policy; - Init::Child_policy_provide_rom_file _env_policy; - enum { PAGE_SIZE = 4096, PAGE_MASK = ~(PAGE_SIZE - 1) }; enum { SYSIO_DS_SIZE = PAGE_MASK & (sizeof(Sysio) + PAGE_SIZE - 1) }; @@ -310,25 +206,12 @@ namespace Noux { Session_capability const _noux_session_cap; - struct Local_noux_service : public Service - { - Genode::Session_capability _cap; + Local_noux_service _local_noux_service; + Local_rm_service _local_rm_service; + Service_registry &_parent_services; - /** - * Constructor - * - * \param cap capability to return on session requests - */ - Local_noux_service(Genode::Session_capability cap) - : Service(service_name()), _cap(cap) { } - - Genode::Session_capability session(const char *args) { return _cap; } - void upgrade(Genode::Session_capability, const char *args) { } - void close(Genode::Session_capability) { } - - } _local_noux_service; - - Local_rm_service _local_rm_service; + Child_policy _child_policy; + Genode::Child _child; /** * Exception type for failed file-descriptor lookup @@ -375,7 +258,7 @@ namespace Noux { Args const &args, char const *env, Cap_session *cap_session, - Service_registry *parent_services, + Service_registry &parent_services, Rpc_entrypoint &resources_ep, bool forked) : @@ -393,33 +276,30 @@ namespace Noux { _vfs(vfs), _binary_ds(forked ? Dataspace_capability() : vfs->dataspace_from_file(name)), - _child(_binary_ds, _resources.ram.cap(), _resources.cpu.cap(), - _resources.rm.cap(), &_entrypoint, this), - _parent_services(parent_services), - _labeling_policy(_name), - _binary_policy("binary", _binary_ds, &_entrypoint), - _args_policy( "args", _args.cap(), &_entrypoint), - _env_policy( "env", _env.cap(), &_entrypoint), _sysio_ds(Genode::env()->ram_session(), SYSIO_DS_SIZE), _sysio(_sysio_ds.local_addr()), _noux_session_cap(Session_capability(_entrypoint.manage(this))), _local_noux_service(_noux_session_cap), - _local_rm_service(_entrypoint, _resources.ds_registry) + _local_rm_service(_entrypoint, _resources.ds_registry), + _parent_services(parent_services), + _child_policy(name, _binary_ds, _args.cap(), _env.cap(), + _entrypoint, _local_noux_service, + _local_rm_service, _parent_services, + *this, _exit_context_cap, _resources.ram), + _child(_binary_ds, _resources.ram.cap(), _resources.cpu.cap(), + _resources.rm.cap(), &_entrypoint, &_child_policy) { _args.dump(); - strncpy(_name, name, sizeof(_name)); } ~Child() { - PDBG("Destructing child %p", this); - _sig_rec->dissolve(&_execve_cleanup_dispatcher); _sig_rec->dissolve(&_exit_dispatcher); - /* XXX _binary_ds */ - _entrypoint.dissolve(this); + + _vfs->release_dataspace_for_file(_child_policy.name(), _binary_ds); } void start() { _entrypoint.activate(); } @@ -439,61 +319,6 @@ namespace Noux { Dataspace_registry &ds_registry() { return _resources.ds_registry; } - /**************************** - ** Child_policy interface ** - ****************************/ - - const char *name() const { return _name; } - - Service *resolve_session_request(const char *service_name, - const char *args) - { - Service *service = 0; - - /* check for local ROM file requests */ - if ((service = _args_policy.resolve_session_request(service_name, args)) - || (service = _env_policy.resolve_session_request(service_name, args)) - || (service = _binary_policy.resolve_session_request(service_name, args))) - return service; - - /* check for locally implemented noux service */ - if (strcmp(service_name, Session::service_name()) == 0) - return &_local_noux_service; - - /* - * Check for the creation of an RM session, which is used by - * the dynamic linker to manually manage a part of the address - * space. - */ - if (strcmp(service_name, Rm_session::service_name()) == 0) - return &_local_rm_service; - - return _parent_services->find(service_name); - } - - void filter_session_args(const char *service, - char *args, size_t args_len) - { - _labeling_policy.filter_session_args(service, args, args_len); - } - - void exit(int exit_value) - { - PINF("child %s exited with exit value %d", _name, exit_value); - - wakeup_parent(exit_value); - - /* handle exit of the init process */ - if (parent() == 0) - Signal_transmitter(_exit_context_cap).submit(); - } - - Ram_session *ref_ram_session() - { - return &_resources.ram; - } - - /**************************** ** Noux session interface ** ****************************/ diff --git a/ports/src/noux/child_policy.h b/ports/src/noux/child_policy.h new file mode 100644 index 0000000000..4511673e13 --- /dev/null +++ b/ports/src/noux/child_policy.h @@ -0,0 +1,125 @@ +/* + * \brief Noux child policy + * \author Norman Feske + * \date 2012-02-25 + */ + +/* + * Copyright (C) 2012 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__CHILD_POLICY_H_ +#define _NOUX__CHILD_POLICY_H_ + +/* Genode includes */ +#include + +/* Noux includes */ +#include +#include +#include + +namespace Noux { + + class Child_policy : public Genode::Child_policy + { + private: + + enum { NAME_MAX_LEN = 128 }; + char _name_buf[NAME_MAX_LEN]; + char const *_name; + Init::Child_policy_enforce_labeling _labeling_policy; + Init::Child_policy_provide_rom_file _binary_policy; + Init::Child_policy_provide_rom_file _args_policy; + Init::Child_policy_provide_rom_file _env_policy; + Local_noux_service &_local_noux_service; + Local_rm_service &_local_rm_service; + Service_registry &_parent_services; + Family_member &_family_member; + Signal_context_capability _exit_context_cap; + Ram_session &_ref_ram_session; + + public: + + Child_policy(char const *name, + Dataspace_capability binary_ds, + Dataspace_capability args_ds, + Dataspace_capability env_ds, + Rpc_entrypoint &entrypoint, + Local_noux_service &local_noux_service, + Local_rm_service &local_rm_service, + Service_registry &parent_services, + Family_member &family_member, + Signal_context_capability exit_context_cap, + Ram_session &ref_ram_session) + : + _name(strncpy(_name_buf, name, sizeof(_name_buf))), + _labeling_policy(_name), + _binary_policy("binary", binary_ds, &entrypoint), + _args_policy( "args", args_ds, &entrypoint), + _env_policy( "env", env_ds, &entrypoint), + _local_noux_service(local_noux_service), + _local_rm_service(local_rm_service), + _parent_services(parent_services), + _family_member(family_member), + _exit_context_cap(exit_context_cap), + _ref_ram_session(ref_ram_session) + { } + + const char *name() const { return _name; } + + Service *resolve_session_request(const char *service_name, + const char *args) + { + Service *service = 0; + + /* check for local ROM file requests */ + if ((service = _args_policy.resolve_session_request(service_name, args)) + || (service = _env_policy.resolve_session_request(service_name, args)) + || (service = _binary_policy.resolve_session_request(service_name, args))) + return service; + + /* check for locally implemented noux service */ + if (strcmp(service_name, Session::service_name()) == 0) + return &_local_noux_service; + + /* + * Check for the creation of an RM session, which is used by + * the dynamic linker to manually manage a part of the address + * space. + */ + if (strcmp(service_name, Rm_session::service_name()) == 0) + return &_local_rm_service; + + return _parent_services.find(service_name); + } + + void filter_session_args(const char *service, + char *args, size_t args_len) + { + _labeling_policy.filter_session_args(service, args, args_len); + } + + void exit(int exit_value) + { + PINF("child %s exited with exit value %d", _name, exit_value); + + _family_member.wakeup_parent(exit_value); + + /* handle exit of the init process */ + if (_family_member.parent() == 0) + Signal_transmitter(_exit_context_cap).submit(); + } + + Ram_session *ref_ram_session() + { + return &_ref_ram_session; + } + }; +} + +#endif /* _NOUX__CHILD_POLICY_H_ */ + diff --git a/ports/src/noux/dataspace_registry.h b/ports/src/noux/dataspace_registry.h index 896c3e6bff..ad5e9df570 100644 --- a/ports/src/noux/dataspace_registry.h +++ b/ports/src/noux/dataspace_registry.h @@ -15,20 +15,12 @@ #define _NOUX__DATASPACE_REGISTRY_H_ /* Genode includes */ -#include +#include namespace Noux { using namespace Genode; - /* - * XXX not used yet - */ - struct Dataspace_destroyer - { - virtual void destroy(Dataspace_capability) = 0; - }; - class Dataspace_registry; @@ -39,19 +31,18 @@ namespace Noux { size_t _size; Dataspace_capability _ds_cap; - Dataspace_destroyer &_destroyer; public: - Dataspace_info(Dataspace_capability ds_cap, - Dataspace_destroyer &destroyer) + Dataspace_info(Dataspace_capability ds_cap) : Object_pool::Entry(ds_cap), _size(Dataspace_client(ds_cap).size()), - _ds_cap(ds_cap), - _destroyer(destroyer) + _ds_cap(ds_cap) { } + virtual ~Dataspace_info() { } + size_t size() const { return _size; } Dataspace_capability ds_cap() const { return _ds_cap; } @@ -67,7 +58,6 @@ namespace Noux { * \return capability for the new dataspace */ virtual Dataspace_capability fork(Ram_session_capability ram, - Dataspace_destroyer &destroyer, Dataspace_registry &ds_registry, Rpc_entrypoint &ep) = 0; @@ -79,8 +69,6 @@ namespace Noux { * \param len length of source buffer in bytes */ virtual void poke(addr_t dst_offset, void const *src, size_t len) = 0; - - Dataspace_destroyer &destroyer() { return _destroyer; } }; @@ -92,6 +80,26 @@ namespace Noux { public: + ~Dataspace_registry() + { + /* + * At the time the destructor is called, most 'Dataspace_info' + * objects are expected to be gone already because + * 'Child::_resources' and 'Child::_child' are destructed + * before the 'Child::_ds_registry'. However, RM dataspaces + * created via 'Rm_dataspace_info::fork', are not handled by + * those destructors. So we have to clean them up here. + */ + for (;;) { + Dataspace_info *info = _pool.first(); + if (!info) + return; + + _pool.remove(info); + destroy(Genode::env()->heap(), info); + } + } + void insert(Dataspace_info *info) { _pool.insert(info); diff --git a/ports/src/noux/directory_service.h b/ports/src/noux/directory_service.h index e0ec75f0a4..310318cb3d 100644 --- a/ports/src/noux/directory_service.h +++ b/ports/src/noux/directory_service.h @@ -30,6 +30,7 @@ namespace Noux { struct Directory_service { virtual Genode::Dataspace_capability dataspace(char const *path) = 0; + virtual void release(Genode::Dataspace_capability) = 0; virtual Vfs_handle *open(Sysio *sysio, char const *path) = 0; diff --git a/ports/src/noux/family_member.h b/ports/src/noux/family_member.h new file mode 100644 index 0000000000..bf12b8afa3 --- /dev/null +++ b/ports/src/noux/family_member.h @@ -0,0 +1,109 @@ +/* + * \brief Helper for handling the relationship between Noux processes + * \author Norman Feske + * \date 2012-02-25 + */ + +/* + * Copyright (C) 2012 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__FAMILY_MEMBER_H_ +#define _NOUX__FAMILY_MEMBER_H_ + +/* Genode includes */ +#include +#include + +namespace Noux { + + class Family_member : public List::Element + { + private: + + int const _pid; + Lock _lock; + List _list; + Family_member * const _parent; + bool _has_exited; + int _exit_status; + Semaphore _wait4_blocker; + + void _wakeup_wait4() { _wait4_blocker.up(); } + + public: + + Family_member(int pid, Family_member *parent) + : _pid(pid), _parent(parent), _has_exited(false), _exit_status(0) + { } + + virtual ~Family_member() { } + + int pid() const { return _pid; } + + Family_member *parent() { return _parent; } + + int exit_status() const { return _exit_status; } + + /** + * Called by the parent at creation time of the process + */ + void insert(Family_member *member) + { + Lock::Guard guard(_lock); + _list.insert(member); + } + + /** + * Called by the parent from the return path of the wait4 syscall + */ + void remove(Family_member *member) + { + Lock::Guard guard(_lock); + _list.remove(member); + } + + /** + * Tell the parent that we exited + */ + void wakeup_parent(int exit_status) + { + _exit_status = exit_status; + _has_exited = true; + if (_parent) + _parent->_wakeup_wait4(); + } + + Family_member *poll4() + { + Lock::Guard guard(_lock); + + /* check if any of our children has exited */ + Family_member *curr = _list.first(); + for (; curr; curr = curr->next()) { + if (curr->_has_exited) + return curr; + } + return 0; + } + + /** + * Wait for the exit of any of our children + */ + Family_member *wait4() + { + for (;;) { + Family_member *result = poll4(); + if (result) + return result; + + _wait4_blocker.down(); + } + } + }; +} + +#endif /* _NOUX__FAMILY_MEMBER_H_ */ diff --git a/ports/src/noux/local_noux_service.h b/ports/src/noux/local_noux_service.h new file mode 100644 index 0000000000..dc109d3c8e --- /dev/null +++ b/ports/src/noux/local_noux_service.h @@ -0,0 +1,42 @@ +/* + * \brief Locally-provided Noux service + * \author Norman Feske + * \date 2011-02-17 + */ + +/* + * Copyright (C) 2012 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__LOCAL_NOUX_SERVICE_H_ +#define _NOUX__LOCAL_NOUX_SERVICE_H_ + +/* Genode includes */ +#include + +namespace Noux { + + using namespace Genode; + + struct Local_noux_service : public Service + { + Genode::Session_capability _cap; + + /** + * Constructor + * + * \param cap capability to return on session requests + */ + Local_noux_service(Genode::Session_capability cap) + : Service(Session::service_name()), _cap(cap) { } + + Genode::Session_capability session(const char *args) { return _cap; } + void upgrade(Genode::Session_capability, const char *args) { } + void close(Genode::Session_capability) { } + }; +} + +#endif /* _NOUX__LOCAL_NOUX_SERVICE_H_ */ diff --git a/ports/src/noux/local_rm_service.h b/ports/src/noux/local_rm_service.h index 997bf806e9..bd814cd128 100644 --- a/ports/src/noux/local_rm_service.h +++ b/ports/src/noux/local_rm_service.h @@ -30,38 +30,52 @@ namespace Noux { { private: - struct Dummy_destroyer : Dataspace_destroyer - { - void destroy(Dataspace_capability) { } - } _dummy_destroyer; - - Rm_session_component &_sub_rm; + Rm_session_component * const _sub_rm; + Rpc_entrypoint &_ep; + Rm_session_capability _rm_cap; public: - Rm_dataspace_info(Rm_session_component &sub_rm) + /** + * Constructor + * + * \param sub_rm pointer to 'Rm_session_component' that belongs + * to the 'Rm_dataspace_info' object + * \param ep entrypoint to manage the 'Rm_session_component' + * + * The ownership of the pointed-to object gets transferred to the + * 'Rm_dataspace_info' object. I.e., 'sub_rm' will get destructed + * on the destruction of its corresponding 'Rm_dataspace_info' + * object. Also, 'Rm_dataspace_info' takes care of associating + * 'sub_rm' with 'ep'. + */ + Rm_dataspace_info(Rm_session_component *sub_rm, + Rpc_entrypoint &ep) : - Dataspace_info(sub_rm.dataspace(), _dummy_destroyer), - _sub_rm(sub_rm) + Dataspace_info(sub_rm->dataspace()), + _sub_rm(sub_rm), _ep(ep), _rm_cap(_ep.manage(_sub_rm)) { } + ~Rm_dataspace_info() + { + _ep.dissolve(_sub_rm); + destroy(Genode::env()->heap(), _sub_rm); + } + + Rm_session_capability rm_cap() { return _rm_cap; } + Dataspace_capability fork(Ram_session_capability ram, - Dataspace_destroyer &, Dataspace_registry &ds_registry, Rpc_entrypoint &ep) { Rm_session_component *new_sub_rm = new Rm_session_component(ds_registry, 0, size()); - Rm_session_capability rm_cap = ep.manage(new_sub_rm); + Rm_dataspace_info *rm_info = new Rm_dataspace_info(new_sub_rm, ep); - /* - * XXX Where to dissolve the RM session? - */ + _sub_rm->replay(ram, rm_info->rm_cap(), ds_registry, ep); - _sub_rm.replay(ram, rm_cap, ds_registry, ep); - - ds_registry.insert(new Rm_dataspace_info(*new_sub_rm)); + ds_registry.insert(rm_info); return new_sub_rm->dataspace(); } @@ -72,7 +86,7 @@ namespace Noux { PERR("illegal attemt to write beyond RM boundary"); return; } - _sub_rm.poke(dst_offset, src, len); + _sub_rm->poke(dst_offset, src, len); } }; @@ -100,18 +114,34 @@ namespace Noux { Rm_session_component *rm = new Rm_session_component(_ds_registry, start, size); - Genode::Session_capability cap = _ep.manage(rm); - - _ds_registry.insert(new Rm_dataspace_info(*rm)); - - return cap; + Rm_dataspace_info *info = new Rm_dataspace_info(rm, _ep); + _ds_registry.insert(info); + return info->rm_cap(); } void upgrade(Genode::Session_capability, const char *args) { } - void close(Genode::Session_capability) + void close(Genode::Session_capability session) { - PWRN("Local_rm_service::close not implemented, leaking memory"); + Rm_session_component *rm_session = + dynamic_cast(_ep.obj_by_cap(session)); + + if (!rm_session) { + PWRN("Unexpected call of close with non-RM-session argument"); + return; + } + + /* use RM dataspace as key to obtain the dataspace info object */ + Dataspace_capability ds_cap = rm_session->dataspace(); + + /* release dataspace info */ + Dataspace_info *info = _ds_registry.lookup_info(ds_cap); + if (info) { + _ds_registry.remove(info); + destroy(Genode::env()->heap(), info); + } else { + PWRN("Could not lookup dataspace info for local RM session"); + } } }; } diff --git a/ports/src/noux/main.cc b/ports/src/noux/main.cc index e498d8d105..bfdc7ed428 100644 --- a/ports/src/noux/main.cc +++ b/ports/src/noux/main.cc @@ -176,6 +176,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) _assign_io_channels_to(child); /* signal main thread to remove ourself */ + PINF("submit signal to _execve_cleanup_context_cap"); Genode::Signal_transmitter(_execve_cleanup_context_cap).submit(); /* start executing the new process */ @@ -294,7 +295,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) * unique name that includes the PID instead of just * reusing the name of the parent. */ - Child *child = new Child(name(), + Child *child = new Child(_child_policy.name(), this, new_pid, _sig_rec, @@ -342,6 +343,11 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) /* destroy 'Noux::Child' */ destroy(Genode::env()->heap(), exited); + + PINF("quota: avail=%zd, used=%zd", + Genode::env()->ram_session()->avail(), + Genode::env()->ram_session()->used()); + } else { _sysio->wait4_out.pid = 0; _sysio->wait4_out.status = 0; @@ -519,7 +525,7 @@ int main(int argc, char **argv) args_of_init_process(), env_string_of_init_process(), &cap, - &parent_services, + parent_services, resources_ep, false); diff --git a/ports/src/noux/ram_session_component.h b/ports/src/noux/ram_session_component.h index 0c546497a1..ba892303e5 100644 --- a/ports/src/noux/ram_session_component.h +++ b/ports/src/noux/ram_session_component.h @@ -24,7 +24,7 @@ #define _NOUX__RAM_SESSION_COMPONENT_H_ /* Genode includes */ -#include +#include #include #include @@ -38,12 +38,10 @@ namespace Noux { struct Ram_dataspace_info : Dataspace_info, List::Element { - Ram_dataspace_info(Ram_dataspace_capability ds_cap, - Dataspace_destroyer &destroyer) - : Dataspace_info(ds_cap, destroyer) { } + Ram_dataspace_info(Ram_dataspace_capability ds_cap) + : Dataspace_info(ds_cap) { } Dataspace_capability fork(Ram_session_capability ram, - Dataspace_destroyer &destroyer, Dataspace_registry &, Rpc_entrypoint &) { @@ -101,8 +99,7 @@ namespace Noux { }; - class Ram_session_component : public Rpc_object, - public Dataspace_destroyer + class Ram_session_component : public Rpc_object { private: @@ -136,19 +133,6 @@ namespace Noux { } - /*********************************** - ** Dataspace_destroyer interface ** - ***********************************/ - - /* - * XXX not used yet - */ - void destroy(Dataspace_capability ds) - { - free(static_cap_cast(ds)); - } - - /*************************** ** Ram_session interface ** ***************************/ @@ -158,7 +142,7 @@ namespace Noux { Ram_dataspace_capability ds_cap = env()->ram_session()->alloc(size); Ram_dataspace_info *ds_info = new (env()->heap()) - Ram_dataspace_info(ds_cap, *this); + Ram_dataspace_info(ds_cap); _used_quota += ds_info->size(); diff --git a/ports/src/noux/rm_session_component.h b/ports/src/noux/rm_session_component.h index fe19cfefa3..9e02b2af80 100644 --- a/ports/src/noux/rm_session_component.h +++ b/ports/src/noux/rm_session_component.h @@ -105,16 +105,6 @@ namespace Noux { Dataspace_registry &ds_registry, Rpc_entrypoint &ep) { - /* - * XXX remove this - */ - struct Dummy_destroyer : Dataspace_destroyer - { - void destroy(Dataspace_capability) { } - }; - - static Dummy_destroyer dummy_destroyer; - for (Region *curr = _regions.first(); curr; curr = curr->next()) { Dataspace_capability ds; @@ -123,11 +113,7 @@ namespace Noux { if (info) { - /* - * XXX Using 'this' as destroyer may be false, the - * destroyer should better correspond to dst_ram. - */ - ds = info->fork(dst_ram, dummy_destroyer, ds_registry, ep); + ds = info->fork(dst_ram, ds_registry, ep); /* * XXX We could detect dataspaces that are attached @@ -148,7 +134,6 @@ namespace Noux { * like to detect unexpected dataspaces. */ ds = curr->ds; - PWRN("replay: unknown dataspace type, assume ROM"); } if (!ds.valid()) { diff --git a/ports/src/noux/tar_file_system.h b/ports/src/noux/tar_file_system.h index 511b0dfb0c..be80738275 100644 --- a/ports/src/noux/tar_file_system.h +++ b/ports/src/noux/tar_file_system.h @@ -274,19 +274,25 @@ namespace Noux { } try { - Attached_ram_dataspace *ds = new (env()->heap()) - Attached_ram_dataspace(env()->ram_session(), record->size()); + Ram_dataspace_capability ds_cap = + env()->ram_session()->alloc(record->size()); - PDBG("copying %s (%zd bytes) into new dataspace", path, record->size()); + void *local_addr = env()->rm_session()->attach(ds_cap); + memcpy(local_addr, record->data(), record->size()); + env()->rm_session()->detach(local_addr); - memcpy(ds->local_addr(), record->data(), record->size()); - return ds->cap(); + return ds_cap; } catch (...) { PDBG("Could not create new dataspace"); } return Dataspace_capability(); } + void release(Genode::Dataspace_capability ds_cap) + { + env()->ram_session()->free(static_cap_cast(ds_cap)); + } + bool stat(Sysio *sysio, char const *path) { Lookup_exact lookup_criterion(path); diff --git a/ports/src/noux/vfs.h b/ports/src/noux/vfs.h index 2bdfa77854..e722b4ab93 100644 --- a/ports/src/noux/vfs.h +++ b/ports/src/noux/vfs.h @@ -46,6 +46,16 @@ namespace Noux { return Genode::Dataspace_capability(); } + void release_dataspace_for_file(char const *filename, + Genode::Dataspace_capability ds_cap) + { + for (File_system *fs = _file_systems.first(); fs; fs = fs->next()) { + char const *fs_local_path = fs->local_path(filename); + if (fs_local_path) + fs->release(ds_cap); + } + } + void add_file_system(File_system *file_system) { _file_systems.insert(file_system); diff --git a/ports/src/noux/vfs_handle.h b/ports/src/noux/vfs_handle.h index 30dec802f4..78e5ceb631 100644 --- a/ports/src/noux/vfs_handle.h +++ b/ports/src/noux/vfs_handle.h @@ -51,6 +51,8 @@ namespace Noux { return Genode::Dataspace_capability(); } + void release(Genode::Dataspace_capability) { } + bool stat(Sysio *, char const *) { return _msg("stat"); } Vfs_handle *open(Sysio *, char const *) { _msg("open"); return 0; } void close(Vfs_handle *) { _msg("close"); }