Using QFile instead of calling ExternalCommand to read /proc/mdstat and mdadm.conf files.
This commit is contained in:
parent
2298d08c41
commit
c1e393240b
|
@ -26,6 +26,7 @@
|
||||||
#include "util/externalcommand.h"
|
#include "util/externalcommand.h"
|
||||||
|
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
|
#include <QFile>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
|
||||||
#define d_ptr std::static_pointer_cast<SoftwareRAIDPrivate>(d)
|
#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]+)"));
|
QRegularExpression re(QStringLiteral("md([\\/\\w]+)\\s+:\\s+([\\w]+)"));
|
||||||
QRegularExpressionMatchIterator i = re.globalMatch(scanRaid.output());
|
QRegularExpressionMatchIterator i = re.globalMatch(content);
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
QRegularExpressionMatch reMatch = i.next();
|
QRegularExpressionMatch reMatch = i.next();
|
||||||
|
|
||||||
|
@ -194,6 +201,10 @@ void SoftwareRAID::scanSoftwareRAID(QList<Device*>& devices)
|
||||||
|
|
||||||
SoftwareRAID* d = static_cast<SoftwareRAID *>(CoreBackendManager::self()->backend()->scanDevice(deviceNode));
|
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;
|
const QStringList constAvailableInConf = availableInConf;
|
||||||
|
|
||||||
for (const QString& path : constAvailableInConf)
|
for (const QString& path : constAvailableInConf)
|
||||||
|
@ -206,14 +217,14 @@ void SoftwareRAID::scanSoftwareRAID(QList<Device*>& devices)
|
||||||
d->setStatus(SoftwareRAID::Status::Inactive);
|
d->setStatus(SoftwareRAID::Status::Inactive);
|
||||||
|
|
||||||
if (d->raidLevel() > 0) {
|
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.hasMatch()) {
|
||||||
if (reMirrorStatusMatch.captured(1) == QStringLiteral("resync"))
|
if (reMirrorStatusMatch.captured(2) == QStringLiteral("resync"))
|
||||||
d->setStatus(SoftwareRAID::Status::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);
|
d->setStatus(SoftwareRAID::Status::Recovery);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -375,6 +386,34 @@ bool SoftwareRAID::reassembleSoftwareRAID(const QString &deviceNode)
|
||||||
return stopSoftwareRAID(deviceNode) && assembleSoftwareRAID(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()
|
void SoftwareRAID::initPartitions()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -394,7 +433,16 @@ QString SoftwareRAID::getDetail(const QString &path)
|
||||||
|
|
||||||
QString SoftwareRAID::getRAIDConfiguration(const QString &configurationPath)
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,8 @@ public:
|
||||||
|
|
||||||
static bool reassembleSoftwareRAID(const QString& deviceNode);
|
static bool reassembleSoftwareRAID(const QString& deviceNode);
|
||||||
|
|
||||||
|
static bool isRaidMember(const QString& path);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void initPartitions() override;
|
void initPartitions() override;
|
||||||
|
|
||||||
|
|
|
@ -136,15 +136,33 @@ Device* SfdiskBackend::scanDevice(const QString& deviceNode)
|
||||||
qint64 deviceSize = sizeCommand.output().trimmed().toLongLong();
|
qint64 deviceSize = sizeCommand.output().trimmed().toLongLong();
|
||||||
int logicalSectorSize = sizeCommand2.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 )
|
if (mdstat.open(QIODevice::ReadOnly)) {
|
||||||
{
|
QTextStream stream(&mdstat);
|
||||||
Log(Log::Level::information) << xi18nc("@info:status", "Software RAID Device found: %1", deviceNode);
|
|
||||||
|
|
||||||
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 )
|
if ( d == nullptr && modelCommand.run(-1) && modelCommand.exitCode() == 0 )
|
||||||
|
|
Loading…
Reference in New Issue