v86 / docs /filesystem.md
peterpeter8585's picture
Upload 553 files
8df6da4 verified

A 9p filesystem is supported by v86, using a virtio transport. There are several ways it can be set up.

Guest mount

In all cases, the filesystem is mounted in the guest system using the 9p filesystem type and the host9p device tag. Typically you want to be specific with the version and transport options:

mount -t 9p -o trans=virtio,version=9p2000.L host9p /mnt/9p/

Here are kernel arguments you can use to boot directly off the 9p filesystem:

rw root=host9p rootfstype=9p rootflags=trans=virtio,version=9p2000.L

The aname option can be used to pick the directory from 9p to mount. The rw argument makes this a read-write root filesystem.

JSON/HTTP Filesystem

This is the standard way to setup the 9p filesystem. It loads files over HTTP on-demand into an in-memory filesystem in JS. This allows files to be exchanged with the guest OS. See create_file and read_file in starter.js.

This mode is enabled by passing the following options to V86:

filesystem: {
    basefs: "../9p/fs.json",
    baseurl: "../9p/base/",
}

Here, basefs is a json file created using fs2json.py and the baseurl directory is created using copy-to-sha256.py.

If basefs and baseurl are omitted, an empty 9p filesystem is created. Unless you configure one of the alternative modes.

Function Handler

You can handle 9p messages directly in JavaScript yourself by providing a function as handle9p under filesystem:

filesystem: {
    handle9p: async (reqBuf, reply) => {
        // reqBuf is a Uint8Array of the entire request frame.
        // you can parse these bytes using a library or reading the 9p spec.
        // once you formulate a response, you send the reply frame as a
        // Uint8Array by passing it to reply: reply(respBuf)
    }
}

This allows you to implement a 9p server or custom proxy in JS. However, this filesystem will not be cached (unless cached in the guest OS), functions like create_file and read_file will not be available, and you will be responsible for keeping its state in sync with any machine save states.

WebSocket Proxy

You can also back the 9p virtio filesystem with a 9p server over WebSocket by providing a WS proxy URL:

filesystem: {
    proxy_url: "ws://localhost:8080/"
}

Simlar to using handle9p, this filesystem will not be available in JS and will need to be re-mounted after restoring state.

The WS proxy just needs to hand off messages with a connection to a normal 9p server. Each binary WebSocket message is the full buffer of a request or a reply.

To implement, request message bytes can just be sent directly to the 9p connection, but the 9p reply stream needs to be buffered into a single binary WebSocket message. The proxy must at least parse the first 4 bytes to get the message size and use it to buffer a full message before sending over WebSocket.

The wanix CLI has a serve command that not only serves a directory over HTTP, but also over 9P via WebSocket. You can see how it implements a proxy in Go.