tools/testing/selftests/bpf/prog_tests/cgroup_hierarchical_stats.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/prog_tests/cgroup_hierarchical_stats.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/bpf/prog_tests/cgroup_hierarchical_stats.c- Extension
.c- Size
- 9168 bytes
- Lines
- 340
- Domain
- Support Tooling And Documentation
- Bucket
- tools
- Inferred role
- Support Tooling And Documentation: implementation source
- Status
- source implementation candidate
Why This File Exists
Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
asm-generic/errno.herrno.hsys/types.hsys/mount.hsys/stat.hunistd.htest_progs.hbpf/libbpf.hbpf/bpf.hcgroup_helpers.hcgroup_hierarchical_stats.skel.h
Detected Declarations
function cgroup_rstat_updatedfunction read_from_filefunction setup_bpffsfunction cleanup_bpffsfunction setup_cgroupsfunction cleanup_cgroupsfunction setup_hierarchyfunction destroy_hierarchyfunction attach_processesfunction get_attach_counterfunction check_attach_countersfunction setup_cgroup_iterfunction setup_progsfunction destroy_progsfunction test_cgroup_hierarchical_stats
Annotated Snippet
if (pid == 0) {
if (join_parent_cgroup(cgroups[i].path))
exit(EACCES);
exit(0);
}
/* Cleanup child */
waitpid(pid, &status, 0);
if (!ASSERT_TRUE(WIFEXITED(status), "child process exited"))
return 1;
if (!ASSERT_EQ(WEXITSTATUS(status), 0,
"child process exit code"))
return 1;
}
}
return 0;
}
static unsigned long long
get_attach_counter(unsigned long long cgroup_id, const char *file_name)
{
unsigned long long attach_counter = 0, id = 0;
static char buf[128], path[128];
/* For every cgroup, read the file generated by cgroup_iter */
snprintf(path, 128, "%s%s", BPFFS_ATTACH_COUNTERS, file_name);
if (!ASSERT_OK(read_from_file(path, buf, 128), "read cgroup_iter"))
return 0;
/* Check the output file formatting */
ASSERT_EQ(sscanf(buf, "cg_id: %llu, attach_counter: %llu\n",
&id, &attach_counter), 2, "output format");
/* Check that the cgroup_id is displayed correctly */
ASSERT_EQ(id, cgroup_id, "cgroup_id");
/* Check that the counter is non-zero */
ASSERT_GT(attach_counter, 0, "attach counter non-zero");
return attach_counter;
}
static void check_attach_counters(void)
{
unsigned long long attach_counters[N_CGROUPS], root_attach_counter;
int i;
for (i = 0; i < N_CGROUPS; i++)
attach_counters[i] = get_attach_counter(cgroups[i].id,
cgroups[i].name);
/* Read stats for root too */
root_attach_counter = get_attach_counter(CG_ROOT_ID, CG_ROOT_NAME);
/* Check that all leafs cgroups have an attach counter of 3 */
for (i = N_NON_LEAF_CGROUPS; i < N_CGROUPS; i++)
ASSERT_EQ(attach_counters[i], PROCESSES_PER_CGROUP,
"leaf cgroup attach counter");
/* Check that child1 == child1_1 + child1_2 */
ASSERT_EQ(attach_counters[1], attach_counters[3] + attach_counters[4],
"child1_counter");
/* Check that child2 == child2_1 + child2_2 */
ASSERT_EQ(attach_counters[2], attach_counters[5] + attach_counters[6],
"child2_counter");
/* Check that test == child1 + child2 */
ASSERT_EQ(attach_counters[0], attach_counters[1] + attach_counters[2],
"test_counter");
/* Check that root >= test */
ASSERT_GE(root_attach_counter, attach_counters[1], "root_counter");
}
/* Creates iter link and pins in bpffs, returns 0 on success, -errno on failure.
*/
static int setup_cgroup_iter(struct cgroup_hierarchical_stats *obj,
int cgroup_fd, const char *file_name)
{
DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, opts);
union bpf_iter_link_info linfo = {};
struct bpf_link *link;
static char path[128];
int err;
/*
* Create an iter link, parameterized by cgroup_fd. We only want to
* traverse one cgroup, so set the traversal order to "self".
*/
linfo.cgroup.cgroup_fd = cgroup_fd;
linfo.cgroup.order = BPF_CGROUP_ITER_SELF_ONLY;
opts.link_info = &linfo;
opts.link_info_len = sizeof(linfo);
link = bpf_program__attach_iter(obj->progs.dumper, &opts);
Annotation
- Immediate include surface: `asm-generic/errno.h`, `errno.h`, `sys/types.h`, `sys/mount.h`, `sys/stat.h`, `unistd.h`, `test_progs.h`, `bpf/libbpf.h`.
- Detected declarations: `function cgroup_rstat_updated`, `function read_from_file`, `function setup_bpffs`, `function cleanup_bpffs`, `function setup_cgroups`, `function cleanup_cgroups`, `function setup_hierarchy`, `function destroy_hierarchy`, `function attach_processes`, `function get_attach_counter`.
- Atlas domain: Support Tooling And Documentation / tools.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.