iovisor / iovisor/bcc

[Proposal] Support compile libbpf-tools to Wasm(WebAssembly) and get tools running from the cloud in 1 line

Open
#4,306 5 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
22.7k
Forks
4.1k
Avg merge
10d 4h
Merged PRs (30d)
3

Description

Hi, community!

I propose that maybe we can try to compile the `libbpf-tools` C code to OCI-compatible [WebAssembly](https://webassembly.org/) module, and then use a launcher to get eBPF programs running from the cloud to the kernel in 1 line of bash?

Just like what [bumblebee](https://github.com/solo-io/bumblebee) has done, but with the help of WebAssembly:

- don't need to create another OCI Artifact, we can use the existing Wasm tools to get OCI-compatible eBPF programs running from the cloud, for example, [docker + wasm: Introducing the Docker+Wasm Technical Preview](https://docs.docker.com/desktop/wasm/)
- don't need to `rewrite` the existing libbpf-tools or do a lot of `code modification`, we can use the existing C code and compile it to Wasm
- can make a single pre-build libbpf-tool run on different arch without re-compiled(`Compile once, run everywhere`). We have tested some tools on `x86` and `arm` to prove it.
- Make libbpf tools possible for `plugin` in other systems, like what Envoy has done: [WebAssembly-in-Envoy](https://github.com/proxy-wasm/spec/blob/master/docs/WebAssembly-in-Envoy.md)
- Allowing developers to write user space programs in `other languages`(Go, Rust, Java, TypeScript, etc.), Over 30 programming languages can be compiled to WebAssembly modules.

As far as I know, Bumblebee seems cannot support running on Arm: [Fail installation on ARM and document supported architecture](https://github.com/solo-io/bumblebee/issues/87).

We have created a `prove-of-concept` library and a demo tool to show how to compile libbpf base tools to Wasm and run it:

- Our library: [https://github.com/eunomia-bpf/eunomia-bpf](https://github.com/eunomia-bpf/eunomia-bpf)
- A sigsnoop tool demo port to wasm: [sigsnoop](https://github.com/eunomia-bpf/eunomia-bpf/blob/example/examples/bpftools/sigsnoop/app.c). This tool is based on the [libbpf-tools/sigsnoop](https://github.com/iovisor/bcc/blob/master/libbpf-tools/sigsnoop.c) in libbpf-tools, which Traces standard and real-time signals sent to processes.

## Background

What is Wasm?

> [WebAssembly](https://webassembly.org/), often shortened to Wasm, is a relatively new technology that allows you to compile application code written in over 40+ languages (including Rust, C, C++, JavaScript, and Golang) and run it inside sandboxed environments.
>
> The original use cases were focused on running native code in web browsers, such as [Figma](https://www.figma.com/blog/webassembly-cut-figmas-load-time-by-3x/), [AutoCAD](https://blogs.autodesk.com/autocad/autocad-web-app-google-io-2018/), and [Photoshop](https://web.dev/ps-on-the-web/). In fact, [fastq.bio](https://fastq.bio/) saw a [20x speed improvement](https://www.smashingmagazine.com/2019/04/webassembly-speed-web-app/) when converting their web-based DNA sequence quality analyzer to Wasm. And Disney built their [Disney+ Application Development Kit](https://medium.com/disney-streaming/introducing-the-disney-application-development-kit-adk-ad85ca139073) on top of Wasm! The benefits in the browser are easy to see.
>
> But Wasm is quickly spreading beyond the browser thanks to the [WebAssembly System Interface](https://wasi.dev/) (WASI). Companies like [Vercel](https://vercel.com/docs/concepts/functions/edge-functions/wasm), [Fastly](https://docs.fastly.com/products/compute-at-edge), [Shopify](https://shopify.engineering/shopify-webassembly), and [Cloudflare](https://developers.cloudflare.com/workers/platform/languages/) support using Wasm for running code at the edge, and [Fermyon](https://www.fermyon.com/) is building a platform to run Wasm microservices in the cloud.

What is [WASI](https://github.com/WebAssembly/WASI)?

> The WebAssembly System Interface is not a monolithic standard system interface, but is instead a modular collection of standardized APIs. None of the APIs are required to be implemented to have a compliant runtime. Instead, host environments can choose which APIs make sense for their use cases.

## The compile workflow

The workflow to compile a `libbpf-tool` to `Wasm` maybe like this:

1. Compile the libbpf-tools bpf object as usual
2. Generate a special header file for the bpf object with a modified `bpftool`
3. Include some special headers in the C code(change the include path of origin libbpf headers to the special headers)
4. Write the C source code as usual
5. Compile the C code to Wasm use clang with `WASI` support
6. Use a `launcher` to load the Wasm module in user space: export some helper functions to the WebAssembly runtime, and then load the bpf object into the kernel from the wasm module with the helper functions.

## What needs to be done?

What maybe need to be done in libbpf-tools next if we want to support wasm target:

1. define some ABI interfaces or helpers for the WebAssembly Runtime to load the bpf object into the kernel and interact with it, because `WASI` does not have any modules for executing eBPF programs. In other words, we need to create an abstraction layer between the WebAssembly Runtime and the libbpf library.
2. port some library to wasm, like `argp` to wasm, because `WASI` only has standard c library supported.
3. create some special headers to replace the origin libbpf headers, which will convert the `libbpf` APIs to our ABI interfaces between libbpf and WebAssembly runtime.

> Note: We must do data serialization for passing all structured data or class objects between the two worlds of WASM and native(eBPF).

Some small problems may need to be fixed, but I think we may no need to do many code modifications.

## some usage examples

Take the `sigsnoop` tool as an example, we can use the following command to run it from the cloud:

```console
$ sudo ./ecli run sigsnoop
TIME PID COMM SIG TPID RESULT
12:47:32 2268659 node 0 2268239 0
12:47:32 0 swapper/1 14 847 0
12:47:32 2554426 cpptools-srv 0 2268736 0
12:47:32 2268659 node 0 2268239 0
12:47:32 2211204 YDService 0 2268239 0
12:47:32 2211204 YDService 0 2268229 0
12:47:32 2211204 YDService 0 2268185 0
12:47:32 2211204 YDService 0 2268184 0
```

Or you can compile the `sigsnoop` tool locally to Wasm and run it:

```console
$ sudo ./ecli run sigsnoop.wasm
Trace standard and real-time signals.

USAGE: sigsnoop [-h] [-x] [-k] [-n] [-p PID] [-s SIGNAL]

EXAMPLES:
sigsnoop # trace signals system-wide
sigsnoop -k # trace signals issued by kill syscall only
sigsnoop -x # trace failed signals only
sigsnoop -p 1216 # only trace PID 1216
sigsnoop -s 9 # only trace signal
```

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with libbpf-tools/sigsnoop.c and the referenced eunomia-bpf sigsnoop example, then review the proposed bpftool, WASI, ABI, and launcher workflow. Done would require a defined runtime interface, the needed wasm support, and a working sigsnoop wasm execution path as described in the proposal.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, linux, wasm
Domain
cloud, devtools, operating-systems
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.