/*
 * DF-2802 instrumented reproducer: serialized jail(2) churn, logging the
 * kernel-assigned jid (sysmsg_result) of every successful jail() to stderr
 * along with the iteration.  Run with stderr redirected to a file.
 * One child at a time (parent waits) — no zombie pile, no maxproc noise.
 */
#include <sys/param.h>
#include <sys/jail.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

int
main(int argc, char **argv)
{
	int iters = argc > 1 ? atoi(argv[1]) : 5000;

	if (getuid() != 0) {
		printf("must run as root\n");
		return (2);
	}
	for (int i = 0; i < iters; i++) {
		pid_t pid = fork();
		if (pid == 0) {
			struct jail j;
			int jid;

			memset(&j, 0, sizeof(j));
			j.version = 1;
			j.path = "/tmp";
			j.hostname = "trace";
			j.n_ips = 0;
			j.ips = NULL;
			jid = syscall(SYS_jail, &j);
			dprintf(2, "iter %d jid %d pid %d\n", i, jid,
				getpid());
			_exit(0);
		}
		int st;
		waitpid(pid, &st, 0);
		if ((i % 1000) == 0) {
			printf("progress %d\n", i);
			fflush(stdout);
		}
	}
	printf("trace done\n");
	return (0);
}
