diff --git a/src/modules/partition/CMakeLists.txt b/src/modules/partition/CMakeLists.txt index ac47714ce..07f1eaf5d 100644 --- a/src/modules/partition/CMakeLists.txt +++ b/src/modules/partition/CMakeLists.txt @@ -80,6 +80,7 @@ if ( KPMcore_FOUND AND Qt5DBus_FOUND AND KF5CoreAddons_FOUND AND KF5Config_FOUND gui/ReplaceWidget.cpp gui/VolumeGroupBaseDialog.cpp jobs/AutoMountManagementJob.cpp + jobs/ChangeFilesystemLabelJob.cpp jobs/ClearMountsJob.cpp jobs/ClearTempMountsJob.cpp jobs/CreatePartitionJob.cpp @@ -117,3 +118,4 @@ else() calamares_skip_module( "partition (missing dependencies for KPMcore)" ) endif() endif() + diff --git a/src/modules/partition/core/KPMHelpers.cpp b/src/modules/partition/core/KPMHelpers.cpp index e9e69456d..ed105e28b 100644 --- a/src/modules/partition/core/KPMHelpers.cpp +++ b/src/modules/partition/core/KPMHelpers.cpp @@ -46,11 +46,13 @@ createNewPartition( PartitionNode* parent, const Device& device, const PartitionRole& role, FileSystem::Type fsType, + const QString& fsLabel, qint64 firstSector, qint64 lastSector, PartitionTable::Flags flags ) { FileSystem* fs = FileSystemFactory::create( fsType, firstSector, lastSector, device.logicalSize() ); + fs->setLabel( fsLabel ); return new Partition( parent, device, role, @@ -71,6 +73,7 @@ createNewEncryptedPartition( PartitionNode* parent, const Device& device, const PartitionRole& role, FileSystem::Type fsType, + const QString& fsLabel, qint64 firstSector, qint64 lastSector, const QString& passphrase, @@ -92,6 +95,7 @@ createNewEncryptedPartition( PartitionNode* parent, fs->createInnerFileSystem( fsType ); fs->setPassphrase( passphrase ); + fs->setLabel( fsLabel ); Partition* p = new Partition( parent, device, PartitionRole( newRoles ), diff --git a/src/modules/partition/core/KPMHelpers.h b/src/modules/partition/core/KPMHelpers.h index ad25689f3..89a019f6c 100644 --- a/src/modules/partition/core/KPMHelpers.h +++ b/src/modules/partition/core/KPMHelpers.h @@ -55,6 +55,7 @@ Partition* createNewPartition( PartitionNode* parent, const Device& device, const PartitionRole& role, FileSystem::Type fsType, + const QString& fsLabel, qint64 firstSector, qint64 lastSector, PartitionTable::Flags flags ); @@ -63,6 +64,7 @@ Partition* createNewEncryptedPartition( PartitionNode* parent, const Device& device, const PartitionRole& role, FileSystem::Type fsType, + const QString& fsLabel, qint64 firstSector, qint64 lastSector, const QString& passphrase, diff --git a/src/modules/partition/core/PartitionActions.cpp b/src/modules/partition/core/PartitionActions.cpp index d4301578b..1a3f6246b 100644 --- a/src/modules/partition/core/PartitionActions.cpp +++ b/src/modules/partition/core/PartitionActions.cpp @@ -132,6 +132,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO *dev, PartitionRole( PartitionRole::Primary ), FileSystem::Fat32, + QString(), firstFreeSector, lastSector, KPM_PARTITION_FLAG( None ) ); @@ -180,6 +181,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO *dev, PartitionRole( PartitionRole::Primary ), FileSystem::LinuxSwap, + QStringLiteral( "swap" ), lastSectorForRoot + 1, dev->totalLogical() - 1, KPM_PARTITION_FLAG( None ) ); @@ -190,6 +192,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO *dev, PartitionRole( PartitionRole::Primary ), FileSystem::LinuxSwap, + QStringLiteral( "swap" ), lastSectorForRoot + 1, dev->totalLogical() - 1, o.luksPassphrase, diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index f99c78745..058c10d18 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -22,6 +22,7 @@ #include "core/PartitionInfo.h" #include "core/PartitionModel.h" #include "jobs/AutoMountManagementJob.h" +#include "jobs/ChangeFilesystemLabelJob.h" #include "jobs/ClearMountsJob.h" #include "jobs/ClearTempMountsJob.h" #include "jobs/CreatePartitionJob.h" @@ -541,6 +542,16 @@ PartitionCoreModule::formatPartition( Device* device, Partition* partition ) deviceInfo->makeJob< FormatPartitionJob >( partition ); } +void +PartitionCoreModule::setFilesystemLabel( Device* device, Partition* partition, const QString& newLabel ) +{ + auto deviceInfo = infoForDevice( device ); + Q_ASSERT( deviceInfo ); + + OperationHelper helper( partitionModelForDevice( device ), this ); + deviceInfo->makeJob< ChangeFilesystemLabelJob >( partition, newLabel ); +} + void PartitionCoreModule::resizePartition( Device* device, Partition* partition, qint64 first, qint64 last ) { @@ -911,6 +922,14 @@ PartitionCoreModule::layoutApply( Device* dev, = std::find_if( partList.constBegin(), partList.constEnd(), is_boot ) != partList.constEnd(); for ( Partition* part : partList ) { + if ( is_boot( part ) ) + { + part->setLabel( "boot" ); + } + if ( is_root( part ) ) + { + part->setLabel( "root" ); + } if ( ( separate_boot_partition && is_boot( part ) ) || ( !separate_boot_partition && is_root( part ) ) ) { createPartition( diff --git a/src/modules/partition/core/PartitionCoreModule.h b/src/modules/partition/core/PartitionCoreModule.h index 46604b97c..492348187 100644 --- a/src/modules/partition/core/PartitionCoreModule.h +++ b/src/modules/partition/core/PartitionCoreModule.h @@ -147,6 +147,8 @@ public: void formatPartition( Device* device, Partition* partition ); + void setFilesystemLabel( Device* device, Partition* partition, const QString& newLabel ); + void resizePartition( Device* device, Partition* partition, qint64 first, qint64 last ); void setPartitionFlags( Device* device, Partition* partition, PartitionTable::Flags flags ); diff --git a/src/modules/partition/core/PartitionLayout.cpp b/src/modules/partition/core/PartitionLayout.cpp index d6f817af7..23eaeda62 100644 --- a/src/modules/partition/core/PartitionLayout.cpp +++ b/src/modules/partition/core/PartitionLayout.cpp @@ -230,6 +230,7 @@ PartitionLayout::createPartitions( Device* dev, *dev, role, entry.partFileSystem, + entry.partLabel, currentSector, currentSector + sectors - 1, KPM_PARTITION_FLAG( None ) ); @@ -240,6 +241,7 @@ PartitionLayout::createPartitions( Device* dev, *dev, role, entry.partFileSystem, + entry.partLabel, currentSector, currentSector + sectors - 1, luksPassphrase, diff --git a/src/modules/partition/core/PartitionModel.cpp b/src/modules/partition/core/PartitionModel.cpp index 9a8f4d96c..b4ea57adb 100644 --- a/src/modules/partition/core/PartitionModel.cpp +++ b/src/modules/partition/core/PartitionModel.cpp @@ -167,6 +167,10 @@ PartitionModel::data( const QModelIndex& index, int role ) const { return CalamaresUtils::Partition::prettyNameForFileSystemType( partition->fileSystem().type() ); } + if ( col == FileSystemLabelColumn ) + { + return partition->fileSystem().label(); + } if ( col == MountPointColumn ) { return PartitionInfo::mountPoint( partition ); @@ -296,6 +300,8 @@ PartitionModel::headerData( int section, Qt::Orientation, int role ) const return tr( "Name" ); case FileSystemColumn: return tr( "File System" ); + case FileSystemLabelColumn: + return tr( "File System Label" ); case MountPointColumn: return tr( "Mount Point" ); case SizeColumn: diff --git a/src/modules/partition/core/PartitionModel.h b/src/modules/partition/core/PartitionModel.h index f91479adc..433fa0620 100644 --- a/src/modules/partition/core/PartitionModel.h +++ b/src/modules/partition/core/PartitionModel.h @@ -79,6 +79,7 @@ public: { NameColumn, FileSystemColumn, + FileSystemLabelColumn, MountPointColumn, SizeColumn, ColumnCount // Must remain last diff --git a/src/modules/partition/gui/CreatePartitionDialog.cpp b/src/modules/partition/gui/CreatePartitionDialog.cpp index 3b51010b8..c765bf1f7 100644 --- a/src/modules/partition/gui/CreatePartitionDialog.cpp +++ b/src/modules/partition/gui/CreatePartitionDialog.cpp @@ -202,17 +202,19 @@ CreatePartitionDialog::createPartition() FileSystem::Type fsType = m_role.has( PartitionRole::Extended ) ? FileSystem::Extended : FileSystem::typeForName( m_ui->fsComboBox->currentText() ); + const QString fsLabel = m_ui->filesystemLabelEdit->text(); Partition* partition = nullptr; QString luksPassphrase = m_ui->encryptWidget->passphrase(); if ( m_ui->encryptWidget->state() == EncryptWidget::Encryption::Confirmed && !luksPassphrase.isEmpty() ) { partition = KPMHelpers::createNewEncryptedPartition( - m_parent, *m_device, m_role, fsType, first, last, luksPassphrase, newFlags() ); + m_parent, *m_device, m_role, fsType, fsLabel, first, last, luksPassphrase, newFlags() ); } else { - partition = KPMHelpers::createNewPartition( m_parent, *m_device, m_role, fsType, first, last, newFlags() ); + partition + = KPMHelpers::createNewPartition( m_parent, *m_device, m_role, fsType, fsLabel, first, last, newFlags() ); } if ( m_device->type() == Device::Type::LVM_Device ) diff --git a/src/modules/partition/gui/CreatePartitionDialog.ui b/src/modules/partition/gui/CreatePartitionDialog.ui index 24e05e2e1..dad932101 100644 --- a/src/modules/partition/gui/CreatePartitionDialog.ui +++ b/src/modules/partition/gui/CreatePartitionDialog.ui @@ -130,10 +130,10 @@ SPDX-License-Identifier: GPL-3.0-or-later - + - + Qt::Vertical @@ -149,17 +149,17 @@ SPDX-License-Identifier: GPL-3.0-or-later - + LVM LV name - + - + &Mount Point: @@ -169,7 +169,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - + true @@ -179,21 +179,21 @@ SPDX-License-Identifier: GPL-3.0-or-later - + - + Flags: - + true @@ -206,7 +206,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - + Qt::Vertical @@ -219,6 +219,29 @@ SPDX-License-Identifier: GPL-3.0-or-later + + + + + 150 + 16777215 + + + + Label for the filesystem + + + 16 + + + + + + + FS Label: + + + diff --git a/src/modules/partition/gui/EditExistingPartitionDialog.cpp b/src/modules/partition/gui/EditExistingPartitionDialog.cpp index 3de6e0c4c..e2d7ac5ba 100644 --- a/src/modules/partition/gui/EditExistingPartitionDialog.cpp +++ b/src/modules/partition/gui/EditExistingPartitionDialog.cpp @@ -62,6 +62,10 @@ EditExistingPartitionDialog::EditExistingPartitionDialog( Device* device, this, &EditExistingPartitionDialog::checkMountPointSelection ); + // The filesystem label dialog is always enabled, because we may want to change + // the label on the current filesystem without formatting. + m_ui->fileSystemLabelEdit->setText( m_partition->fileSystem().label() ); + replacePartResizerWidget(); connect( m_ui->formatRadioButton, &QAbstractButton::toggled, [this]( bool doFormat ) { @@ -146,6 +150,7 @@ EditExistingPartitionDialog::applyChanges( PartitionCoreModule* core ) ? FileSystem::Extended : FileSystem::typeForName( m_ui->fileSystemComboBox->currentText() ); } + const QString fsLabel = m_ui->fileSystemLabelEdit->text(); const auto resultFlags = newFlags(); const auto currentFlags = PartitionInfo::flags( m_partition ); @@ -158,6 +163,7 @@ EditExistingPartitionDialog::applyChanges( PartitionCoreModule* core ) *m_device, m_partition->roles(), fsType, + fsLabel, newFirstSector, newLastSector, resultFlags ); @@ -190,6 +196,7 @@ EditExistingPartitionDialog::applyChanges( PartitionCoreModule* core ) { core->setPartitionFlags( m_device, m_partition, resultFlags ); } + core->setFilesystemLabel( m_device, m_partition, fsLabel ); } else // otherwise, we delete and recreate the partition with new fs type { @@ -197,6 +204,7 @@ EditExistingPartitionDialog::applyChanges( PartitionCoreModule* core ) *m_device, m_partition->roles(), fsType, + fsLabel, m_partition->firstSector(), m_partition->lastSector(), resultFlags ); @@ -214,6 +222,14 @@ EditExistingPartitionDialog::applyChanges( PartitionCoreModule* core ) { core->setPartitionFlags( m_device, m_partition, resultFlags ); } + // In this case, we are not formatting the partition, but we are setting the + // label on the current filesystem, if any. We only create the job if the + // label actually changed. + if ( m_partition->fileSystem().type() != FileSystem::Type::Unformatted + && fsLabel != m_partition->fileSystem().label() ) + { + core->setFilesystemLabel( m_device, m_partition, fsLabel ); + } core->refreshPartition( m_device, m_partition ); } } diff --git a/src/modules/partition/gui/EditExistingPartitionDialog.ui b/src/modules/partition/gui/EditExistingPartitionDialog.ui index 9c0c996f6..7599bc772 100644 --- a/src/modules/partition/gui/EditExistingPartitionDialog.ui +++ b/src/modules/partition/gui/EditExistingPartitionDialog.ui @@ -11,7 +11,7 @@ SPDX-License-Identifier: GPL-3.0-or-later 0 0 450 - 579 + 615 @@ -147,14 +147,14 @@ SPDX-License-Identifier: GPL-3.0-or-later - + Flags: - + true @@ -167,13 +167,36 @@ SPDX-License-Identifier: GPL-3.0-or-later - + + + + + + 150 + 16777215 + + + + Label for the filesystem + + + 16 + + + + + + + FS Label: + + + diff --git a/src/modules/partition/jobs/ChangeFilesystemLabelJob.cpp b/src/modules/partition/jobs/ChangeFilesystemLabelJob.cpp new file mode 100644 index 000000000..2df2db5e4 --- /dev/null +++ b/src/modules/partition/jobs/ChangeFilesystemLabelJob.cpp @@ -0,0 +1,105 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2016, Lisa Vitolo + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Calamares is Free Software: see the License-Identifier above. + * + */ + +#include "ChangeFilesystemLabelJob.h" + +#include "utils/Logger.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +ChangeFilesystemLabelJob::ChangeFilesystemLabelJob( Device* device, Partition* partition, const QString& newLabel ) + : PartitionJob( partition ) + , m_device( device ) + , m_label( newLabel ) +{ +} + + +QString +ChangeFilesystemLabelJob::prettyName() const +{ + return tr( "Set filesystem label on %1." ).arg( partition()->partitionPath() ); +} + + +QString +ChangeFilesystemLabelJob::prettyDescription() const +{ + return tr( "Set filesystem label %1 to partition " + "%2." ) + .arg( m_label ) + .arg( partition()->partitionPath() ); +} + + +QString +ChangeFilesystemLabelJob::prettyStatusMessage() const +{ + return prettyDescription(); +} + + +Calamares::JobResult +ChangeFilesystemLabelJob::exec() +{ + if ( m_label == partition()->fileSystem().label() ) + { + return Calamares::JobResult::ok(); + } + + Report report( nullptr ); + CoreBackend* backend = CoreBackendManager::self()->backend(); + + QScopedPointer< CoreBackendDevice > backendDevice( backend->openDevice( m_device->deviceNode() ) ); + if ( !backendDevice.data() ) + { + return Calamares::JobResult::error( tr( "Could not open device '%1'." ).arg( m_device->deviceNode() ), + report.toText() ); + } + + QScopedPointer< CoreBackendPartitionTable > backendPartitionTable( backendDevice->openPartitionTable() ); + if ( !backendPartitionTable.data() ) + { + return Calamares::JobResult::error( + tr( "Could not open partition table on device '%1'." ).arg( m_device->deviceNode() ), report.toText() ); + } + + QScopedPointer< CoreBackendPartition > backendPartition( + ( partition()->roles().has( PartitionRole::Extended ) ) + ? backendPartitionTable->getExtendedPartition() + : backendPartitionTable->getPartitionBySector( partition()->firstSector() ) ); + if ( !backendPartition.data() ) + { + return Calamares::JobResult::error( tr( "Could not find partition '%1'." ).arg( partition()->partitionPath() ), + report.toText() ); + } + + FileSystem& fs = m_partition->fileSystem(); + fs.setLabel( m_label ); + + if ( !backendPartitionTable->setPartitionSystemType( report, *m_partition ) ) + { + return Calamares::JobResult::error( + tr( "The installer failed to update partition table on disk '%1'." ).arg( m_device->name() ), + report.toText() ); + } + + backendPartitionTable->commit(); + return Calamares::JobResult::ok(); +} + + +#include "ChangeFilesystemLabelJob.moc" diff --git a/src/modules/partition/jobs/ChangeFilesystemLabelJob.h b/src/modules/partition/jobs/ChangeFilesystemLabelJob.h new file mode 100644 index 000000000..ac3960538 --- /dev/null +++ b/src/modules/partition/jobs/ChangeFilesystemLabelJob.h @@ -0,0 +1,40 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2016, Lisa Vitolo + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Calamares is Free Software: see the License-Identifier above. + * + */ + +#ifndef CHANGEFILESYSTEMLABELJOB_H +#define CHANGEFILESYSTEMLABELJOB_H + +#include "PartitionJob.h" + +#include + +class Device; +class Partition; + +/** + * This job changes the flags on an existing partition. + */ +class ChangeFilesystemLabelJob : public PartitionJob +{ + Q_OBJECT +public: + ChangeFilesystemLabelJob( Device* device, Partition* partition, const QString& newLabel ); + QString prettyName() const override; + QString prettyDescription() const override; + QString prettyStatusMessage() const override; + Calamares::JobResult exec() override; + + Device* device() const; + +private: + Device* m_device; + QString m_label; +}; + +#endif // CHANGEFILESYSTEMLABELJOB_H diff --git a/src/modules/partition/jobs/CreatePartitionJob.cpp b/src/modules/partition/jobs/CreatePartitionJob.cpp index 2b6451c3e..b4d89c5eb 100644 --- a/src/modules/partition/jobs/CreatePartitionJob.cpp +++ b/src/modules/partition/jobs/CreatePartitionJob.cpp @@ -33,7 +33,7 @@ CreatePartitionJob::CreatePartitionJob( Device* device, Partition* partition ) { } -static const QMap < QString, QString > gptTypePrettyStrings = { +static const QMap< QString, QString > gptTypePrettyStrings = { { "44479540-f297-41b2-9af7-d131d5f0458a", "Linux Root Partition (x86)" }, { "4f68bce3-e8cd-4db1-96e7-fbcaf984b709", "Linux Root Partition (x86-64)" }, { "69dad710-2ce4-4e3c-b16c-21a1d49abed3", "Linux Root Partition (32-bit ARM)" }, @@ -115,17 +115,17 @@ CreatePartitionJob::prettyName() const if ( !entries.isEmpty() ) { return tr( "Create new %1MiB partition on %3 (%2) with entries %4." ) - .arg( CalamaresUtils::BytesToMiB( m_partition->capacity() ) ) - .arg( m_device->name() ) - .arg( m_device->deviceNode() ) - .arg( entries ); + .arg( CalamaresUtils::BytesToMiB( m_partition->capacity() ) ) + .arg( m_device->name() ) + .arg( m_device->deviceNode() ) + .arg( entries ); } else { return tr( "Create new %1MiB partition on %3 (%2)." ) - .arg( CalamaresUtils::BytesToMiB( m_partition->capacity() ) ) - .arg( m_device->name() ) - .arg( m_device->deviceNode() ); + .arg( CalamaresUtils::BytesToMiB( m_partition->capacity() ) ) + .arg( m_device->name() ) + .arg( m_device->deviceNode() ); } } @@ -146,18 +146,19 @@ CreatePartitionJob::prettyDescription() const QString entries = prettyGptEntries( m_partition ); if ( !entries.isEmpty() ) { - return tr( "Create new %1MiB partition on %3 (%2) with entries %4." ) - .arg( CalamaresUtils::BytesToMiB( m_partition->capacity() ) ) - .arg( m_device->name() ) - .arg( m_device->deviceNode() ) - .arg( entries ); + return tr( "Create new %1MiB partition on %3 (%2) with entries " + "%4." ) + .arg( CalamaresUtils::BytesToMiB( m_partition->capacity() ) ) + .arg( m_device->name() ) + .arg( m_device->deviceNode() ) + .arg( entries ); } else { return tr( "Create new %1MiB partition on %3 (%2)." ) - .arg( CalamaresUtils::BytesToMiB( m_partition->capacity() ) ) - .arg( m_device->name() ) - .arg( m_device->deviceNode() ); + .arg( CalamaresUtils::BytesToMiB( m_partition->capacity() ) ) + .arg( m_device->name() ) + .arg( m_device->deviceNode() ); } } @@ -186,9 +187,7 @@ CreatePartitionJob::prettyStatusMessage() const type = userVisibleFS( m_partition->fileSystem() ); } - return tr( "Creating new %1 partition on %2." ) - .arg( type ) - .arg( m_device->deviceNode() ); + return tr( "Creating new %1 partition on %2." ).arg( type ).arg( m_device->deviceNode() ); } return tr( "Creating new %1 partition on %2." ) diff --git a/src/modules/partition/tests/AutoMountTests.cpp b/src/modules/partition/tests/AutoMountTests.cpp index fcebe02bd..45a7b4f12 100644 --- a/src/modules/partition/tests/AutoMountTests.cpp +++ b/src/modules/partition/tests/AutoMountTests.cpp @@ -9,8 +9,8 @@ #include "jobs/AutoMountManagementJob.h" -#include "utils/Logger.h" #include "JobQueue.h" +#include "utils/Logger.h" #include #include @@ -52,7 +52,8 @@ AutoMountJobTests::testRunThrice() CalamaresUtils::Partition::automountRestore( original ); } -void AutoMountJobTests::testRunQueue() +void +AutoMountJobTests::testRunQueue() { Calamares::JobQueue q; Calamares::job_ptr jp( new AutoMountManagementJob( false ) ); @@ -68,8 +69,8 @@ void AutoMountJobTests::testRunQueue() QVERIFY( !q.isRunning() ); QEventLoop loop; - QTimer::singleShot( std::chrono::milliseconds( 100 ), [&q](){ q.start(); } ); - QTimer::singleShot( std::chrono::milliseconds( 5000 ), [&loop](){ loop.quit(); } ); + QTimer::singleShot( std::chrono::milliseconds( 100 ), [&q]() { q.start(); } ); + QTimer::singleShot( std::chrono::milliseconds( 5000 ), [&loop]() { loop.quit(); } ); connect( &q, &Calamares::JobQueue::finished, &loop, &QEventLoop::quit ); loop.exec(); diff --git a/src/modules/partition/tests/PartitionJobTests.cpp b/src/modules/partition/tests/PartitionJobTests.cpp index 57dc2579c..4dddf4377 100644 --- a/src/modules/partition/tests/PartitionJobTests.cpp +++ b/src/modules/partition/tests/PartitionJobTests.cpp @@ -377,6 +377,7 @@ PartitionJobTests::testResizePartition() *m_device, PartitionRole( PartitionRole::Primary ), FileSystem::Ext4, + QStringLiteral( "testp" ), oldFirst, oldLast, KPM_PARTITION_FLAG( None ) );