Commit 22110ad2 authored by Alban Crequy's avatar Alban Crequy

Add filter by cgroup-v2 id

To get the cgroup id, you can use the following program to call
name_to_handle_at(), borrowed from
linux/tools/testing/selftests/bpf/cgroup_helpers.c:
```
wget https://gist.githubusercontent.com/alban/4a9aea9636d9fdf11709eddd21df4cc4/raw/f4fc915483a069d6044957e27df091923f95c48b/getcgroupid.c
gcc -Wall -o getcgroupid getcgroupid.c
./getcgroupid /sys/fs/cgroup/unified/
0x100000001
4294967297
```

To test it, I run the tracer in one terminal:
```
./build.sh
sudo ./build-release/src/bpftrace -e 'tracepoint:syscalls:sys_enter_openat /cgroup == 0x100000001/ { printf("%s\n", str(args->filename)); }'
```

And some tests in another terminal:
```
sudo -s
echo $$ > /sys/fs/cgroup/unified/cgroup.procs
cat /dev/null
```

And observe the output of the tracer:
```
Attaching 1 probe...
/etc/ld.so.cache
/lib64/libc.so.6
/usr/lib/locale/locale-archive
/dev/null
^C
```
parent 4c606137
......@@ -130,6 +130,9 @@ bpftrace -e 'hardware:cache-misses:1000000 { @[comm, pid] = count(); }'
# Profile user-level stacks at 99 Hertz, for PID 189:
bpftrace -e 'profile:hz:99 /pid == 189/ { @[ustack] = count(); }'
# Files opened, for processes in the root cgroup-v2
bpftrace -e 'tracepoint:syscalls:sys_enter_open /cgroup == 0x100000001/ { printf("%s\n", str(args->filename)); }'
```
## Tools
......@@ -233,6 +236,7 @@ The following variables and functions are available for use in bpftrace scripts:
Variables:
- `pid` - Process ID (kernel tgid)
- `tid` - Thread ID (kernel pid)
- `cgroup` - Cgroup ID of the current process
- `uid` - User ID
- `gid` - Group ID
- `nsecs` - Nanosecond timestamp
......
......@@ -54,6 +54,10 @@ void CodegenLLVM::visit(Builtin &builtin)
expr_ = b_.CreateAnd(pidtgid, 0xffffffff);
}
}
else if (builtin.ident == "cgroup")
{
expr_ = b_.CreateGetCurrentCgroupId();
}
else if (builtin.ident == "uid" || builtin.ident == "gid" || builtin.ident == "username")
{
Value *uidgid = b_.CreateGetUidGid();
......
......@@ -411,6 +411,19 @@ CallInst *IRBuilderBPF::CreateGetPidTgid()
return CreateCall(getpidtgid_func, {}, "get_pid_tgid");
}
CallInst *IRBuilderBPF::CreateGetCurrentCgroupId()
{
// u64 bpf_get_current_cgroup_id(void)
// Return: 64-bit cgroup-v2 id
FunctionType *getcgroupid_func_type = FunctionType::get(getInt64Ty(), false);
PointerType *getcgroupid_func_ptr_type = PointerType::get(getcgroupid_func_type, 0);
Constant *getcgroupid_func = ConstantExpr::getCast(
Instruction::IntToPtr,
getInt64(BPF_FUNC_get_current_cgroup_id),
getcgroupid_func_ptr_type);
return CreateCall(getcgroupid_func, {}, "get_cgroup_id");
}
CallInst *IRBuilderBPF::CreateGetUidGid()
{
// u64 bpf_get_current_uid_gid(void)
......
......@@ -38,6 +38,7 @@ public:
Value *CreateStrcmp(Value* val, std::string str, bool inverse=false);
CallInst *CreateGetNs();
CallInst *CreateGetPidTgid();
CallInst *CreateGetCurrentCgroupId();
CallInst *CreateGetUidGid();
CallInst *CreateGetCpuId();
CallInst *CreateGetCurrentTask();
......
......@@ -31,6 +31,7 @@ void SemanticAnalyser::visit(Builtin &builtin)
if (builtin.ident == "nsecs" ||
builtin.ident == "pid" ||
builtin.ident == "tid" ||
builtin.ident == "cgroup" ||
builtin.ident == "uid" ||
builtin.ident == "gid" ||
builtin.ident == "cpu" ||
......
......@@ -48,7 +48,7 @@ path :(\\.|[_\-\./a-zA-Z0-9])*:
<COMMENT>"*/" BEGIN(INITIAL);
<COMMENT>"EOF" driver.error(loc, std::string("end of file during comment"));
pid|tid|uid|gid|nsecs|cpu|comm|stack|ustack|arg[0-9]|retval|func|name|curtask|rand|ctx|username|args {
pid|tid|cgroup|uid|gid|nsecs|cpu|comm|stack|ustack|arg[0-9]|retval|func|name|curtask|rand|ctx|username|args {
return Parser::make_BUILTIN(yytext, loc); }
{path} { return Parser::make_PATH(yytext, loc); }
{map} { return Parser::make_MAP(yytext, loc); }
......
......@@ -25,6 +25,7 @@ TEST(Parser, builtin_variables)
{
test("kprobe:f { pid }", "Program\n kprobe:f\n builtin: pid\n");
test("kprobe:f { tid }", "Program\n kprobe:f\n builtin: tid\n");
test("kprobe:f { cgroup }", "Program\n kprobe:f\n builtin: cgroup\n");
test("kprobe:f { uid }", "Program\n kprobe:f\n builtin: uid\n");
test("kprobe:f { username }", "Program\n kprobe:f\n builtin: username\n");
test("kprobe:f { gid }", "Program\n kprobe:f\n builtin: gid\n");
......
......@@ -48,6 +48,7 @@ TEST(semantic_analyser, builtin_variables)
{
test("kprobe:f { pid }", 0);
test("kprobe:f { tid }", 0);
test("kprobe:f { cgroup }", 0);
test("kprobe:f { uid }", 0);
test("kprobe:f { username }", 0);
test("kprobe:f { gid }", 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment