diff --git a/archinstall/lib/disk/device_handler.py b/archinstall/lib/disk/device_handler.py index 3365a89363..a0eaa0e5e7 100644 --- a/archinstall/lib/disk/device_handler.py +++ b/archinstall/lib/disk/device_handler.py @@ -464,8 +464,22 @@ def lvm_export_vg(self, vg: LvmVolumeGroup) -> None: SysCommand(cmd) def lvm_import_vg(self, vg: LvmVolumeGroup) -> None: - cmd = f'vgimport {vg.name}' + # Check if the VG is actually exported before trying to import it + check_cmd = f'vgs --noheadings -o vg_exported {vg.name}' + + try: + result = SysCommand(check_cmd) + is_exported = result.decode().strip() == 'exported' + except SysCallError: + # VG might not exist yet, skip import + debug(f'Volume group {vg.name} not found, skipping import') + return + + if not is_exported: + debug(f'Volume group {vg.name} is already active (not exported), skipping import') + return + cmd = f'vgimport {vg.name}' debug(f'vgimport: {cmd}') SysCommand(cmd) @@ -477,33 +491,22 @@ def lvm_vol_reduce(self, vol_path: Path, amount: Size) -> None: SysCommand(cmd) def lvm_pv_create(self, pvs: Iterable[Path]) -> None: - cmd = 'pvcreate ' + ' '.join([str(pv) for pv in pvs]) + pvs_str = ' '.join([str(pv) for pv in pvs]) + # Signatures are already wiped by wipefs, -f is just for safety + cmd = f'pvcreate -f --yes {pvs_str}' + # note flags used in scripting debug(f'Creating LVM PVS: {cmd}') - - worker = SysCommandWorker(cmd) - worker.poll() - worker.write(b'y\n', line_ending=False) - - # Wait for the command to complete - while worker.is_alive(): - worker.poll() + SysCommand(cmd) # Sync with udev to ensure the PVs are visible self.udev_sync() def lvm_vg_create(self, pvs: Iterable[Path], vg_name: str) -> None: pvs_str = ' '.join([str(pv) for pv in pvs]) - cmd = f'vgcreate --yes {vg_name} {pvs_str}' + cmd = f'vgcreate --yes --force {vg_name} {pvs_str}' debug(f'Creating LVM group: {cmd}') - - worker = SysCommandWorker(cmd) - worker.poll() - worker.write(b'y\n', line_ending=False) - - # Wait for the command to complete - while worker.is_alive(): - worker.poll() + SysCommand(cmd) # Sync with udev to ensure the VG is visible self.udev_sync() @@ -750,6 +753,17 @@ def partition( disk.commit() + # Wipe filesystem/LVM signatures from newly created partitions + # to prevent "signature detected" errors + for part_mod in filtered_part: + if part_mod.dev_path: + debug(f'Wiping signatures from: {part_mod.dev_path}') + SysCommand(f'wipefs --all {part_mod.dev_path}') + + # Sync with udev after wiping signatures + if filtered_part: + self.udev_sync() + @staticmethod def swapon(path: Path) -> None: try: diff --git a/archinstall/lib/disk/filesystem.py b/archinstall/lib/disk/filesystem.py index c397afa5d6..1ac4d35f6a 100644 --- a/archinstall/lib/disk/filesystem.py +++ b/archinstall/lib/disk/filesystem.py @@ -145,28 +145,19 @@ def _setup_lvm_encrypted(self, lvm_config: LvmConfiguration, enc_config: DiskEnc self._setup_lvm(lvm_config, enc_mods) self._format_lvm_vols(lvm_config) - # export the lvm group safely otherwise the Luks cannot be closed - self._safely_close_lvm(lvm_config) - - for luks in enc_mods.values(): - luks.lock() + # Don't close LVM or LUKS during setup - keep everything active + # The installation phase will handle unlocking and mounting + # Closing causes "parent leaked" and lvchange errors elif enc_config.encryption_type == EncryptionType.LuksOnLvm: self._setup_lvm(lvm_config) enc_vols = self._encrypt_lvm_vols(lvm_config, enc_config, False) self._format_lvm_vols(lvm_config, enc_vols) + # Lock LUKS devices but keep LVM active + # LVM volumes must remain active for later re-unlock during installation for luks in enc_vols.values(): luks.lock() - self._safely_close_lvm(lvm_config) - - def _safely_close_lvm(self, lvm_config: LvmConfiguration) -> None: - for vg in lvm_config.vol_groups: - for vol in vg.volumes: - device_handler.lvm_vol_change(vol, False) - - device_handler.lvm_export_vg(vg) - def _setup_lvm( self, lvm_config: LvmConfiguration, diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index ca240e3905..0021c9301e 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -248,6 +248,7 @@ def mount_ordered_layout(self) -> None: match self._disk_encryption.encryption_type: case EncryptionType.NoEncryption: + self._import_lvm() self._mount_lvm_layout() case EncryptionType.Luks: luks_handlers = self._prepare_luks_partitions(self._disk_encryption.partitions)