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

View File

@ -30,8 +30,6 @@ namespace Noux {
{
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;
@ -64,7 +62,7 @@ namespace Noux {
Ram_session &ref_ram_session,
bool verbose)
:
_name(strncpy(_name_buf, name, sizeof(_name_buf))),
_name(name),
_labeling_policy(_name),
_binary_policy("binary", binary_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_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
@ -207,11 +207,11 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
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)
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
@ -219,12 +219,12 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
* path because path operations always refer to the global
* root.
*/
if (vfs_handle->ds() == _root_dir)
if (vfs_handle->ds() == root_dir())
leaf_path = _sysio->open_in.path;
Shared_pointer<Io_channel>
channel(new Vfs_io_channel(_sysio->open_in.path,
leaf_path, _root_dir, vfs_handle),
leaf_path, root_dir(), vfs_handle),
Genode::env()->heap());
_sysio->open_out.fd = add_io_channel(channel);
@ -257,7 +257,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
* does not exist.
*/
Dataspace_capability binary_ds =
_root_dir->dataspace(_sysio->execve_in.filename);
root_dir()->dataspace(_sysio->execve_in.filename);
if (!binary_ds.valid()) {
_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,
_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()) {
_sysio->error.execve = Sysio::EXECVE_NONEXISTENT;
return false;
}
_root_dir->release(child_env.binary_name(), binary_ds);
root_dir()->release(child_env.binary_name(), binary_ds);
try {
Child *child = new Child(child_env.binary_name(),
parent(),
pid(),
_sig_rec,
_root_dir,
root_dir(),
child_env.args(),
child_env.env(),
_cap_session,
@ -501,7 +501,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
this,
new_pid,
_sig_rec,
_root_dir,
root_dir(),
_args,
_env.env(),
_cap_session,
@ -584,25 +584,25 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
case SYSCALL_UNLINK:
return _root_dir->unlink(_sysio, _sysio->unlink_in.path);
return root_dir()->unlink(_sysio, _sysio->unlink_in.path);
case SYSCALL_READLINK:
return _root_dir->readlink(_sysio, _sysio->readlink_in.path);
return root_dir()->readlink(_sysio, _sysio->readlink_in.path);
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);
case SYSCALL_MKDIR:
return _root_dir->mkdir(_sysio, _sysio->mkdir_in.path);
return root_dir()->mkdir(_sysio, _sysio->mkdir_in.path);
case SYSCALL_SYMLINK:
return _root_dir->symlink(_sysio, _sysio->symlink_in.newpath);
return root_dir()->symlink(_sysio, _sysio->symlink_in.newpath);
case SYSCALL_USERINFO:
{