Skip to content

Instantly share code, notes, and snippets.

@tage64
Last active August 24, 2023 19:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tage64/73972c2452092c05e6d0017cd448c75d to your computer and use it in GitHub Desktop.
Save tage64/73972c2452092c05e6d0017cd448c75d to your computer and use it in GitHub Desktop.
My experiences of creating Rust Bindings for Libnbd as part of Google Summer of Code 2023

Rust Bindings for Libnbd -- Google Summer of Code 2023

My name is Tage Johansson, and I have just completed my project for Google Summer of Code the summer 2023. This is a short description of what I've done and some thoughts about the project.

Background

Network Block Device (NBD) is a protocol for exporting block devices, either between processes or across the network. Libnbd is a client library for talking to NBD servers. This library had bindings in various languages, including C, Golang and Python, but not in Rust. During the summer in 2023, I participated in Google Summer of Code (GSoC), and the goal of my project was to make ergonomic Rust bindings for Libnbd.

The Programming Steps

Libnbd aims to provide bindings for as many languages as possible. In order not to have to update the bindings for each language individually, the API is defined in some OCaml files, and the bindings are then automatically generated from these bindings by some other OCaml files. So when the API is updated, it will be reflected in all language bindings with little to no intervention by the programmer.

As my goal for this project was to add bindings for Rust, I had to create some OCaml files, (Rust.ml and RustSys.ml), which generates the necessary Rust files. The generated Rust code make calls to a shared object file (libnbd.so) via Rust's foreign function interface (FFI).

A top level directory "rust" was created, containing the actual Rust crate for Libnbd. Apart from the automatically generated Rust files, this directory also contains several static Rust files defining things like general error types and helper functions. When building, after the OCaml generator is complete, this directory will be compiled as a Rust crate by Rust's build tool Cargo.

Asynchronous API

As Libnbd API allows for multiple concurrent calls to the same server, I wanted to investigate whether it would be possible to create an asynchronous version of the bindings, making use of Rust's asynchronous programming tools. The result was another 500 lines of code (plus tests and examples), half of which were OCaml and half of which were Rust. Under the hood, the asynchronous bindings uses Tokio (the at the time of writing most popular asynchronous runtime for Rust), for keeping track of updates to the file descriptor. The asynchronous bindings turned out to be fairly easy to use, and I am quite proud of them. Although most credit goes to Rust's excellent support for asynchronous programming.

Current State of the Project

The code for the normal (not asynchronous) Rust bindings is complete and merged. And the code for the asynchronous Rust bindings is also nearly complete but is still out for review. Apart from that, some more documentation describing how to use the bindings has yet to be written. And last but not least, the libnbd crate should hopefully be published to crates.io.

Conclusion

I have a great passion for programming languages, so this has been a really fun project as I have been dealing with three different languages: OCaml for writing the bindings-generator. Rust because that's the target language of the bindings. And the Rust code is communicating with the C library so I had to read and understand a lot of C code as well.

It was also the first time I made a significant contribution to an open source project. Something I really enjoyed and would like to do more in the future.

All in all, I think Google Summer of Code is an excellent opportunity for a summer internship, and I would encourage other students to try it out.

Contributions and Statistics

I have contributed a delta-count of 3043 lines divided onto 13 commits which are merged upstream so far. In case someone would be interested, I have compiled a list of links to all commits I have contributed below:

See this nice gist for some git commands to retrieve the above statistics.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment