[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