tools/testing/selftests/filesystems/fuse/fusectl_test.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/filesystems/fuse/fusectl_test.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/filesystems/fuse/fusectl_test.c
Extension
.c
Size
3240 bytes
Lines
141
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-or-later
// Copyright (c) 2025 Chen Linxuan <chenlinxuan@uniontech.com>

#define _GNU_SOURCE

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <dirent.h>
#include <sched.h>
#include <linux/limits.h>

#include "kselftest_harness.h"

#define FUSECTL_MOUNTPOINT "/sys/fs/fuse/connections"
#define FUSE_MOUNTPOINT "/tmp/fuse_mnt_XXXXXX"
#define FUSE_DEVICE "/dev/fuse"
#define FUSECTL_TEST_VALUE "1"

static void write_file(struct __test_metadata *const _metadata,
		       const char *path, const char *val)
{
	int fd = open(path, O_WRONLY);
	size_t len = strlen(val);

	ASSERT_GE(fd, 0);
	ASSERT_EQ(write(fd, val, len), len);
	ASSERT_EQ(close(fd), 0);
}

FIXTURE(fusectl){
	char fuse_mountpoint[sizeof(FUSE_MOUNTPOINT)];
	int connection;
};

FIXTURE_SETUP(fusectl)
{
	const char *fuse_mnt_prog = "./fuse_mnt";
	int status, pid;
	struct stat statbuf;
	uid_t uid = getuid();
	gid_t gid = getgid();
	char buf[32];

	/* Setup userns */
	ASSERT_EQ(unshare(CLONE_NEWNS|CLONE_NEWUSER), 0);
	sprintf(buf, "0 %d 1", uid);
	write_file(_metadata, "/proc/self/uid_map", buf);
	write_file(_metadata, "/proc/self/setgroups", "deny");
	sprintf(buf, "0 %d 1", gid);
	write_file(_metadata, "/proc/self/gid_map", buf);
	ASSERT_EQ(mount("", "/", NULL, MS_REC|MS_PRIVATE, NULL), 0);

	strcpy(self->fuse_mountpoint, FUSE_MOUNTPOINT);

	if (!mkdtemp(self->fuse_mountpoint))
		SKIP(return,
		     "Failed to create FUSE mountpoint %s",
		     strerror(errno));

	if (access(FUSECTL_MOUNTPOINT, F_OK))
		SKIP(return,
		     "FUSE control filesystem not mounted");

	pid = fork();
	if (pid < 0)
		SKIP(return,
		     "Failed to fork FUSE daemon process: %s",
		     strerror(errno));

	if (pid == 0) {
		execlp(fuse_mnt_prog, fuse_mnt_prog, self->fuse_mountpoint, NULL);
		exit(errno);
	}

	waitpid(pid, &status, 0);
	if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
		SKIP(return,
		     "Failed to start FUSE daemon %s",
		     strerror(WEXITSTATUS(status)));
	}

	if (stat(self->fuse_mountpoint, &statbuf))

Annotation

Implementation Notes