Skip to content

Commit

Permalink
Handle case where cgroup v1 freezer is disabled
Browse files Browse the repository at this point in the history
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 <michalwsieron@gmail.com>
  • Loading branch information
michalsieron committed Dec 6, 2024
1 parent 52ed588 commit 186ec99
Showing 1 changed file with 33 additions and 1 deletion.
34 changes: 33 additions & 1 deletion src/libcrun/cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <inttypes.h>
#include <time.h>

#include <linux/magic.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
Expand Down Expand Up @@ -142,7 +143,38 @@ libcrun_cgroup_is_container_paused (struct libcrun_cgroup_status *status, bool *

ret = read_all_file (path, &content, NULL, err);
if (UNLIKELY (ret < 0))
return ret;
{
errno = crun_error_get_errno (err);
/* If the file is missing and we were checking for freezer.state
(so either cgroup v1 or hybrid), it may be the freezer is
simply disabled. In such case the container cannot be paused.
On cgroup v2 freezer is always there.
*/
if (errno != ENOENT || cgroup_mode == CGROUP_MODE_UNIFIED)
return ret;

/* Even with freezer disabled, its directory is still there. But
when it's disabled it has type tmpfs, while on systems with
freezer enabled, its type is cgroupfs. Use that to determine
whether freezer is enabled or not.
*/
struct statfs freezer_stat;
if (statfs (CGROUP_ROOT "/freezer", &freezer_stat))
return crun_make_error (err, errno, "error when using statfs on `%s`", CGROUP_ROOT "/freezer");

/* If the freezer is mounted as cgroupfs type, then missing
freezer.state file is an error and should be handled like before.
*/
if (freezer_stat.f_type == CGROUP_SUPER_MAGIC)
return ret;

/* When freezer dir is not mounted as cgroupfs, then it's
disabled, therefore container cannot be in paused state.
*/
crun_error_release (err);
*paused = false;
return 0;
}

*paused = strstr (content, state) != NULL;
return 0;
Expand Down

0 comments on commit 186ec99

Please sign in to comment.