Using QFile instead of calling ExternalCommand to read /proc/mdstat and mdadm.conf files.

This commit is contained in:
Caio Carvalho 2018-07-15 19:38:33 -03:00
parent 2298d08c41
commit c1e393240b
3 changed files with 83 additions and 15 deletions

View File

@ -26,6 +26,7 @@
#include "util/externalcommand.h"
#include <KLocalizedString>
#include <QFile>
#include <QRegularExpression>
#define d_ptr std::static_pointer_cast<SoftwareRAIDPrivate>(d)
@ -181,11 +182,17 @@ void SoftwareRAID::scanSoftwareRAID(QList<Device*>& 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<Device*>& devices)
SoftwareRAID* d = static_cast<SoftwareRAID *>(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<Device*>& 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;
}

View File

@ -87,6 +87,8 @@ public:
static bool reassembleSoftwareRAID(const QString& deviceNode);
static bool isRaidMember(const QString& path);
protected:
void initPartitions() override;

View File

@ -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 )