[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