Skip to content

Commit 69a7fbf

Browse files
authored
Merge pull request #12 from cloudlinux/clos-2565-fix-private-mounts
Fix upgrade on systems with private root mountpoint and multiple partitions
2 parents 35d9ae4 + a4e3d02 commit 69a7fbf

File tree

3 files changed

+35
-4
lines changed

3 files changed

+35
-4
lines changed

packaging/leapp-repository.spec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ py2_byte_compile "%1" "%2"}
4242

4343
Name: leapp-repository
4444
Version: 0.16.0
45-
Release: 7%{?dist}.cloudlinux
45+
Release: 8%{?dist}.cloudlinux
4646
Summary: Repositories for leapp
4747

4848
License: ASL 2.0

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)