tools/testing/selftests/bpf/prog_tests/cgroup_iter.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/prog_tests/cgroup_iter.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/prog_tests/cgroup_iter.c
Extension
.c
Size
9236 bytes
Lines
346
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.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2022 Google */

#include <test_progs.h>
#include <bpf/libbpf.h>
#include <bpf/btf.h>
#include "iters_css_task.skel.h"
#include "cgroup_iter.skel.h"
#include "cgroup_helpers.h"

#define ROOT           0
#define PARENT         1
#define CHILD1         2
#define CHILD2         3
#define NUM_CGROUPS    4

#define PROLOGUE       "prologue\n"
#define EPILOGUE       "epilogue\n"

static const char *cg_path[] = {
	"/", "/parent", "/parent/child1", "/parent/child2"
};

static int cg_fd[] = {-1, -1, -1, -1};
static unsigned long long cg_id[] = {0, 0, 0, 0};
static char expected_output[64];

static int setup_cgroups(void)
{
	int fd, i = 0;

	for (i = 0; i < NUM_CGROUPS; i++) {
		fd = create_and_get_cgroup(cg_path[i]);
		if (fd < 0)
			return fd;

		cg_fd[i] = fd;
		cg_id[i] = get_cgroup_id(cg_path[i]);
	}
	return 0;
}

static void cleanup_cgroups(void)
{
	int i;

	for (i = 0; i < NUM_CGROUPS; i++)
		close(cg_fd[i]);
}

static void read_from_cgroup_iter(struct bpf_program *prog, int cgroup_fd,
				  int order, const char *testname)
{
	DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, opts);
	union bpf_iter_link_info linfo;
	struct bpf_link *link;
	int len, iter_fd;
	static char buf[128];
	size_t left;
	char *p;

	memset(&linfo, 0, sizeof(linfo));
	linfo.cgroup.cgroup_fd = cgroup_fd;
	linfo.cgroup.order = order;
	opts.link_info = &linfo;
	opts.link_info_len = sizeof(linfo);

	link = bpf_program__attach_iter(prog, &opts);
	if (!ASSERT_OK_PTR(link, "attach_iter"))
		return;

	iter_fd = bpf_iter_create(bpf_link__fd(link));
	if (iter_fd < 0)
		goto free_link;

	memset(buf, 0, sizeof(buf));
	left = ARRAY_SIZE(buf);
	p = buf;
	while ((len = read(iter_fd, p, left)) > 0) {
		p += len;
		left -= len;
	}

	ASSERT_STREQ(buf, expected_output, testname);

	/* read() after iter finishes should be ok. */
	if (len == 0)
		ASSERT_OK(read(iter_fd, buf, sizeof(buf)), "second_read");

	close(iter_fd);

Annotation

Implementation Notes