noux: avoid 'no attachment at 0' messages

binary_ds cap is attempted to free up twice by
_root_dir->release(_name, _binary_ds) in ~Child de-constructor and by
Static_dataspace_info _binary_ds_info de-constructor.

This commit keeps all binary related information inside a struct which gets
freed up after all noux session book keep cleaning is done.

Issue #485
This commit is contained in:
Alexander Boettcher 2013-09-17 10:44:33 +02:00 committed by Norman Feske
parent 73bfdb8bb8
commit 94bce1425e
3 changed files with 47 additions and 35 deletions

View File

@ -60,7 +60,6 @@ namespace Noux {
} }
}; };
/** /**
* Return singleton instance of PID allocator * Return singleton instance of PID allocator
*/ */
@ -168,13 +167,29 @@ namespace Noux {
*/ */
Environment _env; Environment _env;
Dir_file_system * const _root_dir;
/** /**
* ELF binary * ELF binary handling
*/ */
struct Elf
{
enum { NAME_MAX_LEN = 128 };
char _name[NAME_MAX_LEN];
Dir_file_system * const _root_dir;
Dataspace_capability const _binary_ds; Dataspace_capability const _binary_ds;
Elf(char const * const binary_name, Dir_file_system * root_dir,
Dataspace_capability binary_ds)
:
_root_dir(root_dir), _binary_ds(binary_ds)
{
strncpy(_name, binary_name, sizeof(_name));
_name[NAME_MAX_LEN - 1] = 0;
}
~Elf() { _root_dir->release(_name, _binary_ds); }
} _elf;
enum { PAGE_SIZE = 4096, PAGE_MASK = ~(PAGE_SIZE - 1) }; enum { PAGE_SIZE = 4096, PAGE_MASK = ~(PAGE_SIZE - 1) };
enum { SYSIO_DS_SIZE = PAGE_MASK & (sizeof(Sysio) + PAGE_SIZE - 1) }; enum { SYSIO_DS_SIZE = PAGE_MASK & (sizeof(Sysio) + PAGE_SIZE - 1) };
@ -235,6 +250,8 @@ namespace Noux {
io->unregister_wake_up_notifier(&notifier); io->unregister_wake_up_notifier(&notifier);
} }
Dir_file_system * const root_dir() { return _elf._root_dir; }
/** /**
* Method for handling noux network related system calls * Method for handling noux network related system calls
*/ */
@ -258,7 +275,7 @@ namespace Noux {
* looked up at the virtual file * looked up at the virtual file
* system * system
*/ */
Child(char const *name, Child(char const *binary_name,
Family_member *parent, Family_member *parent,
int pid, int pid,
Signal_receiver *sig_rec, Signal_receiver *sig_rec,
@ -281,11 +298,10 @@ namespace Noux {
_destruct_context_cap(sig_rec->manage(&_destruct_dispatcher)), _destruct_context_cap(sig_rec->manage(&_destruct_dispatcher)),
_cap_session(cap_session), _cap_session(cap_session),
_entrypoint(cap_session, STACK_SIZE, "noux_process", false), _entrypoint(cap_session, STACK_SIZE, "noux_process", false),
_resources(name, resources_ep, false), _resources(binary_name, resources_ep, false),
_args(ARGS_DS_SIZE, args), _args(ARGS_DS_SIZE, args),
_env(env), _env(env),
_root_dir(root_dir), _elf(binary_name, root_dir, root_dir->dataspace(binary_name)),
_binary_ds(root_dir->dataspace(name)),
_sysio_ds(Genode::env()->ram_session(), SYSIO_DS_SIZE), _sysio_ds(Genode::env()->ram_session(), SYSIO_DS_SIZE),
_sysio(_sysio_ds.local_addr<Sysio>()), _sysio(_sysio_ds.local_addr<Sysio>()),
_noux_session_cap(Session_capability(_entrypoint.manage(this))), _noux_session_cap(Session_capability(_entrypoint.manage(this))),
@ -295,18 +311,18 @@ namespace Noux {
_local_rm_service(_entrypoint, _resources.ds_registry), _local_rm_service(_entrypoint, _resources.ds_registry),
_local_rom_service(_entrypoint, _resources.ds_registry), _local_rom_service(_entrypoint, _resources.ds_registry),
_parent_services(parent_services), _parent_services(parent_services),
_binary_ds_info(_resources.ds_registry, _binary_ds), _binary_ds_info(_resources.ds_registry, _elf._binary_ds),
_sysio_ds_info(_resources.ds_registry, _sysio_ds.cap()), _sysio_ds_info(_resources.ds_registry, _sysio_ds.cap()),
_ldso_ds_info(_resources.ds_registry, ldso_ds_cap()), _ldso_ds_info(_resources.ds_registry, ldso_ds_cap()),
_args_ds_info(_resources.ds_registry, _args.cap()), _args_ds_info(_resources.ds_registry, _args.cap()),
_env_ds_info(_resources.ds_registry, _env.cap()), _env_ds_info(_resources.ds_registry, _env.cap()),
_child_policy(name, _binary_ds, _args.cap(), _env.cap(), _child_policy(_elf._name, _elf._binary_ds, _args.cap(), _env.cap(),
_entrypoint, _local_noux_service, _entrypoint, _local_noux_service,
_local_rm_service, _local_rom_service, _local_rm_service, _local_rom_service,
_parent_services, _parent_services,
*this, *this, _destruct_context_cap, *this, *this, _destruct_context_cap,
_resources.ram, verbose), _resources.ram, verbose),
_child(forked ? Dataspace_capability() : _binary_ds, _child(forked ? Dataspace_capability() : _elf._binary_ds,
_resources.ram.cap(), _resources.cpu.cap(), _resources.ram.cap(), _resources.cpu.cap(),
_resources.rm.cap(), &_entrypoint, &_child_policy, _resources.rm.cap(), &_entrypoint, &_child_policy,
/** /**
@ -317,8 +333,8 @@ namespace Noux {
if (verbose) if (verbose)
_args.dump(); _args.dump();
if (!forked && !_binary_ds.valid()) { if (!forked && !_elf._binary_ds.valid()) {
PERR("Lookup of executable \"%s\" failed", name); PERR("Lookup of executable \"%s\" failed", binary_name);
throw Binary_does_not_exist(); throw Binary_does_not_exist();
} }
} }
@ -328,8 +344,6 @@ namespace Noux {
_sig_rec->dissolve(&_destruct_dispatcher); _sig_rec->dissolve(&_destruct_dispatcher);
_entrypoint.dissolve(this); _entrypoint.dissolve(this);
_root_dir->release(_child_policy.name(), _binary_ds);
} }
void start() { _entrypoint.activate(); } void start() { _entrypoint.activate(); }

View File

@ -30,8 +30,6 @@ namespace Noux {
{ {
private: private:
enum { NAME_MAX_LEN = 128 };
char _name_buf[NAME_MAX_LEN];
char const *_name; char const *_name;
Init::Child_policy_enforce_labeling _labeling_policy; Init::Child_policy_enforce_labeling _labeling_policy;
Init::Child_policy_provide_rom_file _binary_policy; Init::Child_policy_provide_rom_file _binary_policy;
@ -64,7 +62,7 @@ namespace Noux {
Ram_session &ref_ram_session, Ram_session &ref_ram_session,
bool verbose) bool verbose)
: :
_name(strncpy(_name_buf, name, sizeof(_name_buf))), _name(name),
_labeling_policy(_name), _labeling_policy(_name),
_binary_policy("binary", binary_ds, &entrypoint), _binary_policy("binary", binary_ds, &entrypoint),
_args_policy( "args", args_ds, &entrypoint), _args_policy( "args", args_ds, &entrypoint),

View File

@ -175,7 +175,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
case SYSCALL_STAT: case SYSCALL_STAT:
case SYSCALL_LSTAT: /* XXX implement difference between 'lstat' and 'stat' */ case SYSCALL_LSTAT: /* XXX implement difference between 'lstat' and 'stat' */
{ {
bool result = _root_dir->stat(_sysio, _sysio->stat_in.path); bool result = root_dir()->stat(_sysio, _sysio->stat_in.path);
/** /**
* Instead of using the uid/gid given by the actual file system * Instead of using the uid/gid given by the actual file system
@ -207,11 +207,11 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
case SYSCALL_OPEN: case SYSCALL_OPEN:
{ {
Vfs_handle *vfs_handle = _root_dir->open(_sysio, _sysio->open_in.path); Vfs_handle *vfs_handle = root_dir()->open(_sysio, _sysio->open_in.path);
if (!vfs_handle) if (!vfs_handle)
return false; return false;
char const *leaf_path = _root_dir->leaf_path(_sysio->open_in.path); char const *leaf_path = root_dir()->leaf_path(_sysio->open_in.path);
/* /*
* File descriptors of opened directories are handled by * File descriptors of opened directories are handled by
@ -219,12 +219,12 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
* path because path operations always refer to the global * path because path operations always refer to the global
* root. * root.
*/ */
if (vfs_handle->ds() == _root_dir) if (vfs_handle->ds() == root_dir())
leaf_path = _sysio->open_in.path; leaf_path = _sysio->open_in.path;
Shared_pointer<Io_channel> Shared_pointer<Io_channel>
channel(new Vfs_io_channel(_sysio->open_in.path, channel(new Vfs_io_channel(_sysio->open_in.path,
leaf_path, _root_dir, vfs_handle), leaf_path, root_dir(), vfs_handle),
Genode::env()->heap()); Genode::env()->heap());
_sysio->open_out.fd = add_io_channel(channel); _sysio->open_out.fd = add_io_channel(channel);
@ -257,7 +257,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
* does not exist. * does not exist.
*/ */
Dataspace_capability binary_ds = Dataspace_capability binary_ds =
_root_dir->dataspace(_sysio->execve_in.filename); root_dir()->dataspace(_sysio->execve_in.filename);
if (!binary_ds.valid()) { if (!binary_ds.valid()) {
_sysio->error.execve = Sysio::EXECVE_NONEXISTENT; _sysio->error.execve = Sysio::EXECVE_NONEXISTENT;
@ -268,23 +268,23 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
child_env(_sysio->execve_in.filename, binary_ds, child_env(_sysio->execve_in.filename, binary_ds,
_sysio->execve_in.args, _sysio->execve_in.env); _sysio->execve_in.args, _sysio->execve_in.env);
_root_dir->release(_sysio->execve_in.filename, binary_ds); root_dir()->release(_sysio->execve_in.filename, binary_ds);
binary_ds = _root_dir->dataspace(child_env.binary_name()); binary_ds = root_dir()->dataspace(child_env.binary_name());
if (!binary_ds.valid()) { if (!binary_ds.valid()) {
_sysio->error.execve = Sysio::EXECVE_NONEXISTENT; _sysio->error.execve = Sysio::EXECVE_NONEXISTENT;
return false; return false;
} }
_root_dir->release(child_env.binary_name(), binary_ds); root_dir()->release(child_env.binary_name(), binary_ds);
try { try {
Child *child = new Child(child_env.binary_name(), Child *child = new Child(child_env.binary_name(),
parent(), parent(),
pid(), pid(),
_sig_rec, _sig_rec,
_root_dir, root_dir(),
child_env.args(), child_env.args(),
child_env.env(), child_env.env(),
_cap_session, _cap_session,
@ -501,7 +501,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
this, this,
new_pid, new_pid,
_sig_rec, _sig_rec,
_root_dir, root_dir(),
_args, _args,
_env.env(), _env.env(),
_cap_session, _cap_session,
@ -584,25 +584,25 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
case SYSCALL_UNLINK: case SYSCALL_UNLINK:
return _root_dir->unlink(_sysio, _sysio->unlink_in.path); return root_dir()->unlink(_sysio, _sysio->unlink_in.path);
case SYSCALL_READLINK: case SYSCALL_READLINK:
return _root_dir->readlink(_sysio, _sysio->readlink_in.path); return root_dir()->readlink(_sysio, _sysio->readlink_in.path);
case SYSCALL_RENAME: case SYSCALL_RENAME:
return _root_dir->rename(_sysio, _sysio->rename_in.from_path, return root_dir()->rename(_sysio, _sysio->rename_in.from_path,
_sysio->rename_in.to_path); _sysio->rename_in.to_path);
case SYSCALL_MKDIR: case SYSCALL_MKDIR:
return _root_dir->mkdir(_sysio, _sysio->mkdir_in.path); return root_dir()->mkdir(_sysio, _sysio->mkdir_in.path);
case SYSCALL_SYMLINK: case SYSCALL_SYMLINK:
return _root_dir->symlink(_sysio, _sysio->symlink_in.newpath); return root_dir()->symlink(_sysio, _sysio->symlink_in.newpath);
case SYSCALL_USERINFO: case SYSCALL_USERINFO:
{ {