设为首页 加入收藏

TOP

how-to-write-rust-in-wasm(二)
2023-07-23 13:38:59 】 浏览:66
Tags:how-to-write-rust-in-wasm
5946"}

这个包支持用 wit 文件为 rust 客户程序生成绑定。使用这个包的情况下,我们不需要再手动运行 wit-bindgen。

接下来,我们使用 btf2wit 工具,从 BTF 信息生成 wit 文件。可以使用 cargo install btf2wit 安装我们提供的 btf2wit 工具,并编译生成 wit 信息:

cd btf
clang -target bpf -g event-def.c -c -o event.def.o
btf2wit event.def.o -o event-def.wit
cp *.wit ../wit/
  • 其中 event-def.c 是包含了我们需要的结构体信息的的 C 程序文件。只有在导出符号中用到的结构体才会被记录在 BTF 中。

对于 C 结构体生成的 wit 信息,大致如下:

default world host {
    record event {
         pid: s32,
        ppid: s32,
        exit-code: u32,
        --pad0: list<s8>,
        duration-ns: u64,
        comm: list<s8>,
        filename: list<s8>,
        exit-event: s8,
    }
}

wit-bindgen-guest-rust 会为 wit 文件夹中的所有类型信息,自动生成 rust 的类型,例如:

#[repr(C, packed)]
#[derive(Debug, Copy, Clone)]
struct Event {
    pid: i32,
    ppid: i32,
    exit_code: u32,
    __pad0: [u8; 4],
    duration_ns: u64,
    comm: [u8; 16],
    filename: [u8; 127],
    exit_event: u8,
}

编写用户态加载和处理代码

为了在 WASI 上运行,需要为 main.rs 添加 #![no_main] 属性,并且 main 函数需要采用类似如下的形态:

#[export_name = "__main_argc_argv"]
fn main(_env_json: u32, _str_len: i32) -> i32 {

    return 0;
}

用户态加载和挂载代码,和 C/C++ 中类似:

    let obj_ptr =
        binding::wasm_load_bpf_object(bpf_object.as_ptr() as u32, bpf_object.len() as i32);
    if obj_ptr == 0 {
        println!("Failed to load bpf object");
        return 1;
    }
    let attach_result = binding::wasm_attach_bpf_program(
        obj_ptr,
        "handle_exec\0".as_ptr() as u32,
        "\0".as_ptr() as u32,
    );
    ...

polling ring buffer:

    let map_fd = binding::wasm_bpf_map_fd_by_name(obj_ptr, "rb\0".as_ptr() as u32);
    if map_fd < 0 {
        println!("Failed to get map fd: {}", map_fd);
        return 1;
    }
    // binding::wasm
    let buffer = [0u8; 256];
    loop {
        // polling the buffer
        binding::wasm_bpf_buffer_poll(
            obj_ptr,
            map_fd,
            handle_event as i32,
            0,
            buffer.as_ptr() as u32,
            buffer.len() as i32,
            100,
        );
    }

使用 handler 接收返回值:


extern "C" fn handle_event(_ctx: u32, data: u32, _data_sz: u32) {
    let event_slice = unsafe { slice::from_raw_parts(data as *const Event, 1) };
    let event = &event_slice[0];
    let pid = event.pid;
    let ppid = event.ppid;
    let exit_code = event.exit_code;
    if event.exit_event == 1 {
        print!(
            "{:<8} {:<5} {:<16} {:<7} {:<7} [{}]",
            "TIME",
            "EXIT",
            unsafe { CStr::from_ptr(event.comm.as_ptr() as *const i8) }
                .to_str()
                .unwrap(),
            pid,
            ppid,
            exit_code
        );
        ...
}

接下来即可使用 cargo 编译运行:

$ cargo build --target wasi32-wasm
$ sudo wasm-bpf ./target/wasm32-wasi/debug/rust-helloworld.wasm
TIME     EXEC  sh               180245  33666   /bin/sh
TIME     EXEC  which            180246  180245  /usr/bin/which
TIME     EXIT  which            180246  180245  [0] (1ms)
TIME     EXIT  sh               180245  33666   [0] (3ms)
TIME     EXEC  sh               180247  33666   /bin/sh
TIME     EXEC  ps               180248  180247  /usr/bin/ps
TIME     EXIT  ps               180248  180247  [0] (23ms)
TIME     EXIT  sh               180247  33666   [0] (25ms)
TIME     EXEC  sh               180249  33666   /bin/sh
TIME     EXEC  cpuUsage.sh      180250  180249  /root/.vscode-server-insiders/bin/a7d49b0f35f50e460835a55d20a00a735d1665a3/out/vs/base/node/cpuUsage.sh

使用 OCI 镜像发布和管理 eBPF 程序

开放容器协议 (OCI) 是一个轻量级,开放的治理结构,为容器技术定义了规范和标准。在 Linux 基金会的支持下成立,由各大软件企业构成,致力于围绕容器格式和运行时创建开放的行业标准。其中包括了使用 Container Registries 进行工作的 API,正式名称为 OCI 分发规范 (又名“distribution-spec”)。

Docker 也宣布推出与 WebAssembly 集成 (Docker+Wasm) 的首个技术预览版,并表示公司已加入字节码联盟 (Bytecode Alliance),成为投票成员。Docker+Wasm 让开发者能够更容易地快速构建面向 Wasm 运行时的应用程序。

借助于 Wasm 的相关生态,可以非常方便地发布、下载和管理 eBPF 程序,例如,使用 wasm-to-oci 工具,可以将 Wasm 程序打包为 OCI 镜像,获取类似 dock

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Shell命令-常用操作2 下一篇进程间的6种通信

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目