-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tools/bpf: add a selftest for bpf_get_current_cgroup_id() helper
Syscall name_to_handle_at() can be used to get cgroup id for a particular cgroup path in user space. The selftest got cgroup id from both user and kernel, and compare to ensure they are equal to each other. Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Yonghong Song <yhs@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
- Loading branch information
Yonghong Song
authored and
Alexei Starovoitov
committed
Jun 4, 2018
1 parent
c7ddbba
commit f269099
Showing
6 changed files
with
232 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,3 +18,4 @@ urandom_read | |
test_btf | ||
test_sockmap | ||
test_lirc_mode2_user | ||
get_cgroup_id_user |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
// Copyright (c) 2018 Facebook | ||
|
||
#include <linux/bpf.h> | ||
#include "bpf_helpers.h" | ||
|
||
struct bpf_map_def SEC("maps") cg_ids = { | ||
.type = BPF_MAP_TYPE_ARRAY, | ||
.key_size = sizeof(__u32), | ||
.value_size = sizeof(__u64), | ||
.max_entries = 1, | ||
}; | ||
|
||
SEC("tracepoint/syscalls/sys_enter_nanosleep") | ||
int trace(void *ctx) | ||
{ | ||
__u32 key = 0; | ||
__u64 *val; | ||
|
||
val = bpf_map_lookup_elem(&cg_ids, &key); | ||
if (val) | ||
*val = bpf_get_current_cgroup_id(); | ||
|
||
return 0; | ||
} | ||
|
||
char _license[] SEC("license") = "GPL"; | ||
__u32 _version SEC("version") = 1; /* ignored by tracepoints, required by libbpf.a */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
// Copyright (c) 2018 Facebook | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <errno.h> | ||
#include <fcntl.h> | ||
#include <syscall.h> | ||
#include <unistd.h> | ||
#include <linux/perf_event.h> | ||
#include <sys/ioctl.h> | ||
#include <sys/time.h> | ||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
|
||
#include <linux/bpf.h> | ||
#include <bpf/bpf.h> | ||
#include <bpf/libbpf.h> | ||
|
||
#include "cgroup_helpers.h" | ||
#include "bpf_rlimit.h" | ||
|
||
#define CHECK(condition, tag, format...) ({ \ | ||
int __ret = !!(condition); \ | ||
if (__ret) { \ | ||
printf("%s:FAIL:%s ", __func__, tag); \ | ||
printf(format); \ | ||
} else { \ | ||
printf("%s:PASS:%s\n", __func__, tag); \ | ||
} \ | ||
__ret; \ | ||
}) | ||
|
||
static int bpf_find_map(const char *test, struct bpf_object *obj, | ||
const char *name) | ||
{ | ||
struct bpf_map *map; | ||
|
||
map = bpf_object__find_map_by_name(obj, name); | ||
if (!map) | ||
return -1; | ||
return bpf_map__fd(map); | ||
} | ||
|
||
#define TEST_CGROUP "/test-bpf-get-cgroup-id/" | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
const char *probe_name = "syscalls/sys_enter_nanosleep"; | ||
const char *file = "get_cgroup_id_kern.o"; | ||
int err, bytes, efd, prog_fd, pmu_fd; | ||
struct perf_event_attr attr = {}; | ||
int cgroup_fd, cgidmap_fd; | ||
struct bpf_object *obj; | ||
__u64 kcgid = 0, ucgid; | ||
int exit_code = 1; | ||
char buf[256]; | ||
__u32 key = 0; | ||
|
||
err = setup_cgroup_environment(); | ||
if (CHECK(err, "setup_cgroup_environment", "err %d errno %d\n", err, | ||
errno)) | ||
return 1; | ||
|
||
cgroup_fd = create_and_get_cgroup(TEST_CGROUP); | ||
if (CHECK(cgroup_fd < 0, "create_and_get_cgroup", "err %d errno %d\n", | ||
cgroup_fd, errno)) | ||
goto cleanup_cgroup_env; | ||
|
||
err = join_cgroup(TEST_CGROUP); | ||
if (CHECK(err, "join_cgroup", "err %d errno %d\n", err, errno)) | ||
goto cleanup_cgroup_env; | ||
|
||
err = bpf_prog_load(file, BPF_PROG_TYPE_TRACEPOINT, &obj, &prog_fd); | ||
if (CHECK(err, "bpf_prog_load", "err %d errno %d\n", err, errno)) | ||
goto cleanup_cgroup_env; | ||
|
||
cgidmap_fd = bpf_find_map(__func__, obj, "cg_ids"); | ||
if (CHECK(cgidmap_fd < 0, "bpf_find_map", "err %d errno %d\n", | ||
cgidmap_fd, errno)) | ||
goto close_prog; | ||
|
||
snprintf(buf, sizeof(buf), | ||
"/sys/kernel/debug/tracing/events/%s/id", probe_name); | ||
efd = open(buf, O_RDONLY, 0); | ||
if (CHECK(efd < 0, "open", "err %d errno %d\n", efd, errno)) | ||
goto close_prog; | ||
bytes = read(efd, buf, sizeof(buf)); | ||
close(efd); | ||
if (CHECK(bytes <= 0 || bytes >= sizeof(buf), "read", | ||
"bytes %d errno %d\n", bytes, errno)) | ||
goto close_prog; | ||
|
||
attr.config = strtol(buf, NULL, 0); | ||
attr.type = PERF_TYPE_TRACEPOINT; | ||
attr.sample_type = PERF_SAMPLE_RAW; | ||
attr.sample_period = 1; | ||
attr.wakeup_events = 1; | ||
|
||
/* attach to this pid so the all bpf invocations will be in the | ||
* cgroup associated with this pid. | ||
*/ | ||
pmu_fd = syscall(__NR_perf_event_open, &attr, getpid(), -1, -1, 0); | ||
if (CHECK(pmu_fd < 0, "perf_event_open", "err %d errno %d\n", pmu_fd, | ||
errno)) | ||
goto close_prog; | ||
|
||
err = ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0); | ||
if (CHECK(err, "perf_event_ioc_enable", "err %d errno %d\n", err, | ||
errno)) | ||
goto close_pmu; | ||
|
||
err = ioctl(pmu_fd, PERF_EVENT_IOC_SET_BPF, prog_fd); | ||
if (CHECK(err, "perf_event_ioc_set_bpf", "err %d errno %d\n", err, | ||
errno)) | ||
goto close_pmu; | ||
|
||
/* trigger some syscalls */ | ||
sleep(1); | ||
|
||
err = bpf_map_lookup_elem(cgidmap_fd, &key, &kcgid); | ||
if (CHECK(err, "bpf_map_lookup_elem", "err %d errno %d\n", err, errno)) | ||
goto close_pmu; | ||
|
||
ucgid = get_cgroup_id(TEST_CGROUP); | ||
if (CHECK(kcgid != ucgid, "compare_cgroup_id", | ||
"kern cgid %llx user cgid %llx", kcgid, ucgid)) | ||
goto close_pmu; | ||
|
||
exit_code = 0; | ||
printf("%s:PASS\n", argv[0]); | ||
|
||
close_pmu: | ||
close(pmu_fd); | ||
close_prog: | ||
bpf_object__close(obj); | ||
cleanup_cgroup_env: | ||
cleanup_cgroup_environment(); | ||
return exit_code; | ||
} |