diff --git a/src/modules/partition/Config.cpp b/src/modules/partition/Config.cpp index 085c451791e96d10c34e286b200007d33c2c039f..b2f88789a5ef92682cb8c1767bf7931b9333db84 100644 --- a/src/modules/partition/Config.cpp +++ b/src/modules/partition/Config.cpp @@ -451,9 +451,11 @@ Config::setConfigurationMap( const QVariantMap& configurationMap ) { bool bogus = true; const auto lvmConfiguration = Calamares::getSubMap( configurationMap, "lvm", bogus ); - m_isLVMEnabled = Calamares::getBool( lvmConfiguration, "enable", true); + m_isLVMEnabled = Calamares::getBool( lvmConfiguration, "enable", true ); } + m_essentialMounts= Calamares::getStringList( configurationMap, "essentialMounts" ); + Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); gs->insert( "armInstall", Calamares::getBool( configurationMap, "armInstall", false ) ); fillGSConfigurationEFI( gs, configurationMap ); diff --git a/src/modules/partition/Config.h b/src/modules/partition/Config.h index 13da58ac44c445d482af2db68ae1977fd515b92b..d2dfec64d16157b067a06c34dc2bb21a1e89f015 100644 --- a/src/modules/partition/Config.h +++ b/src/modules/partition/Config.h @@ -40,6 +40,8 @@ class Config : public QObject Q_PROPERTY( bool lvmEnabled READ isLVMEnabled CONSTANT FINAL ) + Q_PROPERTY( QStringList essentialMounts READ essentialMounts CONSTANT FINAL ) + public: Config( QObject* parent ); ~Config() override = default; @@ -178,6 +180,14 @@ public: bool isLVMEnabled() const { return m_isLVMEnabled; } + /** @brief A list of names that can follow /dev/mapper/ that must not be closed + * + * These names (if any) are skipped by the ClearMountsJob. + * The names may contain a trailing '*' which acts as a wildcard. + * In any other position, '*' is interpreted literally. + */ + QStringList essentialMounts() const { return m_essentialMounts; } + public Q_SLOTS: void setInstallChoice( int ); ///< Translates a button ID or so to InstallChoice void setInstallChoice( InstallChoice ); @@ -213,6 +223,7 @@ private: bool m_preCheckEncryption = false; bool m_showNotEncryptedBootMessage = true; bool m_isLVMEnabled = true; + QStringList m_essentialMounts; }; /** @brief Given a set of swap choices, return a sensible value from it. diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index c2fd61db9aebf956d2c593edcfd8c77ef03d58c8..d92c66f72dccdd2837f76573a03103679c7f2e54 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -610,7 +610,7 @@ PartitionCoreModule::setPartitionFlags( Device* device, Partition* partition, Pa STATICTEST QStringList findEssentialLVs( const QList< PartitionCoreModule::DeviceInfo* >& infos ) { - QStringList doNotClose; + QStringList essentialLV; cDebug() << "Checking LVM use on" << infos.count() << "devices"; for ( const auto* info : infos ) { @@ -635,12 +635,12 @@ findEssentialLVs( const QList< PartitionCoreModule::DeviceInfo* >& infos ) cDebug() << Logger::SubEntry << partPath << "is an essential LV filesystem=" << partition->fileSystem().type(); QString lvName = partPath.right( partPath.length() - devicePath.length() ); - doNotClose.append( info->device->name() + '-' + lvName ); + essentialLV.append( info->device->name() + '-' + lvName ); } } } } - return doNotClose; + return essentialLV; } Calamares::JobList @@ -670,14 +670,14 @@ PartitionCoreModule::jobs( const Config* config ) const #ifdef DEBUG_PARTITION_SKIP cWarning() << "Partitioning actions are skipped."; #else - const QStringList doNotClose = findEssentialLVs( m_deviceInfos ); + const QStringList essentialMounts = findEssentialLVs( m_deviceInfos ) + config->essentialMounts(); for ( const auto* info : m_deviceInfos ) { if ( info->isDirty() ) { auto* job = new ClearMountsJob( info->device.data() ); - job->setMapperExceptions( doNotClose ); + job->setMapperExceptions( essentialMounts ); lst << Calamares::job_ptr( job ); } } diff --git a/src/modules/partition/jobs/ClearMountsJob.cpp b/src/modules/partition/jobs/ClearMountsJob.cpp index 2fbafb5dc754d40dccbb18aa512c67d6a3712287..b4ebfebf490d3759ad51fcef42d3b0402c58bff5 100644 --- a/src/modules/partition/jobs/ClearMountsJob.cpp +++ b/src/modules/partition/jobs/ClearMountsJob.cpp @@ -123,6 +123,23 @@ isSpecial( const QString& baseName ) return specialForFedora || specialMapperControl || specialVentoy; } +static inline bool +matchesExceptions( const QStringList& mapperExceptions, const QString& basename ) +{ + for ( const auto& e : mapperExceptions ) + { + if ( basename == e ) + { + return true; + } + if ( e.endsWith( '*' ) && basename.startsWith( e.left( e.length() - 1 ) ) ) + { + return true; + } + } + return false; +} + /** @brief Returns a list of unneeded crypto devices * * These are the crypto devices to unmount and close; some are "needed" @@ -139,7 +156,7 @@ getCryptoDevices( const QStringList& mapperExceptions ) for ( const QFileInfo& fi : fiList ) { QString baseName = fi.baseName(); - if ( isSpecial( baseName ) || mapperExceptions.contains( baseName ) ) + if ( isSpecial( baseName ) || matchesExceptions( mapperExceptions, baseName ) ) { continue; } diff --git a/src/modules/partition/partition.conf b/src/modules/partition/partition.conf index 2f56df71582a368bcf64d3f69a6a718f1a3b0b45..4c78f58140fa65cb84893371545ff998f5038fc5 100644 --- a/src/modules/partition/partition.conf +++ b/src/modules/partition/partition.conf @@ -266,6 +266,13 @@ defaultFileSystemType: "ext4" # even if the directory is part of a filesystem on a # different mountpoint. Defaults to false. +# The ClearMounts job unmounts / unmaps things before partitioning. +# Some special entries under /dev/mapper are excepted from this process. +# The example lists the three hard-coded exceptions which always apply +# (they don't need to be listed here). Add other names or wildcards (with +# a trailing '*') to this list if the live-ISO has additional mounts. +essentialMounts: [ "live-*", "control", "ventoy" ] + # Show/hide LUKS related functionality in automated partitioning modes. # Disable this if you choose not to deploy early unlocking support in GRUB2 # and/or your distribution's initramfs solution. diff --git a/src/modules/partition/partition.schema.yaml b/src/modules/partition/partition.schema.yaml index 4bd2fa4ae0f6e94d3e759f9c4b205377ad0e2bdf..07763aef4ca6879f6a203047cdf9f39743091020 100644 --- a/src/modules/partition/partition.schema.yaml +++ b/src/modules/partition/partition.schema.yaml @@ -42,6 +42,7 @@ properties: luksGeneration: { type: string, enum: [luks1, luks2] } # Also allows "luks" as alias of "luks1" enableLuksAutomatedPartitioning: { type: boolean, default: false } preCheckEncryption: { type: boolean, default: false } + essentialMounts: { type: array, items: { type: string } } # List of names under /dev/mapper not to close allowManualPartitioning: { type: boolean, default: true } showNotEncryptedBootMessage: { type: boolean, default: true }