Add LVM operations

This commit is contained in:
Chantara Tith 2016-06-24 01:41:55 +07:00 committed by Andrius Štikonas
parent 933ecc9cce
commit 3b7eda5933
7 changed files with 157 additions and 45 deletions

View File

@ -28,6 +28,7 @@
#include <QStringList>
#include <KMountPoint>
#include <KDiskFreeSpaceInfo>
#include <KLocalizedString>
/** Constructs a representation of LVM device with functionning LV as Partition
*
@ -58,13 +59,28 @@ void LvmDevice::initPartitions()
foreach (Partition* p, scanPartitions(*this, pTable)) {
pTable->append(p);
}
// Manually insert unallocated space as Partition.
// TODO: PartitionTable's updateUnallocated seem not to works.
if (freePE()) {
qint64 startUnallocated = lastusable - freePE() + 1;
qint64 endUnallocated = lastusable;
pTable->append(new Partition(pTable,
*this,
PartitionRole(PartitionRole::Unallocated),
FileSystemFactory::create(FileSystem::Unknown,startUnallocated, endUnallocated),
startUnallocated,
endUnallocated,
QString())
);
}
setPartitionTable(pTable);
}
/**
* @returns sorted Partition(LV) Array
*/
QList<Partition*> LvmDevice::scanPartitions(const Device& dev, PartitionTable* pTable) const
QList<Partition*> LvmDevice::scanPartitions(const LvmDevice& dev, PartitionTable* pTable) const
{
QList<Partition*> pList;
foreach (QString lvPath, lvPathList()) {
@ -76,7 +92,7 @@ QList<Partition*> LvmDevice::scanPartitions(const Device& dev, PartitionTable* p
/**
* @returns sorted Partition(LV) Array
*/
Partition* LvmDevice::scanPartition(const QString& lvpath, const Device& dev, PartitionTable* pTable) const
Partition* LvmDevice::scanPartition(const QString& lvpath, const LvmDevice& dev, PartitionTable* pTable) const
{
/*
* NOTE:
@ -204,7 +220,7 @@ QString LvmDevice::getUUID(const QString& vgname)
}
/** Query LVM details with field name
/** Get LVM vgs command output with field name
*
* @param fieldName lvm field name
* @param vgname
@ -246,7 +262,7 @@ qint32 LvmDevice::getTotalLE(const QString& lvpath)
return -1;
}
bool LvmDevice::removeLV(Device& dev, Partition& part)
bool LvmDevice::removeLV(Report& report, LvmDevice& dev, Partition& part)
{
ExternalCommand cmd(QStringLiteral("lvm"),
{ QStringLiteral("lvremove"),
@ -254,9 +270,79 @@ bool LvmDevice::removeLV(Device& dev, Partition& part)
part.partitionPath()});
if (cmd.run(-1) && cmd.exitCode() == 0) {
//TODO: remove Partition from PartitionTable and delete from memory
//TODO: remove Partition from PartitionTable and delete from memory ??
dev.partitionTable()->remove(&part);
return true;
}
report.line() << xi18nc("@info/plain", "Failed to add Logical Volume");
return false;
}
bool LvmDevice::createLV(Report& report, LvmDevice& dev, Partition& part, const QString& lvname)
{
ExternalCommand cmd(QStringLiteral("lvm"),
{ QStringLiteral("lvcreate"),
QStringLiteral("--yes"),
QStringLiteral("--extents"),
QString::number(part.length()),
QStringLiteral("--name"),
lvname,
dev.name()});
if (cmd.run(-1) && cmd.exitCode() == 0) {
return true;
}
//report.line() << xi18nc("@info/plain", "Failed to add Logical Volume");
report.line() << cmd.output();
return false;
}
bool LvmDevice::resizeLv(Report& report, LvmDevice& dev, Partition& part)
{
Q_UNUSED(dev);
//TODO: through tests
ExternalCommand cmd(QStringLiteral("lvm"),
{ QStringLiteral("lvresize"),
//QStringLiteral("--yes"), // this command could corrupt user data
QStringLiteral("--extents"),
QString::number(part.length()),
part.partitionPath()});
if (cmd.run(-1) && cmd.exitCode() == 0) {
return true;
}
report.line() << cmd.output();
return false;
}
bool LvmDevice::removePV(Report& report, LvmDevice& dev, const QString& pvPath)
{
//TODO: through tests
ExternalCommand cmd(QStringLiteral("lvm"),
{ QStringLiteral("vgreduce"),
//QStringLiteral("--yes"), // potentially corrupt user data
dev.name(),
pvPath});
if (cmd.run(-1) && cmd.exitCode() == 0) {
return true;
}
report.line() << cmd.output();
return false;
}
bool LvmDevice::insertPV(Report& report, LvmDevice& dev, const QString& pvPath)
{
//TODO: through tests
ExternalCommand cmd(QStringLiteral("lvm"),
{ QStringLiteral("vgextend"),
//QStringLiteral("--yes"), // potentially corrupt user data
dev.name(),
pvPath});
if (cmd.run(-1) && cmd.exitCode() == 0) {
return true;
}
report.line() << cmd.output();
return false;
}

View File

@ -22,6 +22,7 @@
#include "core/volumemanagerdevice.h"
#include "util/libpartitionmanagerexport.h"
#include "util/report.h"
#include <QString>
#include <QObject>
@ -48,8 +49,8 @@ public:
LvmDevice(const QString& name, const QString& iconname = QString());
public:
QList<Partition*> scanPartitions(const Device& dev, PartitionTable* pTable) const;
Partition* scanPartition(const QString& lvPath, const Device& dev, PartitionTable* pTable) const;
QList<Partition*> scanPartitions(const LvmDevice& dev, PartitionTable* pTable) const;
Partition* scanPartition(const QString& lvPath, const LvmDevice& dev, PartitionTable* pTable) const;
static qint32 getPeSize(const QString& vgname);
static qint32 getTotalPE(const QString& vgname);
@ -60,7 +61,12 @@ public:
static qint32 getTotalLE(const QString& lvpath);
static bool removeLV(Device& dev, Partition& part);
static bool removeLV(Report& report, LvmDevice& dev, Partition& part);
static bool createLV(Report& report, LvmDevice& dev, Partition& part, const QString& lvname);
static bool resizeLv(Report& report, LvmDevice& dev, Partition& part);
static bool removePV(Report& report, LvmDevice& dev, const QString& pvPath);
static bool insertPV(Report& report, LvmDevice& dev, const QString& pvPath);
protected:
void initPartitions();

View File

@ -53,25 +53,29 @@ bool CreateFileSystemJob::run(Report& parent)
if (partition().fileSystem().supportCreate() == FileSystem::cmdSupportFileSystem) {
if (partition().fileSystem().create(*report, partition().deviceNode())) {
CoreBackendDevice* backendDevice = CoreBackendManager::self()->backend()->openDevice(device().deviceNode());
if (device().type() == Device::Disk_Device) {
CoreBackendDevice* backendDevice = CoreBackendManager::self()->backend()->openDevice(device().deviceNode());
if (backendDevice) {
CoreBackendPartitionTable* backendPartitionTable = backendDevice->openPartitionTable();
if (backendDevice) {
CoreBackendPartitionTable* backendPartitionTable = backendDevice->openPartitionTable();
if (backendPartitionTable) {
if (backendPartitionTable->setPartitionSystemType(*report, partition())) {
rval = true;
backendPartitionTable->commit();
if (backendPartitionTable) {
if (backendPartitionTable->setPartitionSystemType(*report, partition())) {
rval = true;
backendPartitionTable->commit();
} else
report->line() << xi18nc("@info:progress", "Failed to set the system type for the file system on partition <filename>%1</filename>.", partition().deviceNode());
delete backendPartitionTable;
} else
report->line() << xi18nc("@info:progress", "Failed to set the system type for the file system on partition <filename>%1</filename>.", partition().deviceNode());
report->line() << xi18nc("@info:progress", "Could not open partition table on device <filename>%1</filename> to set the system type for partition <filename>%2</filename>.", device().deviceNode(), partition().deviceNode());
delete backendPartitionTable;
delete backendDevice;
} else
report->line() << xi18nc("@info:progress", "Could not open partition table on device <filename>%1</filename> to set the system type for partition <filename>%2</filename>.", device().deviceNode(), partition().deviceNode());
delete backendDevice;
} else
report->line() << xi18nc("@info:progress", "Could not open device <filename>%1</filename> to set the system type for partition <filename>%2</filename>.", device().deviceNode(), partition().deviceNode());
report->line() << xi18nc("@info:progress", "Could not open device <filename>%1</filename> to set the system type for partition <filename>%2</filename>.", device().deviceNode(), partition().deviceNode());
} else if (device().type() == Device::LVM_Device) {
rval = true;
}
}
}

View File

@ -25,6 +25,7 @@
#include "core/partition.h"
#include "core/device.h"
#include "core/lvmdevice.h"
#include "util/report.h"
@ -74,7 +75,10 @@ bool CreatePartitionJob::run(Report& parent)
} else
report->line() << xi18nc("@info:progress", "Could not open device <filename>%1</filename> to create new partition <filename>%2</filename>.", device().deviceNode(), partition().deviceNode());
} else if (device().type() == Device::LVM_Device) {
LvmDevice& dev = dynamic_cast<LvmDevice&>(device());
rval = LvmDevice::createLV(*report, dev, partition(), QStringLiteral("randomLV"));
partition().setPartitionPath(dev.deviceNode() + QStringLiteral("/randomLV"));
partition().setState(Partition::StateNone);
}
jobFinished(*report, rval);

View File

@ -44,16 +44,20 @@ bool CreatePartitionTableJob::run(Report& parent)
Report* report = jobStarted(parent);
CoreBackendDevice* backendDevice = CoreBackendManager::self()->backend()->openDevice(device().deviceNode());
if (device().type() == Device::Disk_Device) {
CoreBackendDevice* backendDevice = CoreBackendManager::self()->backend()->openDevice(device().deviceNode());
if (backendDevice != nullptr) {
Q_ASSERT(device().partitionTable());
if (backendDevice != nullptr) {
Q_ASSERT(device().partitionTable());
rval = backendDevice->createPartitionTable(*report, *device().partitionTable());
rval = backendDevice->createPartitionTable(*report, *device().partitionTable());
delete backendDevice;
} else
report->line() << xi18nc("@info:progress", "Creating partition table failed: Could not open device <filename>%1</filename>.", device().deviceNode());
delete backendDevice;
} else
report->line() << xi18nc("@info:progress", "Creating partition table failed: Could not open device <filename>%1</filename>.", device().deviceNode());
} else if (device().type() == Device::LVM_Device) {
//TODO: figure what to do wit LVM partitionTable
}
jobFinished(*report, rval);

View File

@ -80,7 +80,8 @@ bool DeletePartitionJob::run(Report& parent)
} else
report->line() << xi18nc("@info:progress", "Deleting partition failed: Could not open device <filename>%1</filename>.", device().deviceNode());
} else if (device().type() == Device::LVM_Device) {
rval = LvmDevice::removeLV(device(), partition());
LvmDevice& dev = dynamic_cast<LvmDevice&>(device());
rval = LvmDevice::removeLV(*report, dev, partition());
}
jobFinished(*report, rval);

View File

@ -54,26 +54,33 @@ bool SetPartGeometryJob::run(Report& parent)
Report* report = jobStarted(parent);
CoreBackendDevice* backendDevice = CoreBackendManager::self()->backend()->openDevice(device().deviceNode());
if(device().type() == Device::Disk_Device) {
CoreBackendDevice* backendDevice = CoreBackendManager::self()->backend()->openDevice(device().deviceNode());
if (backendDevice) {
CoreBackendPartitionTable* backendPartitionTable = backendDevice->openPartitionTable();
if (backendDevice) {
CoreBackendPartitionTable* backendPartitionTable = backendDevice->openPartitionTable();
if (backendPartitionTable) {
rval = backendPartitionTable->updateGeometry(*report, partition(), newStart(), newStart() + newLength() - 1);
if (backendPartitionTable) {
rval = backendPartitionTable->updateGeometry(*report, partition(), newStart(), newStart() + newLength() - 1);
if (rval) {
partition().setFirstSector(newStart());
partition().setLastSector(newStart() + newLength() - 1);
backendPartitionTable->commit();
if (rval) {
partition().setFirstSector(newStart());
partition().setLastSector(newStart() + newLength() - 1);
backendPartitionTable->commit();
}
delete backendPartitionTable;
}
delete backendPartitionTable;
}
delete backendDevice;
} else
report->line() << xi18nc("@info:progress", "Could not open device <filename>%1</filename> while trying to resize/move partition <filename>%2</filename>.", device().deviceNode(), partition().deviceNode());
delete backendDevice;
} else
report->line() << xi18nc("@info:progress", "Could not open device <filename>%1</filename> while trying to resize/move partition <filename>%2</filename>.", device().deviceNode(), partition().deviceNode());
} else if (device().type() == Device::LVM_Device) {
//TODO: resize given LVM LV
partition().setFirstSector(newStart());
partition().setLastSector(newStart() + newLength() - 1);
}
jobFinished(*report, rval);