diff --git a/src/modules/partition/CMakeLists.txt b/src/modules/partition/CMakeLists.txt index 0323af79c..663ba8913 100644 --- a/src/modules/partition/CMakeLists.txt +++ b/src/modules/partition/CMakeLists.txt @@ -31,6 +31,7 @@ calamares_add_plugin( partition EditExistingPartitionDialog.cpp FillGlobalStorageJob.cpp FormatPartitionJob.cpp + MoveFileSystemJob.cpp PartitionCoreModule.cpp PartitionInfo.cpp PartitionIterator.cpp diff --git a/src/modules/partition/MoveFileSystemJob.cpp b/src/modules/partition/MoveFileSystemJob.cpp new file mode 100644 index 000000000..f704cb14c --- /dev/null +++ b/src/modules/partition/MoveFileSystemJob.cpp @@ -0,0 +1,125 @@ +/* === This file is part of Calamares - === + * + * Copyright 2014, Aurélien Gâteau + * + * 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 . + */ + +// This class is heavily based on the MoveFileSystemJob class from KDE Partition +// Manager. Original copyright follow: + +/*************************************************************************** + * Copyright (C) 2008 by Volker Lanz * + * * + * This program 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 2 of the License, or * + * (at your option) any later version. * + * * + * This program 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 this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include + +// CalaPM +#include +#include +#include +#include +#include +#include + +static bool +copyBlocks( Report& report, CopyTargetDevice& target, CopySourceDevice& source ) +{ + return false; +} + +static bool +rollbackCopyBlocks( Report& report, CopyTargetDevice& target, CopySourceDevice& source ) +{ + return false; +} + +MoveFileSystemJob::MoveFileSystemJob( Device* device, Partition* partition, qint64 firstSector ) + : PartitionJob( partition ) + , m_device( device ) + , m_firstSector( firstSector ) +{} + +QString +MoveFileSystemJob::prettyName() const +{ + return tr( "Moving file system of partition %1." ).arg( partition()->partitionPath() ); +} + +Calamares::JobResult +MoveFileSystemJob::exec() +{ + Report report( nullptr ); + QString partitionPath = partition()->partitionPath(); + FileSystem& fs = partition()->fileSystem(); + CopySourceDevice moveSource( *m_device, fs.firstSector(), fs.lastSector() ); + CopyTargetDevice moveTarget( *m_device, m_firstSector, m_firstSector + fs.length() ); + + if ( !moveSource.open() ) + return Calamares::JobResult::error( + QString(), + tr( "Could not open file system on partition %1 for moving." ).arg( partitionPath ) + ); + + if ( !moveTarget.open() ) + return Calamares::JobResult::error( + QString(), + tr( "Could not create target for moving file system on partition %1." ).arg( partitionPath ) + ); + + bool ok = copyBlocks( report, moveTarget, moveSource ); + if ( !ok ) + { + if ( rollbackCopyBlocks( report, moveTarget, moveSource ) ) + return Calamares::JobResult::error( + QString(), + tr( "Moving of partition %1 failed, changes have been rolled back." ).arg( partitionPath ) + + '\n' + report.toText() + ); + else + return Calamares::JobResult::error( + QString(), + tr( "Moving of partition %1 failed. Roll back of the changes have failed." ).arg( partitionPath ) + + '\n' + report.toText() + ); + } + + const qint64 savedLength = fs.length(); + fs.setFirstSector( m_firstSector ); + fs.setLastSector( m_firstSector + savedLength - 1 ); + + if ( !fs.updateBootSector( report, partitionPath ) ) + return Calamares::JobResult::error( + QString(), + tr( "Updating boot sector after the moving of partition %1 failed." ).arg( partitionPath ) + + '\n' + report.toText() + ); + + return Calamares::JobResult::ok(); +} diff --git a/src/modules/partition/MoveFileSystemJob.h b/src/modules/partition/MoveFileSystemJob.h new file mode 100644 index 000000000..38c34ad83 --- /dev/null +++ b/src/modules/partition/MoveFileSystemJob.h @@ -0,0 +1,62 @@ +/* === This file is part of Calamares - === + * + * Copyright 2014, Aurélien Gâteau + * + * 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 . + */ + +// This class is heavily based on the MoveFileSystemJob class from KDE Partition +// Manager. Original copyright follow: + +/*************************************************************************** + * Copyright (C) 2008 by Volker Lanz * + * * + * This program 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 2 of the License, or * + * (at your option) any later version. * + * * + * This program 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 this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ +#ifndef MOVEFILESYSTEMJOB_H +#define MOVEFILESYSTEMJOB_H + +#include + +class Device; +class Partition; + +class MoveFileSystemJob : public PartitionJob +{ +public: + MoveFileSystemJob( Device* device, Partition* partition, qint64 firstSector ); + + QString prettyName() const override; + + Calamares::JobResult exec() override; + +private: + Device* m_device; + qint64 m_firstSector; +}; + +#endif /* MOVEFILESYSTEMJOB_H */ diff --git a/src/modules/partition/ResizePartitionJob.cpp b/src/modules/partition/ResizePartitionJob.cpp index 7c67bba8d..dc1c06d2d 100644 --- a/src/modules/partition/ResizePartitionJob.cpp +++ b/src/modules/partition/ResizePartitionJob.cpp @@ -40,7 +40,7 @@ #include -//#include +#include // CalaPM #include @@ -50,10 +50,6 @@ #include #include #include -/* -#include -#include -*/ #include // Qt @@ -71,7 +67,6 @@ struct Context qint64 oldLastSector; QScopedPointer< CoreBackendPartitionTable > backendPartitionTable; - QString errorMessage; }; //- ResizeFileSystemJob -------------------------------------------------------- @@ -101,7 +96,7 @@ public: case FileSystem::cmdSupportBackend: if ( !backendResize( &report ) ) return Calamares::JobResult::error( - m_context->errorMessage, + QString(), tr( "Parted failed to resize filesystem." ) + '\n' + report.toText() ); break; @@ -111,7 +106,7 @@ public: bool ok = fs.resize( report, partition->partitionPath(), byteLength ); if ( !ok ) return Calamares::JobResult::error( - m_context->errorMessage, + QString(), tr( "Failed to resize filesystem." ) + '\n' + report.toText() ); break; @@ -163,7 +158,7 @@ public: if ( !ok ) { return Calamares::JobResult::error( - m_context->errorMessage, + QString(), tr( "Failed to change the geometry of the partition." ) + '\n' + report.toText() ); } partition->setFirstSector( m_firstSector ); @@ -178,24 +173,6 @@ private: qint64 m_length; }; -//- MoveFileSystemJob ---------------------------------------------------------- -class MoveFileSystemJob : public Calamares::Job -{ -public: - MoveFileSystemJob( Context* context, qint64 firstSector ) - {} - - QString prettyName() const override - { - return QString(); - } - - Calamares::JobResult exec() override - { - return Calamares::JobResult::ok(); - } -}; - //- ResizePartitionJob --------------------------------------------------------- ResizePartitionJob::ResizePartitionJob( Device* device, Partition* partition, qint64 firstSector, qint64 lastSector ) : PartitionJob( partition ) @@ -231,14 +208,13 @@ ResizePartitionJob::exec() Context context( this ); context.oldFirstSector = m_oldFirstSector; context.oldLastSector = m_oldLastSector; - context.errorMessage = tr( "The installer failed to resize partition %1 on disk '%2'." ).arg( partitionPath, m_device->name() ); CoreBackend* backend = CoreBackendManager::self()->backend(); QScopedPointer backendDevice( backend->openDevice( m_device->deviceNode() ) ); if ( !backendDevice.data() ) { return Calamares::JobResult::error( - context.errorMessage, + QString(), tr( "Could not open device '%1'." ).arg( m_device->deviceNode() ) ); } @@ -265,7 +241,7 @@ ResizePartitionJob::exec() // shrunk, or to the original length (it may or may not then later be grown, we don't care here) const qint64 length = shrink ? newLength : oldLength; jobs << Calamares::job_ptr( new SetPartGeometryJob( &context, m_newFirstSector, length ) ); - jobs << Calamares::job_ptr( new MoveFileSystemJob( &context, m_newFirstSector ) ); + jobs << Calamares::job_ptr( new MoveFileSystemJob( m_device, m_partition, m_newFirstSector ) ); } if ( grow ) { @@ -290,13 +266,21 @@ ResizePartitionJob::updatePreview() Calamares::JobResult ResizePartitionJob::execJobList( const QList< Calamares::job_ptr >& jobs ) { + QString errorMessage = tr( "The installer failed to resize partition %1 on disk '%2'." ) + .arg( m_partition->partitionPath() ) + .arg( m_device->name() ); + int nbJobs = jobs.size(); int count = 0; for ( Calamares::job_ptr job : jobs ) { Calamares::JobResult result = job->exec(); if ( !result ) + { + if ( result.message().isEmpty() ) + result.setMessage( errorMessage ); return result; + } ++count; progress( qreal( count ) / nbJobs ); } diff --git a/src/modules/partition/tests/CMakeLists.txt b/src/modules/partition/tests/CMakeLists.txt index aa1663f43..65e64af57 100644 --- a/src/modules/partition/tests/CMakeLists.txt +++ b/src/modules/partition/tests/CMakeLists.txt @@ -5,6 +5,7 @@ set( jobtests_SRCS ${PartitionModule_SOURCE_DIR}/CreatePartitionJob.cpp ${PartitionModule_SOURCE_DIR}/CreatePartitionTableJob.cpp ${PartitionModule_SOURCE_DIR}/DeletePartitionJob.cpp + ${PartitionModule_SOURCE_DIR}/MoveFileSystemJob.cpp ${PartitionModule_SOURCE_DIR}/PartitionInfo.cpp ${PartitionModule_SOURCE_DIR}/PartitionIterator.cpp ${PartitionModule_SOURCE_DIR}/PartitionJob.cpp