个人学习bcc也有一段时间了,针对个人需求,也写了一个bcc的脚本,主要用于trace cwnd,因为自己在编写过程中也遇到了一些难点,所以把自己的代码发出来,跟大家分享一下,给大家一个参照,毕竟光指着reference_guide、tutorial和bcc Python Developer Tutorial还是会有些问题,当然了,我个人也是主要参考了这些资料。大家看了有疑问的话可以评论问我。
#!/usr/bin/python
from __future__ import print_function
from bcc import BPF
from time import sleep
# load BPF program
bpf_text="""
#include<linux/tcp.h>
struct key_t {
u64 cwnd;
u64 ts;
};
BPF_HASH(snd_cwnd);
BPF_HASH(cwnd_count);
BPF_HASH(statsave, struct key_t);
int tcp_rcv_established_entry(struct pt_regs *ctx, struct sock *sk) {
struct tcp_sock *tp = tcp_sk(sk);
u64 cwnd, *cwnd_pre, *count_pre, count, key_cwnd = 0, key_count = 0, zero = 0;
struct key_t key_save = {};
cwnd = tp->snd_cwnd;
cwnd_pre = snd_cwnd.lookup(&key_cwnd);
if (cwnd_pre == NULL) {
snd_cwnd.update(&key_cwnd, &zero);
return 0;
}
count_pre = cwnd_count.lookup(&key_count);
if (count_pre == NULL)
count = 1;
else
count = *count_pre;
if (cwnd != *cwnd_pre) {
key_save.cwnd = *cwnd_pre;
key_save.ts = bpf_ktime_get_ns();
statsave.update(&key_save, &count);
snd_cwnd.update(&key_cwnd, &cwnd);
count = 1;
cwnd_count.update(&key_count, &count);
} else {
count++;
cwnd_count.update(&key_count, &count);
}
return 0;
}
"""
### Python
# load BPF program
b = BPF(text=bpf_text)
b.attach_kprobe(event="tcp_rcv_established",
fn_name="tcp_rcv_established_entry")
try:
sleep(9999999999)
except KeyboardInterrupt:
pass
# print output
print("")
print(" %s %s %s" % ("time(ns)", "CWND", "COUNT"))
counts = b.get_table("statsave")
for k, v in sorted(counts.items(), key = lambda counts: counts[0].ts):
print("%d %5d %5d" % (k.ts, k.cwnd, v.value))
如果觉得这篇文章有用的话,可以点赞、评论或者收藏,万分感谢,goodbye~