All, Some time ago I wanted to experiment with implementing block devices, preferably in userspace (for prototyping purposes). NBD provides a nice framework for this, since it can be used on any Linux host (kernel module), as well as thanks to the native Qemu/KVM support for the protocol (to back virtual machines).
Since the existing C NBD server isn't really modular/reusable, and I tend to do most prototyping using Haskell lately, after going through the docs and deciphering the protocol I created a Haskell library which eases implementing an NBD server (or client) in Haskell, using the Conduit library. You can find it at [1]. More information at [2], and API docs at [3]. The library only supports the 'modern' protocol, but should support all its features. There's a low-level API in Network.NBD.Server, and a high-level one in Network.NBD.Server.Simple. The protocol implementation is not tied to any transport protocol (and neither is any 'server' implementation), and has been tested using TCP/IP (using the Linux kernel module as well as Qemu/KVM) as well as Unix domain sockets (with Qemu/KVM) and in-memory queues in the testsuite. At [4] you can find a demo server (using the 'Simple' API) which exports all files provided on command line (using the filename as export name). It's very basic, but does support all protocol features (read/write/flush/trim/FUA). The server is fully multi-threaded, using GHC's threaded RTS (non-blocking IO, microthreads mapped to N OS-threads, the lot). As-is, the server listens on a Unix socket called 'nbdsock', but changing line 84 into TCPServerSettings (and providing host/port/... constructor arguments) turns it into a TCP/IP server in a snap. Even though some of you might think using Haskell for this is a very bad choice performance-wise, some very unscientific 'benchmarking' shows the demo server is slightly quicker than the default C server. Usage of pread/pwrite instead of seek+read/write, and the fact less recv calls are required to read commands from the client socket (larger blocks are read at once, then buffered), might explain this, as well as the fact there are no 'COW' or 'multi-file volume' execution paths. In the end it should at least be on par. But, as said before, this is very unscientific and without any serious profiling. Feel free to prove me wrong ;-) Thought this might be useful one day for some... Regards, Nicolas [1] https://github.com/NicolasT/nbd/ [2] http://nicolast.github.com/nbd/ [3] http://nicolast.github.com/nbd/doc/index.html [4] https://github.com/NicolasT/nbd/blob/master/bin/server.hs ------------------------------------------------------------------------------ Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS, MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft MVPs and experts. ON SALE this month only -- learn more at: http://p.sf.net/sfu/learnmore_123012 _______________________________________________ Nbd-general mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/nbd-general
