diff --git a/src/core/lvmdevice.cpp b/src/core/lvmdevice.cpp index 9f63a33..2bda749 100644 --- a/src/core/lvmdevice.cpp +++ b/src/core/lvmdevice.cpp @@ -28,6 +28,7 @@ #include #include #include +#include /** 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 LvmDevice::scanPartitions(const Device& dev, PartitionTable* pTable) const +QList LvmDevice::scanPartitions(const LvmDevice& dev, PartitionTable* pTable) const { QList pList; foreach (QString lvPath, lvPathList()) { @@ -76,7 +92,7 @@ QList 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; } diff --git a/src/core/lvmdevice.h b/src/core/lvmdevice.h index 9a1cfda..a03e2af 100644 --- a/src/core/lvmdevice.h +++ b/src/core/lvmdevice.h @@ -22,6 +22,7 @@ #include "core/volumemanagerdevice.h" #include "util/libpartitionmanagerexport.h" +#include "util/report.h" #include #include @@ -48,8 +49,8 @@ public: LvmDevice(const QString& name, const QString& iconname = QString()); public: - QList scanPartitions(const Device& dev, PartitionTable* pTable) const; - Partition* scanPartition(const QString& lvPath, const Device& dev, PartitionTable* pTable) const; + QList 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(); diff --git a/src/jobs/createfilesystemjob.cpp b/src/jobs/createfilesystemjob.cpp index 293a269..5daf76e 100644 --- a/src/jobs/createfilesystemjob.cpp +++ b/src/jobs/createfilesystemjob.cpp @@ -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 %1.", partition().deviceNode()); + + delete backendPartitionTable; } else - report->line() << xi18nc("@info:progress", "Failed to set the system type for the file system on partition %1.", partition().deviceNode()); + report->line() << xi18nc("@info:progress", "Could not open partition table on device %1 to set the system type for partition %2.", device().deviceNode(), partition().deviceNode()); - delete backendPartitionTable; + delete backendDevice; } else - report->line() << xi18nc("@info:progress", "Could not open partition table on device %1 to set the system type for partition %2.", device().deviceNode(), partition().deviceNode()); - - delete backendDevice; - } else - report->line() << xi18nc("@info:progress", "Could not open device %1 to set the system type for partition %2.", device().deviceNode(), partition().deviceNode()); + report->line() << xi18nc("@info:progress", "Could not open device %1 to set the system type for partition %2.", device().deviceNode(), partition().deviceNode()); + } else if (device().type() == Device::LVM_Device) { + rval = true; + } } } diff --git a/src/jobs/createpartitionjob.cpp b/src/jobs/createpartitionjob.cpp index 5c02b05..f3ad9c1 100644 --- a/src/jobs/createpartitionjob.cpp +++ b/src/jobs/createpartitionjob.cpp @@ -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 %1 to create new partition %2.", device().deviceNode(), partition().deviceNode()); } else if (device().type() == Device::LVM_Device) { - + LvmDevice& dev = dynamic_cast(device()); + rval = LvmDevice::createLV(*report, dev, partition(), QStringLiteral("randomLV")); + partition().setPartitionPath(dev.deviceNode() + QStringLiteral("/randomLV")); + partition().setState(Partition::StateNone); } jobFinished(*report, rval); diff --git a/src/jobs/createpartitiontablejob.cpp b/src/jobs/createpartitiontablejob.cpp index 895382f..9e0f002 100644 --- a/src/jobs/createpartitiontablejob.cpp +++ b/src/jobs/createpartitiontablejob.cpp @@ -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 %1.", device().deviceNode()); + delete backendDevice; + } else + report->line() << xi18nc("@info:progress", "Creating partition table failed: Could not open device %1.", device().deviceNode()); + } else if (device().type() == Device::LVM_Device) { + //TODO: figure what to do wit LVM partitionTable + } jobFinished(*report, rval); diff --git a/src/jobs/deletepartitionjob.cpp b/src/jobs/deletepartitionjob.cpp index 54219c4..b626815 100644 --- a/src/jobs/deletepartitionjob.cpp +++ b/src/jobs/deletepartitionjob.cpp @@ -80,7 +80,8 @@ bool DeletePartitionJob::run(Report& parent) } else report->line() << xi18nc("@info:progress", "Deleting partition failed: Could not open device %1.", device().deviceNode()); } else if (device().type() == Device::LVM_Device) { - rval = LvmDevice::removeLV(device(), partition()); + LvmDevice& dev = dynamic_cast(device()); + rval = LvmDevice::removeLV(*report, dev, partition()); } jobFinished(*report, rval); diff --git a/src/jobs/setpartgeometryjob.cpp b/src/jobs/setpartgeometryjob.cpp index 2281ce4..b55e93d 100644 --- a/src/jobs/setpartgeometryjob.cpp +++ b/src/jobs/setpartgeometryjob.cpp @@ -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 %1 while trying to resize/move partition %2.", device().deviceNode(), partition().deviceNode()); + delete backendDevice; + } else + report->line() << xi18nc("@info:progress", "Could not open device %1 while trying to resize/move partition %2.", 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);