Tag Archives: golang

Golang bindings for both libnbd and nbdkit

I have to say for full transparency up front that Golang is not my favourite programming language, even less after using it for a while. Nevertheless with a lot of help from Dan Berrangé we now have Golang bindings for libnbd and nbdkit which are respectively client and server software for the Linux Network Block Device protocol.

The Golang bindings for libnbd let you connect to a server and read and write from it. This is all pretty straightforward so read the manual page if you want to find out more.

The Golang bindings for nbdkit are considerably more interesting because you can use them to write pretty natural and high performance NBD servers to expose “interesting things”.

I’m hoping in particular there are interesting block device sources in the Kubernetes / Docker ecosystem which are probably only available from Golang that we could now expose to other software (although I’m also still researching this area so I don’t yet know what in particular).

You can make a complete Golang NBD server really easily now with only a few lines of code. Minus boilerplate, something like this is sufficient (see this link for complete working examples):

type MyPlugin struct {
	nbdkit.Plugin
}

type MyConnection struct {
	nbdkit.Connection
}

func (p *MyPlugin) Open(readonly bool) (nbdkit.ConnectionInterface, error) {
	return &MyConnection{}, nil
}

func (c *MyConnection) GetSize() (uint64, error) {
	return size, nil
}

func (c *MyConnection) PRead(buf []byte, offset uint64,
	flags uint32) error {
	copy(buf, ... from the source of your data here ...)
	return nil
}

func (c *MyConnection) CanWrite() (bool, error) {
	return true, nil
}

func (c *MyConnection) PWrite(buf []byte, offset uint64,
	flags uint32) error {
	copy(... to the data source here ..., buf)
	return nil
}

Editor note: In an earlier version of these bindings we passed the whole struct to each callback rather than a pointer, hence James’s first comment below.

3 Comments

Filed under Uncategorized

Golang bindings for libguestfs

libguestfs ≥ 1.23.7 now has almost completely functional golang bindings.

So what (you are probably not asking) did I like and dislike about Go? There are some good points:

  • Very fast compilation
  • Interoperability with C
  • Compiles to native code
  • Appears to have proper garbage collection

Unfortunately I think that, like Vala, it’s a bit of a missed opportunity to fill the C replacement niche. It looks as if the language designers have never used a functional language, or if they did, they didn’t “get” it. Some of the real downsides include:

  • No type inference. Because obviously it’s 2013 and I want to write types everywhere.
  • Bondage-and-discipline, but in odd ways and to no apparent benefit. Like what’s the point of all the odd rules around := vs =, and what types you can and can’t assign and pass to functions? And why do you have to declare imports, when the compiler could work them out for you (it’ll even moan if you import something which is not used!)
  • Hello, world is about 8 lines of code. Camel case! Java rang, wants its boilerplate back.
  • No breakthrough on error handling.
  • The whole design of GOROOT/GOPATH is completely broken. It’s actually worse than Java’s broken CLASSPATH crap which is some kind of achievement, I guess.

They refuse to add exceptions (probably a good point), but the alternative is C-style error checking on every other line. It’s not even enforced error checking, so bad programmers will still be able to write bad code. And there are good ways to handle errors, eg. process-based transactions, Erlang-style, etc. But that seems to have passed them by.

Oh well, there’s still room for the breakthrough C replacement language.

4 Comments

Filed under Uncategorized