cgroups.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Christian Brauner <brauner@kernel.org>
To: linux-fsdevel@vger.kernel.org, Josef Bacik <josef@toxicpanda.com>,
	 Jeff Layton <jlayton@kernel.org>
Cc: "Jann Horn" <jannh@google.com>, "Mike Yuan" <me@yhndnzj.com>,
	"Zbigniew Jędrzejewski-Szmek" <zbyszek@in.waw.pl>,
	"Lennart Poettering" <mzxreary@0pointer.de>,
	"Daan De Meyer" <daan.j.demeyer@gmail.com>,
	"Aleksa Sarai" <cyphar@cyphar.com>,
	"Amir Goldstein" <amir73il@gmail.com>,
	"Tejun Heo" <tj@kernel.org>,
	"Johannes Weiner" <hannes@cmpxchg.org>,
	"Thomas Gleixner" <tglx@linutronix.de>,
	"Alexander Viro" <viro@zeniv.linux.org.uk>,
	"Jan Kara" <jack@suse.cz>,
	linux-kernel@vger.kernel.org, cgroups@vger.kernel.org,
	bpf@vger.kernel.org, "Eric Dumazet" <edumazet@google.com>,
	"Jakub Kicinski" <kuba@kernel.org>,
	netdev@vger.kernel.org, "Arnd Bergmann" <arnd@arndb.de>,
	"Christian Brauner" <brauner@kernel.org>
Subject: [PATCH v3 67/70] selftests/namespace: third threaded active reference count test
Date: Fri, 24 Oct 2025 12:53:36 +0200	[thread overview]
Message-ID: <20251024-work-namespace-nstree-listns-v3-67-b6241981b72b@kernel.org> (raw)
In-Reply-To: <20251024-work-namespace-nstree-listns-v3-0-b6241981b72b@kernel.org>

Test that namespaces become inactive after subprocess with multiple
threads exits. Create a subprocess that unshares user and network
namespaces, then creates two threads that share those namespaces. Verify
that after all threads and subprocess exit, the namespaces are no longer
listed by listns() and cannot be opened by open_by_handle_at().

Signed-off-by: Christian Brauner <brauner@kernel.org>
---
 .../selftests/namespaces/ns_active_ref_test.c      | 319 +++++++++++++++++++++
 1 file changed, 319 insertions(+)

diff --git a/tools/testing/selftests/namespaces/ns_active_ref_test.c b/tools/testing/selftests/namespaces/ns_active_ref_test.c
index 24dc8ef106b9..093268f0efaa 100644
--- a/tools/testing/selftests/namespaces/ns_active_ref_test.c
+++ b/tools/testing/selftests/namespaces/ns_active_ref_test.c
@@ -9,6 +9,7 @@
 #include <string.h>
 #include <linux/nsfs.h>
 #include <sys/mount.h>
+#include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -2350,4 +2351,322 @@ TEST(thread_ns_fd_keeps_active)
 	ASSERT_TRUE(errno == ENOENT || errno == ESTALE);
 }
 
+/* Structure for thread data in subprocess */
+struct thread_sleep_data {
+	int syncfd_read;
+};
+
+static void *thread_sleep_and_wait(void *arg)
+{
+	struct thread_sleep_data *data = (struct thread_sleep_data *)arg;
+	char sync_byte;
+
+	/* Wait for signal to exit - read will unblock when pipe is closed */
+	(void)read(data->syncfd_read, &sync_byte, 1);
+	return NULL;
+}
+
+/*
+ * Test that namespaces become inactive after subprocess with multiple threads exits.
+ * Create a subprocess that unshares user and network namespaces, then creates two
+ * threads that share those namespaces. Verify that after all threads and subprocess
+ * exit, the namespaces are no longer listed by listns() and cannot be opened by
+ * open_by_handle_at().
+ */
+TEST(thread_subprocess_ns_inactive_after_all_exit)
+{
+	int pipefd[2];
+	int sv[2];
+	pid_t pid;
+	int status;
+	__u64 user_id, net_id;
+	struct file_handle *user_handle, *net_handle;
+	char user_buf[sizeof(*user_handle) + MAX_HANDLE_SZ];
+	char net_buf[sizeof(*net_handle) + MAX_HANDLE_SZ];
+	char sync_byte;
+	int ret;
+
+	ASSERT_EQ(pipe(pipefd), 0);
+	ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sv), 0);
+
+	pid = fork();
+	ASSERT_GE(pid, 0);
+
+	if (pid == 0) {
+		/* Child process */
+		close(pipefd[0]);
+		close(sv[0]);
+
+		/* Create user namespace with mappings */
+		if (setup_userns() < 0) {
+			fprintf(stderr, "Child: setup_userns() failed: %s\n", strerror(errno));
+			close(pipefd[1]);
+			close(sv[1]);
+			exit(1);
+		}
+		fprintf(stderr, "Child: setup_userns() succeeded\n");
+
+		/* Get user namespace ID */
+		int user_fd = open("/proc/self/ns/user", O_RDONLY);
+		if (user_fd < 0) {
+			fprintf(stderr, "Child: open(/proc/self/ns/user) failed: %s\n", strerror(errno));
+			close(pipefd[1]);
+			close(sv[1]);
+			exit(1);
+		}
+
+		if (ioctl(user_fd, NS_GET_ID, &user_id) < 0) {
+			fprintf(stderr, "Child: ioctl(NS_GET_ID) for user ns failed: %s\n", strerror(errno));
+			close(user_fd);
+			close(pipefd[1]);
+			close(sv[1]);
+			exit(1);
+		}
+		close(user_fd);
+		fprintf(stderr, "Child: user ns ID = %llu\n", (unsigned long long)user_id);
+
+		/* Unshare network namespace */
+		if (unshare(CLONE_NEWNET) < 0) {
+			fprintf(stderr, "Child: unshare(CLONE_NEWNET) failed: %s\n", strerror(errno));
+			close(pipefd[1]);
+			close(sv[1]);
+			exit(1);
+		}
+		fprintf(stderr, "Child: unshare(CLONE_NEWNET) succeeded\n");
+
+		/* Get network namespace ID */
+		int net_fd = open("/proc/self/ns/net", O_RDONLY);
+		if (net_fd < 0) {
+			fprintf(stderr, "Child: open(/proc/self/ns/net) failed: %s\n", strerror(errno));
+			close(pipefd[1]);
+			close(sv[1]);
+			exit(1);
+		}
+
+		if (ioctl(net_fd, NS_GET_ID, &net_id) < 0) {
+			fprintf(stderr, "Child: ioctl(NS_GET_ID) for net ns failed: %s\n", strerror(errno));
+			close(net_fd);
+			close(pipefd[1]);
+			close(sv[1]);
+			exit(1);
+		}
+		close(net_fd);
+		fprintf(stderr, "Child: net ns ID = %llu\n", (unsigned long long)net_id);
+
+		/* Send namespace IDs to parent */
+		if (write(pipefd[1], &user_id, sizeof(user_id)) != sizeof(user_id)) {
+			fprintf(stderr, "Child: write(user_id) failed: %s\n", strerror(errno));
+			exit(1);
+		}
+		if (write(pipefd[1], &net_id, sizeof(net_id)) != sizeof(net_id)) {
+			fprintf(stderr, "Child: write(net_id) failed: %s\n", strerror(errno));
+			exit(1);
+		}
+		close(pipefd[1]);
+		fprintf(stderr, "Child: sent namespace IDs to parent\n");
+
+		/* Create two threads that share the namespaces */
+		pthread_t thread1, thread2;
+		struct thread_sleep_data data;
+		data.syncfd_read = sv[1];
+
+		int ret_thread = pthread_create(&thread1, NULL, thread_sleep_and_wait, &data);
+		if (ret_thread != 0) {
+			fprintf(stderr, "Child: pthread_create(thread1) failed: %s\n", strerror(ret_thread));
+			close(sv[1]);
+			exit(1);
+		}
+		fprintf(stderr, "Child: created thread1\n");
+
+		ret_thread = pthread_create(&thread2, NULL, thread_sleep_and_wait, &data);
+		if (ret_thread != 0) {
+			fprintf(stderr, "Child: pthread_create(thread2) failed: %s\n", strerror(ret_thread));
+			close(sv[1]);
+			pthread_cancel(thread1);
+			exit(1);
+		}
+		fprintf(stderr, "Child: created thread2\n");
+
+		/* Wait for threads to complete - they will unblock when parent writes */
+		fprintf(stderr, "Child: waiting for threads to exit\n");
+		pthread_join(thread1, NULL);
+		fprintf(stderr, "Child: thread1 exited\n");
+		pthread_join(thread2, NULL);
+		fprintf(stderr, "Child: thread2 exited\n");
+
+		close(sv[1]);
+
+		/* Exit - namespaces should become inactive */
+		fprintf(stderr, "Child: all threads joined, exiting with success\n");
+		exit(0);
+	}
+
+	/* Parent process */
+	close(pipefd[1]);
+	close(sv[1]);
+
+	TH_LOG("Parent: waiting to read namespace IDs from child");
+
+	/* Read namespace IDs from child */
+	ret = read(pipefd[0], &user_id, sizeof(user_id));
+	if (ret != sizeof(user_id)) {
+		TH_LOG("Parent: failed to read user_id, ret=%d, errno=%s", ret, strerror(errno));
+		close(pipefd[0]);
+		sync_byte = 'X';
+		(void)write(sv[0], &sync_byte, 1);
+		close(sv[0]);
+		waitpid(pid, NULL, 0);
+		SKIP(return, "Failed to read user namespace ID from child");
+	}
+
+	ret = read(pipefd[0], &net_id, sizeof(net_id));
+	close(pipefd[0]);
+	if (ret != sizeof(net_id)) {
+		TH_LOG("Parent: failed to read net_id, ret=%d, errno=%s", ret, strerror(errno));
+		sync_byte = 'X';
+		(void)write(sv[0], &sync_byte, 1);
+		close(sv[0]);
+		waitpid(pid, NULL, 0);
+		SKIP(return, "Failed to read network namespace ID from child");
+	}
+
+	TH_LOG("Child created user ns %llu and net ns %llu with 2 threads",
+	       (unsigned long long)user_id, (unsigned long long)net_id);
+
+	/* Construct file handles */
+	user_handle = (struct file_handle *)user_buf;
+	user_handle->handle_bytes = sizeof(struct nsfs_file_handle);
+	user_handle->handle_type = FILEID_NSFS;
+	struct nsfs_file_handle *user_fh = (struct nsfs_file_handle *)user_handle->f_handle;
+	user_fh->ns_id = user_id;
+	user_fh->ns_type = 0;
+	user_fh->ns_inum = 0;
+
+	net_handle = (struct file_handle *)net_buf;
+	net_handle->handle_bytes = sizeof(struct nsfs_file_handle);
+	net_handle->handle_type = FILEID_NSFS;
+	struct nsfs_file_handle *net_fh = (struct nsfs_file_handle *)net_handle->f_handle;
+	net_fh->ns_id = net_id;
+	net_fh->ns_type = 0;
+	net_fh->ns_inum = 0;
+
+	/* Verify namespaces are active while subprocess and threads are alive */
+	TH_LOG("Verifying namespaces are active while subprocess with threads is running");
+	int user_fd = open_by_handle_at(FD_NSFS_ROOT, user_handle, O_RDONLY);
+	ASSERT_GE(user_fd, 0);
+
+	int net_fd = open_by_handle_at(FD_NSFS_ROOT, net_handle, O_RDONLY);
+	ASSERT_GE(net_fd, 0);
+
+	close(user_fd);
+	close(net_fd);
+
+	/* Also verify they appear in listns() */
+	TH_LOG("Verifying namespaces appear in listns() while active");
+	struct ns_id_req req = {
+		.size = sizeof(struct ns_id_req),
+		.spare = 0,
+		.ns_id = 0,
+		.ns_type = CLONE_NEWUSER,
+		.spare2 = 0,
+		.user_ns_id = 0,
+	};
+	__u64 ns_ids[256];
+	int nr_ids = sys_listns(&req, ns_ids, 256, 0);
+	if (nr_ids < 0) {
+		TH_LOG("listns() not available, skipping listns verification");
+	} else {
+		/* Check if user_id is in the list */
+		int found_user = 0;
+		for (int i = 0; i < nr_ids; i++) {
+			if (ns_ids[i] == user_id) {
+				found_user = 1;
+				break;
+			}
+		}
+		ASSERT_TRUE(found_user);
+		TH_LOG("User namespace found in listns() as expected");
+
+		/* Check network namespace */
+		req.ns_type = CLONE_NEWNET;
+		nr_ids = sys_listns(&req, ns_ids, 256, 0);
+		if (nr_ids >= 0) {
+			int found_net = 0;
+			for (int i = 0; i < nr_ids; i++) {
+				if (ns_ids[i] == net_id) {
+					found_net = 1;
+					break;
+				}
+			}
+			ASSERT_TRUE(found_net);
+			TH_LOG("Network namespace found in listns() as expected");
+		}
+	}
+
+	/* Signal threads to exit */
+	TH_LOG("Signaling threads to exit");
+	sync_byte = 'X';
+	/* Write two bytes - one for each thread */
+	ASSERT_EQ(write(sv[0], &sync_byte, 1), 1);
+	ASSERT_EQ(write(sv[0], &sync_byte, 1), 1);
+	close(sv[0]);
+
+	/* Wait for child process to exit */
+	waitpid(pid, &status, 0);
+	ASSERT_TRUE(WIFEXITED(status));
+	if (WEXITSTATUS(status) != 0) {
+		TH_LOG("Child process failed with exit code %d", WEXITSTATUS(status));
+		SKIP(return, "Child process failed");
+	}
+
+	TH_LOG("Subprocess and all threads have exited successfully");
+
+	/* Verify namespaces are now inactive - open_by_handle_at should fail */
+	TH_LOG("Verifying namespaces are inactive after subprocess and threads exit");
+	user_fd = open_by_handle_at(FD_NSFS_ROOT, user_handle, O_RDONLY);
+	ASSERT_LT(user_fd, 0);
+	TH_LOG("User namespace inactive as expected: %s (errno=%d)",
+	       strerror(errno), errno);
+	ASSERT_TRUE(errno == ENOENT || errno == ESTALE);
+
+	net_fd = open_by_handle_at(FD_NSFS_ROOT, net_handle, O_RDONLY);
+	ASSERT_LT(net_fd, 0);
+	TH_LOG("Network namespace inactive as expected: %s (errno=%d)",
+	       strerror(errno), errno);
+	ASSERT_TRUE(errno == ENOENT || errno == ESTALE);
+
+	/* Verify namespaces do NOT appear in listns() */
+	TH_LOG("Verifying namespaces do NOT appear in listns() when inactive");
+	memset(&req, 0, sizeof(req));
+	req.size = sizeof(struct ns_id_req);
+	req.ns_type = CLONE_NEWUSER;
+	nr_ids = sys_listns(&req, ns_ids, 256, 0);
+	if (nr_ids >= 0) {
+		int found_user = 0;
+		for (int i = 0; i < nr_ids; i++) {
+			if (ns_ids[i] == user_id) {
+				found_user = 1;
+				break;
+			}
+		}
+		ASSERT_FALSE(found_user);
+		TH_LOG("User namespace correctly not listed in listns()");
+
+		/* Check network namespace */
+		req.ns_type = CLONE_NEWNET;
+		nr_ids = sys_listns(&req, ns_ids, 256, 0);
+		if (nr_ids >= 0) {
+			int found_net = 0;
+			for (int i = 0; i < nr_ids; i++) {
+				if (ns_ids[i] == net_id) {
+					found_net = 1;
+					break;
+				}
+			}
+			ASSERT_FALSE(found_net);
+			TH_LOG("Network namespace correctly not listed in listns()");
+		}
+	}
+}
+
 TEST_HARNESS_MAIN

-- 
2.47.3


  parent reply	other threads:[~2025-10-24 10:59 UTC|newest]

Thread overview: 88+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-24 10:52 [PATCH v3 00/70] nstree: listns() Christian Brauner
2025-10-24 10:52 ` [PATCH v3 01/70] libfs: allow to specify s_d_flags Christian Brauner
2025-10-24 10:52 ` [PATCH v3 02/70] nsfs: use inode_just_drop() Christian Brauner
2025-10-24 10:52 ` [PATCH v3 03/70] nsfs: raise DCACHE_DONTCACHE explicitly Christian Brauner
2025-10-24 10:52 ` [PATCH v3 04/70] pidfs: " Christian Brauner
2025-10-24 10:52 ` [PATCH v3 05/70] nsfs: raise SB_I_NODEV and SB_I_NOEXEC Christian Brauner
2025-10-27 13:13   ` Jeff Layton
2025-10-28 15:35     ` Christian Brauner
2025-10-24 10:52 ` [PATCH v3 06/70] cgroup: add cgroup namespace to tree after owner is set Christian Brauner
2025-10-24 10:52 ` [PATCH v3 07/70] nstree: simplify return Christian Brauner
2025-10-24 10:52 ` [PATCH v3 08/70] ns: initialize ns_list_node for initial namespaces Christian Brauner
2025-10-24 10:52 ` [PATCH v3 09/70] ns: add __ns_ref_read() Christian Brauner
2025-10-24 10:52 ` [PATCH v3 10/70] ns: rename to exit_nsproxy_namespaces() Christian Brauner
2025-10-24 10:52 ` [PATCH v3 11/70] ns: add active reference count Christian Brauner
2025-10-27 16:36   ` Thomas Gleixner
2025-10-28 15:33     ` Christian Brauner
2025-10-28 10:30   ` Simon Horman
2025-10-28 15:32     ` Christian Brauner
2025-10-29  7:02   ` Askar Safin
2025-10-24 10:52 ` [PATCH v3 12/70] ns: use anonymous struct to group list member Christian Brauner
2025-10-24 10:52 ` [PATCH v3 13/70] nstree: introduce a unified tree Christian Brauner
2025-10-24 10:52 ` [PATCH v3 14/70] nstree: allow lookup solely based on inode Christian Brauner
2025-10-27 13:48   ` Jeff Layton
2025-10-24 10:52 ` [PATCH v3 15/70] nstree: assign fixed ids to the initial namespaces Christian Brauner
2025-10-24 10:52 ` [PATCH v3 16/70] ns: maintain list of owned namespaces Christian Brauner
2025-10-24 10:52 ` [PATCH v3 17/70] nstree: add listns() Christian Brauner
2025-10-24 14:06   ` Arnd Bergmann
2025-10-28 15:20     ` Christian Brauner
2025-10-27 14:04   ` Jeff Layton
2025-10-28 15:39     ` Christian Brauner
2025-10-28 10:36   ` Simon Horman
2025-10-28 13:33     ` Christian Brauner
2025-10-29  7:52   ` Askar Safin
2025-10-24 10:52 ` [PATCH v3 18/70] arch: hookup listns() system call Christian Brauner
2025-10-24 14:08   ` Arnd Bergmann
2025-10-24 10:52 ` [PATCH v3 19/70] nsfs: update tools header Christian Brauner
2025-10-24 10:52 ` [PATCH v3 20/70] selftests/filesystems: remove CLONE_NEWPIDNS from setup_userns() helper Christian Brauner
2025-10-24 10:52 ` [PATCH v3 21/70] selftests/namespaces: first active reference count tests Christian Brauner
2025-10-24 10:52 ` [PATCH v3 22/70] selftests/namespaces: second " Christian Brauner
2025-10-24 10:52 ` [PATCH v3 23/70] selftests/namespaces: third " Christian Brauner
2025-10-24 10:52 ` [PATCH v3 24/70] selftests/namespaces: fourth " Christian Brauner
2025-10-24 10:52 ` [PATCH v3 25/70] selftests/namespaces: fifth " Christian Brauner
2025-10-24 10:52 ` [PATCH v3 26/70] selftests/namespaces: sixth " Christian Brauner
2025-10-24 10:52 ` [PATCH v3 27/70] selftests/namespaces: seventh " Christian Brauner
2025-10-24 10:52 ` [PATCH v3 28/70] selftests/namespaces: eigth " Christian Brauner
2025-10-24 10:52 ` [PATCH v3 29/70] selftests/namespaces: ninth " Christian Brauner
2025-10-24 10:52 ` [PATCH v3 30/70] selftests/namespaces: tenth " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 31/70] selftests/namespaces: eleventh " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 32/70] selftests/namespaces: twelth " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 33/70] selftests/namespaces: thirteenth " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 34/70] selftests/namespaces: fourteenth " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 35/70] selftests/namespaces: fifteenth " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 36/70] selftests/namespaces: add listns() wrapper Christian Brauner
2025-10-24 10:53 ` [PATCH v3 37/70] selftests/namespaces: first listns() test Christian Brauner
2025-10-24 10:53 ` [PATCH v3 38/70] selftests/namespaces: second " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 39/70] selftests/namespaces: third " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 40/70] selftests/namespaces: fourth " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 41/70] selftests/namespaces: fifth " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 42/70] selftests/namespaces: sixth " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 43/70] selftests/namespaces: seventh " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 44/70] selftests/namespaces: eigth " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 45/70] selftests/namespaces: ninth " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 46/70] selftests/namespaces: first listns() permission test Christian Brauner
2025-10-24 10:53 ` [PATCH v3 47/70] selftests/namespaces: second " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 48/70] selftests/namespaces: third " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 49/70] selftests/namespaces: fourth " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 50/70] selftests/namespaces: fifth " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 51/70] selftests/namespaces: sixth " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 52/70] selftests/namespaces: seventh " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 53/70] selftests/namespaces: first inactive namespace resurrection test Christian Brauner
2025-10-24 10:53 ` [PATCH v3 54/70] selftests/namespaces: second " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 55/70] selftests/namespaces: third " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 56/70] selftests/namespaces: fourth " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 57/70] selftests/namespaces: fifth " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 58/70] selftests/namespaces: sixth " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 59/70] selftests/namespaces: seventh " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 60/70] selftests/namespaces: eigth " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 61/70] selftests/namespaces: ninth " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 62/70] selftests/namespaces: tenth " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 63/70] selftests/namespaces: eleventh " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 64/70] selftests/namespaces: twelth " Christian Brauner
2025-10-24 10:53 ` [PATCH v3 65/70] selftests/namespace: first threaded active reference count test Christian Brauner
2025-10-24 10:53 ` [PATCH v3 66/70] selftests/namespace: second " Christian Brauner
2025-10-24 10:53 ` Christian Brauner [this message]
2025-10-24 10:53 ` [PATCH v3 68/70] selftests/namespace: commit_creds() active reference tests Christian Brauner
2025-10-24 10:53 ` [PATCH v3 69/70] selftests/namespace: add stress test Christian Brauner
2025-10-24 10:53 ` [PATCH v3 70/70] selftests/namespace: test listns() pagination Christian Brauner
2025-10-27 14:10 ` [PATCH v3 00/70] nstree: listns() Jeff Layton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251024-work-namespace-nstree-listns-v3-67-b6241981b72b@kernel.org \
    --to=brauner@kernel.org \
    --cc=amir73il@gmail.com \
    --cc=arnd@arndb.de \
    --cc=bpf@vger.kernel.org \
    --cc=cgroups@vger.kernel.org \
    --cc=cyphar@cyphar.com \
    --cc=daan.j.demeyer@gmail.com \
    --cc=edumazet@google.com \
    --cc=hannes@cmpxchg.org \
    --cc=jack@suse.cz \
    --cc=jannh@google.com \
    --cc=jlayton@kernel.org \
    --cc=josef@toxicpanda.com \
    --cc=kuba@kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=me@yhndnzj.com \
    --cc=mzxreary@0pointer.de \
    --cc=netdev@vger.kernel.org \
    --cc=tglx@linutronix.de \
    --cc=tj@kernel.org \
    --cc=viro@zeniv.linux.org.uk \
    --cc=zbyszek@in.waw.pl \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).