[RFC,4/4] cr-service: use inherit-fd keys to ask for FD

Submitted by Adrian Reber on Aug. 3, 2018, 3:28 p.m.

Details

Message ID 20180803152808.25928-5-adrian@lisas.de
State New
Series "Series without cover letter"
Headers show

Commit Message

Adrian Reber Aug. 3, 2018, 3:28 p.m.
From: Adrian Reber <areber@redhat.com>

Using inherit-fd in RPC mode uses the notify mechanism to ask the RPC
client for the real FD.

Signed-off-by: Adrian Reber <areber@redhat.com>
---
 criu/action-scripts.c         | 10 +++++++---
 criu/cr-service.c             | 28 +++++++++++++++++++++++++---
 criu/files.c                  | 10 ++++++++++
 criu/include/action-scripts.h |  4 ++--
 criu/include/files.h          |  1 +
 criu/tty.c                    |  2 +-
 6 files changed, 46 insertions(+), 9 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/action-scripts.c b/criu/action-scripts.c
index 4e9eb65cf..1a7523527 100644
--- a/criu/action-scripts.c
+++ b/criu/action-scripts.c
@@ -100,7 +100,11 @@  static int run_shell_scripts(const char *action)
 	return retval;
 }
 
-int rpc_send_fd(enum script_actions act, int fd)
+/*
+ * The name of this function is misleading. Right now it only
+ * sends an FD in one of three possible use cases.
+ */
+int rpc_send_fd(enum script_actions act, int fd, char *key)
 {
 	const char *action = action_names[act];
 	int rpc_sk;
@@ -113,7 +117,7 @@  int rpc_send_fd(enum script_actions act, int fd)
 		return -1;
 
 	pr_debug("\tRPC\n");
-	return send_criu_rpc_script(act, (char *)action, rpc_sk, fd);
+	return send_criu_rpc_script(act, (char *)action, rpc_sk, fd, key);
 }
 
 int run_scripts(enum script_actions act)
@@ -127,7 +131,7 @@  int run_scripts(enum script_actions act)
 		return 0;
 
 	if (scripts_mode == SCRIPTS_RPC) {
-		ret = rpc_send_fd(act, -1);
+		ret = rpc_send_fd(act, -1, NULL);
 		goto out;
 	}
 
diff --git a/criu/cr-service.c b/criu/cr-service.c
index 643aba9cf..b3383198e 100644
--- a/criu/cr-service.c
+++ b/criu/cr-service.c
@@ -188,9 +188,10 @@  int send_criu_restore_resp(int socket_fd, bool success, int pid)
 	return send_criu_msg(socket_fd, &msg);
 }
 
-int send_criu_rpc_script(enum script_actions act, char *name, int sk, int fd)
+int send_criu_rpc_script(enum script_actions act, char *name, int sk, int fd, char *key)
 {
 	int ret;
+	int ret_fd = 0;
 	CriuResp msg = CRIU_RESP__INIT;
 	CriuReq *req;
 	CriuNotify cn = CRIU_NOTIFY__INIT;
@@ -211,6 +212,15 @@  int send_criu_rpc_script(enum script_actions act, char *name, int sk, int fd)
 		cn.has_pid = true;
 		cn.pid = root_item->pid->real;
 		break;
+	case ACT_REQ_INHERIT_FD:
+		/*
+		 * Sending a 'ACT_REQ_INHERIT_FD' notify message
+		 * only makes sense when 'key' is set.
+		 */
+		if (!key)
+			return -1;
+		cn.inherit_fd_key = key;
+		break;
 	default:
 		break;
 	}
@@ -219,6 +229,18 @@  int send_criu_rpc_script(enum script_actions act, char *name, int sk, int fd)
 	if (ret < 0)
 		return ret;
 
+	if (act == ACT_REQ_INHERIT_FD) {
+		/*
+		 * Sending a ACT_REQ_INHERIT_FD notify message means, that CRIU
+		 * expects to get a FD from the RPC client.
+		 */
+		ret_fd = recv_fd(sk);
+		if (ret_fd <= 0) {
+			pr_perror("recv_fd error\n");
+			return -1;
+		}
+	}
+
 	ret = recv_criu_msg(sk, &req);
 	if (ret < 0)
 		return ret;
@@ -229,7 +251,7 @@  int send_criu_rpc_script(enum script_actions act, char *name, int sk, int fd)
 	}
 
 	criu_req__free_unpacked(req, NULL);
-	return 0;
+	return ret_fd;
 }
 
 static char images_dir[PATH_MAX];
@@ -485,7 +507,7 @@  static int setup_opts_from_req(int sk, CriuOpts *req)
 		goto err;
 	}
 	for (i = 0; i < req->n_inherit_fd; i++) {
-		if (inherit_fd_add(req->inherit_fd[i]->fd, req->inherit_fd[i]->key))
+		if (inherit_fd_add_rpc(req->inherit_fd[i]->key))
 			goto err;
 	}
 
diff --git a/criu/files.c b/criu/files.c
index 4ed84305e..6d71bb9df 100644
--- a/criu/files.c
+++ b/criu/files.c
@@ -26,6 +26,7 @@ 
 #include "sockets.h"
 #include "pstree.h"
 #include "tty.h"
+#include "action-scripts.h"
 #include "pipes.h"
 #include "fifo.h"
 #include "eventfd.h"
@@ -1572,6 +1573,15 @@  int inherit_fd_parse(char *optarg)
 	return inherit_fd_add(fd, cp);
 }
 
+int inherit_fd_add_rpc(char *key)
+{
+	int fd;
+	fd = rpc_send_fd(ACT_REQ_INHERIT_FD, -1, key);
+	if (fd <= 0)
+		return -1;
+	return inherit_fd_add(fd, key);
+}
+
 int inherit_fd_add(int fd, char *key)
 {
 	struct inherit_fd *inh;
diff --git a/criu/include/action-scripts.h b/criu/include/action-scripts.h
index 4b90feb92..bd96e256d 100644
--- a/criu/include/action-scripts.h
+++ b/criu/include/action-scripts.h
@@ -23,7 +23,7 @@  enum script_actions {
 extern int add_script(char *path);
 extern int add_rpc_notify(int sk);
 extern int run_scripts(enum script_actions);
-extern int rpc_send_fd(enum script_actions, int fd);
-extern int send_criu_rpc_script(enum script_actions act, char *name, int sk, int fd);
+extern int rpc_send_fd(enum script_actions, int fd, char *key);
+extern int send_criu_rpc_script(enum script_actions act, char *name, int sk, int fd, char *key);
 
 #endif /* __CR_ACTION_SCRIPTS_H__ */
diff --git a/criu/include/files.h b/criu/include/files.h
index 75757bd1d..9cffe960c 100644
--- a/criu/include/files.h
+++ b/criu/include/files.h
@@ -188,6 +188,7 @@  extern int dump_unsupp_fd(struct fd_parms *p, int lfd,
 		char *more, char *info, FdinfoEntry *);
 
 extern int inherit_fd_parse(char *optarg);
+extern int inherit_fd_add_rpc(char *key);
 extern int inherit_fd_add(int fd, char *key);
 extern void inherit_fd_log(void);
 extern int inherit_fd_resolve_clash(int fd);
diff --git a/criu/tty.c b/criu/tty.c
index 30e3d7288..676ad888c 100644
--- a/criu/tty.c
+++ b/criu/tty.c
@@ -984,7 +984,7 @@  static int pty_open_unpaired_slave(struct file_desc *d, struct tty_info *slave)
 			unlock_pty(master);
 
 			if (opts.orphan_pts_master &&
-			    rpc_send_fd(ACT_ORPHAN_PTS_MASTER, master) == 0) {
+			    rpc_send_fd(ACT_ORPHAN_PTS_MASTER, master, NULL) == 0) {
 
 				fd = open_tty_reg(slave->reg_d, slave->tfe->flags);
 				if (fd < 0) {