Skip to content

Commit a13feaf

Browse files
committed
restore: restore freezer cgroup state
Issue checkpoint-restore#20. (Support C/R of frozen cgroup) 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]>
1 parent 6c5a8bc commit a13feaf

File tree

3 files changed

+44
-2
lines changed

3 files changed

+44
-2
lines changed

cgroup.c

+39
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ static unsigned int n_sets;
100100
static CgSetEntry **rst_sets;
101101
static unsigned int n_controllers;
102102
static CgControllerEntry **controllers;
103+
static CgroupPropEntry *freezer_state;
103104
static char *cg_yard;
104105
static struct cg_set *root_cgset; /* Set root item lives in */
105106
static struct cg_set *criu_cgset; /* Set criu process lives in */
@@ -1077,6 +1078,43 @@ int prepare_cgroup_properties(void)
10771078
return 0;
10781079
}
10791080

1081+
int restore_freezer_state(void)
1082+
{
1083+
char paux[PATH_MAX];
1084+
int ctrl_off, i;
1085+
CgroupDirEntry *entry;
1086+
CgControllerEntry *freezer_ctrl = NULL;
1087+
1088+
if (!freezer_state)
1089+
return 0;
1090+
1091+
for (i = 0; i < n_controllers; i++) {
1092+
CgControllerEntry *ctrl = controllers[i];
1093+
1094+
if (cgroup_contains(ctrl->cnames, ctrl->n_cnames, "freezer")) {
1095+
freezer_ctrl = ctrl;
1096+
break;
1097+
}
1098+
}
1099+
1100+
if (!freezer_ctrl) {
1101+
pr_err("Can't restore freezer cgroup state: root freezer cgroup not found\n");
1102+
return -1;
1103+
}
1104+
1105+
/*
1106+
* Here we rely on --freeze-cgroup option assumption that all tasks are in a
1107+
* specified freezer cgroup hierarchy, so we need to freeze only one root freezer cgroup.
1108+
*/
1109+
BUG_ON(freezer_ctrl->n_dirs != 1);
1110+
entry = freezer_ctrl->dirs[0];
1111+
1112+
ctrl_off = ctrl_dir_and_opt(freezer_ctrl, paux, sizeof(paux), NULL, 0);
1113+
snprintf(paux + ctrl_off, sizeof(paux) - ctrl_off, "/%s", entry->dir_name);
1114+
1115+
return restore_cgroup_prop(freezer_state, paux, ctrl_off);
1116+
}
1117+
10801118
static int restore_special_cpuset_props(char *paux, size_t off, CgroupDirEntry *e)
10811119
{
10821120
int i, j;
@@ -1358,6 +1396,7 @@ int prepare_cgroup(void)
13581396
rst_sets = ce->sets;
13591397
n_controllers = ce->n_controllers;
13601398
controllers = ce->controllers;
1399+
freezer_state = ce->freezer_state;
13611400

13621401
if (n_sets)
13631402
/*

cr-restore.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -1915,7 +1915,6 @@ static int restore_root_task(struct pstree_item *init)
19151915
goto out_kill;
19161916

19171917
ret = prepare_cgroup_properties();
1918-
fini_cgroup();
19191918
if (ret < 0)
19201919
goto out_kill;
19211920

@@ -1958,8 +1957,11 @@ static int restore_root_task(struct pstree_item *init)
19581957
if (clear_breakpoints())
19591958
pr_err("Unable to flush breakpoints\n");
19601959

1961-
if (ret == 0)
1960+
if (ret == 0) {
19621961
finalize_restore();
1962+
ret = restore_freezer_state();
1963+
}
1964+
fini_cgroup();
19631965

19641966
/* Detaches from processes and they continue run through sigreturn. */
19651967
finalize_restore_detach(ret);

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)