[CRIU] [PATCH 3/3] libcriu: allow user to specify service fd, v2

Ruslan Kuprieiev rkuprieiev at cloudlinux.com
Thu Jul 16 05:42:25 PDT 2015


Currently, libcriu is connecting to CRIU service
by itself, just asking user for a path to socket.
But in some cases users need to provide fd instead
path. For example, sometimes task has no access to
criu socket because of strict security mesures, but
is able to inherit fd from a parent that has access
to criu socket.

v2, use union for addr and fd

Signed-off-by: Ruslan Kuprieiev <rkuprieiev at cloudlinux.com>
---
 lib/criu.c | 46 ++++++++++++++++++++++++++++++++++++++--------
 lib/criu.h | 27 +++++++++++++++++++++++++--
 2 files changed, 63 insertions(+), 10 deletions(-)

diff --git a/lib/criu.c b/lib/criu.c
index 3b36ddd..ffa161d 100644
--- a/lib/criu.c
+++ b/lib/criu.c
@@ -18,16 +18,40 @@
 
 const char *criu_lib_version = CRIU_VERSION;
 
-static char *service_address = CR_DEFAULT_SERVICE_ADDRESS;
 static criu_opts *global_opts;
 static int saved_errno;
 
-void criu_set_service_address(char *path)
+void criu_local_set_service_comm(criu_opts *opts, enum criu_service_comm comm)
+{
+	opts->service_comm = comm;
+}
+
+void criu_set_service_comm(enum criu_service_comm comm)
+{
+	criu_local_set_service_comm(global_opts, comm);
+}
+
+void criu_local_set_service_address(criu_opts *opts, char *path)
 {
 	if (path)
-		service_address = path;
+		opts->service_address = path;
 	else
-		service_address = CR_DEFAULT_SERVICE_ADDRESS;
+		opts->service_address = CR_DEFAULT_SERVICE_ADDRESS;
+}
+
+void criu_set_service_address(char *path)
+{
+	criu_local_set_service_address(global_opts, path);
+}
+
+void criu_local_set_service_fd(criu_opts *opts, int fd)
+{
+	opts->service_fd = fd;
+}
+
+void criu_set_service_fd(int fd)
+{
+	criu_local_set_service_fd(global_opts, fd);
 }
 
 int criu_local_init_opts(criu_opts **o)
@@ -57,6 +81,9 @@ int criu_local_init_opts(criu_opts **o)
 	opts->rpc	= rpc;
 	opts->notify	= NULL;
 
+	opts->service_comm	= CRIU_COMM_SK;
+	opts->service_address	= CR_DEFAULT_SERVICE_ADDRESS;
+
 	*o = opts;
 
 	return 0;
@@ -636,12 +663,15 @@ static int send_notify_ack(int socket_fd, int ret)
 	return ret ? : send_ret;
 }
 
-static int criu_connect(void)
+static int criu_connect(criu_opts *opts)
 {
 	int fd, ret;
 	struct sockaddr_un addr;
 	socklen_t addr_len;
 
+	if (opts->service_comm == CRIU_COMM_FD)
+		return opts->service_fd;
+
 	fd = socket(AF_LOCAL, SOCK_SEQPACKET, 0);
 	if (fd < 0) {
 		saved_errno = errno;
@@ -652,7 +682,7 @@ static int criu_connect(void)
 	memset(&addr, 0, sizeof(addr));
 	addr.sun_family = AF_LOCAL;
 
-	strncpy(addr.sun_path, service_address, sizeof(addr.sun_path));
+	strncpy(addr.sun_path, opts->service_address, sizeof(addr.sun_path));
 
 	addr_len = strlen(addr.sun_path) + sizeof(addr.sun_family);
 
@@ -717,7 +747,7 @@ static int send_req_and_recv_resp(criu_opts *opts, CriuReq *req, CriuResp **resp
 	int fd;
 	int ret	= 0;
 
-	fd = criu_connect();
+	fd = criu_connect(opts);
 	if (fd < 0) {
 		perror("Can't connect to criu");
 		ret = -ECONNREFUSED;
@@ -819,7 +849,7 @@ int criu_local_dump_iters(criu_opts *opts, int (*more)(criu_predump_info pi))
 		goto exit;
 
 	ret = -ECONNREFUSED;
-	fd = criu_connect();
+	fd = criu_connect(opts);
 	if (fd < 0)
 		goto exit;
 
diff --git a/lib/criu.h b/lib/criu.h
index ae34357..1655c02 100644
--- a/lib/criu.h
+++ b/lib/criu.h
@@ -22,7 +22,19 @@
 #include <stdbool.h>
 #include "rpc.pb-c.h"
 
+enum criu_service_comm {
+	CRIU_COMM_SK,
+	CRIU_COMM_FD
+};
+
 void criu_set_service_address(char *path);
+void criu_set_service_fd(int fd);
+
+/*
+ * You can choose if you want libcriu to connect to service socket
+ * by itself or just use provided file descriptor
+ */
+void criu_set_service_comm(enum criu_service_comm);
 
 /*
  * Set opts to defaults. _Must_ be called first before using any functions from
@@ -122,12 +134,23 @@ int criu_dump_iters(int (*more)(criu_predump_info pi));
  */
 
 typedef struct {
-	CriuOpts	*rpc; /* Generic RPC options in protobuf format */
-	int		(*notify)(char *action, criu_notify_arg_t na);
+	CriuOpts		*rpc; /* Generic RPC options in protobuf format */
+	int			(*notify)(char *action, criu_notify_arg_t na);
+	enum criu_service_comm	service_comm;
+	union {
+		char		*service_address;
+		int		service_fd;
+	};
 } criu_opts;
 
 int criu_local_init_opts(criu_opts **opts);
 
+void criu_local_set_service_address(criu_opts *opts, char *path);
+void criu_local_set_service_fd(criu_opts *opts, int fd);
+void criu_local_set_service_comm(criu_opts *opts, enum criu_service_comm);
+
+void criu_local_set_service_fd(criu_opts *opts, int fd);
+
 void criu_local_set_pid(criu_opts *opts, int pid);
 void criu_local_set_images_dir_fd(criu_opts *opts, int fd); /* must be set for dump/restore */
 void criu_local_set_parent_images(criu_opts *opts, char *path);
-- 
2.1.0



More information about the CRIU mailing list