[CRIU] [PATCH] [PATCH 3/4] service: add multireq support

Ruslan Kuprieiev kupruser at gmail.com
Sun Feb 2 02:55:57 PST 2014


Signed-off-by: Ruslan Kuprieiev <kupruser at gmail.com>
---
 cr-service.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 74 insertions(+), 10 deletions(-)

diff --git a/cr-service.c b/cr-service.c
index 6c682c6..68c9fcc 100644
--- a/cr-service.c
+++ b/cr-service.c
@@ -365,22 +365,18 @@ out:
 	return success ? 0 : -1;
 }
 
-static int cr_service_work(int sk)
+static int subworker(int sk, CriuReq *msg)
 {
 	int ret = -1;
 
-	CriuReq *msg = 0;
 	CriuResp resp = CRIU_RESP__INIT;
 
 	init_opts();
 
-	if (recv_criu_msg(sk, &msg) == -1) {
-		pr_perror("Can't recv request");
-		return -1;
-	}
-
 	resp.success	= false;
 	resp.type	= msg->type;
+	resp.has_id	= msg->has_id;
+	resp.id		= msg->id;
 
 	switch (msg->type) {
 	case CRIU_REQ_TYPE__DUMP:
@@ -405,10 +401,8 @@ static int cr_service_work(int sk)
 		ret = -1;
 	}
 
-	if (send_criu_msg(sk, &resp)) {
-		pr_perror("Can't send resp");
+	if (send_criu_msg(sk, &resp))
 		ret = -1;
-	}
 
 	return ret;
 }
@@ -476,6 +470,76 @@ static int restore_sigchld_handler()
 	return 0;
 }
 
+static int multireq_mode(int sk, CriuReq *req)
+{
+	CriuResp resp = CRIU_RESP__INIT;
+
+	resp.type	= CRIU_REQ_TYPE__MULTIREQ;
+	resp.success	= true;
+	resp.has_id	= req->has_id;
+	resp.id		= req->id;
+
+	init_opts();
+
+	if (setup_opts_from_req(sk, req->opts)) {
+		pr_perror("Can't setup opts");
+		resp.success = false;
+	}
+
+	if (setup_sigchld_handler())
+		resp.success = false;
+
+	if (send_criu_msg(sk, &resp))
+		resp.success = false;
+
+	if (resp.success == false)
+		return -1;
+
+	while (1) {
+		int ret;
+
+		criu_req__free_unpacked(req, NULL);
+
+		if (recv_criu_msg(sk, &req))
+			return -1;
+
+		if (req->type == CRIU_REQ_TYPE__MULTIREQ) {
+			resp.has_id	= req->has_id;
+			resp.id		= req->id;
+			return send_criu_msg(sk, &resp);
+		}
+
+		ret = fork();
+
+		if (ret < 0) {
+			pr_perror("Can't fork");
+			return -1;
+		}
+
+		if (ret > 0)
+			continue;
+
+		if (restore_sigchld_handler())
+			exit(1);
+
+		exit(subworker(sk, req));
+
+	}
+}
+
+static int cr_service_work(int sk)
+{
+	CriuReq *msg = 0;
+
+	if (recv_criu_msg(sk, &msg))
+		return -1;
+
+	if (msg->type == CRIU_REQ_TYPE__MULTIREQ)
+		return multireq_mode(sk, msg);
+	else
+		return subworker(sk, msg);
+}
+
 int cr_service(bool daemon_mode)
 {
 	int server_fd = -1, n;
-- 
1.8.3.2



More information about the CRIU mailing list