tools/testing/selftests/namespaces/ns_active_ref_test.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/namespaces/ns_active_ref_test.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/namespaces/ns_active_ref_test.c
Extension
.c
Size
71121 bytes
Lines
2673
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

struct thread_ns_info {
	__u64 ns_id;
	int pipefd;
	int syncfd_read;
	int syncfd_write;
	int exit_code;
};

static void *thread_create_namespace(void *arg)
{
	struct thread_ns_info *info = (struct thread_ns_info *)arg;
	int ret;

	/* Create new network namespace */
	ret = unshare(CLONE_NEWNET);
	if (ret < 0) {
		info->exit_code = 1;
		return NULL;
	}

	/* Get namespace ID */
	int fd = open("/proc/thread-self/ns/net", O_RDONLY);
	if (fd < 0) {
		info->exit_code = 2;
		return NULL;
	}

	ret = ioctl(fd, NS_GET_ID, &info->ns_id);
	close(fd);
	if (ret < 0) {
		info->exit_code = 3;
		return NULL;
	}

	/* Send namespace ID to main thread */
	if (write(info->pipefd, &info->ns_id, sizeof(info->ns_id)) != sizeof(info->ns_id)) {
		info->exit_code = 4;
		return NULL;
	}

	/* Wait for signal to exit */
	char sync_byte;
	if (read(info->syncfd_read, &sync_byte, 1) != 1) {
		info->exit_code = 5;
		return NULL;
	}

	info->exit_code = 0;
	return NULL;
}

/*
 * Test that namespace becomes inactive after thread exits.
 * This verifies active reference counting works with threads, not just processes.
 */
TEST(thread_ns_inactive_after_exit)
{
	pthread_t thread;
	struct thread_ns_info info;
	struct file_handle *handle;
	int pipefd[2];
	int syncpipe[2];
	int ret;
	char sync_byte;
	char buf[sizeof(*handle) + MAX_HANDLE_SZ];

	ASSERT_EQ(pipe(pipefd), 0);
	ASSERT_EQ(pipe(syncpipe), 0);

	info.pipefd = pipefd[1];
	info.syncfd_read = syncpipe[0];
	info.syncfd_write = -1;
	info.exit_code = -1;

	/* Create thread that will create a namespace */
	ret = pthread_create(&thread, NULL, thread_create_namespace, &info);
	ASSERT_EQ(ret, 0);

	/* Read namespace ID from thread */
	__u64 ns_id;
	ret = read(pipefd[0], &ns_id, sizeof(ns_id));
	if (ret != sizeof(ns_id)) {
		sync_byte = 'X';
		write(syncpipe[1], &sync_byte, 1);
		pthread_join(thread, NULL);
		close(pipefd[0]);
		close(pipefd[1]);
		close(syncpipe[0]);
		close(syncpipe[1]);
		SKIP(return, "Failed to read namespace ID from thread");

Annotation

Implementation Notes