diff --git a/src/core/lvmdevice.cpp b/src/core/lvmdevice.cpp index 6f31f2d..341dca5 100644 --- a/src/core/lvmdevice.cpp +++ b/src/core/lvmdevice.cpp @@ -1,6 +1,5 @@ /************************************************************************* - * Copyright (C) 2008 by Volker Lanz * - * Copyright (C) 2016 by Andrius Štikonas * + * Copyright (C) 2016 by Chantara Tith * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -17,11 +16,15 @@ *************************************************************************/ #include "core/lvmdevice.h" +#include "fs/filesystem.h" +#include "fs/filesystemfactory.h" +#include "core/partition.h" #include "core/partitiontable.h" #include "util/externalcommand.h" #include +#include /** Constructs a representation of LVM device with functionning LV as Partition @param name Volume Group name @@ -37,20 +40,100 @@ LvmDevice::LvmDevice(const QString& name, const QString& iconname) , m_totalPE(getTotalPE(name)) , m_allocPE(getAllocatedPE(name)) , m_freePE(getFreePE(name)) + , m_UUID(getUUID(name)) { - //called to initialize member variables - //refresh(); initPartitions(); } + /* -void LvmDevice::refresh() const +void LvmDevice::update() const { } */ -void LvmDevice::initPartitions() const +void LvmDevice::initPartitions() { - //PartitionTable* pTable = new PartitionTable(PartitionTable::TableType::vmd,0, ) + qint64 firstUsable = 0; + qint64 lastusable = totalPE() - 1; + PartitionTable* pTable = new PartitionTable(PartitionTable::vmd, firstUsable, lastusable); + + foreach (Partition* p, scanPartitions(*this, pTable)) { + pTable->append(p); + } + + this->setPartitionTable(pTable); +} + +/** + return sorted Partition(LV) Array +*/ +QList LvmDevice::scanPartitions(const Device& dev, PartitionTable* pTable) const +{ + QList pList; + QList lvNodeList; + + ExternalCommand cmd(QStringLiteral("lvm"), + { QStringLiteral("lvdisplay"), + QStringLiteral("--units"), + QStringLiteral("B"), + dev.name()}); + if (cmd.run(-1) && cmd.exitCode() == 0) { + QRegularExpression pathRE(QStringLiteral("LV Path\\h+((\\w|\/)+)")); + QRegularExpressionMatchIterator pathMatch = pathRE.globalMatch(cmd.output()); + while (pathMatch.hasNext()) { + QRegularExpressionMatch path = pathMatch.next(); + lvNodeList << path.captured(1); + } + } + + foreach (QString lvNode, lvNodeList) { + pList.append(this->scanPartition(lvNode, dev, pTable)); + } + + return pList; +} + +/** + return sorted Partition(LV) Array +*/ +Partition* LvmDevice::scanPartition(const QString& lvPath, const Device& dev, PartitionTable* pTable) const +{ + qint64 startSector; + qint64 endSector; + QString mountPoint = QString(); + bool mounted = false; + + ExternalCommand cmd(QStringLiteral("lvm"), + { QStringLiteral("lvdisplay"), + QStringLiteral("--units"), + QStringLiteral("B"), + QStringLiteral("--maps"), + lvPath}); + + if (cmd.run(-1) && cmd.exitCode() == 0) { + + //TODO: regex for first and last sector of the LV + //TODO: stringing PE into one large contingiuous array of PE ?? + QRegularExpression re(QStringLiteral("Physical extents\\h+(\\d+)\\sto\\s(\\d+)")); + QRegularExpressionMatch match = re.match(cmd.output()); + if (match.hasMatch()) { + startSector = match.captured(1).toLongLong(); + endSector = match.captured(2).toLongLong(); + } + } + FileSystem* fs = FileSystemFactory::create(FileSystem::detectFileSystem(lvPath), startSector, endSector); + + Partition* part = new Partition(pTable, + dev, + PartitionRole(PartitionRole::Lvm_Lv), + fs, + startSector, + endSector, + lvPath, + PartitionTable::Flag::FlagLvm, + mountPoint, + mounted); + return part; } qint32 LvmDevice::getPeSize(const QString& vgname) @@ -95,7 +178,7 @@ qint32 LvmDevice::getAllocatedPE(const QString& vgname) QStringLiteral("B"), vgname}); if (cmd.run(-1) && cmd.exitCode() == 0) { - QRegularExpression re(QStringLiteral("Alloc PE.*\\h+(\\d+)")); + QRegularExpression re(QStringLiteral("Alloc PE / Size\\h+(\\d+)")); QRegularExpressionMatch match = re.match(cmd.output()); if (match.hasMatch()) { return match.captured(1).toInt(); @@ -112,7 +195,7 @@ qint32 LvmDevice::getFreePE(const QString& vgname) QStringLiteral("B"), vgname}); if (cmd.run(-1) && cmd.exitCode() == 0) { - QRegularExpression re(QStringLiteral("Free PE.*\\h+(\\d+)")); + QRegularExpression re(QStringLiteral("Free PE / Size\\h+(\\d+)")); QRegularExpressionMatch match = re.match(cmd.output()); if (match.hasMatch()) { return match.captured(1).toInt(); @@ -120,3 +203,20 @@ qint32 LvmDevice::getFreePE(const QString& vgname) } return -1; } + +QString LvmDevice::getUUID(const QString& vgname) +{ + ExternalCommand cmd(QStringLiteral("lvm"), + { QStringLiteral("vgdisplay"), + QStringLiteral("--units"), + QStringLiteral("B"), + vgname}); + if (cmd.run(-1) && cmd.exitCode() == 0) { + QRegularExpression re(QStringLiteral("LV UUID\\h+(\\w+)")); + QRegularExpressionMatch match = re.match(cmd.output()); + if (match.hasMatch()) { + return match.captured(1); + } + } + return QStringLiteral("---"); +} diff --git a/src/core/lvmdevice.h b/src/core/lvmdevice.h index 524e821..0a801ea 100644 --- a/src/core/lvmdevice.h +++ b/src/core/lvmdevice.h @@ -67,9 +67,14 @@ public: static qint32 getTotalPE(const QString& name); static qint32 getAllocatedPE(const QString& name); static qint32 getFreePE(const QString& name); + static QString getUUID(const QString& name); protected: -// void init() const; - void initPartitions() const; + void update(); + void initPartitions(); +public: + QList scanPartitions(const Device& dev, PartitionTable* pTable) const; + Partition* scanPartition(const QString& lvPath, const Device& dev, PartitionTable* pTable) const; + private: @@ -77,6 +82,7 @@ private: qint32 m_totalPE; qint32 m_allocPE; qint32 m_freePE; + QString m_UUID; }; #endif