Category Archives: Uncategorized

And now you can write nbdkit plugins in Lua

See here.

Previously Tcl …


Leave a comment

Filed under Uncategorized

You can now write nbdkit plugins in Tcl

I have a soft spot for the Tcl programming language because Tcl/Tk was one of the earliest and best rapid GUI development environments available on Unix.

Well now you can write nbdkit plugins in Tcl.

Here’s an example:

# This is called from: nbdkit tcl example.tcl --dump-plugin
proc dump_plugin {} {
    puts "example_tcl=1"

# We expect a file=... parameter pointing to the file to serve.
proc config {key value} {
    global file

    if { $key == "file" } {
        set file $value
    } else {
        error "unknown parameter $key=$value"

# Check the file parameter was passed.
proc config_complete {} {
    global file

    if { ![info exists file] } {
        error "file parameter missing"

# Open a new client connection.
proc plugin_open {readonly} {
    global file

    # Open the file.
    if { $readonly } {
        set flags "r"
    } else {
        set flags "r+"
    set fh [open $file $flags]

    # Stop Tcl from trying to convert to and from UTF-8.
    fconfigure $fh -translation binary

    # We can return any Tcl object as the handle.  In this
    # plugin it's convenient to return the file handle.
    return $fh

# Close a client connection.
proc plugin_close {fh} {
    close $fh

proc get_size {fh} {
    global file

    return [file size $file]

proc pread {fh count offset} {
    seek $fh $offset
    return [read $fh $count]

proc pwrite {fh buf offset} {
    seek $fh $offset
    puts -nonewline $fh $buf

1 Comment

Filed under Uncategorized


The Network Block Device (NBD) protocol is really useful to us when we deal with virtual machines and disk images. It lets us share disk images between machines and is also the universal protocol we use for communicating disk images between different bits of software. I wrote a pluggable NBD server called nbdkit to make this even easier.

However there was a problem: The protocol has no concept of logins. If you have an open NBD port, then anyone can connect and read or write your disk image. This is not quite as terrible as it sounds since when two processes are talking NBD to each other, we use a Unix domain socket and we hide the socket in a directory with restrictive permissions. But there are still cases — such as communicating between separate servers — where authentication would be useful.

NBD does let you upgrade the protocol to use TLS, and all the important NBD servers support that. You can use TLS to do client authentication but it’s seriously clunky and difficult to set up because you have to use X.509 certificates, and if we’ve learned anything from the web we know that X.509 is a plot by the NSA to stop us using encryption (only joking, spooks!)

It turns out there’s a more sensible corner of the TLS specification called TLS-PSK. This uses usernames and randomly generated Pre-Shared Keys (PSK). As long as you can ensure that both the client and server can read a simple username:key file of keys, and the keys are kept secret, you can both authenticate and communicate securely.

Unfortunately just implementing TLS doesn’t get you PSK as well, and no existing NBD server supports TLS-PSK.

So I had to add support. To qemu and qemu-nbd. And to nbdkit.

Amazingly it all works, and qemu and nbdkit interoperate too. Here’s how you could use it:

$ mkdir -m 0700 /tmp/keys
$ psktool -u rich -p /tmp/keys/keys.psk
$ nbdkit -n \
    --tls=require --tls-psk=/tmp/keys/keys.psk \
    file file=disk.img
$ qemu-img info \
    --object "tls-creds-psk,id=tls0,endpoint=client,username=rich,dir=/tmp/keys" \
    --image-opts "file.driver=nbd,,file.port=10809,file.tls-creds=tls0"

The qemu command line is a bit clunky, but it’s overall much simpler than setting up certificates, although not as scalable for large installations.


Filed under Uncategorized

Fedora/RISC-V nightly builds

Thanks to David Abdurachmanov for doing the hard work of making Fedora/RISC-V nightly Fedora 29 builds available. To learn how you can boot and play with these in qemu on x86, see this page.

1 Comment

Filed under Uncategorized

New in nbdkit

nbdkit is our toolkit for writing flexible Network Block Device servers with both normal and esoteric plugins as data sources. You can use it to pull data into qemu or other hypervisors, or with libguestfs.

Since I last mentioned nbdkit ([1] and [2]) there have been a few new developments:

  • There are now stable (1.2) and development (1.3) branches. Most of the features discussed below are only available on the development branch at this time.
  • If you use bash, you can now tab-complete many nbdkit commands, including automatically getting a list of flags, plugins and plugin parameters.
  • The highly optimized and multithreaded file plugin now supports hole-punching (trim/discard) thanks to Eric Blake’s work.
  • Eric also wrote new filters: a log filter for enhanced logging, and blocksize, nozero and fua filters for modifying requests from clients.
  • I wrote some new plugins too: The ext2 plugin allows you to read and write files within ext2 filesystems (my response to this very long qemu-devel discussion). The zero and random plugins are largely for testing awkward corner cases in NBD clients and the nbdkit code itself.
  • Eric added support for zeroing to non-C plugins.
  • Pino Toscano added the nbdkit_realpath utility function for plugins.
  • For programmers writing plugins, Eric Blake has done a lot of work on the plugin API. If your plugins use:
    #define NBDKIT_API_VERSION 2

    then the plugin functions all have flags exposing FUA (flush) commands from the client. Of course the old plugins are still supported both as source and binaries.

  • The default NBD protocol served in ≥ 1.3 changed to “newstyle”, but you can continue to serve “oldstyle” by adding the -o option.

nbdkit can be downloaded from here and older versions (probably not including the features above) are available in all popular Linux distributions.

Leave a comment

Filed under Uncategorized

Half-baked ideas: Server remote management with an RPi Zero

For more half-baked ideas see the ideas tag

I guess like most people who work a lot with computers, I have a large number of computers in a “server room” (my loft). I’m too cheap to buy actual servers though, so most of these computers lack any sort of remote management / IPMI / BMC etc. I also just bought 6 Intel NUCs and these are also ideal as development servers, but unless you buy very specific (and unobtainium) versions they don’t come with remote management either.

Could we design a small USB device which would turn an ordinary PC into a remotely managed server?

What would we want it to do?

  1. Reboot remotely (like hitting the power switch, but remote).
  2. Unattended operating system install and reinstall.
  3. Modify BIOS settings.

At first the answer is obviously no since you cannot capture the display output from this device, but let’s ignore the display for a moment.

My initial idea was that you could simply have a USB flash drive which would have some kind of minimal remote operating environment. You would have to reconfigure the server BIOS so it always boots off the USB drive, and the USB drive then either chain boots to the operating system or can interrupt the boot process to download a new image. This lets you reinstall an OS, but not much else.

However USB can do a whole lot more, including acting as a keyboard, and it’s possible for a single USB port to provide multiple functions like drive + keyboard. Could we design a USB peripheral which would inject keys (like Ctrl+Alt+Del to soft reboot)? It could also blindly control the BIOS by injecting keys.

Designing a USB peripheral is a bunch of work, but the hardware to do it already exists. The Raspberry Pi Zero can act as a USB device (known as a Linux USB gadget).

So the idea is you’d connect the RPi Zero to the server using a USB OTG cable. It would appear as a keyboard and mass storage device (but unlike above you would not change the server to boot off USB, it boots normally). The RPi Zero could be remotely accessed over wifi and using that you could inject keypresses (like Ctrl+Alt+Del), and present a boot disk to the server, and using blind keypresses negotiate the BIOS menus to select an alternate boot disk when you want to reinstall. You can also act as a virtual serial console gadget allowing simpler interactive use for some operating systems.

One problem here is the RPi is powered from the server, so when it reboots it’s possible it will shutdown (but perhaps not if plugged into the yellow USB ports since I guess those should have constant power).

Another problem is you can’t see the display, so you’re driving the BIOS and other menus blind. But it’ll probably work in most automated cases. USB has a video class but I’m not clear if it would help here (it also wouldn’t be any good unless the server BIOS could use it).

A third problem is you cannot hard reboot the server in case it hangs.


Filed under Uncategorized

My talk from the RISC-V workshop in Barcelona

Leave a comment

Filed under Uncategorized