[CRIU] [PATCH 2/2] zdtm: Tech that pdeath_sig is preserved

Pavel Emelyanov xemul at parallels.com
Fri Jun 27 08:27:19 PDT 2014


Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
 test/zdtm.sh                       |   1 +
 test/zdtm/live/static/Makefile     |   1 +
 test/zdtm/live/static/pdeath_sig.c | 109 +++++++++++++++++++++++++++++++++++++
 3 files changed, 111 insertions(+)
 create mode 100644 test/zdtm/live/static/pdeath_sig.c

diff --git a/test/zdtm.sh b/test/zdtm.sh
index 6c5f19d..4532255 100755
--- a/test/zdtm.sh
+++ b/test/zdtm.sh
@@ -101,6 +101,7 @@ static/fpu01
 static/mmx00
 static/sse00
 static/sse20
+static/pdeath_sig
 static/fdt_shared
 static/file_locks00
 static/file_locks01
diff --git a/test/zdtm/live/static/Makefile b/test/zdtm/live/static/Makefile
index 7dad8e6..f41fd80 100644
--- a/test/zdtm/live/static/Makefile
+++ b/test/zdtm/live/static/Makefile
@@ -71,6 +71,7 @@ TST_NOFILE	=				\
 		maps05				\
 		xids00				\
 		groups				\
+		pdeath_sig			\
 		file_fown			\
 		proc-self			\
 		eventfs00			\
diff --git a/test/zdtm/live/static/pdeath_sig.c b/test/zdtm/live/static/pdeath_sig.c
new file mode 100644
index 0000000..4f2292a
--- /dev/null
+++ b/test/zdtm/live/static/pdeath_sig.c
@@ -0,0 +1,109 @@
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/prctl.h>
+#include <sys/wait.h>
+
+#include "zdtmtst.h"
+
+const char *test_doc	= "Check that pdeath sig is preserved";
+const char *test_author	= "Pavel Emelianov <xemul at parallels.com>";
+
+static int sigrecvd = 0;
+static void sigh(int s, siginfo_t *i, void *d)
+{
+	sigrecvd = 1;
+}
+
+#ifndef PR_SET_PDEATH_SIGNAL
+#define PR_SET_PDEATH_SIGNAL 1
+#endif
+
+int main(int argc, char **argv)
+{
+	int pid, ret, pw[2], pr[2];
+
+	test_init(argc, argv);
+
+	/*
+	 * Here's what will happen here:
+	 *
+	 *    me -(fork)-> P -(fork)-> C
+	 *     |                       |
+	 *     +-------------->-(pw)->-+
+	 *     +-<-(pr)-<--------------+
+	 *
+	 * We wait for C to prepare himself via pr.
+	 * After C/R we kill P and close pw to wake up
+	 * C. The we wait for it to report back via pr
+	 * which signals has he received.
+	 */
+
+	pipe(pw);
+	pipe(pr);
+
+	pid = fork();
+	if (pid == 0) {
+		pid = fork();
+		if (pid == 0) {
+			struct sigaction sa = {};
+			/* C */
+			close(pw[1]);
+			close(pr[0]);
+			sa.sa_sigaction = sigh;
+			ret = sigaction(SIGUSR1, &sa, NULL);
+			if (ret == 0)
+				ret = prctl(PR_SET_PDEATH_SIGNAL, SIGUSR1, 0, 0, 0);
+			write(pr[1], &ret, sizeof(ret));
+			read(pw[0], &ret, sizeof(ret));
+			write(pr[1], &sigrecvd, sizeof(sigrecvd));
+		} else {
+			/* P, pid == C */
+			close(pw[0]);
+			close(pw[1]);
+			close(pr[0]);
+			close(pr[1]);
+
+			/* Just hang */
+			waitpid(pid, NULL, 0);
+		}
+
+		exit(0);
+	}
+
+	/* me, pid == P */
+	close(pw[0]);
+	close(pr[1]);
+
+	ret = -1;
+	read(pr[0], &ret, sizeof(ret));
+	if (ret != 0) {
+		err("C start error\n");
+		goto out;
+	}
+
+	/*
+	 * P didn't have time to close his pipes?
+	 * That's OK, CRIU should C/R these knots.
+	 */
+
+	test_daemon();
+	test_waitsig();
+
+out:
+	kill(pid, SIGKILL);
+	waitpid(pid, NULL, 0);
+	close(pw[1]);
+
+	if (ret == 0) {
+		read(pr[0], &ret, sizeof(ret));
+		if (ret != 1)
+			fail("USR1 isn't delivered");
+		else
+			pass();
+	}
+
+	return 0;
+}
-- 
1.8.4.2




More information about the CRIU mailing list