From 70a9a0dd9aa63bbda6fe3ce62a96b3570cc51dcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Thu, 8 Sep 2016 01:42:04 +0100 Subject: [PATCH] More optimizations for LVM. --- src/core/devicescanner.cpp | 2 +- src/core/lvmdevice.cpp | 46 ++++++++++---------------- src/core/lvmdevice.h | 15 ++++----- src/fs/lvm2_pv.cpp | 16 ++++++--- src/fs/lvm2_pv.h | 9 +++-- src/jobs/movephysicalvolumejob.cpp | 2 +- src/ops/resizevolumegroupoperation.cpp | 28 +++++++--------- 7 files changed, 57 insertions(+), 61 deletions(-) diff --git a/src/core/devicescanner.cpp b/src/core/devicescanner.cpp index 7b7da43..aa5be4e 100644 --- a/src/core/devicescanner.cpp +++ b/src/core/devicescanner.cpp @@ -63,7 +63,7 @@ void DeviceScanner::scan() clear(); const QList deviceList = CoreBackendManager::self()->backend()->scanDevices(); - const QList lvmList = LvmDevice::scanSystemLVM(); + const QList lvmList = LvmDevice::scanSystemLVM(deviceList); // NOTE: PVs inside LVM won't be scanned for (const auto &d : deviceList) operationStack().addDevice(d); diff --git a/src/core/lvmdevice.cpp b/src/core/lvmdevice.cpp index 91ca2be..f99bc6e 100644 --- a/src/core/lvmdevice.cpp +++ b/src/core/lvmdevice.cpp @@ -37,9 +37,10 @@ /** Constructs a representation of LVM device with initialized LV as Partitions * * @param vgName Volume Group name + * @param devices list of devices where we look for LVM PVs belonging to this VG. * @param iconName Icon representing LVM Volume group */ -LvmDevice::LvmDevice(const QString& vgName, const QString& iconName) +LvmDevice::LvmDevice(const QString& vgName, const QList& devices, const QString& iconName) : VolumeManagerDevice(vgName, (QStringLiteral("/dev/") + vgName), getPeSize(vgName), @@ -52,7 +53,7 @@ LvmDevice::LvmDevice(const QString& vgName, const QString& iconName) m_freePE = getFreePE(vgName); m_allocPE = m_totalPE - m_freePE; m_UUID = getUUID(vgName); - m_PVPathList = new QStringList(getPVs(vgName)); + m_PVs = FS::lvm2_pv::getPVs(devices, vgName); m_LVPathList = new QStringList(getLVs(vgName)); m_LVSizeMap = new QMap(); @@ -67,7 +68,6 @@ QStringList LvmDevice::s_DirtyPVs; LvmDevice::~LvmDevice() { - delete m_PVPathList; delete m_LVPathList; delete m_LVSizeMap; } @@ -198,13 +198,14 @@ Partition* LvmDevice::scanPartition(const QString& lvPath, PartitionTable* pTabl /** scan and contruct list of initialized LvmDevice objects. * + * @param devices list of Devices which we scan for LVM PVs * @return list of initialized LvmDevices */ -QList LvmDevice::scanSystemLVM() +QList LvmDevice::scanSystemLVM(const QList& devices) { QList lvmList; for (const auto &vgName : getVGs()) { - lvmList.append(new LvmDevice(vgName)); + lvmList.append(new LvmDevice(vgName, devices)); } return lvmList; } @@ -226,7 +227,11 @@ qint64 LvmDevice::mappedSector(const QString& lvPath, qint64 sector) const const QStringList LvmDevice::deviceNodes() const { - return *PVPathList(); + QStringList pvList; + for (const auto &p : physicalVolumes()) + pvList << p->partitionPath(); + + return pvList; } const QStringList LvmDevice::partitionNodes() const @@ -252,20 +257,6 @@ const QStringList LvmDevice::getVGs() return vgList; } -const QStringList LvmDevice::getPVs(const QString& vgName) -{ - QStringList devPathList; - QString cmdOutput = getField(QStringLiteral("pv_name"), vgName); - - if (cmdOutput.size()) { - const QStringList tempPathList = cmdOutput.split(QStringLiteral("\n"), QString::SkipEmptyParts); - for (const auto &devPath : tempPathList) { - devPathList.append(devPath.trimmed()); - } - } - return devPathList; -} - const QStringList LvmDevice::getLVs(const QString& vgName) { QStringList lvPathList; @@ -431,21 +422,18 @@ bool LvmDevice::insertPV(Report& report, LvmDevice& d, const QString& pvPath) return (cmd.run(-1) && cmd.exitCode() == 0); } + bool LvmDevice::movePV(Report& report, const QString& pvPath, const QStringList& destinations) { - - if (FS::lvm2_pv::getAllocatedPE(pvPath) <= 0) { + if (FS::lvm2_pv::getAllocatedPE(pvPath) <= 0) return true; - } QStringList args = QStringList(); args << QStringLiteral("pvmove"); args << pvPath; - if (!destinations.isEmpty()) { - for (const auto &destPath : destinations) { + if (!destinations.isEmpty()) + for (const auto &destPath : destinations) args << destPath.trimmed(); - } - } ExternalCommand cmd(report, QStringLiteral("lvm"), args); return (cmd.run(-1) && cmd.exitCode() == 0); @@ -456,9 +444,9 @@ bool LvmDevice::createVG(Report& report, const QString vgName, const QStringList QStringList args = QStringList(); args << QStringLiteral("vgcreate") << QStringLiteral("--physicalextentsize") << QString::number(peSize); args << vgName; - for (const auto &pvNode : pvList) { + for (const auto &pvNode : pvList) args << pvNode.trimmed(); - } + ExternalCommand cmd(report, QStringLiteral("lvm"), args); return (cmd.run(-1) && cmd.exitCode() == 0); diff --git a/src/core/lvmdevice.h b/src/core/lvmdevice.h index 9b66dd3..535d805 100644 --- a/src/core/lvmdevice.h +++ b/src/core/lvmdevice.h @@ -19,6 +19,7 @@ #define LVMDEVICE__H +#include "core/device.h" #include "core/volumemanagerdevice.h" #include "util/libpartitionmanagerexport.h" @@ -43,7 +44,7 @@ class LIBKPMCORE_EXPORT LvmDevice : public VolumeManagerDevice Q_DISABLE_COPY(LvmDevice) public: - LvmDevice(const QString& name, const QString& iconName = QString()); + LvmDevice(const QString& name, const QList& devices, const QString& iconName = QString()); ~LvmDevice(); public: @@ -54,11 +55,9 @@ public: static QStringList s_DirtyPVs; public: - - static QList scanSystemLVM(); + static QList scanSystemLVM(const QList& devices); static const QStringList getVGs(); - static const QStringList getPVs(const QString& vgName); static const QStringList getLVs(const QString& vgName); static qint64 getPeSize(const QString& vgName); @@ -114,11 +113,11 @@ public: return m_LVPathList; } -protected: - QStringList* PVPathList() const { - return m_PVPathList; + const QList physicalVolumes() const { + return m_PVs; } +protected: QMap* LVSizeMap() const { return m_LVSizeMap; } @@ -131,7 +130,7 @@ private: QString m_UUID; mutable QStringList* m_LVPathList; - mutable QStringList* m_PVPathList; + mutable QList m_PVs; mutable QMap* m_LVSizeMap; }; diff --git a/src/fs/lvm2_pv.cpp b/src/fs/lvm2_pv.cpp index 2688b7f..36ba4d2 100644 --- a/src/fs/lvm2_pv.cpp +++ b/src/fs/lvm2_pv.cpp @@ -71,6 +71,8 @@ void lvm2_pv::init() void lvm2_pv::scan(const QString& deviceNode) { getPESize(deviceNode); + m_AllocatedPE = getAllocatedPE(deviceNode); + m_TotalPE = getTotalPE(deviceNode); } bool lvm2_pv::supportToolFound() const @@ -314,7 +316,7 @@ QString lvm2_pv::getVGName(const QString& deviceNode) return getpvField(QStringLiteral("vg_name"), deviceNode); } -QList lvm2_pv::getFreePVinNode(const PartitionNode* parent) +QList lvm2_pv::getPVinNode(const PartitionNode* parent, const QString& vgName) { QList partitions; if (parent == nullptr) @@ -327,7 +329,7 @@ QList lvm2_pv::getFreePVinNode(const PartitionNode* parent) continue; if (node->children().size() > 0) - partitions.append(getFreePVinNode(node)); + partitions.append(getPVinNode(node, vgName)); // FIXME: reenable newly created PVs (before applying) once everything works if(p->fileSystem().type() == FileSystem::Lvm2_PV && p->mountPoint() == QString() && p->deviceNode() == p->partitionPath()) @@ -337,11 +339,17 @@ QList lvm2_pv::getFreePVinNode(const PartitionNode* parent) return partitions; } -QList lvm2_pv::getFreePV(const QList& devices) +/** construct a list of Partition objects for LVM PVs that are either unused or belong to some VG. + * + * @param devices list of Devices which we scan for LVM PVs + * @param vgName name of the volume group + * @return list of LVM PVs + */ +QList lvm2_pv::getPVs(const QList& devices, const QString& vgName) { QList partitions; for (auto const &d : devices) - partitions.append(getFreePVinNode(d->partitionTable())); + partitions.append(getPVinNode(d->partitionTable(), vgName)); return partitions; } diff --git a/src/fs/lvm2_pv.h b/src/fs/lvm2_pv.h index 554effd..b175411 100644 --- a/src/fs/lvm2_pv.h +++ b/src/fs/lvm2_pv.h @@ -114,9 +114,12 @@ public: static qint64 getPVSize(const QString& deviceNode); // return PV size in bytes static qint64 getPVSize(const QStringList& deviceNodeList); static QString getVGName(const QString& deviceNode); - static QList getFreePVinNode(const PartitionNode* parent); - static QList getFreePV(const QList& devices); + static QList getPVinNode(const PartitionNode* parent, const QString& vgName = QString()); + static QList getPVs(const QList& devices, const QString& vgName = QString()); + qint64 allocatedPE() const { return m_AllocatedPE; }; + qint64 freePE() const { return m_TotalPE - m_AllocatedPE; }; + qint64 totalPE() const { return m_TotalPE; }; qint64 peSize() const { return m_PESize; }; public: @@ -135,6 +138,8 @@ public: private: qint64 m_PESize; + qint64 m_TotalPE; + qint64 m_AllocatedPE; }; } diff --git a/src/jobs/movephysicalvolumejob.cpp b/src/jobs/movephysicalvolumejob.cpp index 8f13985..c22fec0 100644 --- a/src/jobs/movephysicalvolumejob.cpp +++ b/src/jobs/movephysicalvolumejob.cpp @@ -39,7 +39,7 @@ bool MovePhysicalVolumeJob::run(Report& parent) Report* report = jobStarted(parent); - QStringList destinations = LvmDevice::getPVs(device().name()); + QStringList destinations = device().deviceNodes(); for (const auto &partPath : partList()) { if (destinations.contains(partPath)) { destinations.removeAll(partPath); diff --git a/src/ops/resizevolumegroupoperation.cpp b/src/ops/resizevolumegroupoperation.cpp index 159236b..da50205 100644 --- a/src/ops/resizevolumegroupoperation.cpp +++ b/src/ops/resizevolumegroupoperation.cpp @@ -32,32 +32,28 @@ @param d the Device to create the new PartitionTable on @param partlist list of LVM Physical Volumes that should be in LVM Volume Group */ -ResizeVolumeGroupOperation::ResizeVolumeGroupOperation(LvmDevice& d, const QStringList partlist) : - Operation(), - m_Device(d), - m_TargetList(partlist), - m_CurrentList(LvmDevice::getPVs(d.name())), - m_GrowVolumeGroupJob(nullptr), - m_ShrinkVolumeGroupJob(nullptr), - m_MovePhysicalVolumeJob(nullptr) +ResizeVolumeGroupOperation::ResizeVolumeGroupOperation(LvmDevice& d, const QStringList partlist) + : Operation() + , m_Device(d) + , m_TargetList(partlist) + , m_CurrentList(d.deviceNodes()) + , m_GrowVolumeGroupJob(nullptr) + , m_ShrinkVolumeGroupJob(nullptr) + , m_MovePhysicalVolumeJob(nullptr) { const QStringList curList = currentList(); m_TargetSize = FS::lvm2_pv::getPVSize(targetList()); m_CurrentSize = FS::lvm2_pv::getPVSize(currentList()); QStringList toRemoveList = curList; - for (const QString &path : partlist) { - if (toRemoveList.contains(path)) { + for (const QString &path : partlist) + if (toRemoveList.contains(path)) toRemoveList.removeAll(path); - } - } QStringList toInsertList = partlist; - for (const QString &path : curList) { - if (toInsertList.contains(path)) { + for (const QString &path : curList) + if (toInsertList.contains(path)) toInsertList.removeAll(path); - } - } qint64 freePE = FS::lvm2_pv::getFreePE(curList) - FS::lvm2_pv::getFreePE(toRemoveList); qint64 movePE = FS::lvm2_pv::getAllocatedPE(toRemoveList);