Commit 8b04551c authored by Evgeniy Akimov's avatar Evgeniy Akimov Committed by Pavel Emelyanov

restore: restore freezer cgroup state

Patch restores freezer cgroup state between finalize_restore stages.
It should be done after first stage because we cannot unmap restorer blob
from frozen process, and before second stage because we must freeze processes
before they continue run.
We also need to move fini_cgroup between these stages to provide freezer
cgroup state restorer access to cgroup mount directories.
Error handlers contains fini_cgroup, so we are sure that fini_cgroup call
won't be missed.

Patch restores state only for one freezer cgroup from --freeze-cgroup option,
not all states from whole hierarchy, because CRIU supports checkpoint from
freezer cgroup hierarchy only with THAWED state, except root cgroup from
--freeze-cgroup option.
Signed-off-by: 's avatarEvgeniy Akimov <geka666@gmail.com>
Signed-off-by: 's avatarEugene Batalov <eabatalov89@gmail.com>
Acked-by: 's avatarAndrew Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent b3e5cf75
......@@ -1036,6 +1036,31 @@ static int restore_cgroup_prop(const CgroupPropEntry * cg_prop_entry_p,
return 0;
}
static CgroupPropEntry *freezer_state_entry;
static char freezer_path[PATH_MAX];
int restore_freezer_state(void)
{
size_t freezer_path_len;
if (!freezer_state_entry)
return 0;
freezer_path_len = strlen(freezer_path);
return restore_cgroup_prop(freezer_state_entry, freezer_path, freezer_path_len);
}
static void add_freezer_state_for_restore(CgroupPropEntry *entry, char *path, size_t path_len)
{
BUG_ON(freezer_state_entry);
BUG_ON(path_len >= sizeof(freezer_path));
freezer_state_entry = entry;
/* Path is not null terminated at path_len */
strncpy(freezer_path, path, path_len);
freezer_path[path_len] = 0;
}
static int prepare_cgroup_dir_properties(char *path, int off, CgroupDirEntry **ents,
unsigned int n_ents)
{
......@@ -1051,6 +1076,10 @@ static int prepare_cgroup_dir_properties(char *path, int off, CgroupDirEntry **e
off2 += sprintf(path + off, "/%s", e->dir_name);
if (e->n_properties > 0) {
for (j = 0; j < e->n_properties; ++j) {
if (!strcmp(e->properties[j]->name, "freezer.state")) {
add_freezer_state_for_restore(e->properties[j], path, off2);
continue; /* skip restore now */
}
if (restore_cgroup_prop(e->properties[j], path, off2) < 0)
return -1;
}
......
......@@ -2013,7 +2013,6 @@ static int restore_root_task(struct pstree_item *init)
goto out_kill;
ret = prepare_cgroup_properties();
fini_cgroup();
if (ret < 0)
goto out_kill;
......@@ -2059,6 +2058,11 @@ static int restore_root_task(struct pstree_item *init)
if (ret == 0)
finalize_restore();
if (restore_freezer_state())
pr_err("Unable to restore freezer state\n");
fini_cgroup();
/* Detaches from processes and they continue run through sigreturn. */
finalize_restore_detach(ret);
......
......@@ -9,6 +9,7 @@ int prepare_task_cgroup(struct pstree_item *);
int prepare_cgroup(void);
/* Restore things like cpu_limit in known cgroups. */
int prepare_cgroup_properties(void);
int restore_freezer_state(void);
void fini_cgroup(void);
struct cg_controller;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment