Skip to content

Commit 8b04551

Browse files
wtf42xemul
authored andcommitted
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: Evgeniy Akimov <[email protected]> Signed-off-by: Eugene Batalov <[email protected]> Acked-by: Andrew Vagin <[email protected]> Signed-off-by: Pavel Emelyanov <[email protected]>
1 parent b3e5cf7 commit 8b04551

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

cgroup.c

+29
Original file line numberDiff line numberDiff line change
@@ -1036,6 +1036,31 @@ static int restore_cgroup_prop(const CgroupPropEntry * cg_prop_entry_p,
10361036
return 0;
10371037
}
10381038

1039+
static CgroupPropEntry *freezer_state_entry;
1040+
static char freezer_path[PATH_MAX];
1041+
1042+
int restore_freezer_state(void)
1043+
{
1044+
size_t freezer_path_len;
1045+
1046+
if (!freezer_state_entry)
1047+
return 0;
1048+
1049+
freezer_path_len = strlen(freezer_path);
1050+
return restore_cgroup_prop(freezer_state_entry, freezer_path, freezer_path_len);
1051+
}
1052+
1053+
static void add_freezer_state_for_restore(CgroupPropEntry *entry, char *path, size_t path_len)
1054+
{
1055+
BUG_ON(freezer_state_entry);
1056+
BUG_ON(path_len >= sizeof(freezer_path));
1057+
1058+
freezer_state_entry = entry;
1059+
/* Path is not null terminated at path_len */
1060+
strncpy(freezer_path, path, path_len);
1061+
freezer_path[path_len] = 0;
1062+
}
1063+
10391064
static int prepare_cgroup_dir_properties(char *path, int off, CgroupDirEntry **ents,
10401065
unsigned int n_ents)
10411066
{
@@ -1051,6 +1076,10 @@ static int prepare_cgroup_dir_properties(char *path, int off, CgroupDirEntry **e
10511076
off2 += sprintf(path + off, "/%s", e->dir_name);
10521077
if (e->n_properties > 0) {
10531078
for (j = 0; j < e->n_properties; ++j) {
1079+
if (!strcmp(e->properties[j]->name, "freezer.state")) {
1080+
add_freezer_state_for_restore(e->properties[j], path, off2);
1081+
continue; /* skip restore now */
1082+
}
10541083
if (restore_cgroup_prop(e->properties[j], path, off2) < 0)
10551084
return -1;
10561085
}

cr-restore.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -2013,7 +2013,6 @@ static int restore_root_task(struct pstree_item *init)
20132013
goto out_kill;
20142014

20152015
ret = prepare_cgroup_properties();
2016-
fini_cgroup();
20172016
if (ret < 0)
20182017
goto out_kill;
20192018

@@ -2059,6 +2058,11 @@ static int restore_root_task(struct pstree_item *init)
20592058
if (ret == 0)
20602059
finalize_restore();
20612060

2061+
if (restore_freezer_state())
2062+
pr_err("Unable to restore freezer state\n");
2063+
2064+
fini_cgroup();
2065+
20622066
/* Detaches from processes and they continue run through sigreturn. */
20632067
finalize_restore_detach(ret);
20642068

include/cgroup.h

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ int prepare_task_cgroup(struct pstree_item *);
99
int prepare_cgroup(void);
1010
/* Restore things like cpu_limit in known cgroups. */
1111
int prepare_cgroup_properties(void);
12+
int restore_freezer_state(void);
1213
void fini_cgroup(void);
1314

1415
struct cg_controller;

0 commit comments

Comments
 (0)