diff --git a/src/core/raid/softwareraid.cpp b/src/core/raid/softwareraid.cpp index 858bd34..3100b72 100644 --- a/src/core/raid/softwareraid.cpp +++ b/src/core/raid/softwareraid.cpp @@ -42,6 +42,7 @@ public: qint64 m_arraySize; QString m_UUID; QStringList m_devicePathList; + QStringList m_partitionPathList; SoftwareRAID::Status m_status; }; @@ -72,7 +73,7 @@ const QStringList SoftwareRAID::deviceNodes() const const QStringList& SoftwareRAID::partitionNodes() const { - return {}; + return d_ptr->m_partitionPathList; } qint64 SoftwareRAID::partitionSize(QString &partitionPath) const @@ -150,11 +151,6 @@ QString SoftwareRAID::uuid() const return d_ptr->m_UUID; } -QStringList SoftwareRAID::devicePathList() const -{ - return d_ptr->m_devicePathList; -} - SoftwareRAID::Status SoftwareRAID::status() const { return d_ptr->m_status; @@ -169,7 +165,6 @@ void SoftwareRAID::scanSoftwareRAID(QList& devices) { QStringList availableInConf; - // TODO: Support custom config files. QString config = getRAIDConfiguration(); if (!config.isEmpty()) { @@ -213,6 +208,13 @@ void SoftwareRAID::scanSoftwareRAID(QList& devices) if (getUUID(QStringLiteral("/dev/") + path) == d->uuid()) availableInConf.removeAll(path); + QStringList partitionNodes; + + for (const Partition *p : d->partitionTable()->children()) + partitionNodes << p->partitionPath(); + + d->setPartitionNodes(partitionNodes); + devices << d; if (status == QStringLiteral("inactive")) @@ -311,7 +313,6 @@ QString SoftwareRAID::getUUID(const QString &path) // If UUID was not found in detail output, it should be searched in config file - // TODO: Support custom config files. QString config = getRAIDConfiguration(); if (!config.isEmpty()) { @@ -406,15 +407,28 @@ bool SoftwareRAID::createSoftwareRAID(Report &report, bool SoftwareRAID::deleteSoftwareRAID(Report &report, SoftwareRAID &raidDevice) { - Q_UNUSED(report) - Q_UNUSED(raidDevice) + if (raidDevice.status() == SoftwareRAID::Status::Active) + stopSoftwareRAID(report, raidDevice.deviceNode()); - // TODO: Need to stop and remove it from config file - // Erase md superblock for every physical partition of it - // The device should be removed from config file - // according to its UID, not by name + for (const QString& path : raidDevice.deviceNodes()) + eraseDeviceMDSuperblock(path); - return false; + QString config = getRAIDConfiguration(); + + QStringList lines = config.split(QLatin1Char('\n')); + + QString contentUpdated = QStringLiteral("\""); + + for (const QString line : lines) + if (!line.isEmpty() && !line.contains(raidDevice.uuid())) + contentUpdated += line + QLatin1Char('\n'); + + contentUpdated += QLatin1Char('\"'); + + ExternalCommand cmd(QStringLiteral("/usr/") + QStringLiteral(LIBEXECDIRPATH) + QStringLiteral("/kpmcore_mdadmupdateconf"), + { QStringLiteral("--write"), contentUpdated, raidConfigurationFilePath() }); + + return cmd.run(-1) && cmd.exitCode() == 0; } bool SoftwareRAID::assembleSoftwareRAID(const QString& deviceNode) @@ -482,7 +496,7 @@ bool SoftwareRAID::eraseDeviceMDSuperblock(const QString &path) bool SoftwareRAID::updateConfigurationFile(const QString &path) { ExternalCommand cmd(QStringLiteral("/usr/") + QStringLiteral(LIBEXECDIRPATH) + QStringLiteral("/kpmcore_mdadmupdateconf"), - { path, raidConfigurationFilePath() }); + { QStringLiteral("--append"), path, raidConfigurationFilePath() }); return cmd.run(-1) && cmd.exitCode() == 0; } @@ -540,3 +554,8 @@ QString SoftwareRAID::getDefaultRaidConfigFile() return QStringLiteral("/etc/mdadm/mdadm.conf"); return QString(); } + +void SoftwareRAID::setPartitionNodes(const QStringList& partitionNodes) +{ + d_ptr->m_partitionPathList = partitionNodes; +} diff --git a/src/core/raid/softwareraid.h b/src/core/raid/softwareraid.h index 8fec188..7e9b58d 100644 --- a/src/core/raid/softwareraid.h +++ b/src/core/raid/softwareraid.h @@ -55,7 +55,6 @@ public: qint64 totalChunk() const; qint64 arraySize() const; QString uuid() const; - QStringList devicePathList() const; SoftwareRAID::Status status() const; void setStatus(SoftwareRAID::Status status); @@ -111,6 +110,8 @@ private: static QString getDeviceInformation(const QString& deviceName); + void setPartitionNodes(const QStringList& partitionNodes); + private: static QString s_raidConfigurationFile; }; diff --git a/src/jobs/removevolumegroupjob.cpp b/src/jobs/removevolumegroupjob.cpp index 97792f7..7d92065 100644 --- a/src/jobs/removevolumegroupjob.cpp +++ b/src/jobs/removevolumegroupjob.cpp @@ -1,5 +1,6 @@ /************************************************************************* * Copyright (C) 2016 by Chantara Tith * + * Copyright (C) 2018 by Caio Carvalho * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -18,6 +19,7 @@ #include "jobs/removevolumegroupjob.h" #include "core/lvmdevice.h" +#include "core/raid/softwareraid.h" #include "util/report.h" @@ -37,9 +39,10 @@ bool RemoveVolumeGroupJob::run(Report& parent) Report* report = jobStarted(parent); - if (device().type() == Device::Type::LVM_Device) { + if (device().type() == Device::Type::LVM_Device) rval = LvmDevice::removeVG(*report, dynamic_cast(device())); - } + else if (device().type() == Device::Type::SoftwareRAID_Device) + rval = SoftwareRAID::deleteSoftwareRAID(*report, dynamic_cast(device())); jobFinished(*report, rval); @@ -48,5 +51,5 @@ bool RemoveVolumeGroupJob::run(Report& parent) QString RemoveVolumeGroupJob::description() const { - return xi18nc("@info/plain", "Remove Volume Group: %1", device().name()); + return xi18nc("@info/plain", "Remove %1 Volume Group: %2", (device().type() == Device::Type::SoftwareRAID_Device ? QStringLiteral("RAID") : QStringLiteral("LVM")), device().name()); } diff --git a/src/ops/removevolumegroupoperation.cpp b/src/ops/removevolumegroupoperation.cpp index 1c16433..49cf312 100644 --- a/src/ops/removevolumegroupoperation.cpp +++ b/src/ops/removevolumegroupoperation.cpp @@ -22,6 +22,7 @@ #include "core/partition.h" #include "core/partitiontable.h" #include "core/volumemanagerdevice.h" +#include "core/raid/softwareraid.h" #include @@ -40,7 +41,7 @@ RemoveVolumeGroupOperation::RemoveVolumeGroupOperation(VolumeManagerDevice& d) : QString RemoveVolumeGroupOperation::description() const { - return xi18nc("@info/plain", "Remove a LVM volume group."); + return xi18nc("@info/plain", "Remove a %1 volume group.", (device().type() == Device::Type::SoftwareRAID_Device ? QStringLiteral("RAID") : QStringLiteral("LVM"))); } void RemoveVolumeGroupOperation::preview() @@ -88,6 +89,10 @@ bool RemoveVolumeGroupOperation::isRemovable(const VolumeManagerDevice* dev) if (dev->partitionTable()->children().first()->fileSystem().type() == FileSystem::Type::Unknown) return true; } + else if (dev->type() == Device::Type::SoftwareRAID_Device) { + const SoftwareRAID* raid = static_cast(dev); + return raid->status() == SoftwareRAID::Status::Inactive; + } return false; } diff --git a/src/ops/removevolumegroupoperation.h b/src/ops/removevolumegroupoperation.h index 12e78a1..c20fb5d 100644 --- a/src/ops/removevolumegroupoperation.h +++ b/src/ops/removevolumegroupoperation.h @@ -49,6 +49,7 @@ public: virtual bool targets(const Device&) const override { return true; } + virtual bool targets(const Partition&) const override { return false; } @@ -59,11 +60,11 @@ public: static bool isRemovable(const VolumeManagerDevice* dev); protected: - RemoveVolumeGroupJob* removeVolumeGroupJob() { + RemoveVolumeGroupJob* removeVolumeGroupJob() const { return m_RemoveVolumeGroupJob; } - VolumeManagerDevice& device() { + VolumeManagerDevice& device() const { return m_Device; } diff --git a/src/util/mdadmupdateconf.cpp b/src/util/mdadmupdateconf.cpp index 783a562..a8fce70 100644 --- a/src/util/mdadmupdateconf.cpp +++ b/src/util/mdadmupdateconf.cpp @@ -1,16 +1,26 @@ #include #include +#include + +using namespace std; using std::string; int main(int argc, char *argv[]) { - if (argc != 3) + if (argc != 4) return 1; - string command = "mdadm --detail --scan " + string(argv[1]) + " >> " + string(argv[2]); + if (string(argv[1]) == "--append") { + string command = "mdadm --detail --scan " + string(argv[2]) + " >> " + string(argv[3]); - system(command.c_str()); + system(command.c_str()); + } + else if (string(argv[1]) == "--write") { + string command = "echo " + string(argv[2]) + " > " + string(argv[3]); + + system(command.c_str()); + } return 0; }