[CRIU] [PATCH 2/3] dump: add root_only option

Ruslan Kuprieiev rkuprieiev at cloudlinux.com
Thu Jan 5 04:42:19 PST 2017


This option allows to dump only root of a specified process
tree. This behaviour is useful for dumping master processes,
that fork it's children to do the work. I.e. one of such cases
is php process that forks workers. When one uses this option,
he agrees to possible consequences and is ready to handle
recovering from such restore on a dumpee side.

Signed-off-by: Ruslan Kuprieiev <rkuprieiev at cloudlinux.com>
---
 criu/cr-service.c         |  3 +++
 criu/crtools.c            |  5 +++++
 criu/include/cr_options.h |  1 +
 criu/seize.c              | 10 ++++++----
 images/rpc.proto          |  1 +
 lib/c/criu.c              | 11 +++++++++++
 lib/c/criu.h              |  2 ++
 7 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/criu/cr-service.c b/criu/cr-service.c
index 00a2d07..721217c 100644
--- a/criu/cr-service.c
+++ b/criu/cr-service.c
@@ -504,6 +504,9 @@ static int setup_opts_from_req(int sk, CriuOpts *req)
 		}
 	}
 
+	if (req->has_root_only)
+		opts.root_only = req->root_only;
+
 	if (check_namespace_opts())
 		goto err;
 
diff --git a/criu/crtools.c b/criu/crtools.c
index 06b2fa7..61a774c 100644
--- a/criu/crtools.c
+++ b/criu/crtools.c
@@ -286,6 +286,7 @@ int main(int argc, char *argv[], char *envp[])
 		{ "check-only",			no_argument,		0, 1085 },
 		{ "display-stats",		no_argument,		0, 1086 },
 		{ "weak-sysctls",		no_argument,		0, 1087 },
+		{ "root-only",			no_argument,		0, 1088 },
 		{ },
 	};
 
@@ -613,6 +614,9 @@ int main(int argc, char *argv[], char *envp[])
 			pr_msg("Will skip non-existant sysctls on restore\n");
 			opts.weak_sysctls = true;
 			break;
+		case 1088:
+			opts.root_only = true;
+			break;
 		case 'V':
 			pr_msg("Version: %s\n", CRIU_VERSION);
 			if (strcmp(CRIU_GITID, "0"))
@@ -847,6 +851,7 @@ usage:
 "  --check-only          check if checkpointing/restoring will actually work\n"
 "                        the process will keep on running and memory pages\n"
 "                        will not be dumped\n"
+"  --root-only           dump only root task in a specified process tree\n"
 "\n"
 "* External resources support:\n"
 "  --external RES        dump objects from this list as external resources:\n"
diff --git a/criu/include/cr_options.h b/criu/include/cr_options.h
index 4f70b41..3e6e49f 100644
--- a/criu/include/cr_options.h
+++ b/criu/include/cr_options.h
@@ -119,6 +119,7 @@ struct cr_options {
 	bool			display_stats;
 	bool			weak_sysctls;
 	bool			check_only;
+	bool			root_only;
 };
 
 extern struct cr_options opts;
diff --git a/criu/seize.c b/criu/seize.c
index a1cf497..c67f9a3 100644
--- a/criu/seize.c
+++ b/criu/seize.c
@@ -805,10 +805,12 @@ static int collect_task(struct pstree_item *item)
 	if (ret < 0)
 		goto err_close;
 
-	/* Depth-first search (DFS) is used for traversing a process tree. */
-	ret = collect_loop(item, collect_children);
-	if (ret < 0)
-		goto err_close;
+	if (!opts.root_only) {
+		/* Depth-first search (DFS) is used for traversing a process tree. */
+		ret = collect_loop(item, collect_children);
+		if (ret < 0)
+			goto err_close;
+	}
 
 	if ((item->pid.state == TASK_DEAD) && !list_empty(&item->children)) {
 		pr_err("Zombie with children?! O_o Run, run, run!\n");
diff --git a/images/rpc.proto b/images/rpc.proto
index 7cf958c..42052c9 100644
--- a/images/rpc.proto
+++ b/images/rpc.proto
@@ -108,6 +108,7 @@ message criu_opts {
 	optional uint32			timeout			= 45;
 	optional bool			tcp_skip_in_flight	= 46;
 	optional bool			weak_sysctls		= 47;
+	optional bool			root_only		= 48;
 }
 
 message criu_dump_resp {
diff --git a/lib/c/criu.c b/lib/c/criu.c
index 08806c6..4730506 100644
--- a/lib/c/criu.c
+++ b/lib/c/criu.c
@@ -880,6 +880,17 @@ int criu_add_external(char *key)
 	return criu_local_add_external(global_opts, key);
 }
 
+void criu_local_set_root_only(criu_opts *opts, bool root_only)
+{
+	opts->rpc->has_root_only = true;
+	opts->rpc->root_only = root_only;
+}
+
+void criu_set_root_only(bool root_only)
+{
+	criu_local_set_root_only(global_opts, root_only);
+}
+
 static CriuResp *recv_resp(int socket_fd)
 {
 	unsigned char *buf = NULL;
diff --git a/lib/c/criu.h b/lib/c/criu.h
index 5d0b5b6..9928d1d 100644
--- a/lib/c/criu.h
+++ b/lib/c/criu.h
@@ -95,6 +95,7 @@ void criu_set_ghost_limit(unsigned int limit);
 int criu_add_irmap_path(char *path);
 int criu_add_inherit_fd(int fd, char *key);
 int criu_add_external(char *key);
+void criu_set_root_only(bool root_only);
 
 /*
  * The criu_notify_arg_t na argument is an opaque
@@ -206,6 +207,7 @@ int criu_local_add_cg_props_file(criu_opts *opts, char *path);
 int criu_local_add_cg_dump_controller(criu_opts *opts, char *name);
 int criu_local_add_inherit_fd(criu_opts *opts, int fd, char *key);
 int criu_local_add_external(criu_opts *opts, char *key);
+void criu_local_set_root_only(criu_opts *opts, bool root_only);
 
 void criu_local_set_notify_cb(criu_opts *opts, int (*cb)(char *action, criu_notify_arg_t na));
 
-- 
2.5.5



More information about the CRIU mailing list