[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Persistent object handles
Persistent object handles
Sun, 5 Jan 2003 17:34:32 +0100
Espen Skoglund et al. showed that it is feasible to implement transparent
orthogonal persistence in an L4-based system . I don't know if the ideas
in this paper have been used as a basis for implementing a persistent system
so far. However, as the Hurd port to L4 is just starting, I think it would be
wise to keep in mind that at some point we might want to add persistence
mechanisms to it. The point is that persistence can be implemented
separately: for instance, we may need to implement a particular memory server,
but this does not require any interface changes. So persistence should not
influence the overall design.
However, the way object handles are managed *is* important. Since they are
use throughout the system, we need to make sure that they could be made
recoverable. In a previous discussion , Neal Walfield pointed out what the
basic requirements for identifying an object handle (ie. a communication
- when a client does an open, a server can create a tuple consisting of
the client task id, a handle id, and the thread id of its communication
- a client identifies a communication channel with a tuple consisting of the
handle id provided by the server and the server thread id.
The problem is that thread ids are system-wide identifiers, ie. absolute
references. It would not be a problem if every single thread in the system
was persistent and if it could be restarted using the same id (which, I
think, is possible). However, not every thread in the system could be
persistent because (1) there are some task that cannot be made persistent
anyway (eg. drivers) and (2) we might want to choose to just have a few
persistent tasks in the system.
Therefore, in order to be able to make tasks persistent, applications should
not use thread ids *directly*. Instead they should use some other identifier
that is local to the set of persistent tasks. When initiating an IPC, this
local identifier could be translated into the system-wide thread id to which it
maps by some underlying communication library. In this case, there must exist
a name server that keeps a mapping between thread ids and this kind of
identifiers. When a clients wants to start an IPC, it could ask this server
what the thread id corresponding to this id is.
However, the client would not need to ask the name server *each time* it wants
to do some IPC. Instead, it (the communication library) could simply cache
the thread id locally and reuse it directly until an IPC fails. An IPC can
fail either because there is no such thread id or because the thread id does
not designate the same task as before. In both cases, it probably means that
the persistent tasks have just resumed execution after a failure (ie. have
recovered) which means that thread ids have changed. In such a situation, the
client can ask the aforementioned name server for what the new thread id is
(see the architecture described in ).
In the Hurd, PIDs can be made local (by creating a "sub" proc server just like
what happens when booting a subhurd) and persistent (upon recovery, the system
can manage to reassign the same PID as before to each persistent task). The
name server mentioned above could simply be the proc server and client tasks
would identify communication channels using a tuple (server PID, handle id).
This solution would not add too much overhead I think. However, for each
"real" RPC, it would require having a higher-level function which would
the arguments accordingly and call the actual RPC; this can probably be done
with some "macro magic" as the one posted by Neal sometime ago.
I would be interested in trying to design and implement persistence mechanisms
for Hurd/L4 someday. I don't know if I'll ever be able to do it but it's a
good thing to simply make it possible.
- Persistent object handles,
Ludovic Courtès <=