[CRIU] [PATCH 4/4] service: add check request support

Ruslan Kuprieiev kupruser at gmail.com
Fri Nov 15 17:00:16 PST 2013


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

diff --git a/cr-service.c b/cr-service.c
index 65710fd..c2e4a3e 100644
--- a/cr-service.c
+++ b/cr-service.c
@@ -12,12 +12,16 @@
 #include <sys/un.h>
 #include <sys/wait.h>
 #include <sys/stat.h>
+#include <fcntl.h>
 
 #include "crtools.h"
 #include "cr_options.h"
 #include "util.h"
 #include "log.h"
 #include "pstree.h"
+#include "proc_parse.h"
+#include "protobuf.h"
+#include "protobuf/creds.pb-c.h"
 #include "cr-service.h"
 
 unsigned int service_sk_ino = -1;
@@ -217,6 +221,116 @@ exit:
 	return success ? 0 : 1;
 }
 
+static int can_dump(int pid)
+{
+	struct proc_status_creds creds;
+	int ret;
+
+	ret = parse_pid_status(pid, &creds);
+	if (ret < 0) {
+		pr_perror("Can't get task stat");
+		return -1;
+	}
+
+	if (!may_dump(&creds)) {
+		pr_perror("Have no rights to dump task %d", pid);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int can_restore(void)
+{
+	char path[PATH_MAX];
+	struct stat s;
+	CredsEntry *ce;
+	int fd;
+
+	if (check_img_inventory() < 0) {
+		pr_perror("Something wrong with images");
+		return -1;
+	}
+
+	if (prepare_task_entries()) {
+		pr_perror("Can't prepare task ent");
+		return -1;
+	}
+
+	if (read_pstree_image()) {
+		pr_perror("Can't read pstree image");
+		return -1;
+	}
+
+	sprintf(path, "/proc/%d", root_item->pid.real);
+	if (stat(path, &s)) {
+		if (errno != ENOENT)
+			return -1;
+	} else {
+		pr_perror("Process %d exists", root_item->pid.real);
+		return -1;
+	}
+
+	fd = open_image(CR_FD_CREDS, O_RSTR, root_item->pid.virt);
+	if (fd < 0)
+		return -1;
+
+	if (pb_read_one(fd, &ce, PB_CREDS) < 0)
+		return -1;
+
+	close_safe(&fd);
+
+	if (!may_restore(ce)) {
+		pr_perror("Have no rights to restore task");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int check_using_req(int sk, CriuOpts *req)
+{
+	bool success = false;
+	CriuResp msg = CRIU_RESP__INIT;
+	CriuCheckResp resp = CRIU_CHECK_RESP__INIT;
+
+	if (setup_opts_from_req(sk, req) == -1) {
+		pr_perror("Arguments treating fail");
+		goto exit;
+	}
+
+	resp.kernel = true;
+	if (cr_check()) {
+		pr_perror("The kernel support isn't up-to-date");
+		resp.kernel = false;
+	}
+
+	resp.dump = true;
+	if (can_dump(req->pid)) {
+		pr_perror("Can't dump process %d", req->pid);
+		resp.dump = false;
+	}
+
+	resp.restore = true;
+	if (can_restore()) {
+		pr_perror("Can't restore process");
+		resp.restore = false;
+	}
+
+	success = true;
+exit:
+	msg.type = CRIU_REQ_TYPE__CHECK;
+	msg.success = success;
+	msg.check = &resp;
+
+	if (send_criu_msg(sk, &msg) == -1) {
+		pr_perror("Can't send response");
+		success = false;
+	}
+
+	return success ? 0 : 1;
+}
+
 static int cr_service_work(int sk)
 {
 	CriuReq *msg = 0;
@@ -233,6 +347,8 @@ static int cr_service_work(int sk)
 		return dump_using_req(sk, msg->opts);
 	case CRIU_REQ_TYPE__RESTORE:
 		return restore_using_req(sk, msg->opts);
+	case CRIU_REQ_TYPE__CHECK:
+		return check_using_req(sk, msg->opts);
 
 	default: {
 		CriuResp resp = CRIU_RESP__INIT;
-- 
1.8.1.2



More information about the CRIU mailing list