More optimizations for LVM.

This commit is contained in:
Andrius Štikonas 2016-09-08 01:42:04 +01:00
parent 882886c1d4
commit 70a9a0dd9a
7 changed files with 57 additions and 61 deletions

View File

@ -63,7 +63,7 @@ void DeviceScanner::scan()
clear(); clear();
const QList<Device*> deviceList = CoreBackendManager::self()->backend()->scanDevices(); const QList<Device*> deviceList = CoreBackendManager::self()->backend()->scanDevices();
const QList<LvmDevice*> lvmList = LvmDevice::scanSystemLVM(); const QList<LvmDevice*> lvmList = LvmDevice::scanSystemLVM(deviceList); // NOTE: PVs inside LVM won't be scanned
for (const auto &d : deviceList) for (const auto &d : deviceList)
operationStack().addDevice(d); operationStack().addDevice(d);

View File

@ -37,9 +37,10 @@
/** Constructs a representation of LVM device with initialized LV as Partitions /** Constructs a representation of LVM device with initialized LV as Partitions
* *
* @param vgName Volume Group name * @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 * @param iconName Icon representing LVM Volume group
*/ */
LvmDevice::LvmDevice(const QString& vgName, const QString& iconName) LvmDevice::LvmDevice(const QString& vgName, const QList<Device*>& devices, const QString& iconName)
: VolumeManagerDevice(vgName, : VolumeManagerDevice(vgName,
(QStringLiteral("/dev/") + vgName), (QStringLiteral("/dev/") + vgName),
getPeSize(vgName), getPeSize(vgName),
@ -52,7 +53,7 @@ LvmDevice::LvmDevice(const QString& vgName, const QString& iconName)
m_freePE = getFreePE(vgName); m_freePE = getFreePE(vgName);
m_allocPE = m_totalPE - m_freePE; m_allocPE = m_totalPE - m_freePE;
m_UUID = getUUID(vgName); 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_LVPathList = new QStringList(getLVs(vgName));
m_LVSizeMap = new QMap<QString, qint64>(); m_LVSizeMap = new QMap<QString, qint64>();
@ -67,7 +68,6 @@ QStringList LvmDevice::s_DirtyPVs;
LvmDevice::~LvmDevice() LvmDevice::~LvmDevice()
{ {
delete m_PVPathList;
delete m_LVPathList; delete m_LVPathList;
delete m_LVSizeMap; delete m_LVSizeMap;
} }
@ -198,13 +198,14 @@ Partition* LvmDevice::scanPartition(const QString& lvPath, PartitionTable* pTabl
/** scan and contruct list of initialized LvmDevice objects. /** scan and contruct list of initialized LvmDevice objects.
* *
* @param devices list of Devices which we scan for LVM PVs
* @return list of initialized LvmDevices * @return list of initialized LvmDevices
*/ */
QList<LvmDevice*> LvmDevice::scanSystemLVM() QList<LvmDevice*> LvmDevice::scanSystemLVM(const QList<Device*>& devices)
{ {
QList<LvmDevice*> lvmList; QList<LvmDevice*> lvmList;
for (const auto &vgName : getVGs()) { for (const auto &vgName : getVGs()) {
lvmList.append(new LvmDevice(vgName)); lvmList.append(new LvmDevice(vgName, devices));
} }
return lvmList; return lvmList;
} }
@ -226,7 +227,11 @@ qint64 LvmDevice::mappedSector(const QString& lvPath, qint64 sector) const
const QStringList LvmDevice::deviceNodes() 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 const QStringList LvmDevice::partitionNodes() const
@ -252,20 +257,6 @@ const QStringList LvmDevice::getVGs()
return vgList; 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) const QStringList LvmDevice::getLVs(const QString& vgName)
{ {
QStringList lvPathList; QStringList lvPathList;
@ -431,21 +422,18 @@ bool LvmDevice::insertPV(Report& report, LvmDevice& d, const QString& pvPath)
return (cmd.run(-1) && cmd.exitCode() == 0); return (cmd.run(-1) && cmd.exitCode() == 0);
} }
bool LvmDevice::movePV(Report& report, const QString& pvPath, const QStringList& destinations) 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; return true;
}
QStringList args = QStringList(); QStringList args = QStringList();
args << QStringLiteral("pvmove"); args << QStringLiteral("pvmove");
args << pvPath; args << pvPath;
if (!destinations.isEmpty()) { if (!destinations.isEmpty())
for (const auto &destPath : destinations) { for (const auto &destPath : destinations)
args << destPath.trimmed(); args << destPath.trimmed();
}
}
ExternalCommand cmd(report, QStringLiteral("lvm"), args); ExternalCommand cmd(report, QStringLiteral("lvm"), args);
return (cmd.run(-1) && cmd.exitCode() == 0); return (cmd.run(-1) && cmd.exitCode() == 0);
@ -456,9 +444,9 @@ bool LvmDevice::createVG(Report& report, const QString vgName, const QStringList
QStringList args = QStringList(); QStringList args = QStringList();
args << QStringLiteral("vgcreate") << QStringLiteral("--physicalextentsize") << QString::number(peSize); args << QStringLiteral("vgcreate") << QStringLiteral("--physicalextentsize") << QString::number(peSize);
args << vgName; args << vgName;
for (const auto &pvNode : pvList) { for (const auto &pvNode : pvList)
args << pvNode.trimmed(); args << pvNode.trimmed();
}
ExternalCommand cmd(report, QStringLiteral("lvm"), args); ExternalCommand cmd(report, QStringLiteral("lvm"), args);
return (cmd.run(-1) && cmd.exitCode() == 0); return (cmd.run(-1) && cmd.exitCode() == 0);

View File

@ -19,6 +19,7 @@
#define LVMDEVICE__H #define LVMDEVICE__H
#include "core/device.h"
#include "core/volumemanagerdevice.h" #include "core/volumemanagerdevice.h"
#include "util/libpartitionmanagerexport.h" #include "util/libpartitionmanagerexport.h"
@ -43,7 +44,7 @@ class LIBKPMCORE_EXPORT LvmDevice : public VolumeManagerDevice
Q_DISABLE_COPY(LvmDevice) Q_DISABLE_COPY(LvmDevice)
public: public:
LvmDevice(const QString& name, const QString& iconName = QString()); LvmDevice(const QString& name, const QList<Device *>& devices, const QString& iconName = QString());
~LvmDevice(); ~LvmDevice();
public: public:
@ -54,11 +55,9 @@ public:
static QStringList s_DirtyPVs; static QStringList s_DirtyPVs;
public: public:
static QList<LvmDevice*> scanSystemLVM(const QList<Device*>& devices);
static QList<LvmDevice*> scanSystemLVM();
static const QStringList getVGs(); static const QStringList getVGs();
static const QStringList getPVs(const QString& vgName);
static const QStringList getLVs(const QString& vgName); static const QStringList getLVs(const QString& vgName);
static qint64 getPeSize(const QString& vgName); static qint64 getPeSize(const QString& vgName);
@ -114,11 +113,11 @@ public:
return m_LVPathList; return m_LVPathList;
} }
protected: const QList <const Partition*> physicalVolumes() const {
QStringList* PVPathList() const { return m_PVs;
return m_PVPathList;
} }
protected:
QMap<QString, qint64>* LVSizeMap() const { QMap<QString, qint64>* LVSizeMap() const {
return m_LVSizeMap; return m_LVSizeMap;
} }
@ -131,7 +130,7 @@ private:
QString m_UUID; QString m_UUID;
mutable QStringList* m_LVPathList; mutable QStringList* m_LVPathList;
mutable QStringList* m_PVPathList; mutable QList <const Partition*> m_PVs;
mutable QMap<QString, qint64>* m_LVSizeMap; mutable QMap<QString, qint64>* m_LVSizeMap;
}; };

View File

@ -71,6 +71,8 @@ void lvm2_pv::init()
void lvm2_pv::scan(const QString& deviceNode) void lvm2_pv::scan(const QString& deviceNode)
{ {
getPESize(deviceNode); getPESize(deviceNode);
m_AllocatedPE = getAllocatedPE(deviceNode);
m_TotalPE = getTotalPE(deviceNode);
} }
bool lvm2_pv::supportToolFound() const bool lvm2_pv::supportToolFound() const
@ -314,7 +316,7 @@ QString lvm2_pv::getVGName(const QString& deviceNode)
return getpvField(QStringLiteral("vg_name"), deviceNode); return getpvField(QStringLiteral("vg_name"), deviceNode);
} }
QList<const Partition *> lvm2_pv::getFreePVinNode(const PartitionNode* parent) QList<const Partition *> lvm2_pv::getPVinNode(const PartitionNode* parent, const QString& vgName)
{ {
QList<const Partition *> partitions; QList<const Partition *> partitions;
if (parent == nullptr) if (parent == nullptr)
@ -327,7 +329,7 @@ QList<const Partition *> lvm2_pv::getFreePVinNode(const PartitionNode* parent)
continue; continue;
if (node->children().size() > 0) if (node->children().size() > 0)
partitions.append(getFreePVinNode(node)); partitions.append(getPVinNode(node, vgName));
// FIXME: reenable newly created PVs (before applying) once everything works // FIXME: reenable newly created PVs (before applying) once everything works
if(p->fileSystem().type() == FileSystem::Lvm2_PV && p->mountPoint() == QString() && p->deviceNode() == p->partitionPath()) if(p->fileSystem().type() == FileSystem::Lvm2_PV && p->mountPoint() == QString() && p->deviceNode() == p->partitionPath())
@ -337,11 +339,17 @@ QList<const Partition *> lvm2_pv::getFreePVinNode(const PartitionNode* parent)
return partitions; return partitions;
} }
QList<const Partition *> lvm2_pv::getFreePV(const QList<Device*>& 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<const Partition *> lvm2_pv::getPVs(const QList<Device*>& devices, const QString& vgName)
{ {
QList<const Partition *> partitions; QList<const Partition *> partitions;
for (auto const &d : devices) for (auto const &d : devices)
partitions.append(getFreePVinNode(d->partitionTable())); partitions.append(getPVinNode(d->partitionTable(), vgName));
return partitions; return partitions;
} }

View File

@ -114,9 +114,12 @@ public:
static qint64 getPVSize(const QString& deviceNode); // return PV size in bytes static qint64 getPVSize(const QString& deviceNode); // return PV size in bytes
static qint64 getPVSize(const QStringList& deviceNodeList); static qint64 getPVSize(const QStringList& deviceNodeList);
static QString getVGName(const QString& deviceNode); static QString getVGName(const QString& deviceNode);
static QList<const Partition *> getFreePVinNode(const PartitionNode* parent); static QList<const Partition *> getPVinNode(const PartitionNode* parent, const QString& vgName = QString());
static QList<const Partition *> getFreePV(const QList<Device*>& devices); static QList<const Partition *> getPVs(const QList<Device*>& 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; }; qint64 peSize() const { return m_PESize; };
public: public:
@ -135,6 +138,8 @@ public:
private: private:
qint64 m_PESize; qint64 m_PESize;
qint64 m_TotalPE;
qint64 m_AllocatedPE;
}; };
} }

View File

@ -39,7 +39,7 @@ bool MovePhysicalVolumeJob::run(Report& parent)
Report* report = jobStarted(parent); Report* report = jobStarted(parent);
QStringList destinations = LvmDevice::getPVs(device().name()); QStringList destinations = device().deviceNodes();
for (const auto &partPath : partList()) { for (const auto &partPath : partList()) {
if (destinations.contains(partPath)) { if (destinations.contains(partPath)) {
destinations.removeAll(partPath); destinations.removeAll(partPath);

View File

@ -32,32 +32,28 @@
@param d the Device to create the new PartitionTable on @param d the Device to create the new PartitionTable on
@param partlist list of LVM Physical Volumes that should be in LVM Volume Group @param partlist list of LVM Physical Volumes that should be in LVM Volume Group
*/ */
ResizeVolumeGroupOperation::ResizeVolumeGroupOperation(LvmDevice& d, const QStringList partlist) : ResizeVolumeGroupOperation::ResizeVolumeGroupOperation(LvmDevice& d, const QStringList partlist)
Operation(), : Operation()
m_Device(d), , m_Device(d)
m_TargetList(partlist), , m_TargetList(partlist)
m_CurrentList(LvmDevice::getPVs(d.name())), , m_CurrentList(d.deviceNodes())
m_GrowVolumeGroupJob(nullptr), , m_GrowVolumeGroupJob(nullptr)
m_ShrinkVolumeGroupJob(nullptr), , m_ShrinkVolumeGroupJob(nullptr)
m_MovePhysicalVolumeJob(nullptr) , m_MovePhysicalVolumeJob(nullptr)
{ {
const QStringList curList = currentList(); const QStringList curList = currentList();
m_TargetSize = FS::lvm2_pv::getPVSize(targetList()); m_TargetSize = FS::lvm2_pv::getPVSize(targetList());
m_CurrentSize = FS::lvm2_pv::getPVSize(currentList()); m_CurrentSize = FS::lvm2_pv::getPVSize(currentList());
QStringList toRemoveList = curList; QStringList toRemoveList = curList;
for (const QString &path : partlist) { for (const QString &path : partlist)
if (toRemoveList.contains(path)) { if (toRemoveList.contains(path))
toRemoveList.removeAll(path); toRemoveList.removeAll(path);
}
}
QStringList toInsertList = partlist; QStringList toInsertList = partlist;
for (const QString &path : curList) { for (const QString &path : curList)
if (toInsertList.contains(path)) { if (toInsertList.contains(path))
toInsertList.removeAll(path); toInsertList.removeAll(path);
}
}
qint64 freePE = FS::lvm2_pv::getFreePE(curList) - FS::lvm2_pv::getFreePE(toRemoveList); qint64 freePE = FS::lvm2_pv::getFreePE(curList) - FS::lvm2_pv::getFreePE(toRemoveList);
qint64 movePE = FS::lvm2_pv::getAllocatedPE(toRemoveList); qint64 movePE = FS::lvm2_pv::getAllocatedPE(toRemoveList);