Skip to content

Commit 186ec99

Browse files
committed
Handle case where cgroup v1 freezer is disabled
On cgroup v1 it is possible to disable freezer subsystem. In such case freezer.state file won't be present. Due to the race condition handling in libcrun_get_container_state_string, missing freezer.state would be interpreted as cgroup being removed when check is being performed. But as indicated earlier, that is not the case when it's cgroup v1 and the freezer is disabled. Therefore introduce logic that checks for that using type of the filesystem mounted under the freezer directory. When freezer is disabled, container simply cannot be paused. Fixes #1612 Signed-off-by: Michal Sieron <[email protected]>
1 parent 52ed588 commit 186ec99

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed

src/libcrun/cgroup.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <inttypes.h>
3838
#include <time.h>
3939

40+
#include <linux/magic.h>
4041
#include <sys/stat.h>
4142
#include <sys/types.h>
4243
#include <fcntl.h>
@@ -142,7 +143,38 @@ libcrun_cgroup_is_container_paused (struct libcrun_cgroup_status *status, bool *
142143

143144
ret = read_all_file (path, &content, NULL, err);
144145
if (UNLIKELY (ret < 0))
145-
return ret;
146+
{
147+
errno = crun_error_get_errno (err);
148+
/* If the file is missing and we were checking for freezer.state
149+
(so either cgroup v1 or hybrid), it may be the freezer is
150+
simply disabled. In such case the container cannot be paused.
151+
On cgroup v2 freezer is always there.
152+
*/
153+
if (errno != ENOENT || cgroup_mode == CGROUP_MODE_UNIFIED)
154+
return ret;
155+
156+
/* Even with freezer disabled, its directory is still there. But
157+
when it's disabled it has type tmpfs, while on systems with
158+
freezer enabled, its type is cgroupfs. Use that to determine
159+
whether freezer is enabled or not.
160+
*/
161+
struct statfs freezer_stat;
162+
if (statfs (CGROUP_ROOT "/freezer", &freezer_stat))
163+
return crun_make_error (err, errno, "error when using statfs on `%s`", CGROUP_ROOT "/freezer");
164+
165+
/* If the freezer is mounted as cgroupfs type, then missing
166+
freezer.state file is an error and should be handled like before.
167+
*/
168+
if (freezer_stat.f_type == CGROUP_SUPER_MAGIC)
169+
return ret;
170+
171+
/* When freezer dir is not mounted as cgroupfs, then it's
172+
disabled, therefore container cannot be in paused state.
173+
*/
174+
crun_error_release (err);
175+
*paused = false;
176+
return 0;
177+
}
146178

147179
*paused = strstr (content, state) != NULL;
148180
return 0;

0 commit comments

Comments
 (0)