[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