[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Improving object mobility within the Hurd
Re: Improving object mobility within the Hurd
Thu, 21 May 2009 18:44:59 +0200
On Sat, Feb 28, 2009 at 02:17:59PM +0100, Carl Fredrik Hammar wrote:
> On Fri, Jan 30, 2009 at 10:39:51AM +0100, olafBuddenhagen@gmx.net
> > On Thu, Jan 22, 2009 at 10:54:53AM +0100, Carl Fredrik Hammar wrote:
> sorry for the late reply. I had written most of the mail quite a
> while ago, except for the terminology discussion. Then I fell ill,
> and was unable to complete that part, which I felt required a lot of
> concentration. Then it took additional time to get back up on the
> horse and get back into the nitty-gritty details. In hind-sight, I
> should of broken the mail and replied to the different parts as I
> finished them.
Indeed. That would also have made it much easier for me to reply in
Luckily, the authorization discussion has moved to the other thread now,
so I can just skip a considerable part here :-)
> > By "abstract object", I mean a bundle of state and code, but not
> > necessarily bound to a specific interface. It could have multiple
> > interfaces, or a single internal one that can be mapped do different
> > external interfaces (RPC, local function call etc.).
> OK, so it was a distinct concept. I see how it could be useful.
> However, abstract objects seem to be more of a policy and I'm more
> interested in the underlying mechanism, we still need to be able to
> discuss how an abstract object is to be implemented concretely.
> Unless otherwise stated, I'm referring to ``concrete'' objects.
I object to that. (Pun not intended :-) ).
It would be extremely confusing if the term "object" would refer to
something different in the mobility framework than otherwise.
In general, the abstract objects are almost always more relevant. That
is what the user sees -- everything else is just implementation details,
and should be transparent most of the time. Thus, I insist on reserving
the term "object" for abstract objects. When referring to something
else, please always use a more specific term.
> > Or rather, there is a single interface at an abstract level, but
> > this can be implemented using different transport mechanisms or
> > containers or whatever we call them.
While originally I suggested "transport" and "container" as
interchangable terms for the same thing, I realized now that it's
probably better to use them for two distinct things: The container is a
mechanism that allows accessing an (abstract) object by various means.
Transports are specific methods for accessing an object.
Traditional Hurd objects use a trivial container, which makes them
hard-wired to the RPC transport. Store objects use a container that
allows access either with the RPC transport, or with a local function
call transport (using the libstore interface).
> What you call transports, I have called wrapper objects. I prefer
> your terminology, but maintain that transports are distinct objects.
No they aren't. They have no meaning on their own. They are just an
implementation detail -- a means to access an actual object.
> > > A /remote/ object is an object that can be called remotely. A
> > > /local/ object is one that can be called locally.
> > I'm not sure remote object vs. local object is a meaningful
> > distinction.
> > We have the normal Hurd servers, where the objects are hard-wired to
> > the RPC transport. We have the store framework (and hopefully a more
> > generic framework in the future) for mobile objects, which can
> > reside in the server and be accessed through the RPC transport, or
> > be loaded into the client and accessed through local function calls.
> > And we discussed the possibility of objects that can only reside in
> > the client, and could be hard-wired to a local function call
> > transport.
> It isn't meaningful to distinguish objects that can be called remotely
> using RPCs from objects that cannot?
This goes back to the point above: For an *abstract* object, at any
given time being accessed remotely or loaded locally, is just transient
Local vs. remote is only a fixed property for transports. For (abstract)
objects, the only fixed property is the *ability* to be used through
remote and/or local transports, which in turn depends on the features of
the container this object is using.
Traditional Hurd objects are remote-only. Store objects can be used both
remotely and locally. ioctl wrappers would be used only locally.
> The question is where to draw the line of what constitutes a single
> object. While I consider transports as clearly separate objects on a
> concrete level, it's less clear when considering normal Hurd objects.
> Is the RPC handling part an additional interface or a separate proxy
> object? Or if preference is given to the first view, is there any
> point in regarding the proxy as separate from the proxied object?
> An object depends on its interfaces but is independent of its proxies.
> While it controls which interfaces it implements, it has no control
> over its proxies. This makes proxies more flexible and dynamic than
> interfaces, you can have several different or equivalent proxies to
> the same object, and proxy proxies.
> Consider an object bound to several ports, i.e. messages to either
> port will result in the same operation on the same object. Clients
> would not be able to establish that they are bound to the same object
> (in general), thus it is more appropriate to view the ports as
> references to different proxy objects rather then references to the
> same object.
Such a proxy would not count as a transport. A transport is only an
implementation detail. It's a means of accessing an object; it should
have *no* influence on the functionality of the object.
As I said above: Only abstract objects are meaningful on their own.
A proxy that influences the functionality, is obviously an (abstract)
object of its own -- but such proxies are outside the scope of object
migration. They should be implemented as distinct, normal (abstract)
Please keep functional proxies and object mobility clearly separated. If
you start mixing these up, the whole idea of a uniform object system
falls apart; we no longer have any reference point for what is what and
how things should interact...
> > Not sure what you mean by POSIX style vs. Hurd style...
> Take the difference between how read and hurd_io_read returns data,
> read fills specified memory, while hurd_io_read might fill a specified
> buffer or return a new buffer.
I actually never understood the point of that... Seems an unnecessary
complication to me.
(Server-created buffers are also problematic from a resource management
But that's not really relevant to the discussion at hand :-)
> Also note, that I have not ruled out transferring objects from client
> to server (which is why I usually say sender and receiver instead).
> > > Using a file name, you can figure out who controls the file, and
> > > decide whether you trust it based on that. (Or at least I think
> > > so, I'm not sure yet if a malicious file system can't fool you.)
> > >
> > > This might not be impossible with ports, but I imagine it's
> > > trickier.
> > The problem with file names is that they aren't very reliable. For
> > one, they only work if client and server are in the same name space.
> > (You even mentioned chroot yourself...)
> > Also, file names aren't stable temporaly: The meaning of the name
> > could change between the time the server passes the name, and the
> > time the client opens it.
> > In the end, I think the only thing we can do with file names is
> > resolving them, and then doing exactly the same checks we do on a
> > directly passed FD: Checking that the node is owned and writable
> > only by trusted users, and that it resides on a file system that can
> > be trusted regarding this information.
> > I can't see how we could derive any additional trust from the file
> > name itself. It seems only to open additional potential for failure.
> I guess this is true.
> However, if we only want to use files in
> /lib:/usr/lib:$LD_LIBRARY_PATH, we are forced to use file names.
The point was that IMHO it's not useful to do this in the first place.
The reason we trust stuff in /usr is not because it has a certain
component in the file name, but because it's controlled by root -- so
that's what we should check for.
> I like this approach because it's the conventional way to specify
> libraries to use, and thereby to trust.
No -- the motivation for dynamic library paths is different. Libraries
are looked up at run time -- we need a path to know where to look for
When we migrate an object OTOH, we don't need to look the module up: the
sender was already using it, so it knows exactly where it is.
> This is pretty much how libstore does it BTW.
I always found that very limiting... Let's do better than that :-)
> > As I already said, I don't discourage conceptually considering the
> > various indigents of the mobility framework as independant
> > components. But as long as we don't actually have other users, you
> > shouldn't try to make them any more generic than is strictly
> > required for the standard mobility mechanism -- anything else would
> > just be overengineering.
> I'm mostly avoiding artificially coupling components for no apparent
My impression is that you are rather trying artificially to decouple
them, for no apparent benefit :-)
Let me cite some XP mantras: Keep It Simple, Stupid. Do The Simplest
Thing That Could Possibly Work.
> The general problem I'm trying to avoid is that frameworks usually get
> in your way when doing something the original developers didn't
You can still fix the framework once this actually happens...
Here comes another mantra: You Ain't Gonna Need It.
To be honest, I think there is already quite some overengineering in
certain parts of the Hurd. Let't try to cut it down, rather than adding
to it even more...
Don't get me wrong. I'm absolutely against arbitrarily limiting
possibilities. However, I'm *also* against putting extra effort into
making things more generic than necessary, just because it *might* be
useful some day...
> > These stubs are individual for every ioctl: to support a new type of
> > device, new stubs need to be added to libc -- which is obviously
> > painful. Would be nice to have a mechanism that loads the stubs
> > dynamically from some external source.
> Yes, but transforming ioctls to RPCs seems totally independent of the
No, not really. The more I think about it, the more I'm convinced that
it is actually inherently bound to the server.
ioctl()s are always specific to a particular device class, and thus the
server(s) implementing (or proxying) it. It makes perfect sense for a
server implementing a specific device, also to provide the ioctl
wrappers necessary to access it.
> The fact that the client is attempting to do an ioctl is enough to
> warrant loading the code. I figure a proper solution would go
> something like: libc gets a ioctl(fd, KDSETLED, ...), libc loads
Just like for other cases of object mobility, I think it's much more
useful for the sender to provide a direct reference to the actual
module, rather than introducing some symbolic names that need to be
looked up externally.
On a more generic note, obviously it would be possible to create some
special mechanism for loading the ioctl helpers -- but it seems much
more convenient, simply to use the generic object mobility framework for
In fact, I believe now that this is an ideal initial target for the
mobility framework: while it won't employ all aspects of the framework,
it is simple, well-defined, and obviously useful. Much better than
aiming at moving targets like sound or networking; or even trying to
design the framework on a purely theoretical ground, without
implementing any actual use cases at all...
BTW, I meant to ask for a while now, but always forgot: do you have any
problems with IRC? I think it would be very useful if you could join one
of the GSoC IRC meetings, or simply try to catch me on IRC at another
time -- I'm sure many of these things are much easier to discuss
- Re: Improving object mobility within the Hurd,