tools/testing/selftests/namespaces/listns_pagination_bug.c

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

File Facts

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

if (pids[i] == 0) {
			char c;
			close(sv[0]);

			if (setup_userns() < 0) {
				close(sv[1]);
				exit(1);
			}

			/* Signal parent we're ready */
			if (write(sv[1], &c, 1) != 1) {
				close(sv[1]);
				exit(1);
			}

			/* Wait for parent signal to exit */
			if (read(sv[1], &c, 1) != 1) {
				close(sv[1]);
				exit(1);
			}

			close(sv[1]);
			exit(0);
		}
	}

	close(sv[1]);

	/* Wait for all children to signal ready */
	for (i = 0; i < num_children; i++) {
		char c;
		if (read(sv[0], &c, 1) != 1) {
			close(sv[0]);
			for (int j = 0; j < num_children; j++)
				kill(pids[j], SIGKILL);
			for (int j = 0; j < num_children; j++)
				waitpid(pids[j], NULL, 0);
			ASSERT_TRUE(false);
		}
	}

	/* First batch - this should work */
	ret = sys_listns(&req, first_batch, 3, 0);
	if (ret < 0) {
		if (errno == ENOSYS) {
			close(sv[0]);
			for (i = 0; i < num_children; i++)
				kill(pids[i], SIGKILL);
			for (i = 0; i < num_children; i++)
				waitpid(pids[i], NULL, 0);
			SKIP(return, "listns() not supported");
		}
		ASSERT_GE(ret, 0);
	}

	TH_LOG("First batch returned %zd entries", ret);

	if (ret == 3) {
		__u64 second_batch[3];

		/* Second batch - pagination triggers the bug */
		req.ns_id = first_batch[2];  /* Continue from last ID */
		ret = sys_listns(&req, second_batch, 3, 0);

		TH_LOG("Second batch returned %zd entries", ret);
		ASSERT_GE(ret, 0);
	}

	/* Signal all children to exit */
	for (i = 0; i < num_children; i++) {
		char c = 'X';
		if (write(sv[0], &c, 1) != 1) {
			close(sv[0]);
			for (int j = i; j < num_children; j++)
				kill(pids[j], SIGKILL);
			for (int j = 0; j < num_children; j++)
				waitpid(pids[j], NULL, 0);
			ASSERT_TRUE(false);
		}
	}

	close(sv[0]);

	/* Cleanup */
	for (i = 0; i < num_children; i++) {
		int status;
		waitpid(pids[i], &status, 0);
	}
}

Annotation

Implementation Notes