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

Pavel Emelyanov xemul at parallels.com
Tue Jun 17 10:10:46 PDT 2014


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];
+		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);
 
 #endif /* __CRIU_LIB_H__ */
-- 
1.8.4.2


More information about the CRIU mailing list