Skip to content

Commit 805e6a4

Browse files
committed
libcrun: skip cgroup filesystem type check when cgroups are disabled
When --cgroup-manager=disabled (force_no_cgroup) is set, crun should not attempt to detect the cgroup mode by calling statfs on /sys/fs/cgroup. On systems where /sys/fs/cgroup is not mounted as tmpfs or cgroup2 (e.g. Android with Linux Deploy where it is mounted as sysfs), this causes a spurious 'invalid file system type' error even though cgroups are explicitly disabled. Guard the libcrun_get_cgroup_mode() calls in libcrun_container_run_internal() and libcrun_set_mounts() with a check for force_no_cgroup, so the cgroup filesystem type verification and the cgroup v1 deprecation warning are both skipped when cgroups are disabled. Closes: #1413 Signed-off-by: Jindrich Novy <jnovy@redhat.com>
1 parent e5e96a3 commit 805e6a4

File tree

3 files changed

+95
-16
lines changed

3 files changed

+95
-16
lines changed

src/libcrun/container.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2789,12 +2789,15 @@ libcrun_container_run_internal (libcrun_container_t *container, libcrun_context_
27892789
const char *seccomp_bpf_data = find_annotation (container, "run.oci.seccomp_bpf_data");
27902790
int cgroup_mode;
27912791

2792-
cgroup_mode = libcrun_get_cgroup_mode (err);
2793-
if (UNLIKELY (cgroup_mode < 0))
2794-
return cgroup_mode;
2792+
if (! context->force_no_cgroup)
2793+
{
2794+
cgroup_mode = libcrun_get_cgroup_mode (err);
2795+
if (UNLIKELY (cgroup_mode < 0))
2796+
return cgroup_mode;
27952797

2796-
if (cgroup_mode != CGROUP_MODE_UNIFIED)
2797-
libcrun_warning ("cgroup v1 is deprecated and will be removed in a future release. Use cgroup v2");
2798+
if (cgroup_mode != CGROUP_MODE_UNIFIED)
2799+
libcrun_warning ("cgroup v1 is deprecated and will be removed in a future release. Use cgroup v2");
2800+
}
27982801

27992802
ret = setup_container_hooks_output (container, def, &container_args, &hooks_out_fd, &hooks_err_fd, err);
28002803
if (UNLIKELY (ret < 0))

src/libcrun/linux.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2848,20 +2848,23 @@ libcrun_set_mounts (struct container_entrypoint_s *entrypoint_args, libcrun_cont
28482848
get_private_data (container)->remounts = r;
28492849
}
28502850

2851-
cgroup_mode = libcrun_get_cgroup_mode (err);
2852-
if (UNLIKELY (cgroup_mode < 0))
2853-
return cgroup_mode;
2854-
2855-
if (cgroup_mode == CGROUP_MODE_UNIFIED)
2851+
if (! container->context->force_no_cgroup)
28562852
{
2857-
char *unified_cgroup_path = NULL;
2853+
cgroup_mode = libcrun_get_cgroup_mode (err);
2854+
if (UNLIKELY (cgroup_mode < 0))
2855+
return cgroup_mode;
28582856

2859-
/* Read the cgroup path before we enter the cgroupns. */
2860-
ret = libcrun_get_cgroup_process (0, &unified_cgroup_path, true, err);
2861-
if (UNLIKELY (ret < 0))
2862-
return ret;
2857+
if (cgroup_mode == CGROUP_MODE_UNIFIED)
2858+
{
2859+
char *unified_cgroup_path = NULL;
28632860

2864-
get_private_data (container)->unified_cgroup_path = unified_cgroup_path;
2861+
/* Read the cgroup path before we enter the cgroupns. */
2862+
ret = libcrun_get_cgroup_process (0, &unified_cgroup_path, true, err);
2863+
if (UNLIKELY (ret < 0))
2864+
return ret;
2865+
2866+
get_private_data (container)->unified_cgroup_path = unified_cgroup_path;
2867+
}
28652868
}
28662869

28672870
ret = libcrun_container_enter_cgroup_ns (container, err);

tests/test_cgroup_setup.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1369,7 +1369,80 @@ def test_cgroup_v2_mount_options():
13691369

13701370
return 0
13711371

1372+
def _cgroup_disabled_config():
1373+
"""Return a config suitable for --cgroup-manager=disabled: no cgroup mount,
1374+
no resources, no cgroupsPath, no cgroup namespace."""
1375+
conf = base_config()
1376+
add_all_namespaces(conf, cgroupns=False)
1377+
conf['mounts'] = [m for m in conf.get('mounts', [])
1378+
if m.get('destination') != '/sys/fs/cgroup']
1379+
if 'resources' in conf.get('linux', {}):
1380+
del conf['linux']['resources']
1381+
if 'cgroupsPath' in conf.get('linux', {}):
1382+
del conf['linux']['cgroupsPath']
1383+
return conf
1384+
1385+
1386+
def _run_cgroup_disabled(detach):
1387+
"""Run a container with --cgroup-manager=disabled in foreground or detached
1388+
mode. Returns 0 on success, (77, reason) for environment skips, -1 on
1389+
failure.
1390+
1391+
Regression test for https://github.com/containers/crun/issues/1413.
1392+
When cgroups are disabled, crun must not call statfs on /sys/fs/cgroup,
1393+
which would fail on systems where it is not mounted as tmpfs or cgroup2.
1394+
"""
1395+
conf = _cgroup_disabled_config()
1396+
conf['process']['args'] = ['/init', 'pause'] if detach else ['/init', 'true']
1397+
1398+
cid = None
1399+
try:
1400+
if detach:
1401+
_, cid = run_and_get_output(conf, hide_stderr=False, command='run',
1402+
detach=True, cgroup_manager='disabled')
1403+
state = json.loads(run_crun_command(['state', cid]))
1404+
if state['status'] not in ('running', 'created'):
1405+
logger.info("container not running: %s", state['status'])
1406+
return -1
1407+
else:
1408+
run_and_get_output(conf, hide_stderr=False, cgroup_manager='disabled')
1409+
return 0
1410+
except subprocess.CalledProcessError as e:
1411+
output = e.output.decode('utf-8', errors='ignore') if e.output else ''
1412+
if "invalid file system type" in output:
1413+
logger.info("test failed: cgroup filesystem type checked despite --cgroups=disabled")
1414+
return -1
1415+
if any(kw in output.lower() for kw in ["mount", "proc", "rootfs"]):
1416+
return (77, "environment issue, not related to cgroup disabled")
1417+
logger.info("test failed: %s (output: %s)", e, output)
1418+
return -1
1419+
except Exception as e:
1420+
logger.info("test failed: %s", e)
1421+
return -1
1422+
finally:
1423+
if cid is not None:
1424+
run_crun_command(["delete", "-f", cid])
1425+
1426+
1427+
def test_cgroup_disabled():
1428+
"""Test --cgroup-manager=disabled skips cgroup filesystem type verification (foreground).
1429+
1430+
Regression test for https://github.com/containers/crun/issues/1413.
1431+
"""
1432+
return _run_cgroup_disabled(detach=False)
1433+
1434+
1435+
def test_cgroup_disabled_detach():
1436+
"""Test --cgroup-manager=disabled works with run --detach.
1437+
1438+
Regression test for https://github.com/containers/crun/issues/1413.
1439+
"""
1440+
return _run_cgroup_disabled(detach=True)
1441+
1442+
13721443
all_tests = {
1444+
"cgroup-disabled": test_cgroup_disabled,
1445+
"cgroup-disabled-detach": test_cgroup_disabled_detach,
13731446
"cgroup-creation": test_cgroup_creation,
13741447
"cgroup-cleanup": test_cgroup_cleanup,
13751448
"cgroup-with-resources": test_cgroup_with_resources,

0 commit comments

Comments
 (0)