From 739679ad5ab6f7a3fe1edc960fb136d557499781 Mon Sep 17 00:00:00 2001 From: Simon Quigley Date: Fri, 22 Nov 2024 19:36:43 -0600 Subject: [PATCH 1/2] [libcalamares] Add a closeCryptsetup function to properly close LUKS partitions --- src/libcalamares/partition/Mount.cpp | 9 +++++++++ src/libcalamares/partition/Mount.h | 7 +++++++ 2 files changed, 16 insertions(+) --- a/src/libcalamares/partition/Mount.cpp +++ b/src/libcalamares/partition/Mount.cpp @@ -84,6 +84,15 @@ unmount( const QString& path, const QStr return r.getExitCode(); } +int +closeCryptsetup( const QString& luksMapperName ) +{ + QStringList args = { "cryptsetup", "close", luksMapperName }; + auto r = Calamares::System::runCommand( QStringList { "cryptsetup", "close", luksMapperName } , std::chrono::seconds( 10 ) ); + sync(); + return r.getExitCode(); +} + struct TemporaryMount::Private { QString m_devicePath; --- a/src/libcalamares/partition/Mount.h +++ b/src/libcalamares/partition/Mount.h @@ -51,6 +51,13 @@ DLLEXPORT int mount( const QString& devi */ DLLEXPORT int unmount( const QString& path, const QStringList& options = QStringList() ); +/** @brief Use cryptsetup to close the given @p LUKS mapper name. + * + * Runs cryptsetup(8) in the host system. + * + * @returns the program's exit code + */ +DLLEXPORT int closeCryptsetup( const QString& luksMapperName ); /** @brief Mount and automatically unmount a device * --- a/src/modules/umount/UmountJob.cpp +++ b/src/modules/umount/UmountJob.cpp @@ -94,6 +94,38 @@ unmountTargetMounts( const QString& root } static Calamares::JobResult +unmountEncryptedPartitions( const QList& partitions ) +{ + // Iterate on each partition in global storage + for ( const auto& partition : partitions ) + { + // If this partition does not have LUKS information, skip it + QVariantMap partitionMap = partition.toMap(); + if ( !partitionMap.contains("luksMapperName") ) { + continue; + } + + // Define the mount point and ensure it exists + QString luksMapperName = partitionMap.value("luksMapperName").toString(); + QFile deviceFile(QString("/dev/mapper/%1").arg(luksMapperName)); + if ( !deviceFile.exists() ) { + continue; + } + + // Close the device + if ( Calamares::Partition::closeCryptsetup( luksMapperName ) ) + { + return Calamares::JobResult::error( + QCoreApplication::translate( UmountJob::staticMetaObject.className(), + "Could not close encrypted partition on the target system." ) + ); + } + } + + return Calamares::JobResult::ok(); +} + +static Calamares::JobResult exportZFSPools() { auto* gs = Calamares::JobQueue::instance()->globalStorage(); @@ -149,6 +181,15 @@ UmountJob::exec() if ( !r ) { return r; + } + } + + // For encrypted systems, close the partitions + { + auto r = unmountEncryptedPartitions( gs->value("partitions").toList() ); + if ( !r ) + { + return r; } }