NetBSD has puffs - Pass-to-Userspace Framework File System development interface, which provides the support for implementing file servers in userspace. The example of the implemented file server which uses puffs is psshfs.
Puffs has it's own userspace library - libpuffs, upon which the file servers are supposed to be built. It provides:
NetBSD also has pud - Pass-to-Userspace Device, which provides support for implementing pseudo-device servers in userspace. However the pud doesn't have it's userspace library, so in order to implement a device server, one must interact directly with the kernel by reading and writing raw request/response structures.
The goal of the project is to move generic parts from libpuffs to the separate library and provide libpuffs and libpud based on this library.
The code can be found here: http://netbsd-soc.cvs.sourceforge.net/viewvc/netbsd-soc/puffs_libpud/
A base library called libeventloop is created.
libpuffs is updated to use it.
libpud is under construction...
Initial version of libpud and a usage example for char device is implemented.
Moved libvdisk to libpud.
Reverted libpuffs API back to it's original state. No need to rewrite any programs depending on it.
Bug fixes in libeventloop.
Wrote a libpud example: fortune pseudo-device.
Wrote a libpud example: daytime pseudo-device.
Wrote a libpud example: copy-on-write block pseudo-device.
Wrote man pages.
libpuffs operates as a single-threaded program.
In order to serve multiple requests in parallel, it uses puffs continuations (puffs_cc or call context) - a mechanism for switching process execution between requests. In fact it's a wrapper around get/set/make/swapcontext functions.
When the file server issues a long-term I/O operation such as waiting for data over the network, it switches the execution to allow other requests to proceed.
libpuffs also offers puffs_mainloop - a loop in which a given set of file descriptors is monitored for the read and write possibility and then the data is read and written respectively.
To help manipulating the data, puffs offers framebuf. It can be treated as two set of functions.
One set helps manipulating the given data buffer, i.e. allocate, access, resize and destroy it when needed.
The other set helps manipulating the file desriptors which are monitored in the mainloop. It also can enqueue the data buffers, which will be written to the their file descritors in the mainloop.
For in-depth description see the paper entitled "puffs - Pass-to-Userspace Framework File System" (http://2007.asiabsdcon.org/papers/P04-paper.pdf) and the paper discussing the implementation of distributed file systems on top of puffs (http://2008.asiabsdcon.org/papers/P4B-paper.pdf)
Programs which currently use pud use the read-process-put_result loop too.
So the idea is to move callcontext, framebuf and puffs_mainloop into the separate library called libeventloop.
The libpud users will only have to define the necessary pseudo-device operations and libpud (libeventloop behind it) will take care of reading the request from the pud, calling the appropriate user-defined handler and sending back the result.
If the pseudo-device will need to work with the network, framebuf and callcontext will help to implement asynchronous processing of the pud requests.