[CRIU] [PATCH 7/8] zdtm/lib: add test_waitpre so that test knows about predump iters
Pavel Tikhomirov
ptikhomirov at virtuozzo.com
Wed Feb 14 14:29:02 MSK 2018
From: ptikhomirov <ptikhomirov at virtuozzo.com>
- anounce predump finish to a target process from predump loop in
zdtm.py
- propagate SIGUSR1 signal to real test process from ns_init for
ns and uns flavors.
- in ns_init also fix fd leak
So now test's main process can do:
while (!test_waitpre()) {
/* do something after predump */
}
/* do something after restore */
All test_waitsig and test_go still work the same as before.
https://jira.sw.ru/browse/PSBM-67502
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
test/zdtm.py | 8 ++++++++
test/zdtm/lib/ns.c | 46 ++++++++++++++++++++++++++++------------------
test/zdtm/lib/ns.h | 6 ++++++
test/zdtm/lib/test.c | 30 +++++++++++++++++++++++++-----
test/zdtm/lib/zdtmtst.h | 1 +
5 files changed, 68 insertions(+), 23 deletions(-)
diff --git a/test/zdtm.py b/test/zdtm.py
index 767a1ed50..698092bcb 100755
--- a/test/zdtm.py
+++ b/test/zdtm.py
@@ -459,6 +459,13 @@ flavors = {'h': host_flavor, 'ns': ns_flavor, 'uns': userns_flavor}
self.__flavor.fini()
+ def signal_pre_dump(self):
+ if self.__pid == 0:
+ self.getpid()
+ sig = signal.SIGUSR1
+ print "Send the %d signal to %s" % (sig, self.__pid)
+ os.kill(int(self.__pid), sig)
+
def stop(self):
self.__freezer.thaw()
self.getpid() # Read the pid from pidfile back
@@ -1184,6 +1191,7 @@ do_sbs = False
else:
cr_api.dump("pre-dump")
try_run_hook(test, ["--post-pre-dump"])
+ test.signal_pre_dump()
time.sleep(pres[1])
sbs('pre-dump')
diff --git a/test/zdtm/lib/ns.c b/test/zdtm/lib/ns.c
index 7a0949f22..92922e928 100644
--- a/test/zdtm/lib/ns.c
+++ b/test/zdtm/lib/ns.c
@@ -168,9 +168,12 @@ static void ns_sig_hand(int signo)
char buf[128] = "";
if (signo == SIGTERM) {
- futex_set_and_wake(&sig_received, signo);
+ futex_set_and_wake(&sig_received, TEST_SIG_STOP);
len = snprintf(buf, sizeof(buf), "Time to stop and check\n");
goto write_out;
+ } else if (signo == SIGUSR1) {
+ futex_cmpxchg_and_wake(&sig_received, TEST_NO_SIG, TEST_SIG_PRE);
+ return;
}
while (1) {
@@ -179,9 +182,9 @@ static void ns_sig_hand(int signo)
return;
if (pid == -1) {
if (errno == ECHILD) {
- if (futex_get(&sig_received))
+ if (futex_get(&sig_received) == TEST_SIG_STOP)
return;
- futex_set_and_wake(&sig_received, signo);
+ futex_set_and_wake(&sig_received, TEST_SIG_STOP);
len = snprintf(buf, sizeof(buf),
"All test processes exited\n");
} else {
@@ -235,7 +238,7 @@ int ns_init(int argc, char **argv)
.sa_handler = ns_sig_hand,
.sa_flags = SA_RESTART,
};
- int ret, fd, status_pipe = STATUS_FD;
+ int ret, test_ret, fd, status_pipe = STATUS_FD;
char buf[128], *x;
pid_t pid;
bool reap;
@@ -258,6 +261,11 @@ int ns_init(int argc, char **argv)
exit(1);
}
+ if (sigaction(SIGUSR1, &sa, NULL)) {
+ fprintf(stderr, "Can't set SIGUSR1 handler: %m\n");
+ exit(1);
+ }
+
x = malloc(strlen(pidfile) + 3);
sprintf(x, "%sns", pidfile);
pidfile = x;
@@ -273,11 +281,11 @@ int ns_init(int argc, char **argv)
return 0; /* Continue normal test startup */
}
- ret = -1;
- if (waitpid(pid, &ret, 0) < 0)
+ test_ret = -1;
+ if (waitpid(pid, &test_ret, 0) < 0)
fprintf(stderr, "waitpid() failed: %m\n");
- else if (ret)
- fprintf(stderr, "The test returned non-zero code %d\n", ret);
+ else if (test_ret)
+ fprintf(stderr, "The test returned non-zero code %d\n", test_ret);
if (reap && sigaction(SIGCHLD, &sa, NULL)) {
fprintf(stderr, "Can't set SIGCHLD handler: %m\n");
@@ -298,15 +306,6 @@ int ns_init(int argc, char **argv)
fprintf(stderr, "%d return %d\n", pid, status);
}
- /* Daemonize */
- write(status_pipe, &ret, sizeof(ret));
- close(status_pipe);
- if (ret)
- exit(ret);
-
- /* suspend/resume */
- test_waitsig();
-
fd = open(pidfile, O_RDONLY);
if (fd == -1) {
fprintf(stderr, "open(%s) failed: %m\n", pidfile);
@@ -314,12 +313,23 @@ int ns_init(int argc, char **argv)
}
ret = read(fd, buf, sizeof(buf) - 1);
buf[ret] = '\0';
+ close(fd);
if (ret == -1) {
fprintf(stderr, "read() failed: %m\n");
exit(1);
}
-
pid = atoi(buf);
+
+ /* Daemonize */
+ write(status_pipe, &test_ret, sizeof(test_ret));
+ close(status_pipe);
+ if (test_ret)
+ exit(test_ret);
+
+ while (!test_waitpre())
+ kill(pid, SIGUSR1);
+ /* after suspend/resume */
+
fprintf(stderr, "kill(%d, SIGTERM)\n", pid);
if (pid > 0)
kill(pid, SIGTERM);
diff --git a/test/zdtm/lib/ns.h b/test/zdtm/lib/ns.h
index 23378bc60..78395984e 100644
--- a/test/zdtm/lib/ns.h
+++ b/test/zdtm/lib/ns.h
@@ -12,4 +12,10 @@ extern int ns_init(int argc, char **argv);
extern void test_waitsig(void);
extern void parseargs(int, char **);
+enum {
+ TEST_NO_SIG = 0,
+ TEST_SIG_PRE,
+ TEST_SIG_STOP,
+};
+
#endif
diff --git a/test/zdtm/lib/test.c b/test/zdtm/lib/test.c
index 6dce027f0..c16442196 100644
--- a/test/zdtm/lib/test.c
+++ b/test/zdtm/lib/test.c
@@ -35,9 +35,13 @@ static int parent;
static void sig_hand(int signo)
{
- if (parent)
- futex_set_and_wake(&test_shared_state->stage, TEST_FAIL_STAGE);
- futex_set_and_wake(&sig_received, signo);
+ if (signo == SIGUSR1) {
+ futex_cmpxchg_and_wake(&sig_received, TEST_NO_SIG, TEST_SIG_PRE);
+ } else {
+ if (parent)
+ futex_set_and_wake(&test_shared_state->stage, TEST_FAIL_STAGE);
+ futex_set_and_wake(&sig_received, TEST_SIG_STOP);
+ }
}
static char *outfile;
@@ -219,6 +223,11 @@ void test_init(int argc, char **argv)
exit(1);
}
+ if (sigaction(SIGUSR1, &sa, NULL)) {
+ fprintf(stderr, "Can't set SIGUSR1 handler: %m\n");
+ exit(1);
+ }
+
setup_outfile();
redir_stdfds();
@@ -289,12 +298,23 @@ void test_daemon()
int test_go(void)
{
- return !futex_get(&sig_received);
+ return futex_get(&sig_received) != TEST_SIG_STOP;
}
void test_waitsig(void)
{
- futex_wait_while(&sig_received, 0);
+ futex_wait_until(&sig_received, TEST_SIG_STOP);
+}
+
+int test_waitpre(void)
+{
+ int ret;
+
+ futex_wait_while(&sig_received, TEST_NO_SIG);
+ ret = futex_cmpxchg_and_wake(&sig_received, TEST_SIG_PRE, TEST_NO_SIG);
+ if (ret == TEST_SIG_PRE)
+ return 0;
+ return 1;
}
pid_t sys_clone_unified(unsigned long flags, void *child_stack, void *parent_tid,
diff --git a/test/zdtm/lib/zdtmtst.h b/test/zdtm/lib/zdtmtst.h
index dbe825cbc..f7af6dc1b 100644
--- a/test/zdtm/lib/zdtmtst.h
+++ b/test/zdtm/lib/zdtmtst.h
@@ -41,6 +41,7 @@ extern void test_msg(const char *format, ...)
extern int test_go(void);
/* sleep until SIGTERM is delivered */
extern void test_waitsig(void);
+extern int test_waitpre(void);
#include <stdint.h>
--
2.14.3
More information about the CRIU
mailing list