1 /*
2 * CGroupTest Demonstrate how to use BPF cgroup API to collect file open event
3 *
4 * Basic example of cgroup and BPF kprobes.
5 *
6 * USAGE: CGroupTest cgroup2_path
7 *
8 * EXAMPLES:
9 * 1. Create a directory under cgroup2 mountpoint:
10 * $ sudo mkdir /sys/fs/cgroup/unified/test
11 * 2. Add current bash into the testing cgroup:
12 * $ sudo echo $$ | sudo tee -a /sys/fs/cgroup/unified/test/cgroup.procs
13 * 3. Open another bash window, and start CGroupTest as:
14 * $ sudo ./examples/cpp/CGroupTest /sys/fs/cgroup/unified/test
15 * 4. Run file open activity from previous bash window should be printed.
16 *
17 * Copyright (c) Jinshan Xiong
18 * Licensed under the Apache License, Version 2.0 (the "License")
19 */
20
21 #include <unistd.h>
22 #include <fstream>
23 #include <cstdlib>
24 #include <iomanip>
25 #include <iostream>
26 #include <string>
27
28 #include "BPF.h"
29
30 const std::string BPF_PROGRAM = R"(
31 #include <linux/sched.h>
32 #include <linux/path.h>
33 #include <linux/dcache.h>
34
35 BPF_CGROUP_ARRAY(cgroup, 1);
36
37 int on_vfs_open(struct pt_regs *ctx, struct path *path) {
38 if (cgroup.check_current_task(0) > 0)
39 bpf_trace_printk("file '%s' was opened!\n", path->dentry->d_name.name);
40 return 0;
41 }
42 )";
43
main(int argc,char ** argv)44 int main(int argc, char** argv) {
45 if (argc != 2) {
46 std::cerr << argv[0] << ": requires _one_ cgroup path" << std::endl;
47 return 1;
48 }
49
50 ebpf::BPF bpf;
51 auto init_res = bpf.init(BPF_PROGRAM);
52 if (!init_res.ok()) {
53 std::cerr << init_res.msg() << std::endl;
54 return 1;
55 }
56
57 auto cgroup_array = bpf.get_cgroup_array("cgroup");
58 auto update_res = cgroup_array.update_value(0, argv[1]);
59 if (!update_res.ok()) {
60 std::cerr << update_res.msg() << std::endl;
61 return 1;
62 }
63
64 auto attach_res =
65 bpf.attach_kprobe("vfs_open", "on_vfs_open");
66 if (!attach_res.ok()) {
67 std::cerr << attach_res.msg() << std::endl;
68 return 1;
69 }
70
71 std::ifstream pipe("/sys/kernel/debug/tracing/trace_pipe");
72 std::string line;
73
74 std::cout << "Started tracing open event, hit Ctrl-C to terminate." << std::endl;
75 while (std::getline(pipe, line))
76 std::cout << line << std::endl;
77
78 auto detach_res = bpf.detach_kprobe("vfs_open");
79 if (!detach_res.ok()) {
80 std::cerr << detach_res.msg() << std::endl;
81 return 1;
82 }
83
84 return 0;
85 }
86