From 2e88686c5e09c3757ba65c92932b3126030f424e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Sch=C3=A4fer?= Date: Thu, 27 Jul 2023 12:08:35 +0200 Subject: [PATCH] Make sure btrfs root volume is used when needed With the possibility to switch off setting the default volume an issue at other parts in the kiwi code which mounted the btrfs based system were uncovered. Without any default volume set it's required to transport the root volume if different from / and pass the respective subvol= option to the mount. This commit fixes it at the places where kiwi trusted btrfs to have a correct default volume set --- kiwi/bootloader/config/base.py | 8 ++++-- kiwi/bootloader/config/grub2.py | 8 ++++-- kiwi/bootloader/install/grub2.py | 9 ++++++- kiwi/builder/disk.py | 7 +++++- test/unit/bootloader/config/base_test.py | 6 +++-- test/unit/bootloader/config/grub2_test.py | 2 +- test/unit/bootloader/install/grub2_test.py | 29 ++++++++++++++++------ 7 files changed, 53 insertions(+), 16 deletions(-) diff --git a/kiwi/bootloader/config/base.py b/kiwi/bootloader/config/base.py index d3e2cae9b40..b76828eeef0 100644 --- a/kiwi/bootloader/config/base.py +++ b/kiwi/bootloader/config/base.py @@ -501,7 +501,8 @@ def get_gfxmode(self, target): return gfxmode def _mount_system( - self, root_device, boot_device, efi_device=None, volumes=None + self, root_device, boot_device, efi_device=None, + volumes=None, root_volume_name=None ): self.root_mount = MountManager( device=root_device @@ -522,7 +523,10 @@ def _mount_system( mountpoint=self.root_mount.mountpoint + '/boot/efi' ) - self.root_mount.mount() + custom_root_mount_args = [] + if root_volume_name and root_volume_name != '/': + custom_root_mount_args += [f'subvol={root_volume_name}'] + self.root_mount.mount(options=custom_root_mount_args) if not self.root_mount.device == self.boot_mount.device: self.boot_mount.mount() diff --git a/kiwi/bootloader/config/grub2.py b/kiwi/bootloader/config/grub2.py index 3e8bbde7dec..fcfac01bb76 100644 --- a/kiwi/bootloader/config/grub2.py +++ b/kiwi/bootloader/config/grub2.py @@ -233,14 +233,18 @@ def setup_disk_image_config( 'root_device': string, 'boot_device': string, 'efi_device': string, - 'system_volumes': volume_manager_instance.get_volumes() + 'system_volumes': + volume_manager_instance.get_volumes(), + 'system_root_volume': + volume_manager_instance.get_root_volume_name() } """ self._mount_system( boot_options.get('root_device'), boot_options.get('boot_device'), boot_options.get('efi_device'), - boot_options.get('system_volumes') + boot_options.get('system_volumes'), + boot_options.get('system_root_volume') ) config_file = os.sep.join( [ diff --git a/kiwi/bootloader/install/grub2.py b/kiwi/bootloader/install/grub2.py index 565ae38f9ca..637aa3d7fe0 100644 --- a/kiwi/bootloader/install/grub2.py +++ b/kiwi/bootloader/install/grub2.py @@ -52,6 +52,7 @@ def post_init(self, custom_args): { 'target_removable': bool, 'system_volumes': list_of_volumes, + 'system_root_volume': root volume name if required 'firmware': FirmWare_instance, 'efi_device': string, 'boot_device': string, @@ -71,12 +72,15 @@ def post_init(self, custom_args): self.proc_mount = None self.sysfs_mount = None self.volumes = None + self.root_volume_name = None self.volumes_mount = [] self.target_removable = None if custom_args and 'target_removable' in custom_args: self.target_removable = custom_args['target_removable'] if custom_args and 'system_volumes' in custom_args: self.volumes = custom_args['system_volumes'] + if custom_args and 'system_root_volume' in custom_args: + self.root_volume_name = custom_args['system_root_volume'] if custom_args and 'firmware' in custom_args: self.firmware = custom_args['firmware'] if custom_args and 'install_options' in custom_args: @@ -302,7 +306,10 @@ def _mount_device_and_volumes(self): self.root_mount = MountManager( device=self.custom_args['root_device'] ) - self.root_mount.mount() + custom_root_mount_args = [] + if self.root_volume_name and self.root_volume_name != '/': + custom_root_mount_args += [f'subvol={self.root_volume_name}'] + self.root_mount.mount(options=custom_root_mount_args) if self.boot_mount is None: if 's390' in self.arch: diff --git a/kiwi/builder/disk.py b/kiwi/builder/disk.py index 9141d75ef08..b3bb4d0ad13 100644 --- a/kiwi/builder/disk.py +++ b/kiwi/builder/disk.py @@ -1537,7 +1537,12 @@ def _install_bootloader( if self.volume_manager_name: system.umount_volumes() custom_install_arguments.update( - {'system_volumes': system.get_volumes()} + { + 'system_volumes': system.get_volumes(), + 'system_root_volume': + system.get_root_volume_name() + if self.volume_manager_name == 'btrfs' else None + } ) if self.bootloader != 'custom': diff --git a/test/unit/bootloader/config/base_test.py b/test/unit/bootloader/config/base_test.py index 4bf16c51902..f81847b5b5e 100644 --- a/test/unit/bootloader/config/base_test.py +++ b/test/unit/bootloader/config/base_test.py @@ -397,7 +397,7 @@ def mount_managers_effect(**args): 'volume_options': 'subvol=@/boot/grub2', 'volume_device': 'device' } - } + }, root_volume_name='root' ) assert mock_MountManager.call_args_list == [ call(device='rootdev'), @@ -409,7 +409,9 @@ def mount_managers_effect(**args): call(device='/proc', mountpoint='root_mount_point/proc'), call(device='/sys', mountpoint='root_mount_point/sys') ] - root_mount.mount.assert_called_once_with() + root_mount.mount.assert_called_once_with( + options=['subvol=root'] + ) boot_mount.mount.assert_called_once_with() efi_mount.mount.assert_called_once_with() volume_mount.mount.assert_called_once_with( diff --git a/test/unit/bootloader/config/grub2_test.py b/test/unit/bootloader/config/grub2_test.py index 619e75fadb2..5ced6f250ca 100644 --- a/test/unit/bootloader/config/grub2_test.py +++ b/test/unit/bootloader/config/grub2_test.py @@ -955,7 +955,7 @@ def open_file(filename, mode=None): } ) mock_mount_system.assert_called_once_with( - 'rootdev', 'bootdev', None, None + 'rootdev', 'bootdev', None, None, None ) assert mock_Command_run.call_args_list == [ call( diff --git a/test/unit/bootloader/install/grub2_test.py b/test/unit/bootloader/install/grub2_test.py index 8dbaea70018..6b526bb001e 100644 --- a/test/unit/bootloader/install/grub2_test.py +++ b/test/unit/bootloader/install/grub2_test.py @@ -29,6 +29,7 @@ def setup(self): 'root_device': '/dev/mapper/loop0p1', 'efi_device': '/dev/mapper/loop0p3', 'prep_device': '/dev/mapper/loop0p2', + 'system_root_volume': 'root', 'system_volumes': {'boot/grub2': { 'volume_options': 'subvol=@/boot/grub2', 'volume_device': 'device' @@ -167,7 +168,9 @@ def side_effect(device, mountpoint=None): mock_mount_manager.side_effect = side_effect self.bootloader.install() - self.bootloader.root_mount.mount.assert_called_once_with() + self.bootloader.root_mount.mount.assert_called_once_with( + options=['subvol=root'] + ) self.bootloader.boot_mount.mount.assert_called_once_with() mock_glob.assert_called_once_with( 'tmp_root/boot/*/grubenv' @@ -213,7 +216,9 @@ def side_effect(device, mountpoint=None): mock_mount_manager.side_effect = side_effect self.bootloader.install() - self.bootloader.root_mount.mount.assert_called_once_with() + self.bootloader.root_mount.mount.assert_called_once_with( + options=['subvol=root'] + ) self.bootloader.boot_mount.mount.assert_called_once_with() assert mock_command.call_args_list == [ call( @@ -258,7 +263,9 @@ def side_effect(device, mountpoint=None): mock_mount_manager.side_effect = side_effect self.bootloader.install() - self.bootloader.root_mount.mount.assert_called_once_with() + self.bootloader.root_mount.mount.assert_called_once_with( + options=['subvol=root'] + ) self.bootloader.boot_mount.mount.assert_called_once_with() mock_wipe.assert_called_once_with( 'tmp_root/boot/grub2/grubenv' @@ -297,7 +304,9 @@ def side_effect(device, mountpoint=None): mock_mount_manager.side_effect = side_effect self.bootloader.install() - self.bootloader.root_mount.mount.assert_called_once_with() + self.bootloader.root_mount.mount.assert_called_once_with( + options=['subvol=root'] + ) self.bootloader.boot_mount.mount.assert_called_once_with() mock_wipe.assert_called_once_with( 'tmp_root/boot/grub2/grubenv' @@ -338,7 +347,9 @@ def side_effect(device, mountpoint=None): self.bootloader.target_removable = True self.bootloader.install() - self.root_mount.mount.assert_called_once_with() + self.root_mount.mount.assert_called_once_with( + options=['subvol=root'] + ) self.volume_mount.mount.assert_called_once_with( options=['subvol=@/boot/grub2'] ) @@ -398,7 +409,9 @@ def side_effect(device, mountpoint=None): '/usr/sbin/grub2-install' ]) ] - self.root_mount.mount.assert_called_once_with() + self.root_mount.mount.assert_called_once_with( + options=['subvol=root'] + ) self.volume_mount.mount.assert_called_once_with( options=['subvol=@/boot/grub2'] ) @@ -421,7 +434,9 @@ def side_effect(device, mountpoint=None): mock_mount_manager.side_effect = side_effect self.bootloader.secure_boot_install() - self.root_mount.mount.assert_called_once_with() + self.root_mount.mount.assert_called_once_with( + options=['subvol=root'] + ) self.volume_mount.mount.assert_called_once_with( options=['subvol=@/boot/grub2'] )