Commit 5f985fba authored by Ruslan Kuprieiev's avatar Ruslan Kuprieiev Committed by Pavel Emelyanov

libcriu: introduce CRIU_COMM_BIN

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: 's avatarRuslan Kuprieiev <rkuprieiev@cloudlinux.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 7f56602d
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#include "rpc.pb-c.h" #include "rpc.pb-c.h"
#include "cr-service-const.h" #include "cr-service-const.h"
#define CR_DEFAULT_SERVICE_BIN "criu"
const char *criu_lib_version = CRIU_VERSION; const char *criu_lib_version = CRIU_VERSION;
static criu_opts *global_opts; static criu_opts *global_opts;
...@@ -54,6 +56,19 @@ void criu_set_service_fd(int fd) ...@@ -54,6 +56,19 @@ void criu_set_service_fd(int fd)
criu_local_set_service_fd(global_opts, 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) int criu_local_init_opts(criu_opts **o)
{ {
criu_opts *opts = NULL; criu_opts *opts = NULL;
...@@ -718,7 +733,8 @@ static int send_notify_ack(int socket_fd, int ret) ...@@ -718,7 +733,8 @@ static int send_notify_ack(int socket_fd, int ret)
static void swrk_wait(criu_opts *opts) 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) static int swrk_connect(criu_opts *opts)
...@@ -757,7 +773,7 @@ static int swrk_connect(criu_opts *opts) ...@@ -757,7 +773,7 @@ static int swrk_connect(criu_opts *opts)
close(sks[0]); close(sks[0]);
sprintf(fds, "%d", sks[1]); 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"); perror("Can't exec criu swrk");
exit(1); exit(1);
} }
...@@ -781,6 +797,8 @@ static int criu_connect(criu_opts *opts) ...@@ -781,6 +797,8 @@ static int criu_connect(criu_opts *opts)
if (opts->service_comm == CRIU_COMM_FD) if (opts->service_comm == CRIU_COMM_FD)
return opts->service_fd; return opts->service_fd;
else if (opts->service_comm == CRIU_COMM_BIN)
return swrk_connect(opts);
fd = socket(AF_LOCAL, SOCK_SEQPACKET, 0); fd = socket(AF_LOCAL, SOCK_SEQPACKET, 0);
if (fd < 0) { if (fd < 0) {
...@@ -889,6 +907,8 @@ exit: ...@@ -889,6 +907,8 @@ exit:
if (resp) if (resp)
criu_resp__free_unpacked(resp, NULL); criu_resp__free_unpacked(resp, NULL);
swrk_wait(opts);
errno = saved_errno; errno = saved_errno;
return ret; return ret;
...@@ -926,6 +946,8 @@ exit: ...@@ -926,6 +946,8 @@ exit:
if (resp) if (resp)
criu_resp__free_unpacked(resp, NULL); criu_resp__free_unpacked(resp, NULL);
swrk_wait(opts);
errno = saved_errno; errno = saved_errno;
return ret; return ret;
...@@ -995,6 +1017,8 @@ exit: ...@@ -995,6 +1017,8 @@ exit:
if (resp) if (resp)
criu_resp__free_unpacked(resp, NULL); criu_resp__free_unpacked(resp, NULL);
swrk_wait(opts);
errno = saved_errno; errno = saved_errno;
return ret; return ret;
...@@ -1029,6 +1053,8 @@ exit: ...@@ -1029,6 +1053,8 @@ exit:
if (resp) if (resp)
criu_resp__free_unpacked(resp, NULL); criu_resp__free_unpacked(resp, NULL);
swrk_wait(opts);
errno = saved_errno; errno = saved_errno;
return ret; return ret;
...@@ -1042,10 +1068,36 @@ int criu_restore(void) ...@@ -1042,10 +1068,36 @@ int criu_restore(void)
int criu_local_restore_child(criu_opts *opts) int criu_local_restore_child(criu_opts *opts)
{ {
int sk, ret = -1; int sk, ret = -1;
enum criu_service_comm saved_comm;
char *saved_comm_data;
bool save_comm;
CriuReq req = CRIU_REQ__INIT; CriuReq req = CRIU_REQ__INIT;
CriuResp *resp = NULL; 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); sk = swrk_connect(opts);
if (save_comm) {
/* Restore comm */
opts->service_comm = saved_comm;
opts->service_address = saved_comm_data;
}
if (sk < 0) if (sk < 0)
return -1; return -1;
......
...@@ -27,11 +27,13 @@ ...@@ -27,11 +27,13 @@
enum criu_service_comm { enum criu_service_comm {
CRIU_COMM_SK, CRIU_COMM_SK,
CRIU_COMM_FD CRIU_COMM_FD,
CRIU_COMM_BIN
}; };
void criu_set_service_address(char *path); void criu_set_service_address(char *path);
void criu_set_service_fd(int fd); 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 * You can choose if you want libcriu to connect to service socket
...@@ -142,6 +144,7 @@ typedef struct { ...@@ -142,6 +144,7 @@ typedef struct {
union { union {
char *service_address; char *service_address;
int service_fd; int service_fd;
char *service_binary;
}; };
int swrk_pid; int swrk_pid;
} criu_opts; } criu_opts;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment