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/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index 3b5c09362..0ef4dca56 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,15 @@ 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 ) { diff --git a/src/modules/partition/core/PartitionCoreModule.h b/src/modules/partition/core/PartitionCoreModule.h index 46604b97c..47353530b 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/gui/EditExistingPartitionDialog.cpp b/src/modules/partition/gui/EditExistingPartitionDialog.cpp index 6c724bea2..7a4ea138f 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 ) { @@ -70,9 +74,6 @@ EditExistingPartitionDialog::EditExistingPartitionDialog( Device* device, m_ui->fileSystemLabel->setEnabled( doFormat ); m_ui->fileSystemComboBox->setEnabled( doFormat ); - m_ui->fileSystemLabelEdit->setEnabled( doFormat ); - m_ui->fileSystemLabelEdit->setText( m_partition->fileSystem().label() ); - if ( !doFormat ) { m_ui->fileSystemComboBox->setCurrentText( userVisibleFS( m_partition->fileSystem() ) ); @@ -195,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 { @@ -220,6 +222,13 @@ 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/jobs/ChangeFilesystemLabelJob.cpp b/src/modules/partition/jobs/ChangeFilesystemLabelJob.cpp new file mode 100644 index 000000000..54420e96c --- /dev/null +++ b/src/modules/partition/jobs/ChangeFilesystemLabelJob.cpp @@ -0,0 +1,106 @@ +/* === 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(); + } + + CoreBackend* backend = CoreBackendManager::self()->backend(); + + QString errorMessage = tr( "The installer failed to set flags on partition %1." ) + .arg( m_partition->partitionPath() ); + + QScopedPointer< CoreBackendDevice > backendDevice( backend->openDevice( m_device->deviceNode() ) ); + if ( !backendDevice.data() ) + { + return Calamares::JobResult::error( + errorMessage, + tr( "Could not open device '%1'." ).arg( m_device->deviceNode() ) + ); + } + + QScopedPointer< CoreBackendPartitionTable > backendPartitionTable( backendDevice->openPartitionTable() ); + if ( !backendPartitionTable.data() ) + { + return Calamares::JobResult::error( + errorMessage, + tr( "Could not open partition table on device '%1'." ).arg( m_device->deviceNode() ) + ); + } + + QScopedPointer< CoreBackendPartition > backendPartition( + ( partition()->roles().has( PartitionRole::Extended ) ) + ? backendPartitionTable->getExtendedPartition() + : backendPartitionTable->getPartitionBySector( partition()->firstSector() ) + ); + if ( !backendPartition.data() ) { + return Calamares::JobResult::error( + errorMessage, + tr( "Could not find partition '%1'." ).arg( partition()->partitionPath() ) + ); + } + + FileSystem& fs = m_partition->fileSystem(); + fs.setLabel( m_label ); + + 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..3d8982c15 --- /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