mirror of
https://gitlab.com/game-loader/hugo.git
synced 2025-04-20 22:12:07 +08:00
55 lines
2.4 KiB
Markdown
55 lines
2.4 KiB
Markdown
+++
|
||
title = "Bootstrap"
|
||
author = "Logic"
|
||
date = 2022-03-12
|
||
draft = false
|
||
+++
|
||
|
||
## 数据交互 {#数据交互}
|
||
|
||
bootstrap本身是个很基础的bpf程序,但也是一个非常经典的bpf程序,根据作者的说法,这个bpf程序是自己写bpf程序的起点,主要原因在于它是一个经典的bpf程序和用户空间进行数据交互的案例。
|
||
|
||
|
||
### bpf部分 {#bpf部分}
|
||
|
||
bpf部分主要设定了两个数据结构,一个是用于存储调用了exec的进程信息的exec_start,另外一个是保存用于与用户空间进行交互的缓冲区ring buffer,这两个数据结构都放在map节中。在使用SEC宏设定插桩点后,宏后面的函数即为对该插桩点的处理函数,libbpf会进行处理给该函数传递系统调用的参数构成的结构体作为参数。接下来就是bpf程序对进程的一些参数进行处理。
|
||
|
||
|
||
#### exec_start {#exec-start}
|
||
|
||
值得注意的是这一句
|
||
|
||
```C
|
||
bpf_map_update_elem(&exec_start, &pid, &ts, BPF_ANY);
|
||
```
|
||
|
||
这一句更新了exec_start结构中的数据,即添加监视到的进程的pid和调用时间。方便之后使用。
|
||
|
||
|
||
#### ringbuf部分 {#ringbuf部分}
|
||
|
||
该部分核心就是两个函数调用
|
||
|
||
```C
|
||
e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0);
|
||
......(对event中的数据进行一些处理)
|
||
bpf_ringbuf_submit(e, 0);
|
||
```
|
||
|
||
rb是在之前就申请的缓冲区空间,在这里先用reserve在申请的空间中预定event大小的区域用于存放数据,在放入指定数据后使用submit提交给用户空间。
|
||
|
||
|
||
### 用户空间 {#用户空间}
|
||
|
||
用户空间的处理主要由下面两个函数完成
|
||
|
||
```C
|
||
/* Set up ring buffer polling */
|
||
rb = ring_buffer__new(bpf_map__fd(skel->maps.rb), handle_event, NULL, NULL);
|
||
err = ring_buffer__poll(rb, 100 /* timeout, ms */);
|
||
```
|
||
|
||
由注释可知第一句是构建一个ring buffer polling,对于加入该函数对应的修改说明,可以通过查看邮件列表中对应的[patch](https://www.spinics.net/lists/netdev/msg653671.htmll)来查看。其中的说明简单概括为poll为当数据可用时回调,而consume则是无论是否有可用数据都进行处理。处理所用的回调函数就是已经预先构造好的handle_event,这个函数的功能就是简单的打印使用了该系统调用的进程信息。
|
||
|
||
总体来说,流程如下。bpf构造ringbuf->用户空间设定ring buffer polling->bpf监控的监控点有事件发生->将信息放入事件并提交给用户空间->用户空间进行处理
|