Add LVM operations
This commit is contained in:
parent
933ecc9cce
commit
3b7eda5933
|
@ -28,6 +28,7 @@
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <KMountPoint>
|
#include <KMountPoint>
|
||||||
#include <KDiskFreeSpaceInfo>
|
#include <KDiskFreeSpaceInfo>
|
||||||
|
#include <KLocalizedString>
|
||||||
|
|
||||||
/** Constructs a representation of LVM device with functionning LV as Partition
|
/** Constructs a representation of LVM device with functionning LV as Partition
|
||||||
*
|
*
|
||||||
|
@ -58,13 +59,28 @@ void LvmDevice::initPartitions()
|
||||||
foreach (Partition* p, scanPartitions(*this, pTable)) {
|
foreach (Partition* p, scanPartitions(*this, pTable)) {
|
||||||
pTable->append(p);
|
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);
|
setPartitionTable(pTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns sorted Partition(LV) Array
|
* @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;
|
QList<Partition*> pList;
|
||||||
foreach (QString lvPath, lvPathList()) {
|
foreach (QString lvPath, lvPathList()) {
|
||||||
|
@ -76,7 +92,7 @@ QList<Partition*> LvmDevice::scanPartitions(const Device& dev, PartitionTable* p
|
||||||
/**
|
/**
|
||||||
* @returns sorted Partition(LV) Array
|
* @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:
|
* 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 fieldName lvm field name
|
||||||
* @param vgname
|
* @param vgname
|
||||||
|
@ -246,7 +262,7 @@ qint32 LvmDevice::getTotalLE(const QString& lvpath)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LvmDevice::removeLV(Device& dev, Partition& part)
|
bool LvmDevice::removeLV(Report& report, LvmDevice& dev, Partition& part)
|
||||||
{
|
{
|
||||||
ExternalCommand cmd(QStringLiteral("lvm"),
|
ExternalCommand cmd(QStringLiteral("lvm"),
|
||||||
{ QStringLiteral("lvremove"),
|
{ QStringLiteral("lvremove"),
|
||||||
|
@ -254,9 +270,79 @@ bool LvmDevice::removeLV(Device& dev, Partition& part)
|
||||||
part.partitionPath()});
|
part.partitionPath()});
|
||||||
|
|
||||||
if (cmd.run(-1) && cmd.exitCode() == 0) {
|
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);
|
dev.partitionTable()->remove(&part);
|
||||||
return true;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "core/volumemanagerdevice.h"
|
#include "core/volumemanagerdevice.h"
|
||||||
|
|
||||||
#include "util/libpartitionmanagerexport.h"
|
#include "util/libpartitionmanagerexport.h"
|
||||||
|
#include "util/report.h"
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
@ -48,8 +49,8 @@ public:
|
||||||
LvmDevice(const QString& name, const QString& iconname = QString());
|
LvmDevice(const QString& name, const QString& iconname = QString());
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QList<Partition*> scanPartitions(const Device& dev, PartitionTable* pTable) const;
|
QList<Partition*> scanPartitions(const LvmDevice& dev, PartitionTable* pTable) const;
|
||||||
Partition* scanPartition(const QString& lvPath, const Device& dev, PartitionTable* pTable) const;
|
Partition* scanPartition(const QString& lvPath, const LvmDevice& dev, PartitionTable* pTable) const;
|
||||||
|
|
||||||
static qint32 getPeSize(const QString& vgname);
|
static qint32 getPeSize(const QString& vgname);
|
||||||
static qint32 getTotalPE(const QString& vgname);
|
static qint32 getTotalPE(const QString& vgname);
|
||||||
|
@ -60,7 +61,12 @@ public:
|
||||||
|
|
||||||
static qint32 getTotalLE(const QString& lvpath);
|
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:
|
protected:
|
||||||
void initPartitions();
|
void initPartitions();
|
||||||
|
|
|
@ -53,25 +53,29 @@ bool CreateFileSystemJob::run(Report& parent)
|
||||||
|
|
||||||
if (partition().fileSystem().supportCreate() == FileSystem::cmdSupportFileSystem) {
|
if (partition().fileSystem().supportCreate() == FileSystem::cmdSupportFileSystem) {
|
||||||
if (partition().fileSystem().create(*report, partition().deviceNode())) {
|
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) {
|
if (backendDevice) {
|
||||||
CoreBackendPartitionTable* backendPartitionTable = backendDevice->openPartitionTable();
|
CoreBackendPartitionTable* backendPartitionTable = backendDevice->openPartitionTable();
|
||||||
|
|
||||||
if (backendPartitionTable) {
|
if (backendPartitionTable) {
|
||||||
if (backendPartitionTable->setPartitionSystemType(*report, partition())) {
|
if (backendPartitionTable->setPartitionSystemType(*report, partition())) {
|
||||||
rval = true;
|
rval = true;
|
||||||
backendPartitionTable->commit();
|
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
|
} 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
|
} 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());
|
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) {
|
||||||
delete backendDevice;
|
rval = true;
|
||||||
} 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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include "core/partition.h"
|
#include "core/partition.h"
|
||||||
#include "core/device.h"
|
#include "core/device.h"
|
||||||
|
#include "core/lvmdevice.h"
|
||||||
|
|
||||||
#include "util/report.h"
|
#include "util/report.h"
|
||||||
|
|
||||||
|
@ -74,7 +75,10 @@ bool CreatePartitionJob::run(Report& parent)
|
||||||
} else
|
} else
|
||||||
report->line() << xi18nc("@info:progress", "Could not open device <filename>%1</filename> to create new partition <filename>%2</filename>.", device().deviceNode(), partition().deviceNode());
|
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) {
|
} 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);
|
jobFinished(*report, rval);
|
||||||
|
|
|
@ -44,16 +44,20 @@ bool CreatePartitionTableJob::run(Report& parent)
|
||||||
|
|
||||||
Report* report = jobStarted(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) {
|
if (backendDevice != nullptr) {
|
||||||
Q_ASSERT(device().partitionTable());
|
Q_ASSERT(device().partitionTable());
|
||||||
|
|
||||||
rval = backendDevice->createPartitionTable(*report, *device().partitionTable());
|
rval = backendDevice->createPartitionTable(*report, *device().partitionTable());
|
||||||
|
|
||||||
delete backendDevice;
|
delete backendDevice;
|
||||||
} else
|
} else
|
||||||
report->line() << xi18nc("@info:progress", "Creating partition table failed: Could not open device <filename>%1</filename>.", device().deviceNode());
|
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);
|
jobFinished(*report, rval);
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,8 @@ bool DeletePartitionJob::run(Report& parent)
|
||||||
} else
|
} else
|
||||||
report->line() << xi18nc("@info:progress", "Deleting partition failed: Could not open device <filename>%1</filename>.", device().deviceNode());
|
report->line() << xi18nc("@info:progress", "Deleting partition failed: Could not open device <filename>%1</filename>.", device().deviceNode());
|
||||||
} else if (device().type() == Device::LVM_Device) {
|
} 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);
|
jobFinished(*report, rval);
|
||||||
|
|
|
@ -54,26 +54,33 @@ bool SetPartGeometryJob::run(Report& parent)
|
||||||
|
|
||||||
Report* report = jobStarted(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) {
|
if (backendDevice) {
|
||||||
CoreBackendPartitionTable* backendPartitionTable = backendDevice->openPartitionTable();
|
CoreBackendPartitionTable* backendPartitionTable = backendDevice->openPartitionTable();
|
||||||
|
|
||||||
if (backendPartitionTable) {
|
if (backendPartitionTable) {
|
||||||
rval = backendPartitionTable->updateGeometry(*report, partition(), newStart(), newStart() + newLength() - 1);
|
rval = backendPartitionTable->updateGeometry(*report, partition(), newStart(), newStart() + newLength() - 1);
|
||||||
|
|
||||||
if (rval) {
|
if (rval) {
|
||||||
partition().setFirstSector(newStart());
|
partition().setFirstSector(newStart());
|
||||||
partition().setLastSector(newStart() + newLength() - 1);
|
partition().setLastSector(newStart() + newLength() - 1);
|
||||||
backendPartitionTable->commit();
|
backendPartitionTable->commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
delete backendPartitionTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete backendPartitionTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete backendDevice;
|
delete backendDevice;
|
||||||
} else
|
} 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());
|
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);
|
jobFinished(*report, rval);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue