最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

一文解決eBpf在Android上的集成和調試

2023-05-15 16:41 作者:補給站Linux內核  | 我要投稿

eBPF(Extended Berkeley Packet Filter )是一種新興的linux內核功能擴展技術,可以無需修改內核代碼,在保證安全的前提下,靈活的動態(tài)加載程序,實現(xiàn)對內核功能的擴展。

Android平臺上也引入了對eBpf技術的支持,本文以一些典型使用場景,貫穿eBpf在android上的使用流程,展示如何在手機上集成和調試eBpf程序。

如下圖示,為bpf的基本部署流程,在android上也是適用的。




一、Bpf程序編寫

Android的eBpf程序源碼,位于system/bpfprogs,比如打開time_in_state.c可以看到程序總體上分為三個部分:

  • 使用DEFINE_BPF_MAP定義了一些Map數(shù)據(jù)結構,這些是用來實現(xiàn)用戶程序和內核互傳數(shù)據(jù)的共享緩存。

  • 使用DEFINE_BPF_PROG,定義了一個Bpf函數(shù),這個函數(shù)編譯后,可以加載進內核,實現(xiàn)鉤子函數(shù)的功能。

  • LICENSE("GPL") 許可協(xié)議聲明。

上述中,Map的類型,以及Bpf的hook類型,根據(jù)功能的不同有許多種類,可以參考https://github.com/iovisor/bcc/blob/master/docs/kernel-versions.md#program-types,里面有詳細的描述。


二、Bpf程序生成

當以C語言的格式編寫一個Bpf程序后,通過編譯,可以得到一個 “.o” 文件。此文件是以BTF(BPF Type Format) 字節(jié)碼編碼的元數(shù)據(jù)格式文件,并不可以直接執(zhí)行,需要加載到內核中,內核進行解析執(zhí)行,或者JIT轉換后執(zhí)行。

BTF格式文件可查看文檔:

https://www.kernel.org/doc/html/latest/bpf/btf.html


三、加載Bpf程序

Bpf程序在Android上有嚴格的權限控制,在bpfloader.te 中有限制bpf執(zhí)行的sepolicy,限定了bpfloader是唯一可以加載bpf程序的程序。

neverallow { domain -bpfloader } *:bpf { map_create prog_load };

而bpfloader只在手機啟動時執(zhí)行一次,保證了其它模塊無法額外加載系統(tǒng)之外的bpf程序,防止對內核的安全性造成危害。

在system/bpf/bpfloader/BpfLoader.cpp中,bpfloader會使用loadAllElfObjects遍歷/system/etc/bpf下btf格式的”.o”文件。接著使用android::bpf::loadProg解析bpf程序文件,實現(xiàn)創(chuàng)建Bpf程序和相應的Map。

Bpfloader執(zhí)行加載之后,會立即退出。Bpf程序的生命周期管理為引用計數(shù),類似文件句柄fd,當失去所有引用時,Bpf程序和map等對象就會被銷毀。

為了避免bpf prog和map對象在bpfloader執(zhí)行之后被銷毀, 最后會通過bpf_obj_pin把這些bpf對象映射到/sys/fs/bpf文件節(jié)點。映射的文件節(jié)點,其命名有特定的規(guī)則,以便其它的程序能夠通過文件路徑名稱來找到對應的bpf程序。


【文章福利】小編推薦自己的Linux內核技術交流群:【749907784】整理了一些個人覺得比較好的學習書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實戰(zhàn)項目及代碼)? ? ?

四、Attach Bpf程序

Bpf程序被加載之后,并沒有附著到內核函數(shù)上,此時bpf程序不會有任何執(zhí)行,還需要經過attach操作。attach指定把bpf程序hook到哪個內核監(jiān)控點上,具體有tracepoint,kprobe等幾十種類型。成功attach上的話,bpf程序就轉換為內核代碼的一個函數(shù)。

比如attach task_rename 這個tracepoint類型,可以用

cat/sys/kernel/tracing/events/task/task_rename/format來確認參數(shù),使得定義的bpf 函數(shù)和具體的tracepoint 函數(shù)參數(shù)一致。

如果是attach raw tracepoint,則需要自行構建參數(shù),因為raw tracepoint 訪問的是事件的原始參數(shù),未進行參數(shù)封裝,相比之下有更好一點的性能。

比如task_rename 這個tracepoint中,兩種類型的參數(shù)差異:



五、Update map

當Bpf附著到內核函數(shù)上,起到了一個鉤子函數(shù)的作用。鉤子函數(shù)在detach之前,可以一直偵測內核的執(zhí)行,有時候我們需要改變偵測的范圍,或者把偵測的結果上報,此時需要使用Map,Map是用戶監(jiān)控程序和內核間數(shù)據(jù)交換的媒介。用戶態(tài)和內核態(tài)都可以使用類似的接口來訪問Map。

典型操作

  • 在Map中查找記錄

void *bpf_map_lookup_elem(struct bpf_map *map, const void *key)

  • 在Map中更新記錄

long bpf_map_update_elem(struct bpf_map *map, const void *key, const void *value, u64 flags)

  • 在Map中刪除記錄

long bpf_map_delete_elem(struct bpf_map *map, const void *key)


六、Event 上報

一般的Map數(shù)據(jù),需要我們主動去讀取里面的數(shù)據(jù)。有時候,希望有數(shù)據(jù)時,能得到通知,而不是輪詢去讀取。此時,可以通過perf event map實現(xiàn)偵聽數(shù)據(jù)變化的功能。內核數(shù)據(jù)能夠存儲到自定義的數(shù)據(jù)結構中,并且通過 perf 事件ring緩存發(fā)送和廣播到用戶空間進程。

perf event map的構建流程:



上面構建流程完成后,用戶態(tài)和內核態(tài),就存在了event fd關聯(lián)。接著用戶態(tài)使用epoll來持續(xù)偵聽fd上的通知,而fd實際上是映射到了緩存,所以當偵聽到變化時,就可以到緩存中讀取具體的數(shù)據(jù)。




在內核中,則通過

bpf_perf_event_output(ctx,&events,BPF_F_CURRENT_CPU, &data, sizeof(data));

來通知數(shù)據(jù)。


BPF_F_CURRENT_CPU 參數(shù)指定了使用當前cpu的索引值來訪問event map中的fd,進而往fd對應的緩存填充數(shù)據(jù),這樣可以避免多cpu同時傳遞數(shù)據(jù)的同步問題,也解釋了上面event map初始化時,為何需要創(chuàng)建與cpu個數(shù)相等的大小。


七、調試

實際開發(fā)中,免不了需要反復調試的過程,遵照bpf的原理,在android上重新部署一個bpf程序可以采用如下步驟。

  1. Push 新的bpf.o 文件到/system/etc/bpf/ 中。

  2. 舊版本的bpf程序和map的映射文件仍然存在,需要進入/sys/fs/bpf,rm掉映射文件。舊bpf由于沒有了引用,就會被銷毀。

  3. 然后再次執(zhí)行/./system/bin/bpfloader,bpfloader就能夠和開機時一樣,把新的bpf.o再次加載起來。

注意:bpfloader在加載時打印的log太多,會觸發(fā)ratelimiting,有時候發(fā)現(xiàn)bpfloader不能加載新的bpf程序,也不能查到有報錯的信息??梢韵扔?#34;echo on > /proc/sys/kernel/printk_devkmsg" 指令關閉ratelimiting,此時就能正常發(fā)現(xiàn)錯誤了。


在成功掛載bpf程序之后,還需要確認其在內核中執(zhí)行的情況,使用bpf_printk輸出內核log。

查看內核日志可用:

$ echo 1 > /sys/kernel/tracing/tracing_on

$ cat /sys/kernel/tracing/trace_pipe


注意:bpf程序雖然用C 代碼格式書寫,但其最終為內核驗證執(zhí)行,會有許多安全和能力方面的限制,典型的如bpf_printk,只支持3個參數(shù)輸出,超過則會報錯。


八、結語

Bpf 可以hook 系統(tǒng)調用、tracepoint和內核函數(shù)等,其應用場景相當廣泛,目前在Android上的使用比較初步,還有很大的空間讓我們在實踐中進一步探索。

原文作者:內核工匠



一文解決eBpf在Android上的集成和調試的評論 (共 條)

分享到微博請遵守國家法律
明光市| 新营市| 云梦县| 黑龙江省| 甘洛县| 樟树市| 牟定县| 麦盖提县| 乐业县| 商南县| 台北市| 镇康县| 石门县| 唐海县| 盱眙县| 永平县| 建德市| 伊宁市| 开封市| 芮城县| 曲靖市| 甘南县| 梓潼县| 迁西县| 阿克| 中江县| 三穗县| 达拉特旗| 成都市| 新闻| 应城市| 阿瓦提县| 文登市| 巴中市| 武威市| 江城| 仪征市| 临安市| 深泽县| 达拉特旗| 弋阳县|