[CRIU] [PATCHv1 1/3] cgroups: save freezer state during dump

Eugene Batalov eabatalov89 at gmail.com
Tue Dec 8 05:32:28 PST 2015


From: Evgeniy Akimov <geka666 at gmail.com>

CRIU sets freezer.state to "THAWED" during process tree dumping. That's why
we can't simply save freezer.state file contents to cgroups image. New
special function get_real_freezer_state() returns freezer cgroup state
observed before CRIU dumping start. Patch puts its return value to dump file.

Signed-off-by: Evgeniy Akimov <geka666 at gmail.com>
Signed-off-by: Eugene Batalov <eabatalov89 at gmail.com>
---
 cgroup.c        | 33 +++++++++++++++++++++++++++++++++
 include/seize.h |  1 +
 seize.c         |  5 +++++
 3 files changed, 39 insertions(+)

diff --git a/cgroup.c b/cgroup.c
index 7d8f1be..e089f82 100644
--- a/cgroup.c
+++ b/cgroup.c
@@ -17,6 +17,7 @@
 #include "imgset.h"
 #include "util-pie.h"
 #include "namespaces.h"
+#include "seize.h"
 #include "protobuf.h"
 #include "protobuf/core.pb-c.h"
 #include "protobuf/cgroup.pb-c.h"
@@ -493,6 +494,33 @@ out:
 	return exit_code;
 }
 
+static int add_freezer_state(struct cg_controller *controller)
+{
+	struct cgroup_dir *root_dir;
+	struct cgroup_prop *prop;
+
+	/*
+	 * Here we rely on --freeze-cgroup option assumption that all tasks are in a
+	 * specified freezer cgroup hierarchy, so we need to dump only one root freezer cgroup.
+	 */
+	BUG_ON(!list_is_singular(&controller->heads));
+	root_dir = list_first_entry(&controller->heads, struct cgroup_dir, siblings);
+
+	prop = create_cgroup_prop("freezer.state");
+	if (!prop)
+		return -1;
+	prop->value = xstrdup(get_real_freezer_state());
+	if (!prop->value) {
+		free_cgroup_prop(prop);
+		return -1;
+	}
+
+	list_add_tail(&prop->list, &root_dir->properties);
+	root_dir->n_properties++;
+
+	return 0;
+}
+
 static int collect_cgroups(struct list_head *ctls)
 {
 	struct cg_ctl *cc;
@@ -566,6 +594,11 @@ static int collect_cgroups(struct list_head *ctls)
 
 		if (ret < 0)
 			return ret;
+
+		if (opts.freeze_cgroup && !strcmp(cc->name, "freezer") &&
+				add_freezer_state(current_controller)) {
+			return -1;
+		}
 	}
 
 	return 0;
diff --git a/include/seize.h b/include/seize.h
index 3c23e24..315fab2 100644
--- a/include/seize.h
+++ b/include/seize.h
@@ -3,5 +3,6 @@
 
 extern int collect_pstree(pid_t pid);
 extern void pstree_switch_state(struct pstree_item *root_item, int st);
+extern const char *get_real_freezer_state(void);
 
 #endif
diff --git a/seize.c b/seize.c
index de5c929..261dcd3 100644
--- a/seize.c
+++ b/seize.c
@@ -55,6 +55,11 @@ err:
 
 static bool freezer_thawed;
 
+const char *get_real_freezer_state(void)
+{
+	return freezer_thawed ? thawed : frozen;
+}
+
 static int freezer_restore_state(void)
 {
 	int fd;
-- 
1.9.1



More information about the CRIU mailing list