Hello,
I was reading the codes about capabilities, and I found this, which is suspected as a conflict in my understanding.
1) In Cap_index class, we have an id, which is commented as global capability id:
class Cap_index { ...blah uint16_t _id; /* global capability id */ ...blah };
2) But in Native_capability class, there is something like this:
class Native_capability { ...blah int local_name() const { return _idx ? _idx->id() : 0;} ...blah };
here, the id of Cap_index (i.e., commented as global capability id) is returned as local_name. I think it is a conflict or do I miss something? Please enlighten me about this.
Best, Jaeyong
Hi Jaeyong,
Am 09.11.2012 03:46, schrieb jaeyong yoo:
Hello,
I was reading the codes about capabilities, and I found this, which is suspected as a conflict in my understanding.
- In Cap_index class, we have an id, which is commented as global
capability id:
class Cap_index { ...blah uint16_t _id; /* global capability id */ ...blah };
But in Native_capability class, there is something like this:
class Native_capability { ...blah int local_name() const { return _idx ? _idx->id() : 0;} ...blah };
here, the id of Cap_index (i.e., commented as global capability id) is returned as local_name. I think it is a conflict or do I miss something? Please enlighten me about this.
I have to go back a bit further to explain this.
In capability based systems, global names don't exist any more. Every protection domain has its own names for objects. Therefore, the generic interface of a "Native_capability" in Genode contains the "local_name()" accessor.
But, most kernels don't implement capability mechanisms at all, or insufficiently for our framework's needs. Although Fiasco.OC implements a capability mechanism, it's missing an important feature: Every protection domain has to manage its capability name space by itself. When a thread wants to receive capabilities, it has to allocate free slots in the capability space of its protection domain beforehand. Before issuing a receive syscall, it prepares a message descriptor for the kernel that contains the previously allocated capability slots. Now, if the thread receives capabilities via IPC, they should end up in the allocated slots. But, there is no manageable way to identify capability duplicates received via IPC. Using the kernel primitives only, we cannot detect, whether a received capability references an object that is already referenced by a previously existent capability in the same protection domain.
But, the facility to detect capability duplicates is crucial for us. For example, capability slots are rapidly exhausted when using signals in Genode. Have a look at issue #112 in our issue tracker:
https://github.com/genodelabs/genode/issues/112
Even more important, in some cases where capabilities are used as arguments in an RPC, they are used to retrieve objects on the server side. An important example can be found in the parent interface. When a child opens a session via its parent, the parent process at least will store the session capability of the client together with information about resources (e.g.: RAM) it had to delegate from the child to the service provider. Now, if the child wants to close this session, it uses the 'close' call of the parent interface providing the session capability as an argument. The parent process takes that capability to find the information about the delegated resources and reverses the delegation. Thereby, the parent attaches its own context information to the session capability and uses it on later calls to 'close'.
So, we had to implement the retrieval of capabilities by ourselves. Thereby, Genode's capabilities on Fiasco.OC contain a globally valid ID to uniquely identify capabilities received by IPC. That ID gets allocated via the 'cap_session' interface in core. The ID is used to retrieve capabilities, a protection domain already owns. Moreover, it is also used as key to identify the concrete server object behind that capability. This server object retrieval is part of the generic code base and the 'local_name()' method thereby is used as the key.
So far, I hope the answer is more enlightening than confusing.
Regards Stefan