diff --git a/src/modules/partition/jobs/ClearMountsJob.cpp b/src/modules/partition/jobs/ClearMountsJob.cpp index 0a3b880b6..ab563a056 100644 --- a/src/modules/partition/jobs/ClearMountsJob.cpp +++ b/src/modules/partition/jobs/ClearMountsJob.cpp @@ -49,12 +49,14 @@ ClearMountsJob::exec() { QStringList goodNews; + QString deviceName = m_device->deviceNode().split( '/' ).last(); + QProcess process; process.setProgram( "sh" ); process.setArguments( { "-c", QString( "echo $(awk '{print $4}' /proc/partitions | sed -e '/name/d' -e '/^$/d' -e '/[1-9]/!d' | grep %1)" ) - .arg( m_device->deviceNode().split( '/' ).last() ) + .arg( deviceName ) } ); process.start(); process.waitForFinished(); @@ -62,19 +64,65 @@ ClearMountsJob::exec() QString partitions = process.readAllStandardOutput(); QStringList partitionsList = partitions.simplified().split( ' ' ); + // First we umount all LVM logical volumes we can find + process.start( "lvscan", { "-a" } ); + process.waitForFinished(); + if ( process.exitCode() == 0 ) //means LVM2 tools are installed + { + QStringList lvscanLines = QString::fromLocal8Bit( process.readAllStandardOutput() ).split( '\n' ); + foreach ( const QString& lvscanLine, lvscanLines ) + { + QString lvPath = lvscanLine.simplified().split( ' ' ).value( 1 ); //second column + lvPath = lvPath.replace( '\'', "" ); + + QString news = tryUmount( lvPath ); + if ( !news.isEmpty() ) + goodNews.append( news ); + } + } + else + cDebug() << "WARNING: this system does not seem to have LVM2 tools."; + + // Then we go looking for volume groups that use this device for physical volumes + process.start( "pvdisplay", { "-C", "--noheadings" } ); + process.waitForFinished(); + if ( process.exitCode() == 0 ) //means LVM2 tools are installed + { + QString pvdisplayOutput = process.readAllStandardOutput(); + if ( !pvdisplayOutput.simplified().isEmpty() ) //means there is at least one LVM PV + { + QSet< QString > vgSet; + + QStringList pvdisplayLines = pvdisplayOutput.split( '\n' ); + foreach ( const QString& pvdisplayLine, pvdisplayLines ) + { + QString pvPath = pvdisplayLine.simplified().split( ' ' ).value( 0 ); + QString vgName = pvdisplayLine.simplified().split( ' ' ).value( 1 ); + if ( !pvPath.contains( deviceName ) ) + continue; + + vgSet.insert( vgName ); + } + + foreach ( const QString& vgName, vgSet ) + { + process.start( "vgchange", { "-an", vgName } ); + process.waitForFinished(); + if ( process.exitCode() == 0 ) + goodNews.append( QString( "Successfully disabled volume group %1." ).arg( vgName ) ); + } + } + } + else + cDebug() << "WARNING: this system does not seem to have LVM2 tools."; + foreach ( QString p, partitionsList ) { QString partPath = QString( "/dev/%1" ).arg( p ); - process.start( "umount", { partPath } ); - process.waitForFinished(); - if ( process.exitCode() == 0 ) - goodNews.append( QString( "Successfully unmounted %1." ).arg( partPath ) ); - - process.start( "swapoff", { partPath } ); - process.waitForFinished(); - if ( process.exitCode() == 0 ) - goodNews.append( QString( "Successfully disabled swap %1." ).arg( partPath ) ); + QString news = tryUmount( partPath ); + if ( !news.isEmpty() ) + goodNews.append( news ); } Calamares::JobResult ok = Calamares::JobResult::ok(); @@ -86,3 +134,21 @@ ClearMountsJob::exec() return ok; } + + +QString +ClearMountsJob::tryUmount( const QString& partPath ) +{ + QProcess process; + process.start( "umount", { partPath } ); + process.waitForFinished(); + if ( process.exitCode() == 0 ) + return QString( "Successfully unmounted %1." ).arg( partPath ); + + process.start( "swapoff", { partPath } ); + process.waitForFinished(); + if ( process.exitCode() == 0 ) + return QString( "Successfully disabled swap %1." ).arg( partPath ); + + return QString(); +} diff --git a/src/modules/partition/jobs/ClearMountsJob.h b/src/modules/partition/jobs/ClearMountsJob.h index 6a68e2811..e77da3762 100644 --- a/src/modules/partition/jobs/ClearMountsJob.h +++ b/src/modules/partition/jobs/ClearMountsJob.h @@ -35,6 +35,7 @@ public: QString prettyName() const override; Calamares::JobResult exec() override; private: + QString tryUmount( const QString& partPath ); Device* m_device; };