[CRIU] [PATCH 3/4] lib: Implement the criu_restore_sub() call

Andrew Vagin avagin at parallels.com
Mon Jun 23 00:06:08 PDT 2014


On Tue, Jun 17, 2014 at 09:10:46PM +0400, Pavel Emelyanov wrote:
> It fully uses the swrk action of criu. The problems, that caller may
> have is that the restored tasks die _before_ libcriu's call returns.
> Should we return with blocked CHLD signal or require the caller to 
> handle it himself?
> 
> Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
> ---
>  lib/criu.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  lib/criu.h |  1 +
>  2 files changed, 60 insertions(+)
> 
> diff --git a/lib/criu.c b/lib/criu.c
> index 8d06ada..3b2156a 100644
> --- a/lib/criu.c
> +++ b/lib/criu.c
> @@ -1,4 +1,7 @@
>  #include "version.h"
> +#include <sys/prctl.h>
> +#include <sys/wait.h>
> +#include <sys/types.h>
>  #include <sys/socket.h>
>  #include <sys/un.h>
>  #include <limits.h>
> @@ -351,3 +354,59 @@ exit:
>  
>  	return ret;
>  }
> +
> +int criu_restore_sub(void)
> +{
> +	int sks[2], pid, ret = -1;
> +	CriuReq req	= CRIU_REQ__INIT;
> +	CriuResp *resp	= NULL;
> +
> +	if (socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sks))
> +		goto out;
> +
> +	/*
> +	 * Set us as child subreaper so that after the swrk
> +	 * finishes restore and exits the restored subtree
> +	 * gets reparented to us.
> +	 */
> +
> +	if (prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0))
> +		goto err;
> +
> +	pid = fork();
> +	if (pid < 0)
> +		goto err;
> +
> +	if (pid == 0) {
> +		char fds[10];

>>> 1 << 31
2 147 483 648

char fds[11];

I know that it's unreal, but I think Coverity will worry about that.

> +		close(sks[0]);
> +		sprintf(fds, "%d", sks[1]);
> +		execlp("criu", "criu", "swrk", fds, NULL);
> +		exit(1);
> +	}
> +
> +	close(sks[1]);
> +
> +	req.type	= CRIU_REQ_TYPE__RESTORE;
> +	req.opts	= opts;
> +
> +	ret = send_req_and_recv_resp_sk(sks[0], &req, &resp);
> +
> +	close(sks[0]);
> +	waitpid(pid, NULL, 0);
> +	/* Drop the subreaper role _after_ swrk exits */
> +	prctl(PR_SET_CHILD_SUBREAPER, 0, 0, 0);
> +
> +	if (!ret) {
> +		ret = resp->success ? resp->restore->pid : -EBADE;
> +		criu_resp__free_unpacked(resp, NULL);
> +	}
> +
> +out:
> +	return ret;
> +
> +err:
> +	close(sks[1]);
> +	close(sks[0]);
> +	goto out;
> +}
> diff --git a/lib/criu.h b/lib/criu.h
> index f879029..e8c8409 100644
> --- a/lib/criu.h
> +++ b/lib/criu.h
> @@ -67,5 +67,6 @@ int criu_set_exec_cmd(int argc, char *argv[]);
>  int criu_check(void);
>  int criu_dump(void);
>  int criu_restore(void);
> +int criu_restore_sub(void);

Does criu_restore_child() sound better?
>  
>  #endif /* __CRIU_LIB_H__ */
> -- 
> 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