Skip to content

Commit

Permalink
Also virtualize /sys/devices/system/cpu with LXCFS if available
Browse files Browse the repository at this point in the history
Like for /proc, LXCFS provides a virtualized /sys/devices/system/cpu
that only shows the allowed cores.
Of course we want to mount that in the container as well,
at least if the user has not requested /sys to be hidden
or have full access to the host directory.

Fixes #1069
  • Loading branch information
PhilippWendler committed Aug 8, 2024
1 parent 8b818d4 commit 1dab945
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 1 deletion.
13 changes: 12 additions & 1 deletion benchexec/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@
DIR_MODES = [DIR_HIDDEN, DIR_READ_ONLY, DIR_OVERLAY, DIR_FULL_ACCESS]
"""modes how a directory can be mounted in the container"""

LXCFS_PROC_DIR = b"/var/lib/lxcfs/proc"
LXCFS_BASE_DIR = b"/var/lib/lxcfs"
LXCFS_PROC_DIR = LXCFS_BASE_DIR + b"/proc"
SYS_CPU_DIR = b"/sys/devices/system/cpu"

_CLONE_NESTED_CALLBACK = ctypes.CFUNCTYPE(ctypes.c_int)
"""Type for callback of execute_in_namespace, nested in our primary callback."""
Expand Down Expand Up @@ -968,6 +970,15 @@ def setup_container_system_config(basedir, mountdir, dir_modes):
{"h": CONTAINER_HOME, "p": os.path.dirname(CONTAINER_HOME)},
)

# Virtualize CPU info with LXCFS if directory is not hidden nor full-access
if (
os.access(LXCFS_BASE_DIR + SYS_CPU_DIR, os.R_OK)
and determine_directory_mode(dir_modes, SYS_CPU_DIR) == DIR_READ_ONLY
):
make_bind_mount(
LXCFS_BASE_DIR + SYS_CPU_DIR, mountdir + SYS_CPU_DIR, private=True
)


def is_container_system_config_file(file):
"""Determine whether a given file is one of the files created by
Expand Down
11 changes: 11 additions & 0 deletions benchexec/test_runexecutor.py
Original file line number Diff line number Diff line change
Expand Up @@ -1163,6 +1163,17 @@ def test_cpuinfo_with_lxcfs(self):
cpus = [int(line.split()[2]) for line in output if line.startswith("processor")]
self.assertListEqual(cpus, [0], f"Unexpected CPU cores visible in container")

def test_sys_cpu_with_lxcfs(self):
if not os.path.exists("/var/lib/lxcfs/proc"):
self.skipTest("missing lxcfs")
result, output = self.execute_run(
self.cat, "/sys/devices/system/cpu/online", cores=[0]
)
self.check_result_keys(result)
self.check_exitcode(result, 0, "exit code for reading online CPUs is not zero")
cpus = util.parse_int_list(output[-1])
self.assertListEqual(cpus, [0], f"Unexpected CPU cores online in container")

def test_uptime_with_lxcfs(self):
if not os.path.exists("/var/lib/lxcfs/proc"):
self.skipTest("missing lxcfs")
Expand Down

0 comments on commit 1dab945

Please sign in to comment.