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 @@ -1,262 +1,348 @@ /************************************************************************* * 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 * * published by the Free Software Foundation; either version 3 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* *************************************************************************/ #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 "util/helpers.h" #include #include #include #include +#include /** Constructs a representation of LVM device with functionning LV as Partition * * @param name Volume Group name */ LvmDevice::LvmDevice(const QString& name, const QString& iconname) : VolumeManagerDevice(name, (QStringLiteral("/dev/") + name), getPeSize(name), getTotalPE(name), iconname, Device::LVM_Device) , m_peSize(getPeSize(name)) , m_totalPE(getTotalPE(name)) , m_allocPE(getAllocatedPE(name)) , m_freePE(getFreePE(name)) , m_UUID(getUUID(name)) { initPartitions(); } void LvmDevice::initPartitions() { qint64 firstUsable = 0; qint64 lastusable = totalPE() - 1; PartitionTable* pTable = new PartitionTable(PartitionTable::vmd, firstUsable, lastusable); 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()) { pList.append(scanPartition(lvPath, dev, pTable)); } return pList; } /** * @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: * LVM partition have 2 different start and end sector value * 1. representing the actual LV start from 0 -> size of LV - 1 * 2. representing abstract LV's sector inside a VG partitionTable * start from size of last Partitions -> size of LV - 1 * Reason for this is for the LV Partition to worrks nicely with other parts of the codebase * without too many special cases. */ qint64 startSector; qint64 endSector; qint64 lvSize; bool mounted = isMounted(lvpath); QString mountPoint = QString(); KMountPoint::List mountPointList = KMountPoint::currentMountPoints(KMountPoint::NeedRealDeviceName); mountPointList.append(KMountPoint::possibleMountPoints(KMountPoint::NeedRealDeviceName)); mountPoint = mountPointList.findByDevice(lvpath) ? mountPointList.findByDevice(lvpath)->mountPoint() : QString(); lvSize = getTotalLE(lvpath); startSector = mappedSector(lvpath,0); endSector = startSector + (lvSize - 1); const KDiskFreeSpaceInfo freeSpaceInfo = KDiskFreeSpaceInfo::freeSpaceInfo(mountPoint); FileSystem* fs = FileSystemFactory::create(FileSystem::detectFileSystem(lvpath), 0, lvSize - 1); if (mounted && freeSpaceInfo.isValid() && mountPoint != QString()) { //TODO: fix used space report. currently incorrect fs->setSectorsUsed(freeSpaceInfo.used() / logicalSize()); } if (fs->supportGetLabel() != FileSystem::cmdSupportNone) { fs->setLabel(fs->readLabel(lvpath)); } Partition* part = new Partition(pTable, dev, PartitionRole(PartitionRole::Lvm_Lv), fs, startSector, endSector, lvpath, PartitionTable::Flag::FlagLvm, mountPoint, mounted); return part; } qint64 LvmDevice::mappedSector(const QString& lvpath, qint64 sector) const { qint64 mSector = 0; QList lvpathList = lvPathList(); qint32 devIndex = lvpathList.indexOf(lvpath); if (devIndex) { for (int i = 0; i < devIndex; i++) { //TODO: currently going over the same LV again and again is wasteful. Could use some more optimization mSector += getTotalLE(lvpathList[i]); } mSector += sector; } return mSector; } QList LvmDevice::deviceNodeList() const { QList devPathList; QString cmdOutput = getField(QStringLiteral("pv_name"), name()); if (cmdOutput.size()) { QList tempPathList = cmdOutput.split(QStringLiteral("\n"), QString::SkipEmptyParts); foreach(QString devPath, tempPathList) { devPathList.append(devPath.trimmed()); } } return devPathList; } QList LvmDevice::lvPathList() const { QList lvPathList; QString cmdOutput = getField(QStringLiteral("lv_path"), name()); if (cmdOutput.size()) { QList tempPathList = cmdOutput.split(QStringLiteral("\n"), QString::SkipEmptyParts); foreach(QString lvPath, tempPathList) { lvPathList.append(lvPath.trimmed()); } } return lvPathList; } qint32 LvmDevice::getPeSize(const QString& vgname) { QString val = getField(QStringLiteral("vg_extent_size"), vgname); return val.isEmpty() ? -1 : val.toInt(); } qint32 LvmDevice::getTotalPE(const QString& vgname) { QString val = getField(QStringLiteral("vg_extent_count"), vgname); return val.isEmpty() ? -1 : val.toInt(); } qint32 LvmDevice::getAllocatedPE(const QString& vgname) { return getTotalPE(vgname) - getFreePE(vgname); } qint32 LvmDevice::getFreePE(const QString& vgname) { QString val = getField(QStringLiteral("vg_free_count"), vgname); return val.isEmpty() ? -1 : val.toInt(); } QString LvmDevice::getUUID(const QString& vgname) { QString val = getField(QStringLiteral("vg_uuid"), vgname); return val.isEmpty() ? QStringLiteral("---") : val; } -/** Query LVM details with field name +/** Get LVM vgs command output with field name * * @param fieldName lvm field name * @param vgname * @returns raw output of command output, usully with manay spaces within the returned string * */ QString LvmDevice::getField(const QString& fieldName, const QString& vgname) { ExternalCommand cmd(QStringLiteral("lvm"), { QStringLiteral("vgs"), QStringLiteral("--foreign"), QStringLiteral("--readonly"), QStringLiteral("--noheadings"), QStringLiteral("--units"), QStringLiteral("B"), QStringLiteral("--nosuffix"), QStringLiteral("--options"), fieldName, vgname }); if (cmd.run(-1) && cmd.exitCode() == 0) { return cmd.output().trimmed(); } return QString(); } qint32 LvmDevice::getTotalLE(const QString& lvpath) { ExternalCommand cmd(QStringLiteral("lvm"), { QStringLiteral("lvdisplay"), lvpath}); if (cmd.run(-1) && cmd.exitCode() == 0) { QRegularExpression re(QStringLiteral("Current LE\\h+(\\d+)")); QRegularExpressionMatch match = re.match(cmd.output()); if (match.hasMatch()) { return match.captured(1).toInt(); } } return -1; } -bool LvmDevice::removeLV(Device& dev, Partition& part) +bool LvmDevice::removeLV(Report& report, LvmDevice& dev, Partition& part) { ExternalCommand cmd(QStringLiteral("lvm"), { QStringLiteral("lvremove"), QStringLiteral("--yes"), 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 @@ -1,99 +1,105 @@ /************************************************************************* * 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 * * published by the Free Software Foundation; either version 3 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* *************************************************************************/ #if !defined(LVMDEVICE__H) #define LVMDEVICE__H #include "core/volumemanagerdevice.h" #include "util/libpartitionmanagerexport.h" +#include "util/report.h" #include #include #include class PartitionTable; class CreatePartitionTableOperation; class SmartStatus; /** A device. Represents a device like /dev/sda. Devices are the outermost entity; they contain a PartitionTable that itself contains Partitions. @see PartitionTable, Partition @author Volker Lanz */ class LIBKPMCORE_EXPORT LvmDevice : public VolumeManagerDevice { Q_DISABLE_COPY(LvmDevice) 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); static qint32 getAllocatedPE(const QString& vgname); static qint32 getFreePE(const QString& vgname); static QString getUUID(const QString& vgname); static QString getField(const QString& fieldName, const QString& vgname = QString()); 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(); QList deviceNodeList() const override; qint64 mappedSector(const QString& lvpath, qint64 sector) const override; QList lvPathList() const; public: qint32 peSize() const { return m_peSize; } qint32 totalPE() const { return m_totalPE; } qint32 allocatedPE() const { return m_allocPE; } qint32 freePE() const { return m_freePE; } QString UUID() const { return m_UUID; } private: qint32 m_peSize; qint32 m_totalPE; qint32 m_allocPE; qint32 m_freePE; QString m_UUID; }; #endif diff --git a/src/jobs/createfilesystemjob.cpp b/src/jobs/createfilesystemjob.cpp index 35c9e23..5f65ae3 100644 --- a/src/jobs/createfilesystemjob.cpp +++ b/src/jobs/createfilesystemjob.cpp @@ -1,86 +1,90 @@ /************************************************************************* * Copyright (C) 2008, 2011 by Volker Lanz * * Copyright (C) 2016 by Andrius Štikonas * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 3 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* *************************************************************************/ #include "jobs/createfilesystemjob.h" #include "backend/corebackend.h" #include "backend/corebackendmanager.h" #include "backend/corebackenddevice.h" #include "backend/corebackendpartitiontable.h" #include "core/device.h" #include "core/partition.h" #include "fs/filesystem.h" #include "util/report.h" #include /** Creates a new CreateFileSystemJob @param p the Partition the FileSystem to create is on */ CreateFileSystemJob::CreateFileSystemJob(Device& d, Partition& p) : Job(), m_Device(d), m_Partition(p) { } bool CreateFileSystemJob::run(Report& parent) { bool rval = false; Report* report = jobStarted(parent); if (partition().fileSystem().type() == FileSystem::Unformatted) return true; 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/plain", "Failed to set the system type for the file system on partition %1.", partition().deviceNode()); + + delete backendPartitionTable; } else - report->line() << xi18nc("@info/plain", "Failed to set the system type for the file system on partition %1.", partition().deviceNode()); + report->line() << xi18nc("@info/plain", "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/plain", "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/plain", "Could not open device %1 to set the system type for partition %2.", device().deviceNode(), partition().deviceNode()); + report->line() << xi18nc("@info/plain", "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; + } } } jobFinished(*report, rval); return rval; } QString CreateFileSystemJob::description() const { return xi18nc("@info/plain", "Create file system %1 on partition %2", partition().fileSystem().name(), partition().deviceNode()); } diff --git a/src/jobs/createpartitionjob.cpp b/src/jobs/createpartitionjob.cpp index 5789560..c28e870 100644 --- a/src/jobs/createpartitionjob.cpp +++ b/src/jobs/createpartitionjob.cpp @@ -1,91 +1,95 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * Copyright (C) 2016 by Andrius Štikonas * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 3 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* *************************************************************************/ #include "jobs/createpartitionjob.h" #include "backend/corebackend.h" #include "backend/corebackendmanager.h" #include "backend/corebackenddevice.h" #include "backend/corebackendpartitiontable.h" #include "core/partition.h" #include "core/device.h" +#include "core/lvmdevice.h" #include "util/report.h" #include /** Creates a new CreatePartitionJob @param d the Device the Partition to be created will be on @param p the Partition to create */ CreatePartitionJob::CreatePartitionJob(Device& d, Partition& p) : Job(), m_Device(d), m_Partition(p) { } bool CreatePartitionJob::run(Report& parent) { Q_ASSERT(partition().devicePath() == device().deviceNode()); bool rval = false; Report* report = jobStarted(parent); if (device().type() == Device::Disk_Device) { CoreBackendDevice* backendDevice = CoreBackendManager::self()->backend()->openDevice(device().deviceNode()); if (backendDevice) { CoreBackendPartitionTable* backendPartitionTable = backendDevice->openPartitionTable(); if (backendPartitionTable) { QString partitionPath = backendPartitionTable->createPartition(*report, partition()); if (partitionPath != QString()) { rval = true; partition().setPartitionPath(partitionPath); partition().setState(Partition::StateNone); backendPartitionTable->commit(); } else report->line() << xi18nc("@info/plain", "Failed to add partition %1 to device %2.", partition().deviceNode(), device().deviceNode()); delete backendPartitionTable; } else report->line() << xi18nc("@info/plain", "Could not open partition table on device %1 to create new partition %2.", device().deviceNode(), partition().deviceNode()); delete backendDevice; } else report->line() << xi18nc("@info/plain", "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); return rval; } QString CreatePartitionJob::description() const { if (partition().number() > 0) return xi18nc("@info/plain", "Create new partition %1", partition().deviceNode()); return xi18nc("@info/plain", "Create new partition on device %1", device().deviceNode()); } diff --git a/src/jobs/createpartitiontablejob.cpp b/src/jobs/createpartitiontablejob.cpp index a7772e4..03d37be 100644 --- a/src/jobs/createpartitiontablejob.cpp +++ b/src/jobs/createpartitiontablejob.cpp @@ -1,66 +1,70 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * Copyright (C) 2016 by Andrius Štikonas * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 3 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* *************************************************************************/ #include "jobs/createpartitiontablejob.h" #include "backend/corebackendmanager.h" #include "backend/corebackenddevice.h" #include "backend/corebackend.h" #include "core/device.h" #include "core/partitiontable.h" #include "util/report.h" #include /** Creates a new CreatePartitionTableJob @param d the Device a new PartitionTable is to be created on */ CreatePartitionTableJob::CreatePartitionTableJob(Device& d) : Job(), m_Device(d) { } bool CreatePartitionTableJob::run(Report& parent) { bool rval = false; 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/plain", "Creating partition table failed: Could not open device %1.", device().deviceNode()); + delete backendDevice; + } else + report->line() << xi18nc("@info/plain", "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); return rval; } QString CreatePartitionTableJob::description() const { return xi18nc("@info/plain", "Create new partition table on device %1", device().deviceNode()); } diff --git a/src/jobs/deletepartitionjob.cpp b/src/jobs/deletepartitionjob.cpp index 01481de..4263c87 100644 --- a/src/jobs/deletepartitionjob.cpp +++ b/src/jobs/deletepartitionjob.cpp @@ -1,94 +1,95 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * Copyright (C) 2016 by Andrius Štikonas * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 3 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* *************************************************************************/ #include "jobs/deletepartitionjob.h" #include "backend/corebackend.h" #include "backend/corebackendmanager.h" #include "backend/corebackenddevice.h" #include "backend/corebackendpartitiontable.h" #include "core/partition.h" #include "core/device.h" #include "core/lvmdevice.h" #include "util/report.h" #include #include /** Creates a new DeletePartitionJob @param d the Device the Partition to delete is on @param p the Partition to delete */ DeletePartitionJob::DeletePartitionJob(Device& d, Partition& p) : Job(), m_Device(d), m_Partition(p) { } bool DeletePartitionJob::run(Report& parent) { Q_ASSERT(device().deviceNode() == partition().devicePath()); if (device().deviceNode() != partition().devicePath()) { qWarning() << "deviceNode: " << device().deviceNode() << ", partition path: " << partition().devicePath(); return false; } bool rval = false; Report* report = jobStarted(parent); if (device().type() == Device::Disk_Device) { CoreBackendDevice* backendDevice = CoreBackendManager::self()->backend()->openDevice(device().deviceNode()); if (backendDevice) { CoreBackendPartitionTable* backendPartitionTable = backendDevice->openPartitionTable(); if (backendPartitionTable) { rval = backendPartitionTable->deletePartition(*report, partition()); if (!rval) report->line() << xi18nc("@info/plain", "Could not delete partition %1.", partition().deviceNode()); else backendPartitionTable->commit(); delete backendPartitionTable; } else report->line() << xi18nc("@info/plain", "Could not open partition table on device %1 to delete partition %2.", device().deviceNode(), partition().deviceNode()); delete backendDevice; } else report->line() << xi18nc("@info/plain", "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); return rval; } QString DeletePartitionJob::description() const { return xi18nc("@info/plain", "Delete the partition %1", partition().deviceNode()); } diff --git a/src/jobs/setpartgeometryjob.cpp b/src/jobs/setpartgeometryjob.cpp index 84c9d5e..541bf75 100644 --- a/src/jobs/setpartgeometryjob.cpp +++ b/src/jobs/setpartgeometryjob.cpp @@ -1,86 +1,92 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * Copyright (C) 2016 by Andrius Štikonas * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 3 of * * the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* *************************************************************************/ #include "jobs/setpartgeometryjob.h" #include "backend/corebackend.h" #include "backend/corebackendmanager.h" #include "backend/corebackenddevice.h" #include "backend/corebackendpartitiontable.h" #include "core/partition.h" #include "core/device.h" #include "util/report.h" #include /** Creates a new SetPartGeometryJob @param d the Device the Partition whose geometry is to be set is on @param p the Partition whose geometry is to be set @param newstart the new start sector for the Partition @param newlength the new length for the Partition @todo Wouldn't it be better to have newfirst (new first sector) and newlast (new last sector) as args instead? Having a length here doesn't seem to be very consistent with the rest of the app, right? */ SetPartGeometryJob::SetPartGeometryJob(Device& d, Partition& p, qint64 newstart, qint64 newlength) : Job(), m_Device(d), m_Partition(p), m_NewStart(newstart), m_NewLength(newlength) { } bool SetPartGeometryJob::run(Report& parent) { bool rval = false; 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/plain", "Could not open device %1 while trying to resize/move partition %2.", device().deviceNode(), partition().deviceNode()); + delete backendDevice; + } else + report->line() << xi18nc("@info/plain", "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); return rval; } QString SetPartGeometryJob::description() const { return xi18nc("@info/plain", "Set geometry of partition %1: Start sector: %2, length: %3", partition().deviceNode(), newStart(), newLength()); }