From 4d5eb90a04a175adb3d2e9493bd754cbdd4411f6 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 14 Sep 2018 07:56:18 -0400 Subject: [PATCH 01/33] [fsresize] Add new module fsresizer - Non-functional as yet, WIP - Intended for use on SBC images and similar, which need to resize the root partition to the size of the SD card they're on. FIXES #921 --- src/modules/fsresizer/CMakeLists.txt | 27 +++++++ src/modules/fsresizer/ResizeFSJob.cpp | 104 ++++++++++++++++++++++++++ src/modules/fsresizer/ResizeFSJob.h | 75 +++++++++++++++++++ src/modules/fsresizer/fsresizer.conf | 30 ++++++++ 4 files changed, 236 insertions(+) create mode 100644 src/modules/fsresizer/CMakeLists.txt create mode 100644 src/modules/fsresizer/ResizeFSJob.cpp create mode 100644 src/modules/fsresizer/ResizeFSJob.h create mode 100644 src/modules/fsresizer/fsresizer.conf diff --git a/src/modules/fsresizer/CMakeLists.txt b/src/modules/fsresizer/CMakeLists.txt new file mode 100644 index 000000000..7d1760cc4 --- /dev/null +++ b/src/modules/fsresizer/CMakeLists.txt @@ -0,0 +1,27 @@ +find_package(ECM ${ECM_VERSION} REQUIRED NO_MODULE) + +find_package( KPMcore 3.3 ) +find_package( Qt5 REQUIRED DBus ) # Needed for KPMCore +find_package( KF5 REQUIRED I18n WidgetsAddons ) # Needed for KPMCore + +if ( KPMcore_FOUND ) + if ( KPMcore_VERSION VERSION_GREATER "3.3.0") + add_definitions(-DWITH_KPMCOREGT33) # kpmcore greater than 3.3 + endif() + + include_directories( ${KPMCORE_INCLUDE_DIR} ) + include_directories( ${PROJECT_BINARY_DIR}/src/libcalamares ) + + calamares_add_plugin( fsresizer + TYPE job + EXPORT_MACRO PLUGINDLLEXPORT_PRO + SOURCES + ResizeFSJob.cpp + LINK_PRIVATE_LIBRARIES + kpmcore + calamares + SHARED_LIB + ) +else() + calamares_skip_module( "fsresizer (missing suitable KPMcore)" ) +endif() diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp new file mode 100644 index 000000000..4a7b0da59 --- /dev/null +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -0,0 +1,104 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Adriaan de Groot + * + * 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 "ResizeFSJob.h" + +#include +#include +#include + +#include "CalamaresVersion.h" +#include "JobQueue.h" +#include "GlobalStorage.h" + +#include "utils/Logger.h" + +ResizeFSJob::RelativeSize::RelativeSize() + : m_unit( None ) + , m_value( 0 ) +{ +} + + +ResizeFSJob::RelativeSize::RelativeSize( const QString& s) + : m_unit( None ) + , m_value( 0 ) +{ + QString valuePart; + + if ( s.endsWith( '%' ) ) + { + valuePart = s.left( s.length() - 1 ); + m_unit = Percent; + } + if ( s.endsWith( "MiB" ) ) + { + valuePart = s.left( s.length() - 3 ); + m_unit = Absolute; + } + + if ( ( m_unit != None ) && !valuePart.isEmpty() ) + m_value = valuePart.toInt(); + + if ( !m_value ) + m_unit = None; +} + + +ResizeFSJob::ResizeFSJob( QObject* parent ) + : Calamares::CppJob( parent ) +{ +} + + +ResizeFSJob::~ResizeFSJob() +{ +} + + +QString +ResizeFSJob::prettyName() const +{ + return tr( "Resize Filesystem Job" ); +} + + +Calamares::JobResult +ResizeFSJob::exec() +{ + return Calamares::JobResult::ok(); +} + + +void +ResizeFSJob::setConfigurationMap( const QVariantMap& configurationMap ) +{ + m_fsname = configurationMap["fs"].toString(); + m_devicename = configurationMap["dev"].toString(); + + if ( m_fsname.isEmpty() && m_devicename.isEmpty() ) + { + cWarning() << "No fs or dev configured for resize."; + return; + } + + m_size = RelativeSize( configurationMap["size"].toString() ); + m_atleast = RelativeSize( configurationMap["atleast"].toString() ); +} + +CALAMARES_PLUGIN_FACTORY_DEFINITION( ResizeFSJobFactory, registerPlugin(); ) diff --git a/src/modules/fsresizer/ResizeFSJob.h b/src/modules/fsresizer/ResizeFSJob.h new file mode 100644 index 000000000..681328f81 --- /dev/null +++ b/src/modules/fsresizer/ResizeFSJob.h @@ -0,0 +1,75 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Adriaan de Groot + * + * 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 RESIZEFSJOB_H +#define RESIZEFSJOB_H + +#include +#include + +#include + +#include + +#include + +class PLUGINDLLEXPORT ResizeFSJob : public Calamares::CppJob +{ + Q_OBJECT + + class RelativeSize + { + public: + RelativeSize(); + RelativeSize( const QString& ); + + enum Unit + { + None, + Percent, + Absolute + }; + + quint64 value() const { return m_value; } + Unit unit() const { return m_unit; } + + private: + quint64 m_value; + Unit m_unit; + } ; + +public: + explicit ResizeFSJob( QObject* parent = nullptr ); + virtual ~ResizeFSJob() override; + + QString prettyName() const override; + + Calamares::JobResult exec() override; + + void setConfigurationMap( const QVariantMap& configurationMap ) override; + +private: + RelativeSize m_size; + RelativeSize m_atleast; + QString m_fsname; // Either this, or devicename, is set, not both + QString m_devicename; +}; + +CALAMARES_PLUGIN_FACTORY_DECLARATION( ResizeFSJobFactory ) + +#endif // RESIZEFSJOB_H diff --git a/src/modules/fsresizer/fsresizer.conf b/src/modules/fsresizer/fsresizer.conf new file mode 100644 index 000000000..1539a7751 --- /dev/null +++ b/src/modules/fsresizer/fsresizer.conf @@ -0,0 +1,30 @@ +# Module that resizes a single FS to fill the entire (rest) of +# a device. This is used in OEM situations where an image is +# flashed onto an SD card (or similar) and used to boot a device, +# after which the FS should expand to fill the SD card. +# +# Example: a distro produces a 6GiB large image that is +# written to an 8GiB SD card; the FS should expand to take +# advantage of the unused 2GiB. The FS should expand much +# more if the same image is written to a 16GiB card. +-- + +# Which FS needs to be grown? Choose one way to identify it: +# - *fs* names a mount point which should already be mounted +# in the system. +# - *dev* names a device +fs: / +# dev: /dev/mmcblk0p1 + +# How much of the total remaining space should the FS use? +# The only sensible amount is "all of it". The value is +# in percent, so set it to 100. Perhaps a fixed size is +# needed (that would be weird though, since you don't know +# how big the card is), use MiB as suffix in that case. +size: 100% + +# Resizing might not be worth it, though. Set the minimum +# that it must grow; if it cannot grow that much, the +# resizing is skipped. Can be in percentage or absolute +# size, as above. +atleast: 1000MiB From fa567f917af80653f4c5aaa35b994590a766f344 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 14 Sep 2018 16:45:24 +0200 Subject: [PATCH 02/33] Changelog: explain new module --- CHANGES | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES b/CHANGES index 56526aad2..f4d86a0e2 100644 --- a/CHANGES +++ b/CHANGES @@ -11,6 +11,11 @@ This release contains contributions from (alphabetically by first name): ## Modules ## + - New module *fsresizer* can be used to resize filesystems. It is intended + for use in OEM installs where an image of fixed size is created, + and then sized to the actual SD card the user has used. + + # 3.2.2 (2018-09-04) # This release contains contributions from (alphabetically by first name): From cdfb55e5cf70c098c83245761bc79f84b4626f71 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 14 Sep 2018 16:49:07 +0200 Subject: [PATCH 03/33] [fsresizer] Just right now it doesn't need KPMCore - Drop the dependency while developing the configuration parser part of the module and writing initial tests. --- src/modules/fsresizer/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/fsresizer/CMakeLists.txt b/src/modules/fsresizer/CMakeLists.txt index 7d1760cc4..5097c53b0 100644 --- a/src/modules/fsresizer/CMakeLists.txt +++ b/src/modules/fsresizer/CMakeLists.txt @@ -4,7 +4,7 @@ find_package( KPMcore 3.3 ) find_package( Qt5 REQUIRED DBus ) # Needed for KPMCore find_package( KF5 REQUIRED I18n WidgetsAddons ) # Needed for KPMCore -if ( KPMcore_FOUND ) +if ( 1 ) # KPMcore_FOUND ) if ( KPMcore_VERSION VERSION_GREATER "3.3.0") add_definitions(-DWITH_KPMCOREGT33) # kpmcore greater than 3.3 endif() @@ -18,7 +18,7 @@ if ( KPMcore_FOUND ) SOURCES ResizeFSJob.cpp LINK_PRIVATE_LIBRARIES - kpmcore + # kpmcore calamares SHARED_LIB ) From a81588190a161b7232690717db8ee6dcbffe8e9f Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 14 Sep 2018 16:51:09 +0200 Subject: [PATCH 04/33] [fsresizer] Simplify and make safer - Make RelativeSize public so we can use it in non-member functions - Make a template out of matching the string suffixes; this is safer because the length of the suffix can be computed at compile-time (+1 for the trailing NUL) rather than writing it out in boilerplate. --- src/modules/fsresizer/ResizeFSJob.cpp | 42 +++++++++++++++------------ src/modules/fsresizer/ResizeFSJob.h | 6 ++-- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index 4a7b0da59..e10894c30 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -29,32 +29,36 @@ #include "utils/Logger.h" ResizeFSJob::RelativeSize::RelativeSize() - : m_unit( None ) - , m_value( 0 ) + : m_value( 0 ) + , m_unit( None ) { } -ResizeFSJob::RelativeSize::RelativeSize( const QString& s) - : m_unit( None ) - , m_value( 0 ) +template +void matchUnitSuffix( + const QString& s, + const char (&suffix)[N], + ResizeFSJob::RelativeSize::Unit matchedUnit, + int& value, + ResizeFSJob::RelativeSize::Unit& unit + ) { - QString valuePart; - - if ( s.endsWith( '%' ) ) + if ( s.endsWith( suffix ) ) { - valuePart = s.left( s.length() - 1 ); - m_unit = Percent; + value = s.left( s.length() - N + 1 ).toInt(); + unit = matchedUnit; } - if ( s.endsWith( "MiB" ) ) - { - valuePart = s.left( s.length() - 3 ); - m_unit = Absolute; - } - - if ( ( m_unit != None ) && !valuePart.isEmpty() ) - m_value = valuePart.toInt(); - +} + + +ResizeFSJob::RelativeSize::RelativeSize( const QString& s) + : m_value( 0 ) + , m_unit( None ) +{ + matchUnitSuffix( s, "%", Percent, m_value, m_unit ); + matchUnitSuffix( s, "MiB", Absolute, m_value, m_unit ); + if ( !m_value ) m_unit = None; } diff --git a/src/modules/fsresizer/ResizeFSJob.h b/src/modules/fsresizer/ResizeFSJob.h index 681328f81..415d04c81 100644 --- a/src/modules/fsresizer/ResizeFSJob.h +++ b/src/modules/fsresizer/ResizeFSJob.h @@ -32,6 +32,7 @@ class PLUGINDLLEXPORT ResizeFSJob : public Calamares::CppJob { Q_OBJECT +public: class RelativeSize { public: @@ -45,15 +46,14 @@ class PLUGINDLLEXPORT ResizeFSJob : public Calamares::CppJob Absolute }; - quint64 value() const { return m_value; } + int value() const { return m_value; } Unit unit() const { return m_unit; } private: - quint64 m_value; + int m_value; Unit m_unit; } ; -public: explicit ResizeFSJob( QObject* parent = nullptr ); virtual ~ResizeFSJob() override; From a6c3899e10c28a366e6b27ae4b5bcce33f4a1e1f Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 14 Sep 2018 17:59:50 +0200 Subject: [PATCH 05/33] [fsresizer] Add tests - Test the parsing of configuration values, that it gets the right values when given correct(-ish) configurations. Doesn't test any situations with bad config. --- src/modules/fsresizer/CMakeLists.txt | 22 ++++- src/modules/fsresizer/Tests.cpp | 126 +++++++++++++++++++++++++++ src/modules/fsresizer/Tests.h | 39 +++++++++ 3 files changed, 185 insertions(+), 2 deletions(-) create mode 100644 src/modules/fsresizer/Tests.cpp create mode 100644 src/modules/fsresizer/Tests.h diff --git a/src/modules/fsresizer/CMakeLists.txt b/src/modules/fsresizer/CMakeLists.txt index 5097c53b0..c3585bbcd 100644 --- a/src/modules/fsresizer/CMakeLists.txt +++ b/src/modules/fsresizer/CMakeLists.txt @@ -1,5 +1,3 @@ -find_package(ECM ${ECM_VERSION} REQUIRED NO_MODULE) - find_package( KPMcore 3.3 ) find_package( Qt5 REQUIRED DBus ) # Needed for KPMCore find_package( KF5 REQUIRED I18n WidgetsAddons ) # Needed for KPMCore @@ -22,6 +20,26 @@ if ( 1 ) # KPMcore_FOUND ) calamares SHARED_LIB ) + + if( ECM_FOUND ) + find_package( Qt5 COMPONENTS Test REQUIRED ) + include( ECMAddTests ) + + ecm_add_test( + Tests.cpp + TEST_NAME + fsresizertest + LINK_LIBRARIES + ${CALAMARES_LIBRARIES} + calamares + calamares_job_fsresizer # From above + ${YAMLCPP_LIBRARY} + Qt5::Core + Qt5::Test + ) + set_target_properties( fsresizertest PROPERTIES AUTOMOC TRUE ) + target_include_directories(fsresizertest PRIVATE /usr/local/include ) + endif() else() calamares_skip_module( "fsresizer (missing suitable KPMcore)" ) endif() diff --git a/src/modules/fsresizer/Tests.cpp b/src/modules/fsresizer/Tests.cpp new file mode 100644 index 000000000..255153fa2 --- /dev/null +++ b/src/modules/fsresizer/Tests.cpp @@ -0,0 +1,126 @@ +/* === This file is part of Calamares - === + * + * Copyright 2017-2018, Adriaan de Groot + * + * 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 "Tests.h" + +#include "GlobalStorage.h" +#include "JobQueue.h" +#include "Settings.h" + +#include "utils/Logger.h" +#include "utils/YamlUtils.h" + +#include + +#include + +#include +#include + +#define private public +#include "ResizeFSJob.h" +#undef private + +QTEST_GUILESS_MAIN( FSResizerTests ) + +FSResizerTests::FSResizerTests() +{ +} + +FSResizerTests::~FSResizerTests() +{ +} + +void +FSResizerTests::initTestCase() +{ +} + +void FSResizerTests::testConfigurationRobust() +{ + ResizeFSJob j; + + // Empty config + j.setConfigurationMap( QVariantMap() ); + QVERIFY( j.m_fsname.isEmpty() ); + QVERIFY( j.m_devicename.isEmpty() ); + QCOMPARE( j.m_size.unit(), ResizeFSJob::RelativeSize::None ); + QCOMPARE( j.m_atleast.unit(), ResizeFSJob::RelativeSize::None ); + + // Config is missing fs and dev, so it isn't valid + YAML::Node doc0 = YAML::Load( R"(--- +size: 100% +atleast: 600MiB +)" ); + j.setConfigurationMap( CalamaresUtils::yamlMapToVariant( doc0 ).toMap() ); + QVERIFY( j.m_fsname.isEmpty() ); + QVERIFY( j.m_devicename.isEmpty() ); + QCOMPARE( j.m_size.unit(), ResizeFSJob::RelativeSize::None ); + QCOMPARE( j.m_atleast.unit(), ResizeFSJob::RelativeSize::None ); + QCOMPARE( j.m_size.value(), 0 ); + QCOMPARE( j.m_atleast.value(), 0 ); +} + +void FSResizerTests::testConfigurationValues() +{ + ResizeFSJob j; + + // Check both + YAML::Node doc0 = YAML::Load( R"(--- +fs: / +size: 100% +atleast: 600MiB +)" ); + j.setConfigurationMap( CalamaresUtils::yamlMapToVariant( doc0 ).toMap() ); + QVERIFY( !j.m_fsname.isEmpty() ); + QVERIFY( j.m_devicename.isEmpty() ); + QCOMPARE( j.m_size.unit(), ResizeFSJob::RelativeSize::Percent ); + QCOMPARE( j.m_atleast.unit(), ResizeFSJob::RelativeSize::Absolute ); + QCOMPARE( j.m_size.value(), 100 ); + QCOMPARE( j.m_atleast.value(), 600 ); + + // Silly config + doc0 = YAML::Load( R"(--- +fs: / +dev: /dev/m00 +size: 72 MiB +atleast: 127 % +)" ); + j.setConfigurationMap( CalamaresUtils::yamlMapToVariant( doc0 ).toMap() ); + QVERIFY( !j.m_fsname.isEmpty() ); + QVERIFY( !j.m_devicename.isEmpty() ); + QCOMPARE( j.m_size.unit(), ResizeFSJob::RelativeSize::Absolute ); + QCOMPARE( j.m_atleast.unit(), ResizeFSJob::RelativeSize::Percent ); + QCOMPARE( j.m_size.value(), 72 ); + QCOMPARE( j.m_atleast.value(), 127 ); + + // Silly config + doc0 = YAML::Load( R"(--- +fs: / +# dev: /dev/m00 +size: 71MiB +# atleast: 127% +)" ); + j.setConfigurationMap( CalamaresUtils::yamlMapToVariant( doc0 ).toMap() ); + QVERIFY( !j.m_fsname.isEmpty() ); + QVERIFY( j.m_devicename.isEmpty() ); + QCOMPARE( j.m_size.unit(), ResizeFSJob::RelativeSize::Absolute ); + QCOMPARE( j.m_atleast.unit(), ResizeFSJob::RelativeSize::None ); + QCOMPARE( j.m_size.value(), 71 ); + QCOMPARE( j.m_atleast.value(), 0 ); +} diff --git a/src/modules/fsresizer/Tests.h b/src/modules/fsresizer/Tests.h new file mode 100644 index 000000000..958c0e655 --- /dev/null +++ b/src/modules/fsresizer/Tests.h @@ -0,0 +1,39 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Adriaan de Groot + * + * 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 TESTS_H +#define TESTS_H + +#include + +class FSResizerTests : public QObject +{ + Q_OBJECT +public: + FSResizerTests(); + ~FSResizerTests() override; + +private Q_SLOTS: + void initTestCase(); + // Can handle missing values + void testConfigurationRobust(); + // Can parse % and MiB values + void testConfigurationValues(); +}; + +#endif From 745629b659997f15f272cc6bfa2d31ea7a3b284c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Sep 2018 06:58:18 -0400 Subject: [PATCH 06/33] [fsresizer] Turn on KPMCore requirement again --- src/modules/fsresizer/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/fsresizer/CMakeLists.txt b/src/modules/fsresizer/CMakeLists.txt index c3585bbcd..ae87de160 100644 --- a/src/modules/fsresizer/CMakeLists.txt +++ b/src/modules/fsresizer/CMakeLists.txt @@ -2,7 +2,7 @@ find_package( KPMcore 3.3 ) find_package( Qt5 REQUIRED DBus ) # Needed for KPMCore find_package( KF5 REQUIRED I18n WidgetsAddons ) # Needed for KPMCore -if ( 1 ) # KPMcore_FOUND ) +if ( KPMcore_FOUND ) if ( KPMcore_VERSION VERSION_GREATER "3.3.0") add_definitions(-DWITH_KPMCOREGT33) # kpmcore greater than 3.3 endif() @@ -16,7 +16,7 @@ if ( 1 ) # KPMcore_FOUND ) SOURCES ResizeFSJob.cpp LINK_PRIVATE_LIBRARIES - # kpmcore + kpmcore calamares SHARED_LIB ) From 40e031411c50e35ce54af3adc26c68e59fce9881 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 20 Sep 2018 07:01:27 -0400 Subject: [PATCH 07/33] [calamares] Improve debug log in module test-loader --- src/calamares/testmain.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/calamares/testmain.cpp b/src/calamares/testmain.cpp index c22342f9a..86f971462 100644 --- a/src/calamares/testmain.cpp +++ b/src/calamares/testmain.cpp @@ -158,7 +158,7 @@ main( int argc, char* argv[] ) std::unique_ptr< Calamares::Settings > settings_p( new Calamares::Settings( QString(), true ) ); std::unique_ptr< Calamares::JobQueue > jobqueue_p( new Calamares::JobQueue( nullptr ) ); - cDebug() << "Calamares test module-loader" << module.moduleName(); + cDebug() << "Calamares module-loader testing" << module.moduleName(); Calamares::Module* m = load_module( module ); if ( !m ) { @@ -175,13 +175,19 @@ main( int argc, char* argv[] ) return 1; } - cDebug() << "Module" << m->name() << m->typeString() << m->interfaceString(); + using TR = Logger::DebugRow; + cDebug() << "Module metadata" + << TR( "name", m->name() ) + << TR( "type", m->typeString() ) + << TR( "interface", m->interfaceString() ); + + cDebug() << "Job outputs:"; Calamares::JobList jobList = m->jobs(); unsigned int count = 1; for ( const auto& p : jobList ) { - cDebug() << count << p->prettyName(); + cDebug() << "Job #" << count << "name" << p->prettyName(); Calamares::JobResult r = p->exec(); if ( !r ) cDebug() << count << ".. failed" << r; From c6e8cdf65b2de2f148ee4e82817149848fd09326 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 20 Sep 2018 07:07:17 -0400 Subject: [PATCH 08/33] [calamares] Better command-line help in module test-loader --- src/calamares/testmain.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/calamares/testmain.cpp b/src/calamares/testmain.cpp index 86f971462..8efdfd80d 100644 --- a/src/calamares/testmain.cpp +++ b/src/calamares/testmain.cpp @@ -59,6 +59,7 @@ handle_args( QCoreApplication& a ) parser.addOption( debugLevelOption ); parser.addPositionalArgument( "module", "Path or name of module to run." ); + parser.addPositionalArgument( "config", "Path of job-config file to use.", "[config]"); parser.process( a ); @@ -140,6 +141,8 @@ load_module( const ModuleConfig& moduleConfig ) ? moduleDirectory + '/' + name + ".conf" : moduleConfig.configFile() ); + cDebug() << "Module" << moduleName << "job-configuration:" << configFile; + Calamares::Module* module = Calamares::Module::fromDescriptor( descriptor, name, configFile, moduleDirectory ); From 39a0d2315b2a31f22242bbfb3622636bd8d5c028 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 20 Sep 2018 07:39:43 -0400 Subject: [PATCH 09/33] [calamares] Better config-loading diagnostics - Be more verbose when things go wrong while loading module- configuration files. - Allow more forms of paths to be specified. In debug mode, this is mostyle helpful for the module test-loader. --- src/libcalamaresui/modulesystem/Module.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/libcalamaresui/modulesystem/Module.cpp b/src/libcalamaresui/modulesystem/Module.cpp index 8d92c37ad..a1349c280 100644 --- a/src/libcalamaresui/modulesystem/Module.cpp +++ b/src/libcalamaresui/modulesystem/Module.cpp @@ -145,8 +145,15 @@ moduleConfigurationCandidates( bool assumeBuildDir, const QString& moduleName, c paths << CalamaresUtils::appDataDir().absoluteFilePath( QString( "modules/%1" ).arg( configFileName ) ); else { + // If an absolute path is given, in debug mode, look for it + // first. The case contains('/'), below, will add the absolute + // path a second time, though. + if ( assumeBuildDir && configFileName.startsWith( '/' ) ) + paths << configFileName; if ( assumeBuildDir ) paths << QDir().absoluteFilePath(QString( "src/modules/%1/%2" ).arg( moduleName ).arg( configFileName ) ); + if ( assumeBuildDir && configFileName.contains( '/' ) ) + paths << QDir().absoluteFilePath( configFileName ); paths << QString( "/etc/calamares/modules/%1" ).arg( configFileName ); paths << CalamaresUtils::appDataDir().absoluteFilePath( QString( "modules/%1" ).arg( configFileName ) ); @@ -168,6 +175,7 @@ Module::loadConfigurationFile( const QString& configFileName ) //throws YAML::Ex YAML::Node doc = YAML::Load( ba.constData() ); if ( doc.IsNull() ) { + cDebug() << "Found empty module configuration" << path; // Special case: empty config files are valid, // but aren't a map. return; @@ -178,14 +186,13 @@ Module::loadConfigurationFile( const QString& configFileName ) //throws YAML::Ex return; } + cDebug() << "Loaded module configuration" << path; m_configurationMap = CalamaresUtils::yamlMapToVariant( doc ).toMap(); m_emergency = m_maybe_emergency && m_configurationMap.contains( EMERGENCY ) && m_configurationMap[ EMERGENCY ].toBool(); return; } - else - continue; } } From bf092de76fdc913e718620c2b7acf7d946848e23 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 20 Sep 2018 07:48:06 -0400 Subject: [PATCH 10/33] [calamares] Explain config-file failures better --- src/modules/test_conf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/test_conf.cpp b/src/modules/test_conf.cpp index b5362d25a..ca6b72cc7 100644 --- a/src/modules/test_conf.cpp +++ b/src/modules/test_conf.cpp @@ -87,7 +87,7 @@ int main(int argc, char** argv) if ( !doc.IsMap() ) { cerr << "WARNING:" << filename << '\n'; - cerr << "WARNING: not-a-YAML-map\n"; + cerr << "WARNING: not-a-YAML-map (type=" << doc.Type() << ")\n"; return 1; } From 3b8fa187e1679a0b7134e6e2df969d17f3c7cfff Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 20 Sep 2018 07:49:49 -0400 Subject: [PATCH 11/33] [fsresizer] Fix syntax error in YAML --- src/modules/fsresizer/fsresizer.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/fsresizer/fsresizer.conf b/src/modules/fsresizer/fsresizer.conf index 1539a7751..5a5700a79 100644 --- a/src/modules/fsresizer/fsresizer.conf +++ b/src/modules/fsresizer/fsresizer.conf @@ -7,7 +7,7 @@ # written to an 8GiB SD card; the FS should expand to take # advantage of the unused 2GiB. The FS should expand much # more if the same image is written to a 16GiB card. --- +--- # Which FS needs to be grown? Choose one way to identify it: # - *fs* names a mount point which should already be mounted From a32149bd927a2c138e0f46d7df6d5ba495528ce7 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 20 Sep 2018 08:02:43 -0400 Subject: [PATCH 12/33] CI: run tests after build as well --- ci/travis-continuous.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ci/travis-continuous.sh b/ci/travis-continuous.sh index eccb6743e..e0bbf1351 100755 --- a/ci/travis-continuous.sh +++ b/ci/travis-continuous.sh @@ -51,4 +51,6 @@ df -h echo "# Install results" install_debugging "$DESTDIR" -$result # Result of make install, above +$result || { echo "! Install failed" ; exit 1 ; } # Result of make install, above + +make test From b0db4780bfb09716b31cf293ac3fe7af1de5c810 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 20 Sep 2018 15:13:43 +0200 Subject: [PATCH 13/33] CI: be more chatty while running tests --- ci/travis-continuous.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ci/travis-continuous.sh b/ci/travis-continuous.sh index e0bbf1351..647d460b8 100755 --- a/ci/travis-continuous.sh +++ b/ci/travis-continuous.sh @@ -53,4 +53,8 @@ install_debugging "$DESTDIR" $result || { echo "! Install failed" ; exit 1 ; } # Result of make install, above -make test +echo "# Running tests" +find . -name test_conf +find . -name loadmodule +ctest -V + From 499dd2ce838a330b8f0f01aad7d24a24547622e0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 20 Sep 2018 15:38:26 +0200 Subject: [PATCH 14/33] [fsresizer] Document configuration - Add some notes on configuration of fsresizer - Convenience methods for checking validity. --- src/modules/fsresizer/ResizeFSJob.cpp | 5 +++++ src/modules/fsresizer/ResizeFSJob.h | 17 +++++++++++++++++ src/modules/fsresizer/fsresizer.conf | 5 ++++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index e10894c30..925301e42 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -85,6 +85,11 @@ ResizeFSJob::prettyName() const Calamares::JobResult ResizeFSJob::exec() { + if ( !isValid() ) + return Calamares::JobResult::error( + tr( "Invalid configuration" ), + tr( "The file-system resize job has an invalid configuration " + "and will not run." ) ); return Calamares::JobResult::ok(); } diff --git a/src/modules/fsresizer/ResizeFSJob.h b/src/modules/fsresizer/ResizeFSJob.h index 415d04c81..6308f12ed 100644 --- a/src/modules/fsresizer/ResizeFSJob.h +++ b/src/modules/fsresizer/ResizeFSJob.h @@ -33,6 +33,12 @@ class PLUGINDLLEXPORT ResizeFSJob : public Calamares::CppJob Q_OBJECT public: + /** @brief Size expressions + * + * Sizes can be specified in MiB or percent (of the device they + * are on). This class handles parsing of such strings from the + * config file. + */ class RelativeSize { public: @@ -49,6 +55,11 @@ public: int value() const { return m_value; } Unit unit() const { return m_unit; } + constexpr bool isValid() const + { + return ( unit() != None ) && ( value() > 0 ); + } + private: int m_value; Unit m_unit; @@ -63,6 +74,12 @@ public: void setConfigurationMap( const QVariantMap& configurationMap ) override; + constexpr bool isValid() const + { + return ( !m_fsname.isEmpty() || !m_devicename.isEmpty() ) && + m_size.isValid(); + } + private: RelativeSize m_size; RelativeSize m_atleast; diff --git a/src/modules/fsresizer/fsresizer.conf b/src/modules/fsresizer/fsresizer.conf index 5a5700a79..f02983e45 100644 --- a/src/modules/fsresizer/fsresizer.conf +++ b/src/modules/fsresizer/fsresizer.conf @@ -21,10 +21,13 @@ fs: / # in percent, so set it to 100. Perhaps a fixed size is # needed (that would be weird though, since you don't know # how big the card is), use MiB as suffix in that case. +# If missing, then it's assumed to be 0, and no resizing +# will happen. size: 100% # Resizing might not be worth it, though. Set the minimum # that it must grow; if it cannot grow that much, the # resizing is skipped. Can be in percentage or absolute -# size, as above. +# size, as above. If missing, then it's assumed to be 0, +# which means resizing is always worthwhile. atleast: 1000MiB From a40864f70974d4bd8f22ca1118d98621bfb61b32 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 20 Sep 2018 15:40:26 +0200 Subject: [PATCH 15/33] CI: mess around with running tests --- ci/travis-continuous.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ci/travis-continuous.sh b/ci/travis-continuous.sh index 647d460b8..b8a1c8548 100755 --- a/ci/travis-continuous.sh +++ b/ci/travis-continuous.sh @@ -56,5 +56,10 @@ $result || { echo "! Install failed" ; exit 1 ; } # Result of make install, abov echo "# Running tests" find . -name test_conf find . -name loadmodule +./test_conf --help +$BUILDDIR/test_conf --help +/build/test_conf --help + +echo "# Running ctest" ctest -V From 45195b9f7ed17b508d662bfa2887a81fd4c1136e Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 20 Sep 2018 10:34:46 -0400 Subject: [PATCH 16/33] [fsresizer] Remove over-enthusiastic constexpr --- src/modules/fsresizer/ResizeFSJob.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/modules/fsresizer/ResizeFSJob.h b/src/modules/fsresizer/ResizeFSJob.h index 6308f12ed..85ed98cdc 100644 --- a/src/modules/fsresizer/ResizeFSJob.h +++ b/src/modules/fsresizer/ResizeFSJob.h @@ -34,7 +34,7 @@ class PLUGINDLLEXPORT ResizeFSJob : public Calamares::CppJob public: /** @brief Size expressions - * + * * Sizes can be specified in MiB or percent (of the device they * are on). This class handles parsing of such strings from the * config file. @@ -55,11 +55,11 @@ public: int value() const { return m_value; } Unit unit() const { return m_unit; } - constexpr bool isValid() const + bool isValid() const { return ( unit() != None ) && ( value() > 0 ); } - + private: int m_value; Unit m_unit; @@ -74,12 +74,12 @@ public: void setConfigurationMap( const QVariantMap& configurationMap ) override; - constexpr bool isValid() const + bool isValid() const { return ( !m_fsname.isEmpty() || !m_devicename.isEmpty() ) && m_size.isValid(); } - + private: RelativeSize m_size; RelativeSize m_atleast; From bc732ccbc70420cc7d023b90defc53ac81dafdab Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 20 Sep 2018 10:53:46 -0400 Subject: [PATCH 17/33] CI: mess around with test-application permissions --- ci/travis-continuous.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ci/travis-continuous.sh b/ci/travis-continuous.sh index b8a1c8548..04e8c2ca2 100755 --- a/ci/travis-continuous.sh +++ b/ci/travis-continuous.sh @@ -54,11 +54,10 @@ install_debugging "$DESTDIR" $result || { echo "! Install failed" ; exit 1 ; } # Result of make install, above echo "# Running tests" -find . -name test_conf -find . -name loadmodule -./test_conf --help +ls -la $BUILDDIR/test_conf +chmod 755 $BUILDDIR/test_conf $BUILDDIR/test_conf --help -/build/test_conf --help +ls -la $BUILDDIR/test_conf echo "# Running ctest" ctest -V From 579f1dfee7fa6e8cce272be24b85b95acf253caa Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 20 Sep 2018 11:07:56 -0400 Subject: [PATCH 18/33] CI: don't try to run tests. - permissions on the tmpfs where everything is built, prevents the test-applications from running. --- ci/travis-continuous.sh | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/ci/travis-continuous.sh b/ci/travis-continuous.sh index 04e8c2ca2..1b3841e54 100755 --- a/ci/travis-continuous.sh +++ b/ci/travis-continuous.sh @@ -52,13 +52,3 @@ echo "# Install results" install_debugging "$DESTDIR" $result || { echo "! Install failed" ; exit 1 ; } # Result of make install, above - -echo "# Running tests" -ls -la $BUILDDIR/test_conf -chmod 755 $BUILDDIR/test_conf -$BUILDDIR/test_conf --help -ls -la $BUILDDIR/test_conf - -echo "# Running ctest" -ctest -V - From 428929b64f1059ed44fba3fb470ddbb8dc9e03f0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 22 Sep 2018 11:11:19 -0400 Subject: [PATCH 19/33] [fsresizer] Tiny step towards getting data from KPMcore --- src/modules/fsresizer/ResizeFSJob.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index 925301e42..490010e0c 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -22,6 +22,9 @@ #include #include +#include +#include + #include "CalamaresVersion.h" #include "JobQueue.h" #include "GlobalStorage.h" @@ -36,8 +39,8 @@ ResizeFSJob::RelativeSize::RelativeSize() template -void matchUnitSuffix( - const QString& s, +void matchUnitSuffix( + const QString& s, const char (&suffix)[N], ResizeFSJob::RelativeSize::Unit matchedUnit, int& value, @@ -50,15 +53,15 @@ void matchUnitSuffix( unit = matchedUnit; } } - - + + ResizeFSJob::RelativeSize::RelativeSize( const QString& s) : m_value( 0 ) , m_unit( None ) { matchUnitSuffix( s, "%", Percent, m_value, m_unit ); matchUnitSuffix( s, "MiB", Absolute, m_value, m_unit ); - + if ( !m_value ) m_unit = None; } @@ -85,11 +88,18 @@ ResizeFSJob::prettyName() const Calamares::JobResult ResizeFSJob::exec() { + auto backend_p = CoreBackendManager::self()->backend(); + if ( backend_p ) + cDebug() << "KPMCore backend @" << (void *)backend_p << backend_p->id() << backend_p->version(); + else + cDebug() << "No KPMCore backend"; + if ( !isValid() ) return Calamares::JobResult::error( tr( "Invalid configuration" ), tr( "The file-system resize job has an invalid configuration " "and will not run." ) ); + return Calamares::JobResult::ok(); } From 35ca813064ce9ad76045ee01e0e0cc632ea0f108 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 25 Sep 2018 06:34:03 -0400 Subject: [PATCH 20/33] [partition] Use "" for including from current directory --- src/modules/partition/core/PartitionIterator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/partition/core/PartitionIterator.cpp b/src/modules/partition/core/PartitionIterator.cpp index 5ed48fd91..8301835c6 100644 --- a/src/modules/partition/core/PartitionIterator.cpp +++ b/src/modules/partition/core/PartitionIterator.cpp @@ -18,7 +18,7 @@ * along with Calamares. If not, see . */ -#include +#include "PartitionIterator.h" // KPMcore #include From 06a00a15c68c9711f72ccbb2a357b61b0c1b2725 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 25 Sep 2018 06:39:14 -0400 Subject: [PATCH 21/33] [fsresizer] Scan for devices, list partitions - The is just debugging output, but it's the start of what needs to happen to find the FS that needs resizing. --- src/modules/fsresizer/CMakeLists.txt | 5 +++- src/modules/fsresizer/ResizeFSJob.cpp | 39 ++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/modules/fsresizer/CMakeLists.txt b/src/modules/fsresizer/CMakeLists.txt index ae87de160..9f0234406 100644 --- a/src/modules/fsresizer/CMakeLists.txt +++ b/src/modules/fsresizer/CMakeLists.txt @@ -10,17 +10,20 @@ if ( KPMcore_FOUND ) include_directories( ${KPMCORE_INCLUDE_DIR} ) include_directories( ${PROJECT_BINARY_DIR}/src/libcalamares ) + # The PartitionIterator is a small class, and it's easiest -- but also a + # gross hack -- to just compile it again from the partition module tree. calamares_add_plugin( fsresizer TYPE job EXPORT_MACRO PLUGINDLLEXPORT_PRO SOURCES ResizeFSJob.cpp + ${PROJECT_SOURCE_DIR}/src/modules/partition/core/PartitionIterator.cpp LINK_PRIVATE_LIBRARIES kpmcore calamares SHARED_LIB ) - + if( ECM_FOUND ) find_package( Qt5 COMPONENTS Test REQUIRED ) include( ECMAddTests ) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index 490010e0c..e3820e535 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -24,6 +24,8 @@ #include #include +#include +#include #include "CalamaresVersion.h" #include "JobQueue.h" @@ -31,6 +33,8 @@ #include "utils/Logger.h" +#include "modules/partition/core/PartitionIterator.h" + ResizeFSJob::RelativeSize::RelativeSize() : m_value( 0 ) , m_unit( None ) @@ -92,7 +96,40 @@ ResizeFSJob::exec() if ( backend_p ) cDebug() << "KPMCore backend @" << (void *)backend_p << backend_p->id() << backend_p->version(); else - cDebug() << "No KPMCore backend"; + { + cDebug() << "No KPMCore backend loaded yet"; + QByteArray backendName = qgetenv( "KPMCORE_BACKEND" ); + if ( !CoreBackendManager::self()->load( backendName.isEmpty() ? CoreBackendManager::defaultBackendName() : backendName ) ) + { + cWarning() << "Could not load KPMCore backend."; + return Calamares::JobResult::error( + tr( "KPMCore not Available" ), + tr( "Calamares cannot start KPMCore for the file-system resize job." ) ); + } + + backend_p = CoreBackendManager::self()->backend(); + } + if ( !backend_p ) + { + cWarning() << "Could not load KPMCore backend (2)."; + return Calamares::JobResult::error( + tr( "KPMCore not Available" ), + tr( "Calamares cannot start KPMCore for the file-system resize job." ) ); + } + + using DeviceList = QList< Device* >; + DeviceList devices = backend_p->scanDevices( false ); + cDebug() << "ResizeFSJob found" << devices.count() << "devices."; + for ( DeviceList::iterator it = devices.begin(); it != devices.end(); ) + { + if ( ! (*it) ) + continue; + cDebug() << "ResizeFSJob found" << ( *it )->deviceNode(); + for ( auto pit = PartitionIterator::begin( *it); pit != PartitionIterator::end( *it); ++pit ) + { + cDebug() << ".." << ( *pit )->mountPoint(); + } + } if ( !isValid() ) return Calamares::JobResult::error( From aae4b38e6979c84ac888d7cde3f68533199f47e0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 27 Sep 2018 03:44:39 -0400 Subject: [PATCH 22/33] [fsresizer] Fix endless loop - Improve variable names - Missing iterator++ --- src/modules/fsresizer/ResizeFSJob.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index e3820e535..06429699b 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -120,14 +120,14 @@ ResizeFSJob::exec() using DeviceList = QList< Device* >; DeviceList devices = backend_p->scanDevices( false ); cDebug() << "ResizeFSJob found" << devices.count() << "devices."; - for ( DeviceList::iterator it = devices.begin(); it != devices.end(); ) + for ( DeviceList::iterator dev_it = devices.begin(); dev_it != devices.end(); ++dev_it ) { - if ( ! (*it) ) + if ( ! (*dev_it) ) continue; - cDebug() << "ResizeFSJob found" << ( *it )->deviceNode(); - for ( auto pit = PartitionIterator::begin( *it); pit != PartitionIterator::end( *it); ++pit ) + cDebug() << "ResizeFSJob found" << ( *dev_it )->deviceNode(); + for ( auto part_it = PartitionIterator::begin( *dev_it); part_it != PartitionIterator::end( *dev_it ); ++part_it ) { - cDebug() << ".." << ( *pit )->mountPoint(); + cDebug() << ".." << ( *part_it )->mountPoint(); } } From 1c2714d832ac832fff008f4615e92c66f9db595a Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 27 Sep 2018 03:56:57 -0400 Subject: [PATCH 23/33] [fsresizer] Match configuration to system - Bail out earlier before doing any work if the configuration is invalid. - If it's valid, look for a matching device. --- src/modules/fsresizer/ResizeFSJob.cpp | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index 06429699b..cf2ea47f6 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -92,6 +92,13 @@ ResizeFSJob::prettyName() const Calamares::JobResult ResizeFSJob::exec() { + if ( !isValid() ) + return Calamares::JobResult::error( + tr( "Invalid configuration" ), + tr( "The file-system resize job has an invalid configuration " + "and will not run." ) ); + + // Get KPMCore auto backend_p = CoreBackendManager::self()->backend(); if ( backend_p ) cDebug() << "KPMCore backend @" << (void *)backend_p << backend_p->id() << backend_p->version(); @@ -117,6 +124,9 @@ ResizeFSJob::exec() tr( "Calamares cannot start KPMCore for the file-system resize job." ) ); } + Device* resize_this_device = nullptr; + Partition* resize_this_partition = nullptr; + using DeviceList = QList< Device* >; DeviceList devices = backend_p->scanDevices( false ); cDebug() << "ResizeFSJob found" << devices.count() << "devices."; @@ -127,16 +137,18 @@ ResizeFSJob::exec() cDebug() << "ResizeFSJob found" << ( *dev_it )->deviceNode(); for ( auto part_it = PartitionIterator::begin( *dev_it); part_it != PartitionIterator::end( *dev_it ); ++part_it ) { - cDebug() << ".." << ( *part_it )->mountPoint(); + cDebug() << ".." << ( *part_it )->mountPoint() << "on" << ( *part_it )->deviceNode(); + if ( ( !m_fsname.isEmpty() && ( *part_it )->mountPoint() == m_fsname ) || + ( !m_devicename.isEmpty() && ( *part_it )->deviceNode() == m_devicename ) ) + { + resize_this_device = ( *dev_it ); + resize_this_partition = ( *part_it ); + cDebug() << ".. matched configuration dev=" << m_devicename << "fs=" << m_fsname; + break; + } } } - if ( !isValid() ) - return Calamares::JobResult::error( - tr( "Invalid configuration" ), - tr( "The file-system resize job has an invalid configuration " - "and will not run." ) ); - return Calamares::JobResult::ok(); } From 9e1c95ad056f4794b7e73bd4b9e09d7dad79bd38 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 27 Sep 2018 04:10:25 -0400 Subject: [PATCH 24/33] [fsresizer] Refactor finding device - Find device in separate function - If device isn't found, bail out --- src/modules/fsresizer/ResizeFSJob.cpp | 56 +++++++++++++++------------ src/modules/fsresizer/ResizeFSJob.h | 9 +++++ 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index cf2ea47f6..68fd166e7 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -88,6 +88,32 @@ ResizeFSJob::prettyName() const return tr( "Resize Filesystem Job" ); } +ResizeFSJob::PartitionMatch +ResizeFSJob::findPartition( CoreBackend* backend ) +{ + using DeviceList = QList< Device* >; + DeviceList devices = backend->scanDevices( false ); + cDebug() << "ResizeFSJob found" << devices.count() << "devices."; + for ( DeviceList::iterator dev_it = devices.begin(); dev_it != devices.end(); ++dev_it ) + { + if ( ! (*dev_it) ) + continue; + cDebug() << "ResizeFSJob found" << ( *dev_it )->deviceNode(); + for ( auto part_it = PartitionIterator::begin( *dev_it); part_it != PartitionIterator::end( *dev_it ); ++part_it ) + { + cDebug() << ".." << ( *part_it )->mountPoint() << "on" << ( *part_it )->deviceNode(); + if ( ( !m_fsname.isEmpty() && ( *part_it )->mountPoint() == m_fsname ) || + ( !m_devicename.isEmpty() && ( *part_it )->deviceNode() == m_devicename ) ) + { + cDebug() << ".. matched configuration dev=" << m_devicename << "fs=" << m_fsname; + return PartitionMatch( *dev_it, *part_it ); + } + } + } + + cDebug() << "No match for configuration dev=" << m_devicename << "fs=" << m_fsname; + return PartitionMatch( nullptr, nullptr ); +} Calamares::JobResult ResizeFSJob::exec() @@ -124,30 +150,12 @@ ResizeFSJob::exec() tr( "Calamares cannot start KPMCore for the file-system resize job." ) ); } - Device* resize_this_device = nullptr; - Partition* resize_this_partition = nullptr; - - using DeviceList = QList< Device* >; - DeviceList devices = backend_p->scanDevices( false ); - cDebug() << "ResizeFSJob found" << devices.count() << "devices."; - for ( DeviceList::iterator dev_it = devices.begin(); dev_it != devices.end(); ++dev_it ) - { - if ( ! (*dev_it) ) - continue; - cDebug() << "ResizeFSJob found" << ( *dev_it )->deviceNode(); - for ( auto part_it = PartitionIterator::begin( *dev_it); part_it != PartitionIterator::end( *dev_it ); ++part_it ) - { - cDebug() << ".." << ( *part_it )->mountPoint() << "on" << ( *part_it )->deviceNode(); - if ( ( !m_fsname.isEmpty() && ( *part_it )->mountPoint() == m_fsname ) || - ( !m_devicename.isEmpty() && ( *part_it )->deviceNode() == m_devicename ) ) - { - resize_this_device = ( *dev_it ); - resize_this_partition = ( *part_it ); - cDebug() << ".. matched configuration dev=" << m_devicename << "fs=" << m_fsname; - break; - } - } - } + PartitionMatch m = findPartition( backend_p ); + if ( !m.first || !m.second ) + return Calamares::JobResult::error( + tr( "Resize Failed" ), + m_fsname.isEmpty() ? tr( "The filesystem %1 could not be found in this system, and can not be resized." ).arg(m_fsname) + : tr( "The device %1 could not be found in this system, and can not be resized." ).arg(m_devicename) ); return Calamares::JobResult::ok(); } diff --git a/src/modules/fsresizer/ResizeFSJob.h b/src/modules/fsresizer/ResizeFSJob.h index 85ed98cdc..72b28e690 100644 --- a/src/modules/fsresizer/ResizeFSJob.h +++ b/src/modules/fsresizer/ResizeFSJob.h @@ -28,6 +28,10 @@ #include +class CoreBackend; // From KPMCore +class Device; // From KPMCore +class Partition; + class PLUGINDLLEXPORT ResizeFSJob : public Calamares::CppJob { Q_OBJECT @@ -74,6 +78,7 @@ public: void setConfigurationMap( const QVariantMap& configurationMap ) override; + /** @brief Is the configuration of this job valid? */ bool isValid() const { return ( !m_fsname.isEmpty() || !m_devicename.isEmpty() ) && @@ -85,6 +90,10 @@ private: RelativeSize m_atleast; QString m_fsname; // Either this, or devicename, is set, not both QString m_devicename; + + using PartitionMatch = QPair; + /** @brief Find the configured FS using KPMCore @p backend */ + PartitionMatch findPartition( CoreBackend* backend ); }; CALAMARES_PLUGIN_FACTORY_DECLARATION( ResizeFSJobFactory ) From 9124281bcbe6addaf7da5546d1639a09f61a4fd5 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 27 Sep 2018 05:28:20 -0400 Subject: [PATCH 25/33] [fsresizer] Calculate resize parameters - apply() a relativesize to a device to find out how much it means in sectors - find the space into which the configured FS can grow. --- src/modules/fsresizer/ResizeFSJob.cpp | 82 ++++++++++++++++++++++++++- src/modules/fsresizer/ResizeFSJob.h | 12 ++++ 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index 68fd166e7..e3744661d 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -26,12 +26,14 @@ #include #include #include +#include #include "CalamaresVersion.h" #include "JobQueue.h" #include "GlobalStorage.h" #include "utils/Logger.h" +#include "utils/Units.h" #include "modules/partition/core/PartitionIterator.h" @@ -70,6 +72,26 @@ ResizeFSJob::RelativeSize::RelativeSize( const QString& s) m_unit = None; } +qint64 +ResizeFSJob::RelativeSize::apply( Device* d ) +{ + if ( !isValid() ) + return -1; + + switch( m_unit ) + { + case None: + return -1; + case Absolute: + return CalamaresUtils::MiBtoBytes( value() ) / d->logicalSize(); + case Percent: + return d->logicalSize() * value() / 100; + } + + // notreached + return -1; +} + ResizeFSJob::ResizeFSJob( QObject* parent ) : Calamares::CppJob( parent ) @@ -99,7 +121,7 @@ ResizeFSJob::findPartition( CoreBackend* backend ) if ( ! (*dev_it) ) continue; cDebug() << "ResizeFSJob found" << ( *dev_it )->deviceNode(); - for ( auto part_it = PartitionIterator::begin( *dev_it); part_it != PartitionIterator::end( *dev_it ); ++part_it ) + for ( auto part_it = PartitionIterator::begin( *dev_it ); part_it != PartitionIterator::end( *dev_it ); ++part_it ) { cDebug() << ".." << ( *part_it )->mountPoint() << "on" << ( *part_it )->deviceNode(); if ( ( !m_fsname.isEmpty() && ( *part_it )->mountPoint() == m_fsname ) || @@ -115,6 +137,51 @@ ResizeFSJob::findPartition( CoreBackend* backend ) return PartitionMatch( nullptr, nullptr ); } +qint64 +ResizeFSJob::findGrownEnd(ResizeFSJob::PartitionMatch m) +{ + if ( !m.first || !m.second ) + return -1; + if ( !ResizeOperation::canGrow( m.second ) ) + return -1; + + qint64 last_available = m.first->totalLogical(); + cDebug() << "Containing device size" << last_available; + qint64 last_currently = m.second->lastSector(); + cDebug() << "Growing partition" << m.second->firstSector() << '-' << last_currently; + + for ( auto part_it = PartitionIterator::begin( m.first ); part_it != PartitionIterator::end( m.first ); ++part_it ) + { + qint64 next_start = ( *part_it )->firstSector(); + cDebug() << ".. comparing" << next_start << '-' << ( *part_it )->lastSector(); + if ( (next_start > last_currently) && (next_start < last_available) ) + { + cDebug() << " .. shrunk last available to" << next_start; + last_available = next_start - 1; // Before that one starts + } + } + + if ( !( last_available > last_currently ) ) + { + cDebug() << "Partition can not grow larger."; + return -1; + } + + qint64 expand = last_available - last_currently; // number of sectors + if ( m_atleast.isValid() ) + { + qint64 required = m_atleast.apply( m.first ); + if ( expand < required ) + { + cDebug() << ".. need to expand by" << required << "but only" << expand << "is available."; + return -1; + } + } + + return last_available; +} + + Calamares::JobResult ResizeFSJob::exec() { @@ -157,6 +224,19 @@ ResizeFSJob::exec() m_fsname.isEmpty() ? tr( "The filesystem %1 could not be found in this system, and can not be resized." ).arg(m_fsname) : tr( "The device %1 could not be found in this system, and can not be resized." ).arg(m_devicename) ); + if ( !ResizeOperation::canGrow( m.second ) ) + { + cDebug() << "canGrow() returned false."; + return Calamares::JobResult::error( + tr( "Resize Failed" ), + m_fsname.isEmpty() ? tr( "The filesystem %1 can not be resized." ).arg(m_fsname) + : tr( "The device %1 can not be resized." ).arg(m_devicename) ); + } + + cDebug() << "Resize from" << m.second->firstSector() + << '+' << m.second->length() << '=' << m.second->lastSector() + << "to" << findGrownEnd( m ); + return Calamares::JobResult::ok(); } diff --git a/src/modules/fsresizer/ResizeFSJob.h b/src/modules/fsresizer/ResizeFSJob.h index 72b28e690..36527ab56 100644 --- a/src/modules/fsresizer/ResizeFSJob.h +++ b/src/modules/fsresizer/ResizeFSJob.h @@ -64,6 +64,15 @@ public: return ( unit() != None ) && ( value() > 0 ); } + /** @brief Apply this size to the given device @p d + * + * For invalid sizes, returns -1. + * For absolute sizes, returns the number of sectors needed. + * For percent sizes, returns the number of sectors matching + * that percentage of the device size. + */ + qint64 apply( Device* d ); + private: int m_value; Unit m_unit; @@ -94,6 +103,9 @@ private: using PartitionMatch = QPair; /** @brief Find the configured FS using KPMCore @p backend */ PartitionMatch findPartition( CoreBackend* backend ); + + /** @brief Return a new end-sector for the given dev-part pair. */ + qint64 findGrownEnd( PartitionMatch ); }; CALAMARES_PLUGIN_FACTORY_DECLARATION( ResizeFSJobFactory ) From 2556891e390ea27e932844f8d855fec549b5c480 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 27 Sep 2018 20:49:28 +0200 Subject: [PATCH 26/33] [fsresizer] Fix backwards logic in error message --- src/modules/fsresizer/ResizeFSJob.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index e3744661d..d501ba4f1 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -221,7 +221,7 @@ ResizeFSJob::exec() if ( !m.first || !m.second ) return Calamares::JobResult::error( tr( "Resize Failed" ), - m_fsname.isEmpty() ? tr( "The filesystem %1 could not be found in this system, and can not be resized." ).arg(m_fsname) + !m_fsname.isEmpty() ? tr( "The filesystem %1 could not be found in this system, and can not be resized." ).arg(m_fsname) : tr( "The device %1 could not be found in this system, and can not be resized." ).arg(m_devicename) ); if ( !ResizeOperation::canGrow( m.second ) ) @@ -229,7 +229,7 @@ ResizeFSJob::exec() cDebug() << "canGrow() returned false."; return Calamares::JobResult::error( tr( "Resize Failed" ), - m_fsname.isEmpty() ? tr( "The filesystem %1 can not be resized." ).arg(m_fsname) + !m_fsname.isEmpty() ? tr( "The filesystem %1 can not be resized." ).arg(m_fsname) : tr( "The device %1 can not be resized." ).arg(m_devicename) ); } From e627633c444061f8490f8a6a23ad7af2acf9aafd Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 27 Sep 2018 21:39:22 +0200 Subject: [PATCH 27/33] [fsresizer] initialize FS support --- src/modules/fsresizer/ResizeFSJob.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index d501ba4f1..b68485815 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -216,7 +216,9 @@ ResizeFSJob::exec() tr( "KPMCore not Available" ), tr( "Calamares cannot start KPMCore for the file-system resize job." ) ); } + backend_p->initFSSupport(); + // Now get the partition and FS we want to work on PartitionMatch m = findPartition( backend_p ); if ( !m.first || !m.second ) return Calamares::JobResult::error( From 14b675571437353b0c1555154ef0741557b5c5d2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 27 Sep 2018 21:47:54 +0200 Subject: [PATCH 28/33] [fsresizer] Initialize harder --- src/modules/fsresizer/ResizeFSJob.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index b68485815..8f5bce917 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -216,7 +216,7 @@ ResizeFSJob::exec() tr( "KPMCore not Available" ), tr( "Calamares cannot start KPMCore for the file-system resize job." ) ); } - backend_p->initFSSupport(); + backend_p->initFSSupport(); // Might not be enough, see below // Now get the partition and FS we want to work on PartitionMatch m = findPartition( backend_p ); @@ -226,6 +226,7 @@ ResizeFSJob::exec() !m_fsname.isEmpty() ? tr( "The filesystem %1 could not be found in this system, and can not be resized." ).arg(m_fsname) : tr( "The device %1 could not be found in this system, and can not be resized." ).arg(m_devicename) ); + m.second->fileSystem().init(); // Initialize support for specific FS if ( !ResizeOperation::canGrow( m.second ) ) { cDebug() << "canGrow() returned false."; From 5dc11b223a29c7e7cd15cf07b444f2c237f13174 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 28 Sep 2018 11:55:16 +0200 Subject: [PATCH 29/33] [fsresizer] Do the resize itself - handle weird partition tables - ignore unallocated space -- that's what we want to expand into - use ResizeOperation for the actual work --- src/modules/fsresizer/ResizeFSJob.cpp | 41 +++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index 8f5bce917..e5b3c0afc 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include "CalamaresVersion.h" #include "JobQueue.h" @@ -145,15 +146,26 @@ ResizeFSJob::findGrownEnd(ResizeFSJob::PartitionMatch m) if ( !ResizeOperation::canGrow( m.second ) ) return -1; - qint64 last_available = m.first->totalLogical(); - cDebug() << "Containing device size" << last_available; + cDebug() << "Containing device size" << m.first->totalLogical(); + qint64 last_available = m.first->totalLogical() - 1; // Numbered from 0 qint64 last_currently = m.second->lastSector(); cDebug() << "Growing partition" << m.second->firstSector() << '-' << last_currently; for ( auto part_it = PartitionIterator::begin( m.first ); part_it != PartitionIterator::end( m.first ); ++part_it ) { qint64 next_start = ( *part_it )->firstSector(); - cDebug() << ".. comparing" << next_start << '-' << ( *part_it )->lastSector(); + qint64 next_end = ( *part_it )->lastSector(); + if ( next_start > next_end ) + { + cWarning() << "Corrupt partition has end" << next_end << " < start" << next_start; + std::swap( next_start, next_end ); + } + if ( ( *part_it )->roles().has( PartitionRole::Unallocated ) ) + { + cDebug() << ".. ignoring unallocated" << next_start << '-' << next_end; + continue; + } + cDebug() << ".. comparing" << next_start << '-' << next_end; if ( (next_start > last_currently) && (next_start < last_available) ) { cDebug() << " .. shrunk last available to" << next_start; @@ -236,9 +248,26 @@ ResizeFSJob::exec() : tr( "The device %1 can not be resized." ).arg(m_devicename) ); } - cDebug() << "Resize from" << m.second->firstSector() - << '+' << m.second->length() << '=' << m.second->lastSector() - << "to" << findGrownEnd( m ); + qint64 new_end = findGrownEnd( m ); + cDebug() << "Resize from" + << m.second->firstSector() << '-' << m.second->lastSector() + << '(' << m.second->length() << ')' + << "to -" << new_end; + + if ( ( new_end > 0 ) && ( new_end > m.second->lastSector() ) ) + { + ResizeOperation op( *m.first, *m.second, m.second->firstSector(), new_end ); + Report op_report( nullptr ); + if ( op.execute( op_report ) ) + cDebug() << "Resize operation OK."; + else + { + cDebug() << "Resize failed." << op_report.output(); + return Calamares::JobResult::error( + tr( "Resize Failed" ), + report.toText() ); + } + } return Calamares::JobResult::ok(); } From c725f6b55263bf00f60be04fc23a9c4301eec38c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 28 Sep 2018 12:05:41 +0200 Subject: [PATCH 30/33] [fsresizer] Distinguish error from no-useful-resize --- src/modules/fsresizer/ResizeFSJob.cpp | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index e5b3c0afc..0d10c5583 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -138,6 +138,14 @@ ResizeFSJob::findPartition( CoreBackend* backend ) return PartitionMatch( nullptr, nullptr ); } +/** @brief Returns the last sector the matched partition should occupy. + * + * Returns a sector number. Returns -1 if something is wrong (e.g. + * can't resize at all, or missing data). Returns 0 if the resize + * won't fit because it doesn't satisfy the settings for atleast + * and size (or won't grow at all because the partition is blocked + * by occupied space after it). + */ qint64 ResizeFSJob::findGrownEnd(ResizeFSJob::PartitionMatch m) { @@ -176,7 +184,7 @@ ResizeFSJob::findGrownEnd(ResizeFSJob::PartitionMatch m) if ( !( last_available > last_currently ) ) { cDebug() << "Partition can not grow larger."; - return -1; + return 0; } qint64 expand = last_available - last_currently; // number of sectors @@ -186,7 +194,7 @@ ResizeFSJob::findGrownEnd(ResizeFSJob::PartitionMatch m) if ( expand < required ) { cDebug() << ".. need to expand by" << required << "but only" << expand << "is available."; - return -1; + return 0; } } @@ -254,6 +262,19 @@ ResizeFSJob::exec() << '(' << m.second->length() << ')' << "to -" << new_end; + if ( new_end < 0 ) + return Calamares::JobResult::error( + tr( "Resize Failed" ), + !m_fsname.isEmpty() ? tr( "The filesystem %1 can not be resized." ).arg(m_fsname) + : tr( "The device %1 can not be resized." ).arg(m_devicename) ); + if ( new_end == 0 ) + { + // TODO: is that a bad thing? is the resize required? + cWarning() << "Resize operation on" << m_fsname << m_devicename + << "skipped as not-useful."; + return Calamares::JobResult::ok(); + } + if ( ( new_end > 0 ) && ( new_end > m.second->lastSector() ) ) { ResizeOperation op( *m.first, *m.second, m.second->firstSector(), new_end ); From aaf27ac2ab63cc4a302dc40d54debfce000a0d22 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 28 Sep 2018 12:32:08 +0200 Subject: [PATCH 31/33] [fsresizer] Apply sizes properly - Distinguish size and atleast; in percentages they mean different things (atleast is a bit weird as a percentage, but hey). - Fix bug in percentage calculation. - Avoid percentage above 100. - Add documentation in config-file. --- src/modules/fsresizer/ResizeFSJob.cpp | 38 ++++++++++++++++++++++----- src/modules/fsresizer/ResizeFSJob.h | 16 ++++++++--- src/modules/fsresizer/fsresizer.conf | 4 +++ 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index 0d10c5583..f71f010bd 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -68,31 +68,48 @@ ResizeFSJob::RelativeSize::RelativeSize( const QString& s) { matchUnitSuffix( s, "%", Percent, m_value, m_unit ); matchUnitSuffix( s, "MiB", Absolute, m_value, m_unit ); + + if ( ( unit() == Percent ) && ( value() > 100 ) ) + { + cDebug() << "Percent value" << value() << "is not valid."; + m_value = 0; + m_unit = None; + } if ( !m_value ) m_unit = None; } qint64 -ResizeFSJob::RelativeSize::apply( Device* d ) +ResizeFSJob::RelativeSize::apply( qint64 totalSectors , qint64 sectorSize ) { if ( !isValid() ) return -1; - + if ( sectorSize < 1 ) + return -1; + switch( m_unit ) { case None: return -1; case Absolute: - return CalamaresUtils::MiBtoBytes( value() ) / d->logicalSize(); + return CalamaresUtils::MiBtoBytes( value() ) / sectorSize; case Percent: - return d->logicalSize() * value() / 100; + if ( value() == 100 ) + return totalSectors; // Common-case, avoid futzing around + else + return totalSectors * value() / 100; } // notreached return -1; } +qint64 +ResizeFSJob::RelativeSize::apply( Device* d ) +{ + return apply( d->totalLogical(), d->logicalSize() ); +} ResizeFSJob::ResizeFSJob( QObject* parent ) : Calamares::CppJob( parent ) @@ -150,9 +167,11 @@ qint64 ResizeFSJob::findGrownEnd(ResizeFSJob::PartitionMatch m) { if ( !m.first || !m.second ) - return -1; + return -1; // Missing device data if ( !ResizeOperation::canGrow( m.second ) ) - return -1; + return -1; // Operation is doomed + if ( !m_size.isValid() ) + return -1; // Must have a grow-size cDebug() << "Containing device size" << m.first->totalLogical(); qint64 last_available = m.first->totalLogical() - 1; // Numbered from 0 @@ -198,6 +217,13 @@ ResizeFSJob::findGrownEnd(ResizeFSJob::PartitionMatch m) } } + qint64 wanted = m_size.apply( expand, m.first->logicalSize() ); + if ( wanted < expand ) + { + cDebug() << ".. only growing by" << wanted << "instead of full" << expand; + last_available -= ( expand - wanted ); + } + return last_available; } diff --git a/src/modules/fsresizer/ResizeFSJob.h b/src/modules/fsresizer/ResizeFSJob.h index 36527ab56..063495e7d 100644 --- a/src/modules/fsresizer/ResizeFSJob.h +++ b/src/modules/fsresizer/ResizeFSJob.h @@ -64,15 +64,23 @@ public: return ( unit() != None ) && ( value() > 0 ); } - /** @brief Apply this size to the given device @p d + /** @brief Apply this size to the number of sectors @p totalSectors . * + * Each sector has size @p sectorSize , for converting absolute + * sizes in MiB to sector counts. + * * For invalid sizes, returns -1. * For absolute sizes, returns the number of sectors needed. - * For percent sizes, returns the number of sectors matching - * that percentage of the device size. + * For percent sizes, returns that percent of the number of sectors. + */ + qint64 apply( qint64 totalSectors, qint64 sectorSize ); + + /** @brief Apply this size to the given device. + * + * Equivalent to apply( d->totalLogical(), d->logicalSize() ) */ qint64 apply( Device* d ); - + private: int m_value; Unit m_unit; diff --git a/src/modules/fsresizer/fsresizer.conf b/src/modules/fsresizer/fsresizer.conf index f02983e45..06141fc7d 100644 --- a/src/modules/fsresizer/fsresizer.conf +++ b/src/modules/fsresizer/fsresizer.conf @@ -23,6 +23,8 @@ fs: / # how big the card is), use MiB as suffix in that case. # If missing, then it's assumed to be 0, and no resizing # will happen. +# +# Percentages apply to **available space**. size: 100% # Resizing might not be worth it, though. Set the minimum @@ -30,4 +32,6 @@ size: 100% # resizing is skipped. Can be in percentage or absolute # size, as above. If missing, then it's assumed to be 0, # which means resizing is always worthwhile. +# +# Percentages apply to **total device size**. atleast: 1000MiB From ed841d16747bb0528099254704ab52af9e318d2e Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 28 Sep 2018 12:34:40 +0200 Subject: [PATCH 32/33] [fsresizer] Typo --- src/modules/fsresizer/ResizeFSJob.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index f71f010bd..0589e1866 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -312,7 +312,7 @@ ResizeFSJob::exec() cDebug() << "Resize failed." << op_report.output(); return Calamares::JobResult::error( tr( "Resize Failed" ), - report.toText() ); + op_report.toText() ); } } From f1ab363f603c35986ef0fae3f1cc3eb58f0f7060 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 28 Sep 2018 12:56:06 +0200 Subject: [PATCH 33/33] Changelog: MD styling FIXES #921 --- CHANGES | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index a996526a3..c7e5432ce 100644 --- a/CHANGES +++ b/CHANGES @@ -19,7 +19,7 @@ This release contains contributions from (alphabetically by first name): is compiled with the newest KPMCore release. * The *keyboard* module now handles the (bogus) Austrian keymap for the system console properly. - - New module *fsresizer* can be used to resize filesystems. It is intended + * New module *fsresizer* can be used to resize filesystems. It is intended for use in OEM installs where an image of fixed size is created, and then sized to the actual SD card the user has used.