Poor Man’s Virtual FileSystem with 9p, Rust, and a Raspberry Pi

Harley Swick
4 min readOct 20, 2018

--

In this tutorial, I’ll be going through how to setup a basic virtual filesystem between a Raspberry Pi and a laptop.

To follow along you’ll need a Raspberry Pi, an Ethernet Cable, and a laptop.

I’m running an Ubuntu laptop, and using the standard Raspian Jessie on the Pi.

Setup Raspberry Pi

I actually had some difficulty in getting my Raspberry Pi setup the way I wanted. There were a number of gotcha’s that weren’t always mentioned in some of the other tutorial’s I was reading. So I’ll try to lay out all of the steps I took here.

I recommend using the Raspbian image provided by Raspberry Pi https://www.raspberrypi.org/downloads/raspbian/. We’ll want to ssh into the Raspberry Pi, but the latest versions of raspbian don’t enable ssh by dfeault. So in order to do that, we need to copy an empty file named ssh into the SD card you put the Raspbian image on. Then simply connect the Pi to your home router with the Ethernet cord.

In order to get the IP address of the Pi, we need to get the IP address of our router. I would just look on Google how to get the IP address for your particular router. Put the IP address in the browser. Then you should see the Pi connected. It showed up on mine with the name raspberrypi. It should have something similar to yours. You can either use the IP address or the hostname. The hostname is obviously easier to remember.

ssh from your laptop to the Pi with this command.

ssh pi@raspberrypi

I recommend changing the password, and you can always change the hostname of the Pi by changing /etc/hostname.

9p protocol

9p is a protocol designed by Bell Labs for the plan9 operating system. 9p specifies a way to encode/decode binary messages between a client and server in such a way to control a virtual file system. One of the novelties of plan9 was it used the 9p protocol for its entire file system. The OS plan9 isn’t widely used today, but the 9p protocol lives on in other operating systems. With linux, the mount command has a type flag (-t) which we can set to 9p and it will use the 9p protocol. So in any linux distribution there is a 9p client.

There are a number of different 9p file server implementations. But I was looking for one that I could extend for other projects I have in mind. A great project I found was, rust-9p. The instructions were simple, and the implementation is very readable. For our 9p file server in this tutorial, we’ll simply use the example application that rust-9p includes.

We will be using that file server over the router’s intranet and mounting the Raspberry Pi’s file to a directory on our laptop. The use case that inspired this for me was that I wanted to edit some code on the Raspberry Pi using my favorite editor configured on my own laptop. I’ve recently been reading a lot about the plan9 operating system and the 9p protocol. A great project I’ve found is rust-9p (https://github.com/pfpacket/rust-9p).

Rust Build Tools FTW!!!

We’ll need to build a binary of the rust-9p example application that is compatible with the Raspberry Pi. A cool thing we can do with Rust is build our project for a different operating system then the one our computer is running on. I found this tutorial to be really useful to make that happen: https://hackernoon.com/compiling-rust-for-the-raspberry-pi-49fdcd7df658

Once you get the dependencies installed by the following the tutorial you can build the unpfs binary with this command:

cd rust-9p/example/unpfs
cargo build --target=armv7-unknown-linux-gnueabihf

Then in /target/armv7-unknown-linux-gnueabihf/release you should see the unpfs binary. You can then use sftp to put the binary on the Raspberry Pi.

Once you get the binary on the Pi, you can start the File Server like this:

./unpfs 'tcp!0.0.0.0!564' /exportdir

Then on your own laptop you can connect to the server and mount the file.

sudo mount -t 9p -o version=9p2000.L,trans=tcp,port=564,uname=$USER *RASPBERRY-PI-IP-ADDRESS* /mountdir

Now anything of in /exportdir will show up in /mountdir, and any writes to /mountdir will change /exportdir.

Conclusion

You may be wondering if there are other possible easier ways to connect to a virtual file system, and you are probably correct. However, I think this approach is interesting in several ways. First, from an educational standpoint, I differently learned a lot, and will never think about file systems the same way. The second reason is that sometimes other solutions might be more complicated, or you have resource constraints. This is an easy replacement. The third, and final reason, is that other options don’t give you the ability to extend a file server for your own purposes. Using the rust-9p as a library, all we have to do is implement the FileSystem trait, and we can be serving up whatever you want. Imagine implementing something like Google search but using the file system instead of a browser. I’m very interested in how far we can push the boundaries for these types of applications.

--

--