diff --git a/src/modules/partition/CMakeLists.txt b/src/modules/partition/CMakeLists.txt index e5c78819f..e73402ce0 100644 --- a/src/modules/partition/CMakeLists.txt +++ b/src/modules/partition/CMakeLists.txt @@ -55,6 +55,7 @@ calamares_add_plugin( partition jobs/MoveFileSystemJob.cpp jobs/PartitionJob.cpp jobs/ResizePartitionJob.cpp + jobs/SetPartitionFlagsJob.cpp UI gui/ChoicePage.ui gui/CreatePartitionDialog.ui diff --git a/src/modules/partition/jobs/SetPartitionFlagsJob.cpp b/src/modules/partition/jobs/SetPartitionFlagsJob.cpp new file mode 100644 index 000000000..c2304d16f --- /dev/null +++ b/src/modules/partition/jobs/SetPartitionFlagsJob.cpp @@ -0,0 +1,156 @@ +/* === This file is part of Calamares - === + * + * Copyright 2016, Teo Mrnjavac + * + * Based on the SetPartFlagsJob class from KDE Partition Manager, + * Copyright 2008, 2010, Volker Lanz + * + * Calamares is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Calamares is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Calamares. If not, see . + */ + +#include "SetPartitionFlagsJob.h" + +#include "utils/Logger.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +SetPartFlagsJob::SetPartFlagsJob( Device* device, + Partition* partition, + PartitionTable::Flags flags ) + : PartitionJob( partition ) + , m_device( device ) + , m_flags( flags ) +{} + + +QString +SetPartFlagsJob::prettyName() const +{ + return tr( "Set flags on partition %1." ).arg( partition()->partitionPath() ); +} + + +QString +SetPartFlagsJob::prettyDescription() const +{ + QStringList flagsList = PartitionTable::flagNames( m_flags ); + if ( flagsList.count() == 0 ) + return tr( "Clear flags on partition %1." ) + .arg( partition()->partitionPath() ); + + return tr( "Flag partition %1 as " + "%2." ) + .arg( partition()->partitionPath() ) + .arg( flagsList.join( ", " ) ); +} + + +QString +SetPartFlagsJob::prettyStatusMessage() const +{ + QStringList flagsList = PartitionTable::flagNames( m_flags ); + if ( flagsList.count() == 0 ) + return tr( "Clearing flags on partition %1." ) + .arg( partition()->partitionPath() ); + + return tr( "Setting flags %2 on partition " + "%1." ) + .arg( partition()->partitionPath() ) + .arg( flagsList.join( ", " ) ); +} + + +Calamares::JobResult +SetPartFlagsJob::exec() +{ + PartitionTable::Flags oldFlags = partition()->availableFlags(); + if ( oldFlags == m_flags ) + 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() ) + ); + } + + quint32 count = 0; + + foreach( const PartitionTable::Flag& f, PartitionTable::flagList() ) + { + emit progress(++count); + + const bool state = ( m_flags & f ) ? true : false; + + Report report( nullptr ); + if ( !backendPartition->setFlag( report, f, state ) ) + { + cDebug() << QStringLiteral( "WARNING: Could not set flag %2 on " + "partition '%1'." ) + .arg( partition()->partitionPath() ) + .arg( PartitionTable::flagName( f ) ); + } + } + + // HACK: Partition (in KPMcore) declares SetPartFlagsJob as friend, but this actually + // refers to an unrelated class SetPartFlagsJob which is in KPMcore but is not + // exported. + // Obviously here we are relying on having a class in Calamares with the same + // name as a private one in KPMcore, which is awful, but it's the least evil + // way to call Partition::setFlags (KPMcore's SetPartFlagsJob needs its friend + // status for the very same reason). + m_partition->setFlags( m_flags ); + + backendPartitionTable->commit(); + + return Calamares::JobResult::ok(); +} + + +#include "SetPartitionFlagsJob.moc" diff --git a/src/modules/partition/jobs/SetPartitionFlagsJob.h b/src/modules/partition/jobs/SetPartitionFlagsJob.h new file mode 100644 index 000000000..0b1914f7f --- /dev/null +++ b/src/modules/partition/jobs/SetPartitionFlagsJob.h @@ -0,0 +1,52 @@ +/* === This file is part of Calamares - === + * + * Copyright 2016, Teo Mrnjavac + * + * Based on the SetPartFlagsJob class from KDE Partition Manager, + * Copyright 2008, 2010, Volker Lanz + * + * Calamares is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Calamares is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Calamares. If not, see . + */ + +#ifndef SETPARTITIONFLAGSJOB_H +#define SETPARTITIONFLAGSJOB_H + +#include + +#include + +class Device; +class Partition; + +/** + * This job changes the flags on an existing partition. + */ +class SetPartFlagsJob : public PartitionJob +{ + Q_OBJECT +public: + SetPartFlagsJob( Device* device, Partition* partition, PartitionTable::Flags flags ); + QString prettyName() const override; + QString prettyDescription() const override; + QString prettyStatusMessage() const override; + Calamares::JobResult exec() override; + + Device* device() const; + +private: + Device* m_device; + PartitionTable::Flags m_flags; +}; + +#endif // SETPARTITIONFLAGSJOB_H