[CRIU] [PATCH cr 12/13] zdtm: add a test init for executing tests in PIDNS

Andrey Vagin avagin at openvz.org
Tue Jun 19 07:53:16 EDT 2012


Add a small program, which clones a process in new PIDNS and executes
a test.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 test/zdtm/lib/Makefile    |    6 ++-
 test/zdtm/lib/test_init.c |  124 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 128 insertions(+), 2 deletions(-)
 create mode 100644 test/zdtm/lib/test_init.c

diff --git a/test/zdtm/lib/Makefile b/test/zdtm/lib/Makefile
index a4ab681..5921c85 100644
--- a/test/zdtm/lib/Makefile
+++ b/test/zdtm/lib/Makefile
@@ -10,13 +10,15 @@ DEPEND.c = $(COMPILE.c) -MM -MP
 %.d:	%.c
 	$(DEPEND.c) $(OUTPUT_OPTION) $<
 
-all:	$(LIB)
+all:	$(LIB) test_init
 install: all
 
 $(LIB):	$(LIB)(${LIBOBJ})
 
+test_init: test_init.c
+
 clean:
-	$(RM) $(LIBOBJ) $(LIB) *~
+	$(RM) $(LIBOBJ) $(LIB) test_init *~
 
 cleandep:
 	$(RM) $(LIBDEP)
diff --git a/test/zdtm/lib/test_init.c b/test/zdtm/lib/test_init.c
new file mode 100644
index 0000000..a75c335
--- /dev/null
+++ b/test/zdtm/lib/test_init.c
@@ -0,0 +1,124 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <signal.h>
+#include <sched.h>
+#include <sys/mman.h>
+#include <linux/limits.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+
+#define STACK_SIZE	(8 * 4096)
+
+static int sig_received;
+static char dir[PATH_MAX];
+static char name[PATH_MAX];
+int status_pipe[2];
+
+static void sig_hand(int signo)
+{
+	sig_received = signo;
+}
+void test_waitsig(void)
+{
+	sigset_t mask, oldmask;
+
+	/* Set up the mask of signals to temporarily block. */
+	sigemptyset(&mask);
+	sigaddset(&mask, SIGTERM);
+	sigaddset(&mask, SIGCHLD);
+
+	/* Wait for a signal to arrive. */
+	sigprocmask(SIG_BLOCK, &mask, &oldmask);
+	while (!sig_received)
+		sigsuspend (&oldmask);
+	sigprocmask (SIG_UNBLOCK, &mask, NULL);
+
+	sig_received = 0;
+}
+
+int fn(void *_arg)
+{
+	struct sigaction sa = {
+		.sa_handler	= sig_hand,
+		.sa_flags	= SA_RESTART,
+	};
+	char cmd[256];
+	int ret;
+
+	close(status_pipe[0]);
+	ret = fcntl(status_pipe[1], F_SETFD, FD_CLOEXEC);
+	if (ret == -1) {
+		fprintf(stderr, "fcntl failed %m\n");
+		exit(1);
+	}
+
+	sigemptyset(&sa.sa_mask);
+
+	if (sigaction(SIGTERM, &sa, NULL)) {
+		fprintf(stderr, "Can't set SIGTERM handler: %m\n");
+		exit(1);
+	}
+
+	/* Start test */
+	snprintf(cmd, sizeof(cmd), "make -C %s %s.pid", dir, name);
+	ret = system(cmd);
+
+	/* Daemonize */
+	write(status_pipe[1], &ret, sizeof(ret));
+	close(status_pipe[1]);
+	if (ret)
+		return ret;
+
+	/* suspend/resume */
+	test_waitsig();
+
+	/* Stop test */
+	snprintf(cmd, sizeof(cmd), "make -C %s %s.out", dir, name);
+	ret = system(cmd);
+	if (ret)
+		return ret;
+
+	ret = 0;
+	while (ret != -1)
+		ret = wait(NULL);
+
+	return 0;
+}
+
+int main(int argc, char *argv[])
+{
+	void *stack;
+	pid_t pid;
+	int ret, status;
+
+	if (argc < 3)
+		exit(1);
+
+	strcpy(dir, argv[1]);
+	strcpy(name, argv[2]);
+
+	stack = mmap(NULL, STACK_SIZE, PROT_WRITE | PROT_READ,
+			MAP_PRIVATE | MAP_GROWSDOWN | MAP_ANONYMOUS, -1, 0);
+	if (stack == MAP_FAILED) {
+		fprintf(stderr, "Can't map stack %m\n");
+		exit(1);
+	}
+	ret = pipe(status_pipe);
+	if (ret) {
+		fprintf(stderr, "Pipe() failed %m\n");
+		exit(1);
+	}
+	pid = clone(fn, stack + STACK_SIZE, CLONE_NEWPID | SIGCHLD, NULL);
+	if (pid < 0) {
+		fprintf(stderr, "clone() failed: %m\n");
+		exit(1);
+	}
+	status = 1;
+	ret = read(status_pipe[0], &status, sizeof(status));
+	if (ret != sizeof(status) || status)
+		exit(1);
+	return 0;
+}
-- 
1.7.1



More information about the CRIU mailing list