Merge branch 'add-automount-control' into calamares

This commit is contained in:
Adriaan de Groot 2021-01-18 16:28:12 +01:00
commit 3ade1fd84a
5 changed files with 209 additions and 2 deletions

View File

@ -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
#
#
@ -252,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( test_automount partition/calautomount.cpp )
target_link_libraries( test_automount calamares Qt5::DBus )
endif()

View File

@ -0,0 +1,89 @@
/* === This file is part of Calamares - <https://calamares.io> ===
*
* SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
* 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 <QtDBus>
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::shared_ptr< AutoMountInfo >
automountDisable( bool disable )
{
auto u = std::make_shared< AutoMountInfo >();
QDBusConnection dbus = QDBusConnection::sessionBus();
querySolidAutoMount( dbus, *u );
enableSolidAutoMount( dbus, !disable );
return u;
}
void
automountRestore( std::shared_ptr< AutoMountInfo >&& t )
{
QDBusConnection dbus = QDBusConnection::sessionBus();
enableSolidAutoMount( dbus, t->wasSolidModuleAutoLoaded );
}
} // namespace Partition
} // namespace CalamaresUtils

View File

@ -0,0 +1,51 @@
/* === This file is part of Calamares - <https://calamares.io> ===
*
* SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
* 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 <memory>
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.
*
* @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::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::shared_ptr< AutoMountInfo >&& t );
} // namespace Partition
} // namespace CalamaresUtils
#endif

View File

@ -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(); }
};

View File

@ -0,0 +1,52 @@
/* === This file is part of Calamares - <https://calamares.io> ===
*
* SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
* 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 "utils/Logger.h"
#include <QCoreApplication>
#include <QDebug>
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;
}
Logger::setupLogfile();
Logger::setupLogLevel( Logger::LOGDEBUG );
CalamaresUtils::Partition::automountDisable( argv[ 1 ][ 1 ] == 'd' );
return 0;
}