[Proposal] Support compile libbpf-tools to Wasm(WebAssembly) and get tools running from the cloud in 1 line
- 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