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

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/prog_tests/d_path.c
Extension
.c
Size
6911 bytes
Lines
264
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
#define _GNU_SOURCE
#include <test_progs.h>
#include <sys/stat.h>
#include <linux/sched.h>
#include <sys/syscall.h>

#define MAX_PATH_LEN		128
#define MAX_FILES		7

#include "test_d_path.skel.h"
#include "test_d_path_check_rdonly_mem.skel.h"
#include "test_d_path_check_types.skel.h"

/* sys_close_range is not around for long time, so let's
 * make sure we can call it on systems with older glibc
 */
#ifndef __NR_close_range
#ifdef __alpha__
#define __NR_close_range 546
#else
#define __NR_close_range 436
#endif
#endif

static int duration;

static struct {
	__u32 cnt;
	char paths[MAX_FILES][MAX_PATH_LEN];
} src;

static int set_pathname(int fd, pid_t pid)
{
	char buf[MAX_PATH_LEN];

	snprintf(buf, MAX_PATH_LEN, "/proc/%d/fd/%d", pid, fd);
	return readlink(buf, src.paths[src.cnt++], MAX_PATH_LEN);
}

static inline long syscall_close(int fd)
{
	return syscall(__NR_close_range,
			(unsigned int)fd,
			(unsigned int)fd,
			0u);
}

static int trigger_fstat_events(pid_t pid)
{
	int sockfd = -1, procfd = -1, devfd = -1;
	int localfd = -1, indicatorfd = -1;
	int pipefd[2] = { -1, -1 };
	struct stat fileStat;
	int ret = -1;

	/* unmountable pseudo-filesystems */
	if (CHECK(pipe(pipefd) < 0, "trigger", "pipe failed\n"))
		return ret;
	/* unmountable pseudo-filesystems */
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (CHECK(sockfd < 0, "trigger", "socket failed\n"))
		goto out_close;
	/* mountable pseudo-filesystems */
	procfd = open("/proc/self/comm", O_RDONLY);
	if (CHECK(procfd < 0, "trigger", "open /proc/self/comm failed\n"))
		goto out_close;
	devfd = open("/dev/urandom", O_RDONLY);
	if (CHECK(devfd < 0, "trigger", "open /dev/urandom failed\n"))
		goto out_close;
	localfd = open("/tmp/d_path_loadgen.txt", O_CREAT | O_RDONLY, 0644);
	if (CHECK(localfd < 0, "trigger", "open /tmp/d_path_loadgen.txt failed\n"))
		goto out_close;
	/* bpf_d_path will return path with (deleted) */
	remove("/tmp/d_path_loadgen.txt");
	indicatorfd = open("/tmp/", O_PATH);
	if (CHECK(indicatorfd < 0, "trigger", "open /tmp/ failed\n"))
		goto out_close;

	ret = set_pathname(pipefd[0], pid);
	if (CHECK(ret < 0, "trigger", "set_pathname failed for pipe[0]\n"))
		goto out_close;
	ret = set_pathname(pipefd[1], pid);
	if (CHECK(ret < 0, "trigger", "set_pathname failed for pipe[1]\n"))
		goto out_close;
	ret = set_pathname(sockfd, pid);
	if (CHECK(ret < 0, "trigger", "set_pathname failed for socket\n"))
		goto out_close;
	ret = set_pathname(procfd, pid);
	if (CHECK(ret < 0, "trigger", "set_pathname failed for proc\n"))

Annotation

Implementation Notes