I recently had cause to pass on an article that I wrote for the now defunct Australian Sun Customer magazine (On#Sun) on the subject of doors. It occurred to me that I really should put this on the blog. Hopefully this will give some insight as to why I think doors are really cool.
If you have had a glance through
/etc you may have come across some files with door in their
name. You may also have noticed calls to door functions if you have run truss over commands
that interact with the name resolver routines or password entry lookup.
Imagine that you have an application that does two things. First, it provides lookup function
into a potentially slow database (e.g. the DNS). Second, it caches the results to minimise
having to make the slower calls.
There are already a number of ways that we could call the cached lookup function from a
client (e.g. RPCs & sockets), but these require that we give up the cpu and wait for a
response from another process. Even for a potentially fast operation, it could be some time
before the client is next scheduled. Wouldn't it be nice if we could complete the operation
within our time slice? Well, this is what the door interface accomplishes.
When you initialise a door server, a number of threads are made available to run a particular
function within the server. I'll call this function the door function. These threads are created as
if they had made a call to
door_return() from within the door function. The server will associate
a file and an open file descriptor with this function.
When the client initialises, it opens the door file and specifies the file descriptor when it calls
door_call(), along with some buffers for arguments and return values. The kernel uses this file
descriptor to work out how to call the door function in the server.
At this point the kernel gets a little clever. Execution is transferred directly to an idle door
thread in the server process, which runs as if the door function had been called with the
arguments that the client specified. As it runs in the server context, it has access to all of the
global variables and other functions available to that process. When the door function is
complete, instead of using
return(), it calls
door_return(). Execution is transferred back to the
client with the result returned in a buffer we passed
door_call(). The server thread is left
If we did not have to give up the CPU in the door function, then we have just gained a major
speed increase. If we did have to give it up, then we didn't really lose anything, as the
overhead is only small.
This is how services such as the name service cache daemon (nscd) work. Library functions
getpwent() and indeed any call whose behaviour is defined in
/etc/nsswitch.conf are implemented with door calls to nscd.
Syslog also uses this interface so that processes are not slowed down substantially because of syslog calls. The door function simply places the request in a queue (a fast operation) for another syslog thread to look after and then calls door_return() (that's actually not how syslog uses it).
For further information see the section 9 man pages on door_create, door_info, door_return