Thursday, October 27, 2016

Playing with Bus1

David Herrmann and Tom Gundersen have been working on new, performant Linux interprocess communication (IPC) proposals for a few years now. First came their proposed kdbus system, which would have provided a DBus-compatible IPC system, but this didn't actually get merged because of several design issues that couldn't be worked around (mostly security-related).

So, they went back to the drawing board, and now have come back with a new IPC system called Bus1, which was described in a LWN article back in August. Yesterday, they posted draft patches to the Linux kernel mailing list, and the kernel module and userspace libraries are available on GitHub for your convenience.

I decided to find out what's involved in getting the experimental Bus1 code up and running on my system. I run Fedora Linux, but broadly similar steps can be used on other Linux distributions.

Installing tools

The first thing to do is to install some development tools and headers.

dnf install git kernel-devel
dnf builddep kernel

I'm going to need git for getting the source code, and the kernel-devel development headers for compiling the Bus1 kernel module. The special dnf builddep command automatically fetches all of the packages needed for compiling a particular package — in this case, we're compiling a kernel module, so just grabbing the tools needed for compiling the kernel should include everything necessary.

Building the kernel module

I need to get the Bus1 kernel module's source code using git:

mkdir ~/git
cd ~/git
git clone https://github.com/bus1/bus1.git
cd bus1

With all of the tools I need already installed, I can very simply run

make

to compile the Bus1 module.

Finally, the Bus1 Makefile provides an all-in-one solution for running the module's tests and loading it into the running kernel:

make tt

After several seconds of testing and benchmarking, I get some messages like:

[ 1555.889884] bus1: module verification failed: signature and/or required key missing - tainting kernel
[ 1555.891534] bus1: run selftests..
[ 1555.893530] bus1: loaded

Success! Now my Linux system has Bus1 loaded into its kernel! But what can be done with it? I need some userspace code that understands how to use Bus1 IPC.

Building the userspace library

The Bus1 authors have provided a basic userspace library for use when writing programs that use Bus1. How about building it and running its tests to check that Bus1 is actually usable?

Some additional tools are needed for compiling libbus1, because it uses GNU Autotools rather than the kernel build system:

sudo dnf install autoconf automake

As before, I need to checkout the source code:

cd ~/git
git clone https://github.com/bus1/libbus1.git

I can then set up its build system and configure the build by running:

./autogen.sh
./configure

But there's a problem! I need to install a couple of obscure dependencies: David Herrmann's c-sundry and c-rbtree libraries.

This is accomplished by something along the lines of:

cd ~/git
git clone https://github.com/c-util/c-sundry.git
git clone https://github.com/c-util/c-rbtree
# Install c-sundry
cd ~/git/c-sundry
./autogen.sh
./configure
make
sudo make install
# Install c-rbtree
cd ~/git/c-rbtree
./autogen.sh
./configure
make
sudo make install

So, with dependency libraries installed, it's now possible to build libbus1. Note that the configure script won't pick up the dependencies installed because on Fedora it doesn't scan the /usr/local/lib/pkgconfig directory by default, so I have to give it a bit of help.

cd ~/git/libbus1
./autogen.sh
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure
make

Amusingly, this failed the first time due to a bug for which I submitted a patch. However, with the patch applied to c-sundry, I've got a successful build of libbus1!

I also ended up having to add /usr/local/lib to /etc/ld.so.conf so that the c-rbtree library got detected properly when running the libbus1 test suite.

Even after that, unfortunately the test suite failed. Clearly the Bus1 userspace libraries aren't as well-developed as the kernel module! Maybe someone could do something about that...?