- Refactoring LVM::pvList to be a class with static QList<LvmPV> attribute instead of extern instance.

- Moving LVM VG verification in canShrink, canMove, canGrow to isLVMPVinNewlyVG method at ResizeOperation.
- Don't grow LVM PVs that are being targeted by CreateVolumeGroupOperations.
This commit is contained in:
Caio Carvalho 2018-05-09 04:09:17 -03:00
parent 6b0af70ccd
commit 9e6cf4063a
7 changed files with 68 additions and 53 deletions

View File

@ -196,18 +196,19 @@ void LvmDevice::scanSystemLVM(QList<Device*>& devices)
lvmList.append(new LvmDevice(vgName)); lvmList.append(new LvmDevice(vgName));
} }
// Some LVM operations require additional information about LVM physical volumes which we store in LVM::pvList // Some LVM operations require additional information about LVM physical volumes which we store in LVM::pvList::list()
LVM::pvList = FS::lvm2_pv::getPVs(devices); LVM::pvList::list().clear();
LVM::pvList::list().append(FS::lvm2_pv::getPVs(devices));
// Look for LVM physical volumes in LVM VGs // Look for LVM physical volumes in LVM VGs
for (const auto &d : lvmList) { for (const auto &d : lvmList) {
devices.append(d); devices.append(d);
LVM::pvList.append(FS::lvm2_pv::getPVinNode(d->partitionTable())); LVM::pvList::list().append(FS::lvm2_pv::getPVinNode(d->partitionTable()));
} }
// Inform LvmDevice about which physical volumes form that particular LvmDevice // Inform LvmDevice about which physical volumes form that particular LvmDevice
for (const auto &d : lvmList) for (const auto &d : lvmList)
for (const auto &p : qAsConst(LVM::pvList)) for (const auto &p : qAsConst(LVM::pvList::list()))
if (p.vgName() == d->name()) if (p.vgName() == d->name())
d->physicalVolumes().append(p.partition()); d->physicalVolumes().append(p.partition());

View File

@ -287,7 +287,7 @@ bool luks::cryptOpen(QWidget* parent, const QString& deviceNode)
if (!m_isCryptOpen) if (!m_isCryptOpen)
return false; return false;
for (auto &p : LVM::pvList) for (auto &p : LVM::pvList::list())
if (p.isLuks() && p.partition()->deviceNode() == deviceNode && p.partition()->fileSystem().type() == FileSystem::Type::Lvm2_PV) if (p.isLuks() && p.partition()->deviceNode() == deviceNode && p.partition()->fileSystem().type() == FileSystem::Type::Lvm2_PV)
p.setLuks(false); p.setLuks(false);
@ -326,7 +326,7 @@ bool luks::cryptClose(const QString& deviceNode)
m_isCryptOpen = (m_innerFs != nullptr); m_isCryptOpen = (m_innerFs != nullptr);
for (auto &p : LVM::pvList) for (auto &p : LVM::pvList::list())
if (!p.isLuks() && p.partition()->deviceNode() == deviceNode) if (!p.isLuks() && p.partition()->deviceNode() == deviceNode)
p.setLuks(true); p.setLuks(true);

View File

@ -296,7 +296,11 @@ QList<LvmPV> lvm2_pv::getPVs(const QList<Device*>& devices)
} }
QList<LvmPV> LVM::pvList; namespace LVM {
QList<LvmPV> pvList::m_list;
}
LvmPV::LvmPV(const QString vgName, const Partition* p, bool isLuks) LvmPV::LvmPV(const QString vgName, const Partition* p, bool isLuks)
: m_vgName(vgName) : m_vgName(vgName)

View File

@ -62,7 +62,22 @@ private:
}; };
namespace LVM { namespace LVM {
extern LIBKPMCORE_EXPORT QList<LvmPV> pvList; /** Class to access a global LVM PV list.
@author Caio Carvalho <caiojcarvalho@gmail.com>
*/
class LIBKPMCORE_EXPORT pvList
{
public:
static QList<LvmPV> &list() {
return m_list;
}
private:
pvList() { }
private:
static QList<LvmPV> m_list;
};
} }
namespace FS namespace FS

View File

@ -128,7 +128,7 @@ bool DeleteOperation::canDelete(const Partition* p, const QList<Operation *> pen
} }
else if (p->fileSystem().type() == FileSystem::Type::Luks || p->fileSystem().type() == FileSystem::Type::Luks2) { else if (p->fileSystem().type() == FileSystem::Type::Luks || p->fileSystem().type() == FileSystem::Type::Luks2) {
// See if innerFS is LVM // See if innerFS is LVM
FileSystem *fs = dynamic_cast<const FS::luks *>(&p->fileSystem())->innerFS(); FileSystem *fs = static_cast<const FS::luks *>(&p->fileSystem())->innerFS();
if (fs) { if (fs) {
if (fs->type() == FileSystem::Type::Lvm2_PV) { if (fs->type() == FileSystem::Type::Lvm2_PV) {

View File

@ -329,11 +329,14 @@ bool ResizeOperation::grow(Report& report)
@param p the Partition in question, may be nullptr. @param p the Partition in question, may be nullptr.
@return true if @p p can be grown. @return true if @p p can be grown.
*/ */
bool ResizeOperation::canGrow(const Partition* p) bool ResizeOperation::canGrow(const Partition* p, const QList<Operation *> pendingOps)
{ {
if (p == nullptr) if (p == nullptr)
return false; return false;
if (isLVMPVinNewlyVG(p, pendingOps))
return false;
// we can always grow, shrink or move a partition not yet written to disk // we can always grow, shrink or move a partition not yet written to disk
if (p->state() == Partition::State::New && !p->roles().has(PartitionRole::Luks)) if (p->state() == Partition::State::New && !p->roles().has(PartitionRole::Luks))
return true; return true;
@ -353,27 +356,8 @@ bool ResizeOperation::canShrink(const Partition* p, const QList<Operation *> pen
if (p == nullptr) if (p == nullptr)
return false; return false;
if (p->fileSystem().type() == FileSystem::Type::Lvm2_PV) { if (isLVMPVinNewlyVG(p, pendingOps))
// See if there is a newly created VG targeting this partition return false;
for (Operation *op : qAsConst(pendingOps)) {
if (dynamic_cast<CreateVolumeGroupOperation *>(op) && op->targets(*p))
return false;
}
}
else if (p->fileSystem().type() == FileSystem::Type::Luks || p->fileSystem().type() == FileSystem::Type::Luks2) {
// See if innerFS is LVM
FileSystem *fs = dynamic_cast<const FS::luks *>(&p->fileSystem())->innerFS();
if (fs) {
if (fs->type() == FileSystem::Type::Lvm2_PV) {
// See if there is a newly created VG targeting this partition
for (Operation *op : qAsConst(pendingOps)) {
if (dynamic_cast<CreateVolumeGroupOperation *>(op) && op->targets(*p))
return false;
}
}
}
}
// we can always grow, shrink or move a partition not yet written to disk // we can always grow, shrink or move a partition not yet written to disk
if (p->state() == Partition::State::New && !p->roles().has(PartitionRole::Luks)) if (p->state() == Partition::State::New && !p->roles().has(PartitionRole::Luks))
@ -397,27 +381,8 @@ bool ResizeOperation::canMove(const Partition* p, const QList<Operation *> pendi
if (p == nullptr) if (p == nullptr)
return false; return false;
if (p->fileSystem().type() == FileSystem::Type::Lvm2_PV) { if (isLVMPVinNewlyVG(p, pendingOps))
// See if there is a newly created VG targeting this partition return false;
for (Operation *op : qAsConst(pendingOps)) {
if (dynamic_cast<CreateVolumeGroupOperation *>(op) && op->targets(*p))
return false;
}
}
else if (p->fileSystem().type() == FileSystem::Type::Luks || p->fileSystem().type() == FileSystem::Type::Luks2) {
// See if innerFS is LVM
FileSystem *fs = dynamic_cast<const FS::luks *>(&p->fileSystem())->innerFS();
if (fs) {
if (fs->type() == FileSystem::Type::Lvm2_PV) {
// See if there is a newly created VG targeting this partition
for (Operation *op : qAsConst(pendingOps)) {
if (dynamic_cast<CreateVolumeGroupOperation *>(op) && op->targets(*p))
return false;
}
}
}
}
// we can always grow, shrink or move a partition not yet written to disk // we can always grow, shrink or move a partition not yet written to disk
if (p->state() == Partition::State::New) if (p->state() == Partition::State::New)
@ -433,3 +398,30 @@ bool ResizeOperation::canMove(const Partition* p, const QList<Operation *> pendi
return p->fileSystem().supportMove() != FileSystem::cmdSupportNone; return p->fileSystem().supportMove() != FileSystem::cmdSupportNone;
} }
bool ResizeOperation::isLVMPVinNewlyVG(const Partition *p, const QList<Operation *> pendingOps)
{
if (p->fileSystem().type() == FileSystem::Type::Lvm2_PV) {
// See if there is a newly created VG targeting this partition
for (Operation *op : qAsConst(pendingOps)) {
if (dynamic_cast<CreateVolumeGroupOperation *>(op) && op->targets(*p))
return true;
}
}
else if (p->fileSystem().type() == FileSystem::Type::Luks || p->fileSystem().type() == FileSystem::Type::Luks2) {
// See if innerFS is LVM
FileSystem *fs = static_cast<const FS::luks *>(&p->fileSystem())->innerFS();
if (fs) {
if (fs->type() == FileSystem::Type::Lvm2_PV) {
// See if there is a newly created VG targeting this partition
for (Operation *op : qAsConst(pendingOps)) {
if (dynamic_cast<CreateVolumeGroupOperation *>(op) && op->targets(*p))
return true;
}
}
}
}
return false;
}

View File

@ -85,7 +85,7 @@ public:
bool targets(const Device& d) const override; bool targets(const Device& d) const override;
bool targets(const Partition& p) const override; bool targets(const Partition& p) const override;
static bool canGrow(const Partition* p); static bool canGrow(const Partition* p, const QList<Operation *> pendingOps = QList<Operation *>());
static bool canShrink(const Partition* p, const QList<Operation *> pendingOps = QList<Operation *>()); static bool canShrink(const Partition* p, const QList<Operation *> pendingOps = QList<Operation *>());
static bool canMove(const Partition* p, const QList<Operation *> pendingOps = QList<Operation *>()); static bool canMove(const Partition* p, const QList<Operation *> pendingOps = QList<Operation *>());
@ -158,6 +158,9 @@ protected:
return m_CheckResizedJob; return m_CheckResizedJob;
} }
private:
static bool isLVMPVinNewlyVG(const Partition* p, const QList<Operation *> pendingOps);
private: private:
Device& m_TargetDevice; Device& m_TargetDevice;
Partition& m_Partition; Partition& m_Partition;