[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