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

Serge Hallyn serge.hallyn at ubuntu.com
Fri Jun 27 10:11:48 PDT 2014


Quoting Pavel Emelyanov (xemul at parallels.com):
> Signed-off-by: Pavel Emelyanov <xemul at parallels.com>

Nice - had to read this twice to really grok it :)

Acked-by: Serge E. Hallyn <serge.hallyn at ubuntu.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
> 
> 
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu


More information about the CRIU mailing list