diff --git a/src/modules/partition/core/PartUtils.cpp b/src/modules/partition/core/PartUtils.cpp index 875de3a63..dac76ca17 100644 --- a/src/modules/partition/core/PartUtils.cpp +++ b/src/modules/partition/core/PartUtils.cpp @@ -22,7 +22,11 @@ #include "core/DeviceModel.h" #include "core/KPMHelpers.h" +#include "core/PartitionIterator.h" +#include +#include +#include #include #include @@ -325,4 +329,95 @@ runOsprober( PartitionCoreModule* core ) } +/** + * Does the given @p device contain the root filesystem? This is true if + * the device contains a partition which is currently mounted at / . + */ +static bool +hasRootPartition( Device* device ) +{ + for ( auto it = PartitionIterator::begin( device ); it != PartitionIterator::end( device ); ++it ) + if ( ( *it )->mountPoint() == "/" ) + return true; + return false; } + +static bool +isMounted( Device* device ) +{ + cDebug() << "Checking for mounted partitions in" << device->deviceNode(); + for ( auto it = PartitionIterator::begin( device ); it != PartitionIterator::end( device ); ++it ) + { + cDebug() << " .." << ( *it )->partitionPath() << "mount" << ( *it )->mountPoint(); + if ( ! ( *it )->mountPoint().isEmpty() ) + return true; + } + return false; +} + +static bool +isIso9660( const Device* device ) +{ + QString path = device->deviceNode(); + if ( path.isEmpty() ) + return false; + + QProcess blkid; + blkid.start( "blkid", { path } ); + blkid.waitForFinished(); + QString output = QString::fromLocal8Bit( blkid.readAllStandardOutput() ); + if ( output.contains( "iso9660" ) ) + return true; + + if ( device->partitionTable() && + !device->partitionTable()->children().isEmpty() ) + { + for ( const Partition* partition : device->partitionTable()->children() ) + { + path = partition->partitionPath(); + blkid.start( "blkid", { path } ); + blkid.waitForFinished(); + QString output = QString::fromLocal8Bit( blkid.readAllStandardOutput() ); + if ( output.contains( "iso9660" ) ) + return true; + } + } + return false; +} + + +QList< Device* > getDevices( bool writableOnly ) +{ + using DeviceList = QList< Device* >; + + CoreBackend* backend = CoreBackendManager::self()->backend(); + DeviceList devices = backend->scanDevices( true ); + + cDebug() << "Winnowing" << devices.count() << "devices."; + + // Remove the device which contains / from the list + for ( DeviceList::iterator it = devices.begin(); it != devices.end(); ) + if ( ! ( *it ) || + ( *it )->deviceNode().startsWith( "/dev/zram" ) + ) + { + cDebug() << " .. Winnowing" << ( ( *it ) ? ( *it )->deviceNode() : QString( "" ) ); + it = devices.erase( it ); + + } + else if ( writableOnly && ( + hasRootPartition( *it ) || + isIso9660( *it ) || + isMounted( *it ) ) + ) + { + cDebug() << " .. Winnowing" << ( ( *it ) ? ( *it )->deviceNode() : QString( "" ) ); + it = devices.erase( it ); + } + else + ++it; + + return devices; +} + +} // nmamespace PartUtils diff --git a/src/modules/partition/core/PartUtils.h b/src/modules/partition/core/PartUtils.h index 21d995965..cd289e046 100644 --- a/src/modules/partition/core/PartUtils.h +++ b/src/modules/partition/core/PartUtils.h @@ -23,6 +23,7 @@ #include +class Device; class PartitionCoreModule; class Partition; @@ -62,6 +63,14 @@ bool canBeResized( PartitionCoreModule* core, const QString& partitionPath ); */ OsproberEntryList runOsprober( PartitionCoreModule* core ); +/** + * @brief Gets a list of storage devices. + * @param writableOnly if set to true, only devices which can be overwritten + * safely are returned (e.g. RO-media are ignored, as are mounted partitions). + * @return a list of Devices meeting this criterium. + */ +QList< Device* > getDevices( bool writableOnly = false ); + } #endif // PARTUTILS_H diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index 6afae1f09..752b7753c 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -55,45 +55,6 @@ #include #include -static bool -hasRootPartition( Device* device ) -{ - for ( auto it = PartitionIterator::begin( device ); it != PartitionIterator::end( device ); ++it ) - if ( ( *it )->mountPoint() == "/" ) - return true; - return false; -} - -static bool -isIso9660( const Device* device ) -{ - QString path = device->deviceNode(); - if ( path.isEmpty() ) - return false; - - QProcess blkid; - blkid.start( "blkid", { path } ); - blkid.waitForFinished(); - QString output = QString::fromLocal8Bit( blkid.readAllStandardOutput() ); - if ( output.contains( "iso9660" ) ) - return true; - - if ( device->partitionTable() && - !device->partitionTable()->children().isEmpty() ) - { - for ( const Partition* partition : device->partitionTable()->children() ) - { - path = partition->partitionPath(); - blkid.start( "blkid", { path } ); - blkid.waitForFinished(); - QString output = QString::fromLocal8Bit( blkid.readAllStandardOutput() ); - if ( output.contains( "iso9660" ) ) - return true; - } - } - return false; -} - //- DeviceInfo --------------------------------------------- PartitionCoreModule::DeviceInfo::DeviceInfo( Device* _device ) : device( _device ) @@ -154,23 +115,7 @@ PartitionCoreModule::doInit() FileSystemFactory::init(); using DeviceList = QList< Device* >; - - CoreBackend* backend = CoreBackendManager::self()->backend(); - DeviceList devices = backend->scanDevices( true ); - - cDebug() << "Winnowing" << devices.count() << "devices."; - - // Remove the device which contains / from the list - for ( DeviceList::iterator it = devices.begin(); it != devices.end(); ) - if ( ! (*it) || hasRootPartition( *it ) || - (*it)->deviceNode().startsWith( "/dev/zram") || - isIso9660( *it ) ) - { - cDebug() << " .. Winnowing" << ( (*it) ? (*it)->deviceNode() : QString( "" ) ); - it = devices.erase( it ); - } - else - ++it; + DeviceList devices = PartUtils::getDevices( true ); cDebug() << "LIST OF DETECTED DEVICES:"; cDebug() << "node\tcapacity\tname\tprettyName"; @@ -200,32 +145,29 @@ PartitionCoreModule::doInit() for ( auto deviceInfo : m_deviceInfos ) { for ( auto it = PartitionIterator::begin( deviceInfo->device.data() ); - it != PartitionIterator::end( deviceInfo->device.data() ); ++it ) + it != PartitionIterator::end( deviceInfo->device.data() ); ++it ) { Partition* partition = *it; for ( auto jt = m_osproberLines.begin(); - jt != m_osproberLines.end(); ++jt ) + jt != m_osproberLines.end(); ++jt ) { if ( jt->path == partition->partitionPath() && - partition->fileSystem().supportGetUUID() != FileSystem::cmdSupportNone && - !partition->fileSystem().uuid().isEmpty() ) - { + partition->fileSystem().supportGetUUID() != FileSystem::cmdSupportNone && + !partition->fileSystem().uuid().isEmpty() ) jt->uuid = partition->fileSystem().uuid(); - } } } } for ( auto deviceInfo : m_deviceInfos ) - { deviceInfo->partitionModel->init( deviceInfo->device.data(), m_osproberLines ); - } m_bootLoaderModel->init( devices ); + //FIXME: this should be removed in favor of + // proper KPM support for EFI if ( QDir( "/sys/firmware/efi/efivars" ).exists() ) - scanForEfiSystemPartitions(); //FIXME: this should be removed in favor of - // proper KPM support for EFI + scanForEfiSystemPartitions(); } PartitionCoreModule::~PartitionCoreModule() @@ -286,8 +228,8 @@ PartitionCoreModule::createPartitionTable( Device* device, PartitionTable::Table } void -PartitionCoreModule::createPartition( Device *device, - Partition *partition, +PartitionCoreModule::createPartition( Device* device, + Partition* partition, PartitionTable::Flags flags ) { auto deviceInfo = infoForDevice( device ); @@ -457,9 +399,7 @@ PartitionCoreModule::jobs() const QStringList jobsDebug; foreach ( auto job, lst ) - { jobsDebug.append( job->prettyName() ); - } cDebug() << "PartitionCodeModule has been asked for jobs. About to return:" << jobsDebug.join( "\n" ); @@ -517,9 +457,11 @@ PartitionCoreModule::refresh() updateHasRootMountPoint(); updateIsDirty(); m_bootLoaderModel->update(); + + //FIXME: this should be removed in favor of + // proper KPM support for EFI if ( QDir( "/sys/firmware/efi/efivars" ).exists() ) - scanForEfiSystemPartitions(); //FIXME: this should be removed in favor of - // proper KPM support for EFI + scanForEfiSystemPartitions(); } void PartitionCoreModule::updateHasRootMountPoint() @@ -561,7 +503,7 @@ PartitionCoreModule::scanForEfiSystemPartitions() QList< Partition* > efiSystemPartitions = KPMHelpers::findPartitions( devices, - []( Partition* partition ) -> bool + []( Partition* partition ) -> bool { if ( partition->activeFlags().testFlag( PartitionTable::FlagEsp ) ) { @@ -581,7 +523,7 @@ PartitionCoreModule::DeviceInfo* PartitionCoreModule::infoForDevice( const Device* device ) const { for ( auto it = m_deviceInfos.constBegin(); - it != m_deviceInfos.constEnd(); ++it ) + it != m_deviceInfos.constEnd(); ++it ) { if ( ( *it )->device.data() == device ) return *it; @@ -627,9 +569,7 @@ void PartitionCoreModule::revertAllDevices() { foreach ( DeviceInfo* devInfo, m_deviceInfos ) - { revertDevice( devInfo->device.data() ); - } refresh(); } @@ -643,7 +583,7 @@ PartitionCoreModule::revertDevice( Device* dev ) return; devInfo->forgetChanges(); CoreBackend* backend = CoreBackendManager::self()->backend(); - Device *newDev = backend->scanDevice( devInfo->device->deviceNode() ); + Device* newDev = backend->scanDevice( devInfo->device->deviceNode() ); devInfo->device.reset( newDev ); devInfo->partitionModel->init( newDev, m_osproberLines ); @@ -680,9 +620,7 @@ void PartitionCoreModule::clearJobs() { foreach ( DeviceInfo* deviceInfo, m_deviceInfos ) - { deviceInfo->forgetChanges(); - } updateIsDirty(); }