From 1c285f011b5067c75f2812343c20a8d2eb457903 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 22 Dec 2020 16:03:51 +0100 Subject: [PATCH 1/7] [libcalamares] Export partition-syncer symbols --- src/libcalamares/partition/Sync.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libcalamares/partition/Sync.h b/src/libcalamares/partition/Sync.h index 8bb516214..bcb2832ed 100644 --- a/src/libcalamares/partition/Sync.h +++ b/src/libcalamares/partition/Sync.h @@ -11,6 +11,8 @@ #ifndef PARTITION_SYNC_H #define PARTITION_SYNC_H +#include "DllMacro.h" + namespace CalamaresUtils { namespace Partition @@ -24,10 +26,10 @@ namespace Partition * are sensitive, and systemd tends to keep disks busy after a change * for a while). */ -void sync(); +DLLEXPORT void sync(); /** @brief RAII class for calling sync() */ -struct Syncer +struct DLLEXPORT Syncer { ~Syncer() { sync(); } }; From 9e6bddf31a61b5f1399c44d20e8c085b5a985f34 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 22 Dec 2020 16:05:20 +0100 Subject: [PATCH 2/7] [partition] Add new AutoMount-manipulating helpers --- src/libcalamares/CMakeLists.txt | 8 +++ src/libcalamares/partition/AutoMount.cpp | 89 ++++++++++++++++++++++++ src/libcalamares/partition/AutoMount.h | 48 +++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 src/libcalamares/partition/AutoMount.cpp create mode 100644 src/libcalamares/partition/AutoMount.h diff --git a/src/libcalamares/CMakeLists.txt b/src/libcalamares/CMakeLists.txt index 3964eb3e6..fd3a678c3 100644 --- a/src/libcalamares/CMakeLists.txt +++ b/src/libcalamares/CMakeLists.txt @@ -77,6 +77,14 @@ set( libSources utils/Yaml.cpp ) +### OPTIONAL Automount support (requires dbus) +# +# +if( Qt5DBus_FOUND) + list( APPEND libSources partition/AutoMount.cpp ) + list( APPEND OPTIONAL_PRIVATE_LIBRARIES Qt5::DBus ) +endif() + ### OPTIONAL Python support # # diff --git a/src/libcalamares/partition/AutoMount.cpp b/src/libcalamares/partition/AutoMount.cpp new file mode 100644 index 000000000..29fbfea5f --- /dev/null +++ b/src/libcalamares/partition/AutoMount.cpp @@ -0,0 +1,89 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2020 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Calamares is Free Software: see the License-Identifier above. + */ + +#include "AutoMount.h" + +#include "utils/Logger.h" + +#include + +namespace CalamaresUtils +{ +namespace Partition +{ + +struct AutoMountInfo +{ + bool wasSolidModuleAutoLoaded = false; +}; + +static inline QDBusMessage +kdedCall( const QString& method ) +{ + return QDBusMessage::createMethodCall( + QStringLiteral( "org.kde.kded5" ), QStringLiteral( "/kded" ), QStringLiteral( "org.kde.kded5" ), method ); +} + +// This code comes, roughly, from the KCM for removable devices. +static void +enableSolidAutoMount( QDBusConnection& dbus, bool enable ) +{ + const auto moduleName = QVariant( QStringLiteral( "device_automounter" ) ); + + // Stop module from auto-loading + { + auto msg = kdedCall( QStringLiteral( "setModuleAutoloading" ) ); + msg.setArguments( { moduleName, QVariant( enable ) } ); + dbus.call( msg, QDBus::NoBlock ); + } + + // Stop module + { + auto msg = kdedCall( enable ? QStringLiteral( "loadModule" ) : QStringLiteral( "unloadModule" ) ); + msg.setArguments( { moduleName } ); + dbus.call( msg, QDBus::NoBlock ); + } +} + +static void +querySolidAutoMount( QDBusConnection& dbus, AutoMountInfo& info ) +{ + const auto moduleName = QVariant( QStringLiteral( "device_automounter" ) ); + + // Find previous setting; this **does** need to block + auto msg = kdedCall( QStringLiteral( "isModuleAutoloaded" ) ); + msg.setArguments( { moduleName } ); + QDBusMessage r = dbus.call( msg, QDBus::Block ); + if ( r.type() == QDBusMessage::ReplyMessage ) + { + auto arg = r.arguments(); + cDebug() << arg; + info.wasSolidModuleAutoLoaded = false; + } +} + +std::unique_ptr< AutoMountInfo > +automountDisable() +{ + auto u = std::make_unique< AutoMountInfo >(); + QDBusConnection dbus = QDBusConnection::sessionBus(); + querySolidAutoMount( dbus, *u ); + enableSolidAutoMount( dbus, false ); + return u; +} + + +void +automountRestore( std::unique_ptr< AutoMountInfo >&& t ) +{ + QDBusConnection dbus = QDBusConnection::sessionBus(); + enableSolidAutoMount( dbus, t->wasSolidModuleAutoLoaded ); +} + +} // namespace Partition +} // namespace CalamaresUtils diff --git a/src/libcalamares/partition/AutoMount.h b/src/libcalamares/partition/AutoMount.h new file mode 100644 index 000000000..ecb1780a0 --- /dev/null +++ b/src/libcalamares/partition/AutoMount.h @@ -0,0 +1,48 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2020 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Calamares is Free Software: see the License-Identifier above. + * + * + */ + +#ifndef PARTITION_AUTOMOUNT_H +#define PARTITION_AUTOMOUNT_H + +#include "DllMacro.h" + +#include + +namespace CalamaresUtils +{ +namespace Partition +{ + +struct AutoMountInfo; + +/** @brief Disable automount + * + * Various subsystems can do "agressive automount", which can get in the + * way of partitioning actions. In particular, Solid can be configured + * to automount every device it sees, and partitioning happens in multiple + * steps (create table, create partition, set partition flags) which are + * blocked if the partition gets mounted partway through the operation. + * + * Returns an opaque structure which can be passed to automountRestore() + * to return the system to the previously-configured automount settings. + */ +DLLEXPORT std::unique_ptr< AutoMountInfo > automountDisable(); + +/** @brief Restore automount settings + * + * Pass the value returned from automountDisable() to restore the + * previous settings. + */ +DLLEXPORT void automountRestore( std::unique_ptr< AutoMountInfo >&& t ); + +} // namespace Partition +} // namespace CalamaresUtils + +#endif From f0a33a235c1bf7d29fa2c08c8120acac8b88c6d0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 22 Dec 2020 21:23:50 +0100 Subject: [PATCH 3/7] [libcalamares] Make automountDisable() more flexible --- src/libcalamares/partition/AutoMount.cpp | 4 ++-- src/libcalamares/partition/AutoMount.h | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libcalamares/partition/AutoMount.cpp b/src/libcalamares/partition/AutoMount.cpp index 29fbfea5f..984662960 100644 --- a/src/libcalamares/partition/AutoMount.cpp +++ b/src/libcalamares/partition/AutoMount.cpp @@ -68,12 +68,12 @@ querySolidAutoMount( QDBusConnection& dbus, AutoMountInfo& info ) } std::unique_ptr< AutoMountInfo > -automountDisable() +automountDisable( bool disable ) { auto u = std::make_unique< AutoMountInfo >(); QDBusConnection dbus = QDBusConnection::sessionBus(); querySolidAutoMount( dbus, *u ); - enableSolidAutoMount( dbus, false ); + enableSolidAutoMount( dbus, !disable ); return u; } diff --git a/src/libcalamares/partition/AutoMount.h b/src/libcalamares/partition/AutoMount.h index ecb1780a0..b77bdbae6 100644 --- a/src/libcalamares/partition/AutoMount.h +++ b/src/libcalamares/partition/AutoMount.h @@ -30,10 +30,13 @@ struct AutoMountInfo; * steps (create table, create partition, set partition flags) which are * blocked if the partition gets mounted partway through the operation. * + * @param disable set this to false to reverse the sense of the function + * call and force *enabling* automount, instead. + * * Returns an opaque structure which can be passed to automountRestore() * to return the system to the previously-configured automount settings. */ -DLLEXPORT std::unique_ptr< AutoMountInfo > automountDisable(); +DLLEXPORT std::unique_ptr< AutoMountInfo > automountDisable( bool disable = true ); /** @brief Restore automount settings * From 1c4bf58fb459c58a2f18c302c724aa44ddf14573 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 22 Dec 2020 21:25:00 +0100 Subject: [PATCH 4/7] [libcalamares] automount-manipulation test-program --- src/libcalamares/CMakeLists.txt | 5 +++ src/libcalamares/partition/calautomount.cpp | 48 +++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 src/libcalamares/partition/calautomount.cpp diff --git a/src/libcalamares/CMakeLists.txt b/src/libcalamares/CMakeLists.txt index fd3a678c3..87eb387fa 100644 --- a/src/libcalamares/CMakeLists.txt +++ b/src/libcalamares/CMakeLists.txt @@ -260,3 +260,8 @@ calamares_add_test( add_executable( test_geoip geoip/test_geoip.cpp ${geoip_src} ) target_link_libraries( test_geoip calamares Qt5::Network yamlcpp ) calamares_automoc( test_geoip ) + +if ( Qt5DBus_FOUND ) + add_executable( calautomount partition/calautomount.cpp ) + target_link_libraries( calautomount calamares Qt5::DBus ) +endif() diff --git a/src/libcalamares/partition/calautomount.cpp b/src/libcalamares/partition/calautomount.cpp new file mode 100644 index 000000000..3eb95be08 --- /dev/null +++ b/src/libcalamares/partition/calautomount.cpp @@ -0,0 +1,48 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2020 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Calamares is Free Software: see the License-Identifier above. + * + * + */ + +/** @brief Command-line tool to enable or disable automounting + * + * This application uses Calamares methods to enable or disable + * automount settings in the running system. This can be used to + * test the automount-manipulating code without running + * a full Calamares or doing an installation. + * + */ + +static const char usage[] = "Usage: calautomount <-e|-d>\n" +"\n" +"Enables (if `-e` is passed as command-line option) or\n" +"Disables (if `-d` is passed as command-line option)\n" +"\n" +"automounting of disks in the host system as best it can.\n" +"Exits with code 0 on success or 1 if an unknown option is\n" +"passed on the command-line.\n\n"; + +#include "AutoMount.h" +#include "Sync.h" + +#include +#include + +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + + if ((argc != 2) || (argv[1][0] != '-') || (argv[1][1] !='e' && argv[1][1] !='d')) + { + qWarning() << usage; + return 1; + } + + CalamaresUtils::Partition::automountDisable( argv[1][1] == 'd'); + + return 0; +} From 3150785ff1aecc4b971ab8faa597d5f4ec6eed02 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 22 Dec 2020 21:29:49 +0100 Subject: [PATCH 5/7] [libcalamares] Use shared_ptr instead of unique_ptr The value inside a unique_ptr can't be opaque, it needs to be known at any site where the pointer may be deleted. shared_ptr does not have that (deletion is part of the shared_ptr object, which is larger than the unique_ptr) and so can be used for opaque deletions. --- src/libcalamares/partition/AutoMount.cpp | 6 +++--- src/libcalamares/partition/AutoMount.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libcalamares/partition/AutoMount.cpp b/src/libcalamares/partition/AutoMount.cpp index 984662960..0fc253067 100644 --- a/src/libcalamares/partition/AutoMount.cpp +++ b/src/libcalamares/partition/AutoMount.cpp @@ -67,10 +67,10 @@ querySolidAutoMount( QDBusConnection& dbus, AutoMountInfo& info ) } } -std::unique_ptr< AutoMountInfo > +std::shared_ptr< AutoMountInfo > automountDisable( bool disable ) { - auto u = std::make_unique< AutoMountInfo >(); + auto u = std::make_shared< AutoMountInfo >(); QDBusConnection dbus = QDBusConnection::sessionBus(); querySolidAutoMount( dbus, *u ); enableSolidAutoMount( dbus, !disable ); @@ -79,7 +79,7 @@ automountDisable( bool disable ) void -automountRestore( std::unique_ptr< AutoMountInfo >&& t ) +automountRestore( std::shared_ptr< AutoMountInfo >&& t ) { QDBusConnection dbus = QDBusConnection::sessionBus(); enableSolidAutoMount( dbus, t->wasSolidModuleAutoLoaded ); diff --git a/src/libcalamares/partition/AutoMount.h b/src/libcalamares/partition/AutoMount.h index b77bdbae6..a9a88e320 100644 --- a/src/libcalamares/partition/AutoMount.h +++ b/src/libcalamares/partition/AutoMount.h @@ -36,14 +36,14 @@ struct AutoMountInfo; * Returns an opaque structure which can be passed to automountRestore() * to return the system to the previously-configured automount settings. */ -DLLEXPORT std::unique_ptr< AutoMountInfo > automountDisable( bool disable = true ); +DLLEXPORT std::shared_ptr< AutoMountInfo > automountDisable( bool disable = true ); /** @brief Restore automount settings * * Pass the value returned from automountDisable() to restore the * previous settings. */ -DLLEXPORT void automountRestore( std::unique_ptr< AutoMountInfo >&& t ); +DLLEXPORT void automountRestore( std::shared_ptr< AutoMountInfo >&& t ); } // namespace Partition } // namespace CalamaresUtils From d74bdbcfd0d6b10dd698abd27034b81f5b5acc61 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 22 Dec 2020 22:07:17 +0100 Subject: [PATCH 6/7] [libcalamares] coding-style, logging in calautomount --- src/libcalamares/partition/calautomount.cpp | 26 ++++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/libcalamares/partition/calautomount.cpp b/src/libcalamares/partition/calautomount.cpp index 3eb95be08..a91fc3dda 100644 --- a/src/libcalamares/partition/calautomount.cpp +++ b/src/libcalamares/partition/calautomount.cpp @@ -18,31 +18,35 @@ */ static const char usage[] = "Usage: calautomount <-e|-d>\n" -"\n" -"Enables (if `-e` is passed as command-line option) or\n" -"Disables (if `-d` is passed as command-line option)\n" -"\n" -"automounting of disks in the host system as best it can.\n" -"Exits with code 0 on success or 1 if an unknown option is\n" -"passed on the command-line.\n\n"; + "\n" + "Enables (if `-e` is passed as command-line option) or\n" + "Disables (if `-d` is passed as command-line option)\n" + "\n" + "automounting of disks in the host system as best it can.\n" + "Exits with code 0 on success or 1 if an unknown option is\n" + "passed on the command-line.\n\n"; #include "AutoMount.h" #include "Sync.h" +#include "utils/Logger.h" #include #include -int main(int argc, char **argv) +int +main( int argc, char** argv ) { - QCoreApplication app(argc, argv); + QCoreApplication app( argc, argv ); - if ((argc != 2) || (argv[1][0] != '-') || (argv[1][1] !='e' && argv[1][1] !='d')) + if ( ( argc != 2 ) || ( argv[ 1 ][ 0 ] != '-' ) || ( argv[ 1 ][ 1 ] != 'e' && argv[ 1 ][ 1 ] != 'd' ) ) { qWarning() << usage; return 1; } - CalamaresUtils::Partition::automountDisable( argv[1][1] == 'd'); + Logger::setupLogfile(); + Logger::setupLogLevel( Logger::LOGDEBUG ); + CalamaresUtils::Partition::automountDisable( argv[ 1 ][ 1 ] == 'd' ); return 0; } From a3eae323f1982945f6e807b4fb345b67d5c73417 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 22 Dec 2020 22:08:23 +0100 Subject: [PATCH 7/7] [libcalamares] Rename test-executable: avoid clashes with 'cala' --- src/libcalamares/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcalamares/CMakeLists.txt b/src/libcalamares/CMakeLists.txt index 87eb387fa..700eff37b 100644 --- a/src/libcalamares/CMakeLists.txt +++ b/src/libcalamares/CMakeLists.txt @@ -262,6 +262,6 @@ target_link_libraries( test_geoip calamares Qt5::Network yamlcpp ) calamares_automoc( test_geoip ) if ( Qt5DBus_FOUND ) - add_executable( calautomount partition/calautomount.cpp ) - target_link_libraries( calautomount calamares Qt5::DBus ) + add_executable( test_automount partition/calautomount.cpp ) + target_link_libraries( test_automount calamares Qt5::DBus ) endif()