From d2f4079a18476adcf82aff0c8055fb72c1fc206b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Sep 2018 06:42:14 -0400 Subject: [PATCH] [partition] Move partitioning options into a class - As (auto) partitioning grows more options, the parameter list becomes more unwieldy. Add some structure to it. --- .../partition/core/PartitionActions.cpp | 49 +++++------- src/modules/partition/core/PartitionActions.h | 76 +++++++++++++------ src/modules/partition/gui/ChoicePage.cpp | 68 ++++++++++------- src/modules/partition/gui/ReplaceWidget.cpp | 14 ++-- 4 files changed, 121 insertions(+), 86 deletions(-) diff --git a/src/modules/partition/core/PartitionActions.cpp b/src/modules/partition/core/PartitionActions.cpp index 7e488367f..e06ff6c36 100644 --- a/src/modules/partition/core/PartitionActions.cpp +++ b/src/modules/partition/core/PartitionActions.cpp @@ -28,7 +28,6 @@ #include "utils/Units.h" #include "JobQueue.h" #include "utils/Logger.h" -#include "GlobalStorage.h" #include #include @@ -43,17 +42,18 @@ using CalamaresUtils::operator""_GiB; using CalamaresUtils::operator""_MiB; qint64 -swapSuggestion( const qint64 availableSpaceB ) +swapSuggestion( const qint64 availableSpaceB, Choices::SwapChoice swap ) { + if ( ( swap != Choices::SmallSwap ) && ( swap != Choices::FullSwap ) ) + return 0; + // See partition.conf for explanation qint64 suggestedSwapSizeB = 0; auto memory = CalamaresUtils::System::instance()->getTotalMemoryB(); qint64 availableRamB = memory.first; qreal overestimationFactor = memory.second; - bool ensureSuspendToDisk = - Calamares::JobQueue::instance()->globalStorage()-> - value( "ensureSuspendToDisk" ).toBool(); + bool ensureSuspendToDisk = swap == Choices::FullSwap; // Ramp up quickly to 8GiB, then follow memory size if ( availableRamB <= 4_GiB ) @@ -97,16 +97,14 @@ bytesToSectors( qint64 bytes, qint64 blocksize ) } void -doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPassphrase ) +doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionOptions o ) { - Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); - - bool isEfi = PartUtils::isEfiSystem(); - - QString defaultFsType = gs->value( "defaultFileSystemType" ).toString(); + QString defaultFsType = o.defaultFsType; if ( FileSystem::typeForName( defaultFsType ) == FileSystem::Unknown ) defaultFsType = "ext4"; + bool isEfi = PartUtils::isEfiSystem(); + // Partition sizes are expressed in MiB, should be multiples of // the logical sector size (usually 512B). EFI starts with 2MiB // empty and a 300MiB EFI boot partition, while BIOS starts at @@ -139,8 +137,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass PartitionTable::FlagNone ); PartitionInfo::setFormat( efiPartition, true ); - PartitionInfo::setMountPoint( efiPartition, gs->value( "efiSystemPartition" ) - .toString() ); + PartitionInfo::setMountPoint( efiPartition, o.efiPartitionMountPoint ); core->createPartition( dev, efiPartition, PartitionTable::FlagEsp ); firstFreeSector = lastSector + 1; } @@ -149,20 +146,18 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass core->createPartitionTable( dev, PartitionTable::msdos ); } - const bool mayCreateSwap = !gs->value( "neverCreateSwap" ).toBool(); + const bool mayCreateSwap = ( o.swap == Choices::SmallSwap ) || ( o.swap == Choices::FullSwap ); bool shouldCreateSwap = false; qint64 suggestedSwapSizeB = 0; if ( mayCreateSwap ) { qint64 availableSpaceB = ( dev->totalLogical() - firstFreeSector ) * dev->logicalSize(); - suggestedSwapSizeB = swapSuggestion( availableSpaceB ); + suggestedSwapSizeB = swapSuggestion( availableSpaceB, o.swap ); // Space required by this installation is what the distro claims is needed // (via global configuration) plus the swap size plus a fudge factor of // 0.6GiB (this was 2.1GiB up to Calamares 3.2.2). - qint64 requiredSpaceB = - GiBtoBytes( gs->value( "requiredStorageGB" ).toDouble() + 0.6 ) + - suggestedSwapSizeB; + qint64 requiredSpaceB = o.requiredSpaceB + 600_MiB + suggestedSwapSizeB; // If there is enough room for ESP + root + swap, create swap, otherwise don't. shouldCreateSwap = availableSpaceB > requiredSpaceB; @@ -175,7 +170,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass } Partition* rootPartition = nullptr; - if ( luksPassphrase.isEmpty() ) + if ( o.luksPassphrase.isEmpty() ) { rootPartition = KPMHelpers::createNewPartition( dev->partitionTable(), @@ -195,7 +190,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass FileSystem::typeForName( defaultFsType ), firstFreeSector, lastSectorForRoot, - luksPassphrase + o.luksPassphrase ); } PartitionInfo::setFormat( rootPartition, true ); @@ -205,7 +200,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass if ( shouldCreateSwap ) { Partition* swapPartition = nullptr; - if ( luksPassphrase.isEmpty() ) + if ( o.luksPassphrase.isEmpty() ) { swapPartition = KPMHelpers::createNewPartition( dev->partitionTable(), @@ -225,7 +220,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass FileSystem::LinuxSwap, lastSectorForRoot + 1, dev->totalLogical() - 1, - luksPassphrase + o.luksPassphrase ); } PartitionInfo::setFormat( swapPartition, true ); @@ -240,13 +235,11 @@ void doReplacePartition( PartitionCoreModule* core, Device* dev, Partition* partition, - const QString& luksPassphrase ) + Choices::ReplacePartitionOptions o ) { cDebug() << "doReplacePartition for device" << partition->partitionPath(); - QString defaultFsType = Calamares::JobQueue::instance()-> - globalStorage()-> - value( "defaultFileSystemType" ).toString(); + QString defaultFsType = o.defaultFsType; if ( FileSystem::typeForName( defaultFsType ) == FileSystem::Unknown ) defaultFsType = "ext4"; @@ -267,7 +260,7 @@ doReplacePartition( PartitionCoreModule* core, } Partition* newPartition = nullptr; - if ( luksPassphrase.isEmpty() ) + if ( o.luksPassphrase.isEmpty() ) { newPartition = KPMHelpers::createNewPartition( partition->parent(), @@ -287,7 +280,7 @@ doReplacePartition( PartitionCoreModule* core, FileSystem::typeForName( defaultFsType ), partition->firstSector(), partition->lastSector(), - luksPassphrase + o.luksPassphrase ); } PartitionInfo::setMountPoint( newPartition, "/" ); diff --git a/src/modules/partition/core/PartitionActions.h b/src/modules/partition/core/PartitionActions.h index 8312d582b..5acf444fa 100644 --- a/src/modules/partition/core/PartitionActions.h +++ b/src/modules/partition/core/PartitionActions.h @@ -27,30 +27,6 @@ class Partition; namespace PartitionActions { - -/** - * @brief doAutopartition sets up an autopartitioning operation on the given Device. - * @param core a pointer to the PartitionCoreModule instance. - * @param dev the device to wipe. - * @param luksPassphrase the passphrase for LUKS encryption (optional, default is empty). - */ -void doAutopartition( PartitionCoreModule* core, - Device* dev, - const QString& luksPassphrase = QString() ); - -/** - * @brief doReplacePartition sets up replace-partitioning with the given partition. - * @param core a pointer to the PartitionCoreModule instance. - * @param dev a pointer to the Device on which to replace a partition. - * @param partition a pointer to the Partition to be replaced. - * @param luksPassphrase the passphrase for LUKS encryption (optional, default is empty). - * @note this function also takes care of requesting PCM to delete the partition. - */ -void doReplacePartition( PartitionCoreModule* core, - Device* dev, - Partition* partition, - const QString& luksPassphrase = QString() ); - /** @brief Namespace for enums * * This namespace houses non-class enums..... @@ -66,7 +42,59 @@ namespace Choices FullSwap, // ensureSuspendToDisk -- at least RAM size SwapFile // use a file (if supported) }; + + struct ReplacePartitionOptions + { + QString defaultFsType; // e.g. "ext4" or "btrfs" + QString luksPassphrase; // optional + + ReplacePartitionOptions( const QString& fs, const QString& luks ) + : defaultFsType( fs ) + , luksPassphrase( luks ) + { + } + }; + + struct AutoPartitionOptions : ReplacePartitionOptions + { + QString efiPartitionMountPoint; // optional, e.g. "/boot" + quint64 requiredSpaceB; // estimated required space for root partition + SwapChoice swap; + + AutoPartitionOptions( const QString& fs, const QString& luks, const QString& efi, qint64 r, SwapChoice s ) + : ReplacePartitionOptions( fs, luks ) + , efiPartitionMountPoint( efi ) + , requiredSpaceB( r > 0 ? r : 0 ) + , swap( s ) + { + } + }; + } // namespace Choices + +/** + * @brief doAutopartition sets up an autopartitioning operation on the given Device. + * @param core a pointer to the PartitionCoreModule instance. + * @param dev the device to wipe. + * @param options settings for autopartitioning. + */ +void doAutopartition( PartitionCoreModule* core, + Device* dev, + Choices::AutoPartitionOptions options ); + +/** + * @brief doReplacePartition sets up replace-partitioning with the given partition. + * @param core a pointer to the PartitionCoreModule instance. + * @param dev a pointer to the Device on which to replace a partition. + * @param partition a pointer to the Partition to be replaced. + * @param options settings for partitioning (not all fields apply) + * + * @note this function also takes care of requesting PCM to delete the partition. + */ +void doReplacePartition( PartitionCoreModule* core, + Device* dev, + Partition* partition, + Choices::ReplacePartitionOptions options ); } // namespace PartitionActions #endif // PARTITIONACTIONS_H diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index 82302ac4c..b5a2ce529 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -42,6 +42,7 @@ #include "utils/CalamaresUtilsGui.h" #include "utils/Logger.h" #include "utils/Retranslator.h" +#include "utils/Units.h" #include "Branding.h" #include "GlobalStorage.h" @@ -417,30 +418,37 @@ ChoicePage::applyActionChoice( ChoicePage::InstallChoice choice ) switch ( choice ) { case Erase: - if ( m_core->isDirty() ) { - ScanningDialog::run( QtConcurrent::run( [ = ] - { - QMutexLocker locker( &m_coreMutex ); - m_core->revertDevice( selectedDevice() ); - } ), - [ = ] - { - PartitionActions::doAutopartition( m_core, - selectedDevice(), - m_encryptWidget->passphrase() ); - emit deviceChosen(); - }, - this ); - } - else - { - PartitionActions::doAutopartition( m_core, - selectedDevice(), - m_encryptWidget->passphrase() ); - emit deviceChosen(); - } + auto gs = Calamares::JobQueue::instance()->globalStorage(); + PartitionActions::Choices::AutoPartitionOptions options { + gs->value( "defaultFileSystemType" ).toString(), + m_encryptWidget->passphrase(), + gs->value( "efiSystemPartition" ).toString(), + CalamaresUtils::GiBtoBytes( gs->value( "requiredStorageGB" ).toDouble() ), + static_cast( m_eraseSwapChoices->currentData().toInt() ) + }; + + if ( m_core->isDirty() ) + { + ScanningDialog::run( QtConcurrent::run( [ = ] + { + QMutexLocker locker( &m_coreMutex ); + m_core->revertDevice( selectedDevice() ); + } ), + [ = ] + { + PartitionActions::doAutopartition( m_core, selectedDevice(), options ); + emit deviceChosen(); + }, + this ); + } + else + { + PartitionActions::doAutopartition( m_core, selectedDevice(), options ); + emit deviceChosen(); + } + } break; case Replace: if ( m_core->isDirty() ) @@ -518,6 +526,7 @@ ChoicePage::doAlongsideSetupSplitter( const QModelIndex& current, ->value( "requiredStorageGB" ) .toDouble(); + // TODO: make this consistent qint64 requiredStorageB = qRound64( requiredStorageGB + 0.1 + 2.0 ) * 1024 * 1024 * 1024; m_afterPartitionSplitterWidget->setSplitPartition( @@ -802,14 +811,19 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current ) if ( homePartitionPath->isEmpty() ) doReuseHomePartition = false; - PartitionActions::doReplacePartition( m_core, - selectedDevice(), - selectedPartition, - m_encryptWidget->passphrase() ); + Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); + + PartitionActions::doReplacePartition( + m_core, + selectedDevice(), + selectedPartition, + { + gs->value( "defaultFileSystemType" ).toString(), + m_encryptWidget->passphrase() + } ); Partition* homePartition = KPMHelpers::findPartitionByPath( { selectedDevice() }, *homePartitionPath ); - Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); if ( homePartition && doReuseHomePartition ) { PartitionInfo::setMountPoint( homePartition, "/home" ); diff --git a/src/modules/partition/gui/ReplaceWidget.cpp b/src/modules/partition/gui/ReplaceWidget.cpp index 524932057..faedc03d4 100644 --- a/src/modules/partition/gui/ReplaceWidget.cpp +++ b/src/modules/partition/gui/ReplaceWidget.cpp @@ -85,6 +85,8 @@ ReplaceWidget::reset() void ReplaceWidget::applyChanges() { + auto gs = Calamares::JobQueue::instance()->globalStorage(); + PartitionModel* model = qobject_cast< PartitionModel* >( m_ui->partitionTreeView->model() ); if ( model ) { @@ -93,7 +95,9 @@ ReplaceWidget::applyChanges() { Device* dev = model->device(); - PartitionActions::doReplacePartition( m_core, dev, partition ); + PartitionActions::doReplacePartition( + m_core, dev, partition, + { gs->value( "defaultFileSystemType" ).toString(), QString() } ); if ( m_isEfi ) { @@ -102,17 +106,13 @@ ReplaceWidget::applyChanges() { PartitionInfo::setMountPoint( efiSystemPartitions.first(), - Calamares::JobQueue::instance()-> - globalStorage()-> - value( "efiSystemPartition" ).toString() ); + gs->value( "efiSystemPartition" ).toString() ); } else if ( efiSystemPartitions.count() > 1 ) { PartitionInfo::setMountPoint( efiSystemPartitions.at( m_ui->bootComboBox->currentIndex() ), - Calamares::JobQueue::instance()-> - globalStorage()-> - value( "efiSystemPartition" ).toString() ); + gs->value( "efiSystemPartition" ).toString() ); } }