dkapture-bpf/observe/hrtimer.bpf.c

254 lines
5.5 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd
//
// SPDX-License-Identifier: GPL-2.0
/**
* 通过使用
* kprobe内核探针在hrtimer_nanosleep函数的入口和退出处放置钩子实现对该系统调用的跟踪
*/
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
// 定义许可证,以允许程序在内核中运行
char LICENSE[] SEC("license") = "Dual BSD/GPL";
const volatile bool filter_cg = false;
const volatile bool targ_relative_time = false;
const volatile bool targ_unit_ms = false;
const volatile pid_t targ_tgid = 0;
const volatile int targ_time = 0;
struct
{
__uint(type, BPF_MAP_TYPE_RINGBUF);
__uint(max_entries, 256 * 1024);
} rb SEC(".maps");
struct
{
__uint(type, BPF_MAP_TYPE_CGROUP_ARRAY);
__type(key, u32);
__type(value, u32);
__uint(max_entries, 1);
} cgroup_map SEC(".maps");
struct nanosleep_args_t
{
struct __kernel_timespec rqt;
struct __kernel_timespec rmt;
};
struct
{
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 4096);
__type(key, u32);
__type(value, struct nanosleep_args_t);
} active_nanosleep_args_map SEC(".maps");
struct clock_nanosleep_args_t
{
clockid_t which_clock;
int flags;
struct __kernel_timespec rqt;
struct __kernel_timespec rmt;
};
struct
{
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 4096);
__type(key, u32);
__type(value, struct clock_nanosleep_args_t);
} active_clock_nanosleep_args_map SEC(".maps");
// 定义一个名为hrtimer_nanosleep的
// kprobe当进入hrtimer_nanosleep函数时它会被触发
SEC("kprobe/hrtimer_nanosleep")
int BPF_KPROBE(
hrtimer_nanosleep,
ktime_t rqtp,
enum hrtimer_mode mode,
clockid_t clockid
) // 捕获函数的参数
{
// 获取当前进程的 PID 和 TGID
__u64 pid_tgid = bpf_get_current_pid_tgid();
__u32 pid = (__u32)(pid_tgid >> 32); // 获取 PID
__u32 tgid = (__u32)(pid_tgid); // 获取 TGID
// if (targ_tgid && targ_tgid != tgid)
// return 0;
// 打印参数到内核日志
bpf_printk(
"hrtimer_nanosleep called with: rqtp=%ld ns, mode=%d, clockid=%d, "
"PID=%d, TGID=%d\n",
rqtp,
mode,
clockid,
pid,
tgid
);
return 0;
}
SEC("tracepoint/syscalls/sys_enter_nanosleep")
int tracepoint__syscalls__sys_enter_nanosleep(
struct trace_event_raw_sys_enter *ctx
)
{
// 获取当前进程的 PID 和 TGID
__u64 pid_tgid = bpf_get_current_pid_tgid();
__u32 tgid = (__u32)(pid_tgid); // 获取 TGID
struct nanosleep_args_t nanosleep_args;
// bpf_printk("sys_enter_clock_nanosleep pid=%d, targ_tgid:PID=%d,
// targ_times_sec = %d, targ_times_msec = %d\n",pid ,targ_tgid,
// targ_times_sec , targ_times_msec);
if (filter_cg && !bpf_current_task_under_cgroup(&cgroup_map, 0))
{
return 0;
}
if (targ_tgid && targ_tgid != tgid)
{
return 0;
}
bpf_probe_read_user(
&nanosleep_args.rqt,
sizeof(nanosleep_args.rqt),
(struct __kernel_timespec *)ctx->args[0]
);
// bpf_printk("sys_enter_nanosleep called with:PID=%d tv_sec = %lld tv_nsec
// = %lld\n", pid ,nanosleep_args.rqtp->tv_sec,
// nanosleep_args.rqtp->tv_nsec);
if (targ_relative_time)
{
if (targ_unit_ms)
{
// nanosleep_args.rqt.tv_sec = 0;
nanosleep_args.rqt.tv_nsec += targ_time * 1000000;
}
else
{
nanosleep_args.rqt.tv_sec += targ_time;
}
}
else
{
if (targ_unit_ms)
{
nanosleep_args.rqt.tv_sec = 0;
nanosleep_args.rqt.tv_nsec = targ_time * 1000000;
}
else
{
nanosleep_args.rqt.tv_sec = targ_time;
nanosleep_args.rqt.tv_nsec = 0;
}
}
bpf_map_update_elem(
&active_nanosleep_args_map,
&tgid,
&nanosleep_args,
BPF_ANY
);
// bpf_printk("sys_enter_nanosleep called with:PID=%d tv_sec =%d tv_sec =
// %d\n",
// tgid, nanosleep_args.rqt.tv_sec, nanosleep_args.rqt.tv_nsec);
bpf_probe_write_user(
(struct __kernel_timespec *)ctx->args[0],
&nanosleep_args.rqt,
sizeof(nanosleep_args.rqt)
);
return 0;
}
SEC("tracepoint/syscalls/sys_enter_clock_nanosleep")
int tracepoint__syscalls__sys_enter_clock_nanosleep(
struct trace_event_raw_sys_enter *ctx
)
{
// 获取当前进程的 PID 和 TGID
__u64 pid_tgid = bpf_get_current_pid_tgid();
__u32 tgid = (__u32)(pid_tgid); // 获取 TGID
struct clock_nanosleep_args_t clock_nanosleep_args;
// bpf_printk("sys_enter_clock_nanosleep pid=%d, targ_tgid:PID=%d,
// targ_times_sec = %d, targ_times_msec = %d\n",pid ,targ_tgid,
// targ_times_sec , targ_times_msec);
if (filter_cg && !bpf_current_task_under_cgroup(&cgroup_map, 0))
{
return 0;
}
if (targ_tgid && targ_tgid != tgid)
{
return 0;
}
bpf_probe_read_user(
&clock_nanosleep_args.rqt,
sizeof(clock_nanosleep_args.rqt),
(struct __kernel_timespec *)ctx->args[2]
);
if (targ_relative_time)
{
if (targ_unit_ms)
{
// clock_nanosleep_args.rqt.tv_sec = 0;
clock_nanosleep_args.rqt.tv_nsec += targ_time * 1000000;
}
else
{
clock_nanosleep_args.rqt.tv_sec += targ_time;
}
}
else
{
if (targ_unit_ms)
{
clock_nanosleep_args.rqt.tv_sec = 0;
clock_nanosleep_args.rqt.tv_nsec = targ_time * 1000000;
}
else
{
clock_nanosleep_args.rqt.tv_sec = targ_time;
clock_nanosleep_args.rqt.tv_nsec = 0;
}
}
bpf_map_update_elem(
&active_nanosleep_args_map,
&tgid,
&clock_nanosleep_args,
BPF_ANY
);
// bpf_printk("sys_enter_clock_nanosleep called with:PID=%d tv_sec = %ld
// tv_nsec = %ld\n", tgid ,clock_nanosleep_args.rqt.tv_sec,
// clock_nanosleep_args.rqt.tv_nsec);
bpf_probe_write_user(
(struct __kernel_timespec *)ctx->args[2],
&clock_nanosleep_args.rqt,
sizeof(clock_nanosleep_args.rqt)
);
return 0;
}