Skip to content

Commit 09a1b39

Browse files
committed
Force creation of shared mount points during overlay creation (CLOS-2565)
leapp is expecting system to have `shared` mounts propagation by default which is wrong for os's like CloudLinux where all mountpoints are created in `private` mode this patch explicitly adds `--make-shared` option to `mount` command to preserve expected behaviour of `shared` mount points during elevation this changed does not affect existing mount points, only those which are temporary created during upgrade process
1 parent 35d9ae4 commit 09a1b39

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

repos/system_upgrade/common/libraries/mounting.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ class MountingMode(object):
3333
""" Used when no actual mount call needs to be issued """
3434

3535

36+
class MountingPropagation(object):
37+
"""
38+
MountingPropagation are types of mounts propagation supported by the library
39+
"""
40+
PRIVATE = 'private'
41+
""" Used for private propagation mounts """
42+
SHARED = 'shared'
43+
""" Used for shared propagation mounts """
44+
45+
3646
def _makedirs(path, mode=0o777, exists_ok=True):
3747
""" Helper function which extends os.makedirs with exists_ok on all versions of python. """
3848
try:
@@ -293,19 +303,32 @@ class MountConfig(object):
293303
class MountingBase(object):
294304
""" Base class for all mount operations """
295305

296-
def __init__(self, source, target, mode, config=MountConfig.Mount):
306+
def __init__(self, source, target, mode,
307+
config=MountConfig.Mount,
308+
propagation=MountingPropagation.SHARED):
297309
self._mode = mode
298310
self.source = source
299311
self.target = target
300312
self._config = config
313+
self.propagation = propagation
301314
self.additional_directories = ()
302315

303316
def _mount_options(self):
304317
"""
305318
Options to use with the mount call, individual implementations may override this function to return the
306319
correct parameters
307320
"""
308-
return ['-o', self._mode, self.source]
321+
return [
322+
'-o', self._mode,
323+
'--make-' + self.propagation,
324+
self.source
325+
]
326+
327+
def _umount_options(self):
328+
"""
329+
Options to use with the umount call.
330+
"""
331+
return ['-fl']
309332

310333
def chroot(self):
311334
""" Create a ChrootActions instance for this mount """
@@ -323,7 +346,7 @@ def _cleanup(self):
323346
""" Cleanup operations """
324347
if os.path.exists(self.target) and os.path.ismount(self.target):
325348
try:
326-
run(['umount', '-fl', self.target], split=False)
349+
run(['umount'] + self._umount_options() + [self.target], split=False)
327350
except (OSError, CalledProcessError) as e:
328351
api.current_logger().warning('Unmounting %s failed with: %s', self.target, str(e))
329352
for directory in itertools.chain(self.additional_directories, (self.target,)):
@@ -404,6 +427,7 @@ def __init__(self, fstype, source, target, config=MountConfig.Mount):
404427
def _mount_options(self):
405428
return [
406429
'-t', self.fstype,
430+
'--make-' + self.propagation,
407431
self.source
408432
]
409433

@@ -421,5 +445,6 @@ def __init__(self, name, source, workdir, config=MountConfig.Mount):
421445
def _mount_options(self):
422446
return [
423447
'-t', 'overlay', 'overlay2',
448+
'--make-' + self.propagation,
424449
'-o', 'lowerdir={},upperdir={},workdir={}'.format(self.source, self._upper_dir, self._work_dir)
425450
]

repos/system_upgrade/common/libraries/overlaygen.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,12 @@ def create_source_overlay(mounts_dir, scratch_dir, xfs_info, storage_info, mount
222222
_create_mounts_dir(scratch_dir, mounts_dir)
223223
mounts = _prepare_required_mounts(scratch_dir, mounts_dir, _get_mountpoints(storage_info), xfs_info)
224224
with mounts.pop('/') as root_mount:
225+
# it's important to make system_overlay shared because we
226+
# later mount it into mount_target with some tricky way:
227+
# 1. create system_overlay mount
228+
# 2. mount system_overlay to mount_target (e.g. installroot)
229+
# 3. mount other mounts like /tmp, /usr inside system_overlay
230+
# if at stage 3 system_overlay is not shared, mounts will not appear in `mount_target`
225231
with mounting.OverlayMount(name='system_overlay', source='/', workdir=root_mount.target) as root_overlay:
226232
if mount_target:
227233
target = mounting.BindMount(source=root_overlay.target, target=mount_target)

0 commit comments

Comments
 (0)