[CRIU] [PATCH 3/3] libcriu: introduce CRIU_COMM_BIN

Ruslan Kuprieiev rkuprieiev at cloudlinux.com
Thu Jul 30 13:40:22 PDT 2015


In this mode libcriu will execute criu binary in swrk
mode, so users are not always obliged to run criu service
daemon.

Signed-off-by: Ruslan Kuprieiev <rkuprieiev at cloudlinux.com>
---
 lib/criu.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 lib/criu.h |  5 ++++-
 2 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/lib/criu.c b/lib/criu.c
index 6cff5a6..a6d8501 100644
--- a/lib/criu.c
+++ b/lib/criu.c
@@ -16,6 +16,8 @@
 #include "rpc.pb-c.h"
 #include "cr-service-const.h"
 
+#define CR_DEFAULT_SERVICE_BIN "criu"
+
 const char *criu_lib_version = CRIU_VERSION;
 
 static criu_opts *global_opts;
@@ -54,6 +56,19 @@ void criu_set_service_fd(int fd)
 	criu_local_set_service_fd(global_opts, fd);
 }
 
+void criu_local_set_service_binary(criu_opts *opts, char *path)
+{
+	if (path)
+		opts->service_binary = path;
+	else
+		opts->service_binary = CR_DEFAULT_SERVICE_BIN;
+}
+
+void criu_set_service_binary(char *path)
+{
+	criu_local_set_service_binary(global_opts, path);
+}
+
 int criu_local_init_opts(criu_opts **o)
 {
 	criu_opts *opts = NULL;
@@ -718,7 +733,8 @@ static int send_notify_ack(int socket_fd, int ret)
 
 static void swrk_wait(criu_opts *opts)
 {
-	waitpid(opts->swrk_pid, NULL, 0);
+	if (opts->service_comm == CRIU_COMM_BIN)
+		waitpid(opts->swrk_pid, NULL, 0);
 }
 
 static int swrk_connect(criu_opts *opts)
@@ -757,7 +773,7 @@ static int swrk_connect(criu_opts *opts)
 		close(sks[0]);
 		sprintf(fds, "%d", sks[1]);
 
-		execlp("criu", "criu", "swrk", fds, NULL);
+		execlp(opts->service_binary, opts->service_binary, "swrk", fds, NULL);
 		perror("Can't exec criu swrk");
 		exit(1);
 	}
@@ -781,6 +797,8 @@ static int criu_connect(criu_opts *opts)
 
 	if (opts->service_comm == CRIU_COMM_FD)
 		return opts->service_fd;
+	else if (opts->service_comm == CRIU_COMM_BIN)
+		return swrk_connect(opts);
 
 	fd = socket(AF_LOCAL, SOCK_SEQPACKET, 0);
 	if (fd < 0) {
@@ -889,6 +907,8 @@ exit:
 	if (resp)
 		criu_resp__free_unpacked(resp, NULL);
 
+	swrk_wait(opts);
+
 	errno = saved_errno;
 
 	return ret;
@@ -926,6 +946,8 @@ exit:
 	if (resp)
 		criu_resp__free_unpacked(resp, NULL);
 
+	swrk_wait(opts);
+
 	errno = saved_errno;
 
 	return ret;
@@ -995,6 +1017,8 @@ exit:
 	if (resp)
 		criu_resp__free_unpacked(resp, NULL);
 
+	swrk_wait(opts);
+
 	errno = saved_errno;
 
 	return ret;
@@ -1029,6 +1053,8 @@ exit:
 	if (resp)
 		criu_resp__free_unpacked(resp, NULL);
 
+	swrk_wait(opts);
+
 	errno = saved_errno;
 
 	return ret;
@@ -1042,10 +1068,36 @@ int criu_restore(void)
 int criu_local_restore_child(criu_opts *opts)
 {
 	int sk, ret = -1;
+	enum criu_service_comm saved_comm;
+	char *saved_comm_data;
+	bool save_comm;
 	CriuReq req	= CRIU_REQ__INIT;
 	CriuResp *resp	= NULL;
 
+	/*
+	 * restore_child is not possible with criu running as a system
+	 * service, so we need to switch comm method to CRIU_COMM_BIN.
+	 * We're doing so because of the backward compatibility, and we
+	 * should probably consider requiring CRIU_COMM_BIN to be set by
+	 * user at some point.
+	 */
+	save_comm = (opts->service_comm != CRIU_COMM_BIN);
+	if (save_comm) {
+		/* Save comm */
+		saved_comm = opts->service_comm;
+		saved_comm_data = opts->service_address;
+
+		opts->service_comm = CRIU_COMM_BIN;
+		opts->service_binary = CR_DEFAULT_SERVICE_BIN;
+	}
+
 	sk = swrk_connect(opts);
+	if (save_comm) {
+		/* Restore comm */
+		opts->service_comm = saved_comm;
+		opts->service_address = saved_comm_data;
+	}
+
 	if (sk < 0)
 		return -1;
 
diff --git a/lib/criu.h b/lib/criu.h
index d2196bf..130e03c 100644
--- a/lib/criu.h
+++ b/lib/criu.h
@@ -27,11 +27,13 @@
 
 enum criu_service_comm {
 	CRIU_COMM_SK,
-	CRIU_COMM_FD
+	CRIU_COMM_FD,
+	CRIU_COMM_BIN
 };
 
 void criu_set_service_address(char *path);
 void criu_set_service_fd(int fd);
+void criu_set_service_binary(char *path);
 
 /*
  * You can choose if you want libcriu to connect to service socket
@@ -142,6 +144,7 @@ typedef struct {
 	union {
 		char		*service_address;
 		int		service_fd;
+		char		*service_binary;
 	};
 	int			swrk_pid;
 } criu_opts;
-- 
1.8.3.1



More information about the CRIU mailing list