mirror of
https://github.com/genodelabs/genode.git
synced 2025-03-02 21:08:47 +00:00
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:
parent
73bfdb8bb8
commit
94bce1425e
@ -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(¬ifier);
|
io->unregister_wake_up_notifier(¬ifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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(); }
|
||||||
|
@ -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),
|
||||||
|
@ -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:
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user