Skip to content

Commit

Permalink
Avoid unnecessary nested mounts in container mode
Browse files Browse the repository at this point in the history
If directory modes for /foo and /foo/bar are given,
and these two modes are the same,
and /foo/bar is not already a mountpoint,
there is no point in doing something for /foo/bar:
The directory mode for /foo will apply to /foo/bar as well anyway.

Avoiding these useless nested mounts is especially good for overlay mounts:
Overlayfs complains (in the kernel log) if we first use .../temp/foo as
upper directory of an overlayfs instance
and then use .../temp/foo/bar as an upper directory of another overlayfs
instance as well.
The message says that we should not create overlayfs instances
with overlapping upper directories.

With the change of this commit we do this less often,
we only create overlapping overlayfs mounts in the following two
situations:
a) if /foo and /foo/bar are both overlays and on different file systems,
but currently this fails anyway due to #776; and
b) if /foo is an overlay, /foo/bar is something else, and /foo/bar/child
is an overlay again.
However, so far this has worked without problems.
This is likely because if we use both .../temp/foo and
.../temp/foo/bar/child as upper directories for two overlayfs instances,
we will never actually access the bar/child directory through the former
instance. Each actual directory in the upper directory is accessed only
via a single overlayfs instance.
  • Loading branch information
PhilippWendler committed Feb 22, 2022
1 parent 7ebe4c3 commit 44c6e57
Showing 1 changed file with 21 additions and 1 deletion.
22 changes: 21 additions & 1 deletion benchexec/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -424,8 +424,29 @@ def duplicate_mount_hierarchy(mount_base, temp_base, work_base, dir_modes):

# Ensure each special dir is a mountpoint such that the next loop covers it.
for special_dir in dir_modes.keys():
if special_dir == b"/":
continue # handled above

mount_path = mount_base + special_dir
temp_path = temp_base + special_dir
# Ensure special_dir exists even if we mount a hidden dir as parent.
os.makedirs(temp_path, exist_ok=True)

mode = determine_directory_mode(dir_modes, special_dir)
parent_mode = determine_directory_mode(dir_modes, os.path.dirname(special_dir))
if mode == parent_mode:
# If special_dir is not a mountpoint, we do not need to do anything for it,
# it will automatically inherit the same directory mode as its parent.
# If special_dir is a mountpoint, it will be covered by the loop below
# anyway. In none of the two cases this loop needs to mark special_dir as
# mountpoint. This avoids useless creation of nested overlay instances.
logging.debug(
"Skipping directory mount for %s "
"because parent already has same mode.",
special_dir,
)
continue

try:
make_bind_mount(mount_path, mount_path)
except OSError as e:
Expand All @@ -439,7 +460,6 @@ def duplicate_mount_hierarchy(mount_base, temp_base, work_base, dir_modes):
)
else:
logging.debug("Failed to make %s a bind mount: %s", mount_path, e)
os.makedirs(temp_path, exist_ok=True)

overlay_count = 0

Expand Down

0 comments on commit 44c6e57

Please sign in to comment.