diff --git a/src/core/raid/softwareraid.cpp b/src/core/raid/softwareraid.cpp index c7c9c42..83d0039 100644 --- a/src/core/raid/softwareraid.cpp +++ b/src/core/raid/softwareraid.cpp @@ -26,6 +26,7 @@ #include "util/externalcommand.h" #include +#include #include #define d_ptr std::static_pointer_cast(d) @@ -181,11 +182,17 @@ void SoftwareRAID::scanSoftwareRAID(QList& devices) } } - ExternalCommand scanRaid(QStringLiteral("cat"), { QStringLiteral("/proc/mdstat") }); + QFile mdstat(QStringLiteral("/proc/mdstat")); + + if (mdstat.open(QIODevice::ReadOnly)) { + QTextStream stream(&mdstat); + + QString content = stream.readAll(); + + mdstat.close(); - if (scanRaid.run(-1) && scanRaid.exitCode() == 0) { QRegularExpression re(QStringLiteral("md([\\/\\w]+)\\s+:\\s+([\\w]+)")); - QRegularExpressionMatchIterator i = re.globalMatch(scanRaid.output()); + QRegularExpressionMatchIterator i = re.globalMatch(content); while (i.hasNext()) { QRegularExpressionMatch reMatch = i.next(); @@ -194,6 +201,10 @@ void SoftwareRAID::scanSoftwareRAID(QList& devices) SoftwareRAID* d = static_cast(CoreBackendManager::self()->backend()->scanDevice(deviceNode)); + // Just to prevent segfault in some case + if (d == nullptr) + continue; + const QStringList constAvailableInConf = availableInConf; for (const QString& path : constAvailableInConf) @@ -206,14 +217,14 @@ void SoftwareRAID::scanSoftwareRAID(QList& devices) d->setStatus(SoftwareRAID::Status::Inactive); if (d->raidLevel() > 0) { - QRegularExpression reMirrorStatus(QStringLiteral("\\[[=>.]+\\]\\s+(resync|recovery)")); + QRegularExpression reMirrorStatus(d->name() + QStringLiteral("\\s+:\\s+(.*\\n\\s+)+\\[[=>.]+\\]\\s+(resync|recovery)")); - QRegularExpressionMatch reMirrorStatusMatch = reMirrorStatus.match(scanRaid.output()); + QRegularExpressionMatch reMirrorStatusMatch = reMirrorStatus.match(content); if (reMirrorStatusMatch.hasMatch()) { - if (reMirrorStatusMatch.captured(1) == QStringLiteral("resync")) + if (reMirrorStatusMatch.captured(2) == QStringLiteral("resync")) d->setStatus(SoftwareRAID::Status::Resync); - else if (reMirrorStatusMatch.captured(1) == QStringLiteral("recovery")) + else if (reMirrorStatusMatch.captured(2) == QStringLiteral("recovery")) d->setStatus(SoftwareRAID::Status::Recovery); } } @@ -375,6 +386,34 @@ bool SoftwareRAID::reassembleSoftwareRAID(const QString &deviceNode) return stopSoftwareRAID(deviceNode) && assembleSoftwareRAID(deviceNode); } +bool SoftwareRAID::isRaidMember(const QString &path) +{ + QFile mdstat(QStringLiteral("/proc/mdstat")); + + if (!mdstat.open(QIODevice::ReadOnly)) + return false; + + QTextStream stream(&mdstat); + + QString content = stream.readAll(); + + mdstat.close(); + + QRegularExpression re(QStringLiteral("(\\w+)\\[\\d+\\]")); + QRegularExpressionMatchIterator i = re.globalMatch(content); + + while (i.hasNext()) { + QRegularExpressionMatch reMatch = i.next(); + + QString match = QStringLiteral("/dev/") + reMatch.captured(1); + + if (match == path) + return true; + } + + return false; +} + void SoftwareRAID::initPartitions() { @@ -394,7 +433,16 @@ QString SoftwareRAID::getDetail(const QString &path) QString SoftwareRAID::getRAIDConfiguration(const QString &configurationPath) { - ExternalCommand cmd(QStringLiteral("cat"), { configurationPath }); + QFile config(configurationPath); - return (cmd.run(-1) && cmd.exitCode() == 0) ? cmd.output() : QString(); + if (!config.open(QIODevice::ReadOnly)) + return QString(); + + QTextStream stream(&config); + + QString result = stream.readAll(); + + config.close(); + + return result; } diff --git a/src/core/raid/softwareraid.h b/src/core/raid/softwareraid.h index a33c5d3..803ec54 100644 --- a/src/core/raid/softwareraid.h +++ b/src/core/raid/softwareraid.h @@ -87,6 +87,8 @@ public: static bool reassembleSoftwareRAID(const QString& deviceNode); + static bool isRaidMember(const QString& path); + protected: void initPartitions() override; diff --git a/src/plugins/sfdisk/sfdiskbackend.cpp b/src/plugins/sfdisk/sfdiskbackend.cpp index 9630b1c..d8a5f36 100644 --- a/src/plugins/sfdisk/sfdiskbackend.cpp +++ b/src/plugins/sfdisk/sfdiskbackend.cpp @@ -136,15 +136,33 @@ Device* SfdiskBackend::scanDevice(const QString& deviceNode) qint64 deviceSize = sizeCommand.output().trimmed().toLongLong(); int logicalSectorSize = sizeCommand2.output().trimmed().toLongLong(); - ExternalCommand softwareRaidCommand(QStringLiteral("mdadm"), { QStringLiteral("--detail"), deviceNode }); + QFile mdstat(QStringLiteral("/proc/mdstat")); - if ( softwareRaidCommand.run(-1) && softwareRaidCommand.exitCode() == 0 ) - { - Log(Log::Level::information) << xi18nc("@info:status", "Software RAID Device found: %1", deviceNode); + if (mdstat.open(QIODevice::ReadOnly)) { + QTextStream stream(&mdstat); - QString deviceName = deviceNode.mid(5); + QString content = stream.readAll(); - d = new SoftwareRAID( deviceName, SoftwareRAID::Status::Active ); + mdstat.close(); + + QRegularExpression re(QStringLiteral("md([\\/\\w]+)\\s+:")); + QRegularExpressionMatchIterator i = re.globalMatch(content); + + while (i.hasNext()) { + + QRegularExpressionMatch reMatch = i.next(); + + QString name = reMatch.captured(1); + + if ((QStringLiteral("/dev/md") + name) == deviceNode) { + Log(Log::Level::information) << xi18nc("@info:status", "Software RAID Device found: %1", deviceNode); + + d = new SoftwareRAID( QStringLiteral("md") + name, SoftwareRAID::Status::Active ); + + break; + } + + } } if ( d == nullptr && modelCommand.run(-1) && modelCommand.exitCode() == 0 )