LVM support #6
|
@ -16,6 +16,9 @@ set(CORE_SRC
|
|||
core/partitionnode.cpp
|
||||
core/partitionalignment.cpp
|
||||
core/device.cpp
|
||||
core/diskdevice.cpp
|
||||
core/volumemanagerdevice.cpp
|
||||
core/lvmdevice.cpp
|
||||
core/operationstack.cpp
|
||||
core/partitionrole.cpp
|
||||
)
|
||||
|
@ -26,6 +29,9 @@ set(CORE_LIB_HDRS
|
|||
core/copytarget.h
|
||||
core/copytargetdevice.h
|
||||
core/device.h
|
||||
core/diskdevice.h
|
||||
core/volumemanagerdevice.h
|
||||
core/lvmdevice.h
|
||||
core/devicescanner.h
|
||||
core/mountentry.h
|
||||
core/operationrunner.h
|
||||
|
|
|
@ -60,7 +60,7 @@ bool CopySourceDevice::open()
|
|||
*/
|
||||
qint32 CopySourceDevice::sectorSize() const
|
||||
{
|
||||
return device().logicalSectorSize();
|
||||
return device().logicalSize();
|
||||
}
|
||||
|
||||
/** Returns the length of this CopySource
|
||||
|
|
|
@ -56,7 +56,7 @@ bool CopyTargetDevice::open()
|
|||
/** @return the Device's sector size */
|
||||
qint32 CopyTargetDevice::sectorSize() const
|
||||
{
|
||||
return device().logicalSectorSize();
|
||||
return device().logicalSize();
|
||||
}
|
||||
|
||||
/** Writes the given number of sectors to the Device.
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
*************************************************************************/
|
||||
|
||||
#include "core/device.h"
|
||||
|
||||
#include "core/partitiontable.h"
|
||||
#include "core/smartstatus.h"
|
||||
|
||||
|
@ -25,73 +24,25 @@
|
|||
|
||||
#include <KLocalizedString>
|
||||
|
||||
#include <QFile>
|
||||
#include <QByteArray>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/fs.h>
|
||||
|
||||
#if !defined(BLKPBSZGET)
|
||||
#define BLKPBSZGET _IO(0x12,123)/* get block physical sector size */
|
||||
#endif
|
||||
|
||||
static qint32 getPhysicalSectorSize(const QString& device_node)
|
||||
{
|
||||
/*
|
||||
* possible ways of getting the physical sector size for a drive:
|
||||
* - ioctl(BLKPBSZGET) -- supported with Linux 2.6.32 and later
|
||||
* - /sys/block/sda/queue/physical_block_size
|
||||
* - libblkid from util-linux-ng 2.17 or later
|
||||
* TODO: implement the blkid method
|
||||
*/
|
||||
|
||||
#if defined(BLKPBSZGET)
|
||||
int phSectorSize = -1;
|
||||
int fd = open(device_node.toLocal8Bit().constData(), O_RDONLY);
|
||||
if (fd != -1) {
|
||||
if (ioctl(fd, BLKPBSZGET, &phSectorSize) >= 0) {
|
||||
close(fd);
|
||||
return phSectorSize;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
QFile f(QStringLiteral("/sys/block/%1/queue/physical_block_size").arg(QString(device_node).remove(QStringLiteral("/dev/"))));
|
||||
|
||||
if (f.open(QIODevice::ReadOnly)) {
|
||||
QByteArray a = f.readLine();
|
||||
return a.trimmed().toInt();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Constructs a Device with an empty PartitionTable.
|
||||
@param name the Device's name, usually some string defined by the manufacturer
|
||||
@param devicenode the Device's node, for example "/dev/sda"
|
||||
@param heads the number of heads in CHS notation
|
||||
@param numSectors the number of sectors in CHS notation
|
||||
@param cylinders the number of cylinders in CHS notation
|
||||
@param sectorSize the size of a sector in bytes
|
||||
@param deviceNode the Device's node, for example "/dev/sda"
|
||||
*/
|
||||
Device::Device(const QString& name, const QString& devicenode, qint32 heads, qint32 numSectors, qint32 cylinders, qint64 sectorSize, const QString& iconname) :
|
||||
QObject(),
|
||||
m_Name(name.length() > 0 ? name : i18n("Unknown Device")),
|
||||
m_DeviceNode(devicenode),
|
||||
m_PartitionTable(nullptr),
|
||||
m_Heads(heads),
|
||||
m_SectorsPerTrack(numSectors),
|
||||
m_Cylinders(cylinders),
|
||||
m_LogicalSectorSize(sectorSize),
|
||||
m_PhysicalSectorSize(getPhysicalSectorSize(devicenode)),
|
||||
m_IconName(iconname.isEmpty() ? QStringLiteral("drive-harddisk") : iconname),
|
||||
m_SmartStatus(new SmartStatus(devicenode))
|
||||
Device::Device(const QString& name,
|
||||
const QString& deviceNode,
|
||||
const qint32 logicalSize,
|
||||
const qint64 totalLogical,
|
||||
const QString& iconName,
|
||||
Device::Type type)
|
||||
: QObject()
|
||||
, m_Name(name.length() > 0 ? name : i18n("Unknown Device"))
|
||||
, m_DeviceNode(deviceNode)
|
||||
, m_LogicalSize(logicalSize)
|
||||
, m_TotalLogical(totalLogical)
|
||||
, m_PartitionTable(nullptr)
|
||||
, m_IconName(iconName.isEmpty() ? QStringLiteral("drive-harddisk") : iconName)
|
||||
, m_SmartStatus(type == Device::Disk_Device ? new SmartStatus(deviceNode) : nullptr)
|
||||
, m_Type(type)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -23,14 +23,13 @@
|
|||
|
||||
#include <QString>
|
||||
#include <QObject>
|
||||
#include <QtGlobal>
|
||||
|
||||
class PartitionTable;
|
||||
class CreatePartitionTableOperation;
|
||||
class CoreBackend;
|
||||
class SmartStatus;
|
||||
|
||||
/** A device.
|
||||
/** A abstract device interface.
|
||||
|
||||
Represents a device like /dev/sda.
|
||||
|
||||
|
@ -47,81 +46,81 @@ class LIBKPMCORE_EXPORT Device : public QObject
|
|||
friend class CoreBackend;
|
||||
|
||||
public:
|
||||
Device(const QString& name, const QString& devicenode, qint32 heads, qint32 numSectors, qint32 cylinders, qint64 sectorSize, const QString& iconname = QString());
|
||||
~Device();
|
||||
enum Type {
|
||||
Disk_Device = 0,
|
||||
LVM_Device = 1, /* VG */
|
||||
RAID_Device = 2, /* software RAID device */
|
||||
Unknown_Device = 4
|
||||
};
|
||||
|
||||
protected:
|
||||
Device(const QString& name, const QString& deviceNode, const qint32 logicalSize, const qint64 totalLogical, const QString& iconName = QString(), Device::Type type = Device::Disk_Device);
|
||||
|
||||
public:
|
||||
bool operator==(const Device& other) const;
|
||||
bool operator!=(const Device& other) const;
|
||||
virtual ~Device();
|
||||
|
||||
const QString& name() const {
|
||||
public:
|
||||
virtual bool operator==(const Device& other) const;
|
||||
virtual bool operator!=(const Device& other) const;
|
||||
|
||||
virtual const QString& name() const {
|
||||
return m_Name; /**< @return the Device's name, usually some manufacturer string */
|
||||
}
|
||||
const QString& deviceNode() const {
|
||||
virtual const QString& deviceNode() const {
|
||||
return m_DeviceNode; /**< @return the Device's node, for example "/dev/sda" */
|
||||
}
|
||||
PartitionTable* partitionTable() {
|
||||
|
||||
virtual PartitionTable* partitionTable() {
|
||||
return m_PartitionTable; /**< @return the Device's PartitionTable */
|
||||
}
|
||||
const PartitionTable* partitionTable() const {
|
||||
virtual const PartitionTable* partitionTable() const {
|
||||
return m_PartitionTable; /**< @return the Device's PartitionTable */
|
||||
}
|
||||
qint32 heads() const {
|
||||
return m_Heads; /**< @return the number of heads on the Device in CHS notation */
|
||||
}
|
||||
qint32 cylinders() const {
|
||||
return m_Cylinders; /**< @return the number of cylinders on the Device in CHS notation */
|
||||
}
|
||||
qint32 sectorsPerTrack() const {
|
||||
return m_SectorsPerTrack; /**< @return the number of sectors on the Device in CHS notation */
|
||||
}
|
||||
qint32 physicalSectorSize() const {
|
||||
return m_PhysicalSectorSize; /**< @return the physical sector size the Device uses or -1 if unknown */
|
||||
}
|
||||
qint32 logicalSectorSize() const {
|
||||
return m_LogicalSectorSize; /**< @return the logical sector size the Device uses */
|
||||
}
|
||||
qint64 totalSectors() const {
|
||||
return static_cast<qint64>(heads()) * cylinders() * sectorsPerTrack(); /**< @return the total number of sectors on the device */
|
||||
}
|
||||
qint64 capacity() const {
|
||||
return totalSectors() * logicalSectorSize(); /**< @return the Device's capacity in bytes */
|
||||
}
|
||||
qint64 cylinderSize() const {
|
||||
return static_cast<qint64>(heads()) * sectorsPerTrack(); /**< @return the size of a cylinder on this Device in sectors */
|
||||
}
|
||||
|
||||
void setIconName(const QString& name) {
|
||||
virtual qint64 capacity() const { /**< @return the Device's capacity in bytes */
|
||||
return logicalSize() * totalLogical();
|
||||
}
|
||||
|
||||
virtual void setIconName(const QString& name) {
|
||||
m_IconName = name;
|
||||
}
|
||||
const QString& iconName() const {
|
||||
virtual const QString& iconName() const {
|
||||
return m_IconName; /**< @return suggested icon name for this Device */
|
||||
}
|
||||
|
||||
SmartStatus& smartStatus() {
|
||||
virtual SmartStatus& smartStatus() {
|
||||
return *m_SmartStatus;
|
||||
}
|
||||
const SmartStatus& smartStatus() const {
|
||||
virtual const SmartStatus& smartStatus() const {
|
||||
return *m_SmartStatus;
|
||||
}
|
||||
|
||||
QString prettyName() const;
|
||||
|
||||
void setPartitionTable(PartitionTable* ptable) {
|
||||
virtual void setPartitionTable(PartitionTable* ptable) {
|
||||
m_PartitionTable = ptable;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual qint32 logicalSize() const {
|
||||
return m_LogicalSize;
|
||||
}
|
||||
virtual qint64 totalLogical() const {
|
||||
return m_TotalLogical;
|
||||
}
|
||||
|
||||
virtual Device::Type type() const {
|
||||
return m_Type;
|
||||
}
|
||||
|
||||
virtual QString prettyName() const;
|
||||
|
||||
protected:
|
||||
QString m_Name;
|
||||
QString m_DeviceNode;
|
||||
qint32 m_LogicalSize;
|
||||
qint64 m_TotalLogical;
|
||||
PartitionTable* m_PartitionTable;
|
||||
qint32 m_Heads;
|
||||
qint32 m_SectorsPerTrack;
|
||||
qint32 m_Cylinders;
|
||||
qint32 m_LogicalSectorSize;
|
||||
qint32 m_PhysicalSectorSize;
|
||||
QString m_IconName;
|
||||
SmartStatus* m_SmartStatus;
|
||||
Device::Type m_Type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,6 +23,12 @@
|
|||
|
||||
#include "core/operationstack.h"
|
||||
#include "core/device.h"
|
||||
#include "core/lvmdevice.h"
|
||||
#include "core/diskdevice.h"
|
||||
|
||||
#include "util/externalcommand.h"
|
||||
#include <QRegularExpression>
|
||||
#include <QDebug>
|
||||
|
||||
/** Constructs a DeviceScanner
|
||||
@param ostack the OperationStack where the devices will be created
|
||||
|
@ -56,10 +62,16 @@ void DeviceScanner::scan()
|
|||
|
||||
clear();
|
||||
|
||||
QList<Device*> deviceList = CoreBackendManager::self()->backend()->scanDevices();
|
||||
const QList<Device*> deviceList = CoreBackendManager::self()->backend()->scanDevices();
|
||||
const QList<LvmDevice*> lvmList = LvmDevice::scanSystemLVM();
|
||||
|
||||
foreach(Device * d, deviceList)
|
||||
for (const auto &d : deviceList)
|
||||
operationStack().addDevice(d);
|
||||
|
||||
operationStack().sortDevices();
|
||||
|
||||
for (const auto &d : lvmList)
|
||||
operationStack().addDevice(d);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
void setupConnections();
|
||||
|
||||
Q_SIGNALS:
|
||||
void progress(const QString& device_node, int progress);
|
||||
void progress(const QString& deviceNode, int progress);
|
||||
|
||||
protected:
|
||||
void run() override;
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2008 by Volker Lanz <vl@fidra.de> *
|
||||
* Copyright (C) 2016 by Andrius Štikonas <andrius@stikonas.eu> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "core/diskdevice.h"
|
||||
|
||||
#include "core/partitiontable.h"
|
||||
#include "core/smartstatus.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
#include <QFile>
|
||||
#include <QByteArray>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/fs.h>
|
||||
|
||||
#if !defined(BLKPBSZGET)
|
||||
#define BLKPBSZGET _IO(0x12,123)/* get block physical sector size */
|
||||
#endif
|
||||
|
||||
static qint32 getPhysicalSectorSize(const QString& device_node)
|
||||
{
|
||||
/*
|
||||
* possible ways of getting the physical sector size for a drive:
|
||||
* - ioctl(BLKPBSZGET) -- supported with Linux 2.6.32 and later
|
||||
* - /sys/block/sda/queue/physical_block_size
|
||||
* - libblkid from util-linux-ng 2.17 or later
|
||||
* TODO: implement the blkid method
|
||||
*/
|
||||
|
||||
#if defined(BLKPBSZGET)
|
||||
int phSectorSize = -1;
|
||||
int fd = open(device_node.toLocal8Bit().constData(), O_RDONLY);
|
||||
if (fd != -1) {
|
||||
if (ioctl(fd, BLKPBSZGET, &phSectorSize) >= 0) {
|
||||
close(fd);
|
||||
return phSectorSize;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
QFile f(QStringLiteral("/sys/block/%1/queue/physical_block_size").arg(QString(device_node).remove(QStringLiteral("/dev/"))));
|
||||
|
||||
if (f.open(QIODevice::ReadOnly)) {
|
||||
QByteArray a = f.readLine();
|
||||
return a.trimmed().toInt();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Constructs a Disk Device with an empty PartitionTable.
|
||||
@param name the Device's name, usually some string defined by the manufacturer
|
||||
@param deviceNode the Device's node, for example "/dev/sda"
|
||||
@param heads the number of heads in CHS notation
|
||||
@param numSectors the number of sectors in CHS notation
|
||||
@param cylinders the number of cylinders in CHS notation
|
||||
@param sectorSize the size of a sector in bytes
|
||||
*/
|
||||
DiskDevice::DiskDevice(const QString& name,
|
||||
const QString& deviceNode,
|
||||
qint32 heads,
|
||||
qint32 numSectors,
|
||||
qint32 cylinders,
|
||||
qint32 sectorSize,
|
||||
const QString& iconName)
|
||||
: Device(name, deviceNode, sectorSize, (static_cast<qint64>(heads) * cylinders * numSectors), iconName, Device::Disk_Device)
|
||||
, m_Heads(heads)
|
||||
, m_SectorsPerTrack(numSectors)
|
||||
, m_Cylinders(cylinders)
|
||||
, m_LogicalSectorSize(sectorSize)
|
||||
, m_PhysicalSectorSize(getPhysicalSectorSize(deviceNode))
|
||||
{
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2008 by Volker Lanz <vl@fidra.de> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(DISKDEVICE__H)
|
||||
|
||||
#define DISKDEVICE__H
|
||||
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
#include "core/device.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QObject>
|
||||
#include <QtGlobal>
|
||||
|
||||
class PartitionTable;
|
||||
class CreatePartitionTableOperation;
|
||||
class CoreBackend;
|
||||
class SmartStatus;
|
||||
|
||||
/** A disk 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 <vl@fidra.de>
|
||||
*/
|
||||
class LIBKPMCORE_EXPORT DiskDevice : public Device
|
||||
{
|
||||
Q_DISABLE_COPY(DiskDevice)
|
||||
|
||||
friend class CreatePartitionTableOperation;
|
||||
friend class CoreBackend;
|
||||
|
||||
public:
|
||||
DiskDevice(const QString& name, const QString& deviceNode, qint32 heads, qint32 numSectors, qint32 cylinders, qint32 sectorSize, const QString& iconName = QString());
|
||||
|
||||
public:
|
||||
qint32 heads() const {
|
||||
return m_Heads; /**< @return the number of heads on the Device in CHS notation */
|
||||
}
|
||||
qint32 cylinders() const {
|
||||
return m_Cylinders; /**< @return the number of cylinders on the Device in CHS notation */
|
||||
}
|
||||
qint32 sectorsPerTrack() const {
|
||||
return m_SectorsPerTrack; /**< @return the number of sectors on the Device in CHS notation */
|
||||
}
|
||||
qint32 physicalSectorSize() const {
|
||||
return m_PhysicalSectorSize; /**< @return the physical sector size the Device uses or -1 if unknown */
|
||||
}
|
||||
qint32 logicalSectorSize() const {
|
||||
return m_LogicalSectorSize; /**< @return the logical sector size the Device uses */
|
||||
}
|
||||
qint64 totalSectors() const {
|
||||
return static_cast<qint64>(heads()) * cylinders() * sectorsPerTrack(); /**< @return the total number of sectors on the device */
|
||||
}
|
||||
qint64 cylinderSize() const {
|
||||
return static_cast<qint64>(heads()) * sectorsPerTrack(); /**< @return the size of a cylinder on this Device in sectors */
|
||||
}
|
||||
|
||||
private:
|
||||
qint32 m_Heads;
|
||||
qint32 m_SectorsPerTrack;
|
||||
qint32 m_Cylinders;
|
||||
qint32 m_LogicalSectorSize;
|
||||
qint32 m_PhysicalSectorSize;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,507 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "core/lvmdevice.h"
|
||||
#include "core/partition.h"
|
||||
#include "fs/filesystem.h"
|
||||
#include "fs/lvm2_pv.h"
|
||||
#include "fs/luks.h"
|
||||
#include "fs/filesystemfactory.h"
|
||||
|
||||
#include "core/partitiontable.h"
|
||||
#include "util/externalcommand.h"
|
||||
#include "util/helpers.h"
|
||||
#include "util/report.h"
|
||||
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include <KDiskFreeSpaceInfo>
|
||||
#include <KLocalizedString>
|
||||
#include <KMountPoint>
|
||||
|
||||
/** Constructs a representation of LVM device with initialized LV as Partitions
|
||||
*
|
||||
* @param vgName Volume Group name
|
||||
* @param iconName Icon representing LVM Volume group
|
||||
*/
|
||||
LvmDevice::LvmDevice(const QString& vgName, const QString& iconName)
|
||||
: VolumeManagerDevice(vgName,
|
||||
(QStringLiteral("/dev/") + vgName),
|
||||
getPeSize(vgName),
|
||||
getTotalPE(vgName),
|
||||
iconName,
|
||||
Device::LVM_Device)
|
||||
{
|
||||
m_peSize = logicalSize();
|
||||
m_totalPE = totalLogical();
|
||||
m_freePE = getFreePE(vgName);
|
||||
m_allocPE = m_totalPE - m_freePE;
|
||||
m_UUID = getUUID(vgName);
|
||||
m_PVPathList = new QStringList(getPVs(vgName));
|
||||
m_LVPathList = new QStringList(getLVs(vgName));
|
||||
m_LVSizeMap = new QMap<QString, qint64>();
|
||||
|
||||
initPartitions();
|
||||
}
|
||||
|
||||
/**
|
||||
* shared list of PV's paths that will be added to any VGs.
|
||||
* (have been added to an operation, but not yet applied)
|
||||
*/
|
||||
QStringList LvmDevice::s_DirtyPVs;
|
||||
|
||||
LvmDevice::~LvmDevice()
|
||||
{
|
||||
delete m_PVPathList;
|
||||
delete m_LVPathList;
|
||||
delete m_LVSizeMap;
|
||||
}
|
||||
|
||||
void LvmDevice::initPartitions()
|
||||
{
|
||||
qint64 firstUsable = 0;
|
||||
qint64 lastusable = totalPE() - 1;
|
||||
PartitionTable* pTable = new PartitionTable(PartitionTable::vmd, firstUsable, lastusable);
|
||||
|
||||
for (const auto &p : scanPartitions(pTable)) {
|
||||
LVSizeMap()->insert(p->partitionPath(), p->length());
|
||||
pTable->append(p);
|
||||
}
|
||||
|
||||
pTable->updateUnallocated(*this);
|
||||
|
||||
setPartitionTable(pTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a initialized Partition(LV) list
|
||||
*/
|
||||
const QList<Partition*> LvmDevice::scanPartitions(PartitionTable* pTable) const
|
||||
{
|
||||
QList<Partition*> pList;
|
||||
for (const auto &lvPath : partitionNodes()) {
|
||||
pList.append(scanPartition(lvPath, pTable));
|
||||
}
|
||||
return pList;
|
||||
}
|
||||
|
||||
/** scan and construct a partition(LV) at a given path
|
||||
*
|
||||
* NOTE:
|
||||
* LVM partition has 2 different start and end sector values
|
||||
* 1. representing the actual LV start from 0 -> size of LV - 1
|
||||
* 2. representing abstract LV's sector inside a VG partitionTable
|
||||
* start from last sector + 1 of last Partitions -> size of LV - 1
|
||||
* Reason for this is for the LV Partition to work nicely with other parts of the codebase
|
||||
* without too many special cases.
|
||||
*
|
||||
* @param lvPath LVM Logical Volume path
|
||||
* @param pTable Abstract partition table representing partitions of LVM Volume Group
|
||||
* @return initialized Partition(LV)
|
||||
*/
|
||||
Partition* LvmDevice::scanPartition(const QString& lvPath, PartitionTable* pTable) const
|
||||
{
|
||||
activateLV(lvPath);
|
||||
|
||||
qint64 lvSize = getTotalLE(lvPath);
|
||||
qint64 startSector = mappedSector(lvPath, 0);
|
||||
qint64 endSector = startSector + lvSize - 1;
|
||||
|
||||
FileSystem::Type type = FileSystem::detectFileSystem(lvPath);
|
||||
FileSystem* fs = FileSystemFactory::create(type, 0, lvSize - 1);
|
||||
|
||||
bool mounted = isMounted(lvPath);
|
||||
QString mountPoint = QString();
|
||||
|
||||
KMountPoint::List mountPointList = KMountPoint::currentMountPoints(KMountPoint::NeedRealDeviceName);
|
||||
mountPointList.append(KMountPoint::possibleMountPoints(KMountPoint::NeedRealDeviceName));
|
||||
|
||||
PartitionRole::Roles r = PartitionRole::Lvm_Lv;
|
||||
|
||||
if (type == FileSystem::Luks) {
|
||||
r |= PartitionRole::Luks;
|
||||
FS::luks* luksFs = static_cast<FS::luks*>(fs);
|
||||
QString mapperNode = FS::luks::mapperName(lvPath);
|
||||
bool isCryptOpen = !mapperNode.isEmpty();
|
||||
luksFs->setCryptOpen(isCryptOpen);
|
||||
luksFs->setLogicalSectorSize(logicalSize());
|
||||
|
||||
if (isCryptOpen) {
|
||||
luksFs->loadInnerFileSystem(lvPath, mapperNode);
|
||||
mountPoint = mountPointList.findByDevice(mapperNode) ?
|
||||
mountPointList.findByDevice(mapperNode)->mountPoint() :
|
||||
QString();
|
||||
mounted = isMounted(mapperNode);
|
||||
if (mounted) {
|
||||
const KDiskFreeSpaceInfo freeSpaceInfo = KDiskFreeSpaceInfo::freeSpaceInfo(mountPoint);
|
||||
if (freeSpaceInfo.isValid() && mountPoint != QString())
|
||||
luksFs->setSectorsUsed((freeSpaceInfo.used() + luksFs->getPayloadOffset(lvPath)) / logicalSize());
|
||||
}
|
||||
} else {
|
||||
mounted = false;
|
||||
}
|
||||
luksFs->setMounted(mounted);
|
||||
} else {
|
||||
mountPoint = mountPointList.findByDevice(lvPath) ?
|
||||
mountPointList.findByDevice(lvPath)->mountPoint() :
|
||||
QString();
|
||||
const KDiskFreeSpaceInfo freeSpaceInfo = KDiskFreeSpaceInfo::freeSpaceInfo(mountPoint);
|
||||
|
||||
//TODO: test used space report. probably incorrect
|
||||
if (logicalSize() > 0) {
|
||||
if (mounted && freeSpaceInfo.isValid() && mountPoint != QString()) {
|
||||
fs->setSectorsUsed(freeSpaceInfo.used() / logicalSize());
|
||||
} else if (fs->supportGetUsed() == FileSystem::cmdSupportFileSystem) {
|
||||
fs->setSectorsUsed(fs->readUsedCapacity(lvPath) / logicalSize());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fs->supportGetLabel() != FileSystem::cmdSupportNone) {
|
||||
fs->setLabel(fs->readLabel(lvPath));
|
||||
}
|
||||
if (fs->supportGetUUID() != FileSystem::cmdSupportNone)
|
||||
fs->setUUID(fs->readUUID(lvPath));
|
||||
|
||||
Partition* part = new Partition(pTable,
|
||||
*this,
|
||||
PartitionRole(r),
|
||||
fs,
|
||||
startSector,
|
||||
endSector,
|
||||
lvPath,
|
||||
PartitionTable::Flag::FlagNone,
|
||||
mountPoint,
|
||||
mounted);
|
||||
return part;
|
||||
}
|
||||
|
||||
/** scan and contruct list of initialized LvmDevice objects.
|
||||
*
|
||||
* @return list of initialized LvmDevice
|
||||
*/
|
||||
QList<LvmDevice*> LvmDevice::scanSystemLVM()
|
||||
{
|
||||
QList<LvmDevice*> lvmList;
|
||||
for (const auto &vgName : getVGs()) {
|
||||
lvmList.append(new LvmDevice(vgName));
|
||||
}
|
||||
return lvmList;
|
||||
}
|
||||
|
||||
qint64 LvmDevice::mappedSector(const QString& lvPath, qint64 sector) const
|
||||
{
|
||||
qint64 mSector = 0;
|
||||
QList<QString> lvpathList = partitionNodes();
|
||||
qint32 devIndex = lvpathList.indexOf(lvPath);
|
||||
|
||||
if (devIndex) {
|
||||
for (int i = 0; i < devIndex; i++) {
|
||||
mSector += LVSizeMap()->value(lvpathList[i]);
|
||||
}
|
||||
mSector += sector;
|
||||
}
|
||||
return mSector;
|
||||
}
|
||||
|
||||
const QStringList LvmDevice::deviceNodes() const
|
||||
{
|
||||
return *PVPathList();
|
||||
}
|
||||
|
||||
const QStringList LvmDevice::partitionNodes() const
|
||||
{
|
||||
return *LVPathList();
|
||||
}
|
||||
|
||||
qint64 LvmDevice::partitionSize(QString& partitionPath) const
|
||||
{
|
||||
return LVSizeMap()->value(partitionPath);
|
||||
}
|
||||
|
||||
const QStringList LvmDevice::getVGs()
|
||||
{
|
||||
QStringList vgList;
|
||||
QString output = getField(QStringLiteral("vg_name"));
|
||||
if (!output.isEmpty()) {
|
||||
const QStringList vgNameList = output.split(QStringLiteral("\n"), QString::SkipEmptyParts);
|
||||
for (const auto &vgName : vgNameList) {
|
||||
vgList.append(vgName.trimmed());
|
||||
}
|
||||
}
|
||||
return vgList;
|
||||
}
|
||||
|
||||
const QStringList LvmDevice::getPVs(const QString& vgName)
|
||||
{
|
||||
QStringList devPathList;
|
||||
QString cmdOutput = getField(QStringLiteral("pv_name"), vgName);
|
||||
|
||||
if (cmdOutput.size()) {
|
||||
const QStringList tempPathList = cmdOutput.split(QStringLiteral("\n"), QString::SkipEmptyParts);
|
||||
for (const auto &devPath : tempPathList) {
|
||||
devPathList.append(devPath.trimmed());
|
||||
}
|
||||
}
|
||||
return devPathList;
|
||||
}
|
||||
|
||||
const QStringList LvmDevice::getLVs(const QString& vgName)
|
||||
{
|
||||
QStringList lvPathList;
|
||||
QString cmdOutput = getField(QStringLiteral("lv_path"), vgName);
|
||||
|
||||
if (cmdOutput.size()) {
|
||||
const QStringList tempPathList = cmdOutput.split(QStringLiteral("\n"), QString::SkipEmptyParts);
|
||||
for (const auto &lvPath : tempPathList) {
|
||||
lvPathList.append(lvPath.trimmed());
|
||||
}
|
||||
}
|
||||
return lvPathList;
|
||||
}
|
||||
|
||||
qint64 LvmDevice::getPeSize(const QString& vgName)
|
||||
{
|
||||
QString val = getField(QStringLiteral("vg_extent_size"), vgName);
|
||||
return val.isEmpty() ? -1 : val.toInt();
|
||||
}
|
||||
|
||||
qint64 LvmDevice::getTotalPE(const QString& vgName)
|
||||
{
|
||||
QString val = getField(QStringLiteral("vg_extent_count"), vgName);
|
||||
return val.isEmpty() ? -1 : val.toInt();
|
||||
}
|
||||
|
||||
qint64 LvmDevice::getAllocatedPE(const QString& vgName)
|
||||
{
|
||||
return getTotalPE(vgName) - getFreePE(vgName);
|
||||
}
|
||||
|
||||
qint64 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;
|
||||
|
||||
}
|
||||
|
||||
/** Get LVM vgs command output with field name
|
||||
*
|
||||
* @param fieldName LVM field name
|
||||
* @param vgName the name of LVM Volume Group
|
||||
* @return raw output of command output, usully with many spaces within the returned string
|
||||
* */
|
||||
|
||||
QString LvmDevice::getField(const QString& fieldName, const QString& vgName)
|
||||
{
|
||||
QStringList args = { QStringLiteral("vgs"),
|
||||
QStringLiteral("--foreign"),
|
||||
QStringLiteral("--readonly"),
|
||||
QStringLiteral("--noheadings"),
|
||||
QStringLiteral("--units"),
|
||||
QStringLiteral("B"),
|
||||
QStringLiteral("--nosuffix"),
|
||||
QStringLiteral("--options"),
|
||||
fieldName };
|
||||
if (!vgName.isEmpty()) {
|
||||
args << vgName;
|
||||
}
|
||||
ExternalCommand cmd(QStringLiteral("lvm"), args);
|
||||
if (cmd.run(-1) && cmd.exitCode() == 0) {
|
||||
return cmd.output().trimmed();
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
qint64 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(Report& report, LvmDevice& d, Partition& p)
|
||||
{
|
||||
ExternalCommand cmd(report, QStringLiteral("lvm"),
|
||||
{ QStringLiteral("lvremove"),
|
||||
QStringLiteral("--yes"),
|
||||
p.partitionPath()});
|
||||
|
||||
if (cmd.run(-1) && cmd.exitCode() == 0) {
|
||||
//TODO: remove Partition from PartitionTable and delete from memory ??
|
||||
d.partitionTable()->remove(&p);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LvmDevice::createLV(Report& report, LvmDevice& d, Partition& p, const QString& lvName)
|
||||
{
|
||||
ExternalCommand cmd(report, QStringLiteral("lvm"),
|
||||
{ QStringLiteral("lvcreate"),
|
||||
QStringLiteral("--yes"),
|
||||
QStringLiteral("--extents"),
|
||||
QString::number(p.length()),
|
||||
QStringLiteral("--name"),
|
||||
lvName,
|
||||
d.name()});
|
||||
|
||||
return (cmd.run(-1) && cmd.exitCode() == 0);
|
||||
}
|
||||
|
||||
bool LvmDevice::createLVSnapshot(Report& report, Partition& p, const QString& name, const qint64 extents)
|
||||
{
|
||||
QString numExtents = (extents > 0) ? QString::number(extents) :
|
||||
QString::number(p.length());
|
||||
ExternalCommand cmd(report, QStringLiteral("lvm"),
|
||||
{ QStringLiteral("lvcreate"),
|
||||
QStringLiteral("--yes"),
|
||||
QStringLiteral("--extents"),
|
||||
numExtents,
|
||||
QStringLiteral("--snapshot"),
|
||||
QStringLiteral("--name"),
|
||||
name,
|
||||
p.partitionPath() });
|
||||
return (cmd.run(-1) && cmd.exitCode() == 0);
|
||||
}
|
||||
|
||||
bool LvmDevice::resizeLV(Report& report, Partition& p)
|
||||
{
|
||||
//TODO: thorough tests and add warning that it could currupt the user data.
|
||||
ExternalCommand cmd(report, QStringLiteral("lvm"),
|
||||
{ QStringLiteral("lvresize"),
|
||||
QStringLiteral("--force"), // this command could corrupt user data
|
||||
QStringLiteral("--yes"),
|
||||
QStringLiteral("--extents"),
|
||||
QString::number(p.length()),
|
||||
p.partitionPath()});
|
||||
|
||||
return (cmd.run(-1) && cmd.exitCode() == 0);
|
||||
}
|
||||
|
||||
bool LvmDevice::removePV(Report& report, LvmDevice& d, const QString& pvPath)
|
||||
{
|
||||
ExternalCommand cmd(report, QStringLiteral("lvm"),
|
||||
{ QStringLiteral("vgreduce"),
|
||||
//QStringLiteral("--yes"), // potentially corrupt user data
|
||||
d.name(),
|
||||
pvPath});
|
||||
|
||||
return (cmd.run(-1) && cmd.exitCode() == 0);
|
||||
}
|
||||
|
||||
bool LvmDevice::insertPV(Report& report, LvmDevice& d, const QString& pvPath)
|
||||
{
|
||||
ExternalCommand cmd(report, QStringLiteral("lvm"),
|
||||
{ QStringLiteral("vgextend"),
|
||||
//QStringLiteral("--yes"), // potentially corrupt user data
|
||||
d.name(),
|
||||
pvPath});
|
||||
|
||||
return (cmd.run(-1) && cmd.exitCode() == 0);
|
||||
}
|
||||
bool LvmDevice::movePV(Report& report, const QString& pvPath, const QStringList& destinations)
|
||||
{
|
||||
|
||||
if (FS::lvm2_pv::getAllocatedPE(pvPath) <= 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
QStringList args = QStringList();
|
||||
args << QStringLiteral("pvmove");
|
||||
args << pvPath;
|
||||
if (!destinations.isEmpty()) {
|
||||
for (const auto &destPath : destinations) {
|
||||
args << destPath.trimmed();
|
||||
}
|
||||
}
|
||||
|
||||
ExternalCommand cmd(report, QStringLiteral("lvm"), args);
|
||||
return (cmd.run(-1) && cmd.exitCode() == 0);
|
||||
}
|
||||
|
||||
bool LvmDevice::createVG(Report& report, const QString vgName, const QStringList pvList, const qint32 peSize)
|
||||
{
|
||||
QStringList args = QStringList();
|
||||
args << QStringLiteral("vgcreate") << QStringLiteral("--physicalextentsize") << QString::number(peSize);
|
||||
args << vgName;
|
||||
for (const auto &pvNode : pvList) {
|
||||
args << pvNode.trimmed();
|
||||
}
|
||||
ExternalCommand cmd(report, QStringLiteral("lvm"), args);
|
||||
|
||||
return (cmd.run(-1) && cmd.exitCode() == 0);
|
||||
}
|
||||
|
||||
bool LvmDevice::removeVG(Report& report, LvmDevice& d)
|
||||
{
|
||||
bool deactivated = deactivateVG(report, d);
|
||||
ExternalCommand cmd(report, QStringLiteral("lvm"),
|
||||
{ QStringLiteral("vgremove"),
|
||||
d.name() });
|
||||
return (deactivated && cmd.run(-1) && cmd.exitCode() == 0);
|
||||
}
|
||||
|
||||
bool LvmDevice::deactivateVG(Report& report, const LvmDevice& d)
|
||||
{
|
||||
ExternalCommand deactivate(report, QStringLiteral("lvm"),
|
||||
{ QStringLiteral("vgchange"),
|
||||
QStringLiteral("--activate"), QStringLiteral("n"),
|
||||
d.name() });
|
||||
return deactivate.run(-1) && deactivate.exitCode() == 0;
|
||||
}
|
||||
|
||||
bool LvmDevice::deactivateLV(Report& report, const Partition& p)
|
||||
{
|
||||
ExternalCommand deactivate(report, QStringLiteral("lvm"),
|
||||
{ QStringLiteral("lvchange"),
|
||||
QStringLiteral("--activate"), QStringLiteral("n"),
|
||||
p.partitionPath() });
|
||||
return deactivate.run(-1) && deactivate.exitCode() == 0;
|
||||
}
|
||||
|
||||
bool LvmDevice::activateVG(Report& report, const LvmDevice& d)
|
||||
{
|
||||
ExternalCommand deactivate(report, QStringLiteral("lvm"),
|
||||
{ QStringLiteral("vgchange"),
|
||||
QStringLiteral("--activate"), QStringLiteral("y"),
|
||||
d.name() });
|
||||
return deactivate.run(-1) && deactivate.exitCode() == 0;
|
||||
}
|
||||
|
||||
bool LvmDevice::activateLV(const QString& lvPath)
|
||||
{
|
||||
ExternalCommand deactivate(QStringLiteral("lvm"),
|
||||
{ QStringLiteral("lvchange"),
|
||||
QStringLiteral("--activate"), QStringLiteral("y"),
|
||||
lvPath });
|
||||
return deactivate.run(-1) && deactivate.exitCode() == 0;
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(LVMDEVICE__H)
|
||||
|
||||
#define LVMDEVICE__H
|
||||
|
||||
#include "core/volumemanagerdevice.h"
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QObject>
|
||||
#include <QtGlobal>
|
||||
#include <QStringList>
|
||||
|
||||
class PartitionTable;
|
||||
class Report;
|
||||
class Partition;
|
||||
class SmartStatus;
|
||||
|
||||
/** Representation of LVM Volume Group(VG).
|
||||
|
||||
Devices are the outermost entity; they contain a PartitionTable that itself contains Partitions.
|
||||
|
||||
@see Device, VolumeManagerDevice, PartitionTable, Partition
|
||||
*/
|
||||
class LIBKPMCORE_EXPORT LvmDevice : public VolumeManagerDevice
|
||||
{
|
||||
Q_DISABLE_COPY(LvmDevice)
|
||||
|
||||
public:
|
||||
LvmDevice(const QString& name, const QString& iconName = QString());
|
||||
~LvmDevice();
|
||||
|
||||
public:
|
||||
const QStringList deviceNodes() const override;
|
||||
const QStringList partitionNodes() const override;
|
||||
qint64 partitionSize(QString& partitionPath) const override;
|
||||
|
||||
static QStringList s_DirtyPVs;
|
||||
|
||||
public:
|
||||
|
||||
static QList<LvmDevice*> scanSystemLVM();
|
||||
|
||||
static const QStringList getVGs();
|
||||
static const QStringList getPVs(const QString& vgName);
|
||||
static const QStringList getLVs(const QString& vgName);
|
||||
|
||||
static qint64 getPeSize(const QString& vgName);
|
||||
static qint64 getTotalPE(const QString& vgName);
|
||||
static qint64 getAllocatedPE(const QString& vgName);
|
||||
static qint64 getFreePE(const QString& vgName);
|
||||
static QString getUUID(const QString& vgName);
|
||||
static QString getField(const QString& fieldName, const QString& vgName = QString());
|
||||
|
||||
static qint64 getTotalLE(const QString& lvPath);
|
||||
|
||||
static bool removeLV(Report& report, LvmDevice& d, Partition& p);
|
||||
static bool createLV(Report& report, LvmDevice& d, Partition& p, const QString& lvName);
|
||||
static bool createLVSnapshot(Report& report, Partition& p, const QString& name, const qint64 extents = 0);
|
||||
static bool resizeLV(Report& report, Partition& p);
|
||||
static bool deactivateLV(Report& report, const Partition& p);
|
||||
static bool activateLV(const QString& deviceNode);
|
||||
|
||||
static bool removePV(Report& report, LvmDevice& d, const QString& pvPath);
|
||||
static bool insertPV(Report& report, LvmDevice& d, const QString& pvPath);
|
||||
static bool movePV(Report& report, const QString& pvPath, const QStringList& destinations = QStringList());
|
||||
|
||||
static bool removeVG(Report& report, LvmDevice& d);
|
||||
static bool createVG(Report& report, const QString vgName, const QStringList pvList, const qint32 peSize = 4); // peSize in megabytes
|
||||
static bool deactivateVG(Report& report, const LvmDevice& d);
|
||||
static bool activateVG(Report& report, const LvmDevice& d);
|
||||
|
||||
protected:
|
||||
|
||||
void initPartitions() override;
|
||||
const QList<Partition*> scanPartitions(PartitionTable* pTable) const;
|
||||
Partition* scanPartition(const QString& lvPath, PartitionTable* pTable) const;
|
||||
qint64 mappedSector(const QString& lvPath, qint64 sector) const override;
|
||||
|
||||
public:
|
||||
qint64 peSize() const {
|
||||
return m_peSize;
|
||||
}
|
||||
qint64 totalPE() const {
|
||||
return m_totalPE;
|
||||
}
|
||||
qint64 allocatedPE() const {
|
||||
return m_allocPE;
|
||||
}
|
||||
qint64 freePE() const {
|
||||
return m_freePE;
|
||||
}
|
||||
QString UUID() const {
|
||||
return m_UUID;
|
||||
}
|
||||
|
||||
protected:
|
||||
QStringList* LVPathList() const {
|
||||
return m_LVPathList;
|
||||
}
|
||||
|
||||
QStringList* PVPathList() const {
|
||||
return m_PVPathList;
|
||||
}
|
||||
|
||||
QMap<QString, qint64>* LVSizeMap() const {
|
||||
return m_LVSizeMap;
|
||||
}
|
||||
|
||||
private:
|
||||
qint64 m_peSize;
|
||||
qint64 m_totalPE;
|
||||
qint64 m_allocPE;
|
||||
qint64 m_freePE;
|
||||
QString m_UUID;
|
||||
|
||||
mutable QStringList* m_LVPathList;
|
||||
mutable QStringList* m_PVPathList;
|
||||
mutable QMap<QString, qint64>* m_LVSizeMap;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -96,8 +96,8 @@ qint32 OperationRunner::numJobs() const
|
|||
{
|
||||
qint32 result = 0;
|
||||
|
||||
foreach(const Operation * op, operationStack().operations())
|
||||
result += op->jobs().size();
|
||||
for (const auto &op : operationStack().operations())
|
||||
result += op->jobs().size();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -457,7 +457,7 @@ bool OperationStack::contains(const Partition* p) const
|
|||
{
|
||||
Q_ASSERT(p);
|
||||
|
||||
foreach(Operation * o, operations()) {
|
||||
for (const auto &o : operations()) {
|
||||
if (o->targets(*p))
|
||||
return true;
|
||||
|
||||
|
@ -503,17 +503,19 @@ Device* OperationStack::findDeviceForPartition(const Partition* p)
|
|||
{
|
||||
QReadLocker lockDevices(&lock());
|
||||
|
||||
foreach(Device * d, previewDevices()) {
|
||||
const auto devices = previewDevices();
|
||||
for (Device *d : devices) {
|
||||
if (d->partitionTable() == nullptr)
|
||||
continue;
|
||||
|
||||
foreach(const Partition * part, d->partitionTable()->children()) {
|
||||
const auto partitions = d->partitionTable()->children();
|
||||
for (const auto *part : partitions) {
|
||||
if (part == p)
|
||||
return d;
|
||||
|
||||
foreach(const Partition * child, part->children())
|
||||
if (child == p)
|
||||
return d;
|
||||
for (const auto &child : part->children())
|
||||
if (child == p)
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -62,11 +62,11 @@ Partition::Partition(PartitionNode* parent, const Device& device, const Partitio
|
|||
m_AvailableFlags(availableFlags),
|
||||
m_ActiveFlags(activeFlags),
|
||||
m_IsMounted(mounted),
|
||||
m_SectorSize(device.logicalSectorSize()),
|
||||
m_State(state)
|
||||
{
|
||||
setPartitionPath(partitionPath);
|
||||
Q_ASSERT(m_Parent);
|
||||
m_SectorSize = device.logicalSize();
|
||||
}
|
||||
|
||||
/** Destroys a Partition, destroying its children and its FileSystem */
|
||||
|
@ -106,7 +106,7 @@ Partition::Partition(const Partition& other) :
|
|||
m_State(other.m_State)
|
||||
{
|
||||
setPartitionPath(other.m_PartitionPath);
|
||||
foreach(const Partition * child, other.children()) {
|
||||
for (const auto &child : other.children()) {
|
||||
Partition* p = new Partition(*child);
|
||||
p->setParent(this);
|
||||
m_Children.append(p);
|
||||
|
@ -121,7 +121,7 @@ Partition& Partition::operator=(const Partition& other)
|
|||
|
||||
clearChildren();
|
||||
|
||||
foreach(const Partition * child, other.children()) {
|
||||
for (const auto &child : other.children()) {
|
||||
Partition* p = new Partition(*child);
|
||||
p->setParent(this);
|
||||
m_Children.append(p);
|
||||
|
@ -179,7 +179,7 @@ qint64 Partition::sectorsUsed() const
|
|||
return fileSystem().sectorsUsed();
|
||||
|
||||
qint64 result = 0;
|
||||
foreach(const Partition * p, children())
|
||||
for (const auto &p : children())
|
||||
if (!p->roles().has(PartitionRole::Unallocated))
|
||||
result += p->length();
|
||||
|
||||
|
@ -190,7 +190,7 @@ qint64 Partition::sectorsUsed() const
|
|||
qint64 Partition::minimumSectors() const
|
||||
{
|
||||
if (roles().has(PartitionRole::Luks))
|
||||
return fileSystem().minCapacity() / sectorSize() + 4096; // 4096 is the default cryptsetup payload offset
|
||||
return ( fileSystem().minCapacity() + (4096 * 512) ) / sectorSize(); // 4096 is the default cryptsetup payload offset
|
||||
return fileSystem().minCapacity() / sectorSize();
|
||||
}
|
||||
|
||||
|
@ -210,12 +210,12 @@ qint64 Partition::maximumSectors() const
|
|||
@param deletedNumber the number of a deleted logical or -1 if none has been deleted
|
||||
@param insertedNumber the number of an inserted logical or -1 if none has been inserted
|
||||
*/
|
||||
void Partition::adjustLogicalNumbers(qint32 deletedNumber, qint32 insertedNumber)
|
||||
void Partition::adjustLogicalNumbers(qint32 deletedNumber, qint32 insertedNumber) const
|
||||
{
|
||||
if (!roles().has(PartitionRole::Extended))
|
||||
return;
|
||||
|
||||
foreach(Partition * p, children()) {
|
||||
for (const auto &p : children()) {
|
||||
QString path = p->partitionPath();
|
||||
path.remove(QRegularExpression(QStringLiteral("(\\d+$)")));
|
||||
if (deletedNumber > 4 && p->number() > deletedNumber)
|
||||
|
@ -230,7 +230,7 @@ qint64 Partition::maxFirstSector() const
|
|||
{
|
||||
qint64 rval = -1;
|
||||
|
||||
foreach(const Partition * child, children())
|
||||
for (const auto &child : children())
|
||||
if (!child->roles().has(PartitionRole::Unallocated) && (child->firstSector() < rval || rval == -1))
|
||||
rval = child->firstSector();
|
||||
|
||||
|
@ -242,7 +242,7 @@ qint64 Partition::minLastSector() const
|
|||
{
|
||||
qint64 rval = -1;
|
||||
|
||||
foreach(const Partition * child, children())
|
||||
for (const auto &child : children())
|
||||
if (!child->roles().has(PartitionRole::Unallocated) && child->lastSector() > rval)
|
||||
rval = child->lastSector();
|
||||
|
||||
|
@ -252,7 +252,7 @@ qint64 Partition::minLastSector() const
|
|||
/** @return true if the Partition has children */
|
||||
bool Partition::hasChildren() const
|
||||
{
|
||||
foreach(const Partition * child, children())
|
||||
for (const auto &child : children())
|
||||
if (!child->roles().has(PartitionRole::Unallocated))
|
||||
return true;
|
||||
|
||||
|
@ -365,7 +365,7 @@ QTextStream& operator<<(QTextStream& stream, const Partition& p)
|
|||
{
|
||||
QStringList flagList;
|
||||
|
||||
foreach(const PartitionTable::Flag & f, PartitionTable::flagList()) {
|
||||
for (const auto &f : PartitionTable::flagList()) {
|
||||
if (p.activeFlags() & f)
|
||||
flagList.append(PartitionTable::flagName(f));
|
||||
}
|
||||
|
|
|
@ -215,7 +215,7 @@ public:
|
|||
bool canMount() const;
|
||||
bool canUnmount() const;
|
||||
|
||||
void adjustLogicalNumbers(qint32 deletedNumber, qint32 insertedNumber);
|
||||
void adjustLogicalNumbers(qint32 deletedNumber, qint32 insertedNumber) const;
|
||||
void checkChildrenMounted();
|
||||
|
||||
void setFirstSector(qint64 s) {
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "core/partition.h"
|
||||
#include "core/partitiontable.h"
|
||||
#include "core/device.h"
|
||||
#include "core/diskdevice.h"
|
||||
|
||||
#include "fs/filesystem.h"
|
||||
|
||||
|
@ -33,11 +34,12 @@ int PartitionAlignment::s_sectorAlignment = 2048;
|
|||
qint64 PartitionAlignment::firstDelta(const Device& d, const Partition& p, qint64 s)
|
||||
{
|
||||
if (d.partitionTable()->type() == PartitionTable::msdos) {
|
||||
if (p.roles().has(PartitionRole::Logical) && s == 2 * d.sectorsPerTrack())
|
||||
return (s - (2 * d.sectorsPerTrack())) % sectorAlignment(d);
|
||||
const DiskDevice& diskDevice = dynamic_cast<const DiskDevice&>(d);
|
||||
if (p.roles().has(PartitionRole::Logical) && s == 2 * diskDevice.sectorsPerTrack())
|
||||
return (s - (2 * diskDevice.sectorsPerTrack())) % sectorAlignment(d);
|
||||
|
||||
if (p.roles().has(PartitionRole::Logical) || s == d.sectorsPerTrack())
|
||||
return (s - d.sectorsPerTrack()) % sectorAlignment(d);
|
||||
if (p.roles().has(PartitionRole::Logical) || s == diskDevice.sectorsPerTrack())
|
||||
return (s - diskDevice.sectorsPerTrack()) % sectorAlignment(d);
|
||||
}
|
||||
|
||||
return s % sectorAlignment(d);
|
||||
|
@ -51,11 +53,12 @@ qint64 PartitionAlignment::lastDelta(const Device& d, const Partition&, qint64 s
|
|||
bool PartitionAlignment::isLengthAligned(const Device& d, const Partition& p)
|
||||
{
|
||||
if (d.partitionTable()->type() == PartitionTable::msdos) {
|
||||
if (p.roles().has(PartitionRole::Logical) && p.firstSector() == 2 * d.sectorsPerTrack())
|
||||
return (p.length() + (2 * d.sectorsPerTrack())) % sectorAlignment(d) == 0;
|
||||
const DiskDevice& diskDevice = dynamic_cast<const DiskDevice&>(d);
|
||||
if (p.roles().has(PartitionRole::Logical) && p.firstSector() == 2 * diskDevice.sectorsPerTrack())
|
||||
return (p.length() + (2 * diskDevice.sectorsPerTrack())) % sectorAlignment(d) == 0;
|
||||
|
||||
if (p.roles().has(PartitionRole::Logical) || p.firstSector() == d.sectorsPerTrack())
|
||||
return (p.length() + d.sectorsPerTrack()) % sectorAlignment(d) == 0;
|
||||
if (p.roles().has(PartitionRole::Logical) || p.firstSector() == diskDevice.sectorsPerTrack())
|
||||
return (p.length() + diskDevice.sectorsPerTrack()) % sectorAlignment(d) == 0;
|
||||
}
|
||||
|
||||
return p.length() % sectorAlignment(d) == 0;
|
||||
|
|
|
@ -139,11 +139,13 @@ void PartitionNode::clearChildren()
|
|||
*/
|
||||
Partition* PartitionNode::findPartitionBySector(qint64 s, const PartitionRole& role)
|
||||
{
|
||||
foreach(Partition * p, children()) {
|
||||
const auto partitions = children();
|
||||
for (auto &p : partitions) {
|
||||
// (women and) children first. ;-)
|
||||
foreach(Partition * child, p->children())
|
||||
if ((child->roles().roles() & role.roles()) && s >= child->firstSector() && s <= child->lastSector())
|
||||
return child;
|
||||
const auto pChildren = p->children();
|
||||
for (auto &child : pChildren)
|
||||
if ((child->roles().roles() & role.roles()) && s >= child->firstSector() && s <= child->lastSector())
|
||||
return child;
|
||||
|
||||
if ((p->roles().roles() & role.roles()) && s >= p->firstSector() && s <= p->lastSector())
|
||||
return p;
|
||||
|
@ -157,10 +159,10 @@ Partition* PartitionNode::findPartitionBySector(qint64 s, const PartitionRole& r
|
|||
*/
|
||||
const Partition* PartitionNode::findPartitionBySector(qint64 s, const PartitionRole& role) const
|
||||
{
|
||||
foreach(const Partition * p, children()) {
|
||||
foreach(const Partition * child, p->children())
|
||||
if ((child->roles().roles() & role.roles()) && s >= child->firstSector() && s <= child->lastSector())
|
||||
return child;
|
||||
for (const auto *p : children()) {
|
||||
for (const auto &child : p->children())
|
||||
if ((child->roles().roles() & role.roles()) && s >= child->firstSector() && s <= child->lastSector())
|
||||
return child;
|
||||
|
||||
if ((p->roles().roles() & role.roles()) && s >= p->firstSector() && s <= p->lastSector())
|
||||
return p;
|
||||
|
@ -190,9 +192,9 @@ qint32 PartitionNode::highestMountedChild() const
|
|||
{
|
||||
qint32 result = -1;
|
||||
|
||||
foreach(const Partition * p, children())
|
||||
if (p->number() > result && p->isMounted())
|
||||
result = p->number();
|
||||
for (const auto * p : children())
|
||||
if (p->number() > result && p->isMounted())
|
||||
result = p->number();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -200,9 +202,9 @@ qint32 PartitionNode::highestMountedChild() const
|
|||
/** @return true if any of the partition's children are mounted */
|
||||
bool PartitionNode::isChildMounted() const
|
||||
{
|
||||
foreach(const Partition * child, children())
|
||||
if (child->isMounted() || (child->hasChildren() && child->isChildMounted()))
|
||||
return true;
|
||||
for (const auto * child : children())
|
||||
if (child->isMounted() || (child->hasChildren() && child->isChildMounted()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ public:
|
|||
Logical = 4, /**< Logical inside an extended */
|
||||
Unallocated = 8, /**< No real Partition, just unallocated space */
|
||||
Luks = 16, /**< Encrypted partition with LUKS key management */
|
||||
Lvm_Lv = 32, /**< Logical Volume of LVM */
|
||||
|
||||
Any = 255 /**< In case we're looking for a Partition with a PartitionRole, any will do */
|
||||
};
|
||||
|
|
|
@ -23,8 +23,9 @@
|
|||
#include "core/partitiontable.h"
|
||||
#include "core/partition.h"
|
||||
#include "core/device.h"
|
||||
#include "core/diskdevice.h"
|
||||
#include "core/lvmdevice.h"
|
||||
#include "core/partitionalignment.h"
|
||||
|
||||
#include "fs/filesystem.h"
|
||||
#include "fs/filesystemfactory.h"
|
||||
|
||||
|
@ -38,13 +39,13 @@
|
|||
/** Creates a new PartitionTable object with type MSDOS
|
||||
@param type name of the PartitionTable type (e.g. "msdos" or "gpt")
|
||||
*/
|
||||
PartitionTable::PartitionTable(TableType type, qint64 first_usable, qint64 last_usable) :
|
||||
PartitionTable::PartitionTable(TableType type, qint64 firstUsable, qint64 lastUsable) :
|
||||
PartitionNode(),
|
||||
m_Children(),
|
||||
m_MaxPrimaries(maxPrimariesForTableType(type)),
|
||||
m_Type(type),
|
||||
m_FirstUsable(first_usable),
|
||||
m_LastUsable(last_usable)
|
||||
m_FirstUsable(firstUsable),
|
||||
m_LastUsable(lastUsable)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -88,11 +89,23 @@ qint64 PartitionTable::freeSectorsAfter(const Partition& p) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
qint64 PartitionTable::freeSectors() const
|
||||
{
|
||||
qint64 sectors = 0;
|
||||
for (const auto &p : children()) {
|
||||
if (p->roles().has(PartitionRole::Unallocated)) {
|
||||
sectors += p->length();
|
||||
}
|
||||
}
|
||||
|
||||
return sectors;
|
||||
}
|
||||
|
||||
/** @return true if the PartitionTable has an extended Partition */
|
||||
bool PartitionTable::hasExtended() const
|
||||
{
|
||||
for (int i = 0; i < children().size(); i++)
|
||||
if (children()[i]->roles().has(PartitionRole::Extended))
|
||||
for (const auto &p : children())
|
||||
if (p->roles().has(PartitionRole::Extended))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -101,9 +114,9 @@ bool PartitionTable::hasExtended() const
|
|||
/** @return pointer to the PartitionTable's extended Partition or nullptr if none exists */
|
||||
Partition* PartitionTable::extended() const
|
||||
{
|
||||
for (int i = 0; i < children().size(); i++)
|
||||
if (children()[i]->roles().has(PartitionRole::Extended))
|
||||
return children()[i];
|
||||
for (const auto &p : children())
|
||||
if (p->roles().has(PartitionRole::Extended))
|
||||
return p;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -129,7 +142,7 @@ int PartitionTable::numPrimaries() const
|
|||
{
|
||||
int result = 0;
|
||||
|
||||
foreach(const Partition * p, children())
|
||||
for (const auto &p : children())
|
||||
if (p->roles().has(PartitionRole::Primary) || p->roles().has(PartitionRole::Extended))
|
||||
result++;
|
||||
|
||||
|
@ -194,7 +207,7 @@ QString PartitionTable::flagName(Flag f)
|
|||
}
|
||||
|
||||
/** @return list of all flags */
|
||||
QList<PartitionTable::Flag> PartitionTable::flagList()
|
||||
const QList<PartitionTable::Flag> PartitionTable::flagList()
|
||||
{
|
||||
QList<PartitionTable::Flag> rval;
|
||||
|
||||
|
@ -240,29 +253,38 @@ QStringList PartitionTable::flagNames(Flags flags)
|
|||
return rval;
|
||||
}
|
||||
|
||||
bool PartitionTable::getUnallocatedRange(const Device& device, PartitionNode& parent, qint64& start, qint64& end)
|
||||
bool PartitionTable::getUnallocatedRange(const Device& d, PartitionNode& parent, qint64& start, qint64& end)
|
||||
{
|
||||
if (!parent.isRoot()) {
|
||||
Partition* extended = dynamic_cast<Partition*>(&parent);
|
||||
if (d.type() == Device::Disk_Device) {
|
||||
const DiskDevice& device = dynamic_cast<const DiskDevice&>(d);
|
||||
if (!parent.isRoot()) {
|
||||
Partition* extended = dynamic_cast<Partition*>(&parent);
|
||||
|
||||
if (extended == nullptr) {
|
||||
qWarning() << "extended is null. start: " << start << ", end: " << end << ", device: " << device.deviceNode();
|
||||
return false;
|
||||
if (extended == nullptr) {
|
||||
qWarning() << "extended is null. start: " << start << ", end: " << end << ", device: " << device.deviceNode();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Leave a track (cylinder aligned) or sector alignment sectors (sector based) free at the
|
||||
// start for a new partition's metadata
|
||||
start += device.partitionTable()->type() == PartitionTable::msdos ? device.sectorsPerTrack() : PartitionAlignment::sectorAlignment(device);
|
||||
|
||||
// .. and also at the end for the metadata for a partition to follow us, if we're not
|
||||
// at the end of the extended partition
|
||||
if (end < extended->lastSector())
|
||||
end -= device.partitionTable()->type() == PartitionTable::msdos ? device.sectorsPerTrack() : PartitionAlignment::sectorAlignment(device);
|
||||
}
|
||||
|
||||
// Leave a track (cylinder aligned) or sector alignment sectors (sector based) free at the
|
||||
// start for a new partition's metadata
|
||||
start += device.partitionTable()->type() == PartitionTable::msdos ? device.sectorsPerTrack() : PartitionAlignment::sectorAlignment(device);
|
||||
|
||||
// .. and also at the end for the metadata for a partition to follow us, if we're not
|
||||
// at the end of the extended partition
|
||||
if (end < extended->lastSector())
|
||||
end -= device.partitionTable()->type() == PartitionTable::msdos ? device.sectorsPerTrack() : PartitionAlignment::sectorAlignment(device);
|
||||
return end - start + 1 >= PartitionAlignment::sectorAlignment(device);
|
||||
} else if (d.type() == Device::LVM_Device) {
|
||||
if (end - start + 1 > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return end - start + 1 >= PartitionAlignment::sectorAlignment(device);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** Creates a new unallocated Partition on the given Device.
|
||||
@param device the Device to create the new Partition on
|
||||
@param parent the parent PartitionNode for the new Partition
|
||||
|
@ -334,13 +356,26 @@ void PartitionTable::insertUnallocated(const Device& d, PartitionNode* p, qint64
|
|||
|
||||
qint64 lastEnd = start;
|
||||
|
||||
foreach(Partition * child, p->children()) {
|
||||
p->insert(createUnallocated(d, *p, lastEnd, child->firstSector() - 1));
|
||||
if (d.type() == Device::LVM_Device && !p->children().isEmpty()) {
|
||||
// rearranging all the partitions sector to keep all the unallocated space at the end
|
||||
lastEnd = 0;
|
||||
for (const auto &child : children()) {
|
||||
qint64 totalSector = child->length();
|
||||
child->setFirstSector(lastEnd);
|
||||
child->setLastSector(lastEnd + totalSector - 1);
|
||||
|
||||
if (child->roles().has(PartitionRole::Extended))
|
||||
insertUnallocated(d, child, child->firstSector());
|
||||
lastEnd += totalSector;
|
||||
}
|
||||
} else {
|
||||
const auto pChildren = p->children();
|
||||
for (const auto &child : pChildren) {
|
||||
p->insert(createUnallocated(d, *p, lastEnd, child->firstSector() - 1));
|
||||
|
||||
lastEnd = child->lastSector() + 1;
|
||||
if (child->roles().has(PartitionRole::Extended))
|
||||
insertUnallocated(d, child, child->firstSector());
|
||||
|
||||
lastEnd = child->lastSector() + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Take care of the free space between the end of the last child and the end
|
||||
|
@ -353,7 +388,7 @@ void PartitionTable::insertUnallocated(const Device& d, PartitionNode* p, qint64
|
|||
Q_ASSERT(extended);
|
||||
}
|
||||
|
||||
if (parentEnd >= firstUsable())
|
||||
if (parentEnd >= firstUsable() && parentEnd >= lastEnd)
|
||||
p->insert(createUnallocated(d, *p, lastEnd, parentEnd));
|
||||
}
|
||||
|
||||
|
@ -369,15 +404,20 @@ void PartitionTable::updateUnallocated(const Device& d)
|
|||
qint64 PartitionTable::defaultFirstUsable(const Device& d, TableType t)
|
||||
{
|
||||
Q_UNUSED(t)
|
||||
return PartitionAlignment::sectorAlignment(d);
|
||||
if (d.type() == Device::LVM_Device) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const DiskDevice& diskDevice = dynamic_cast<const DiskDevice&>(d);
|
||||
return PartitionAlignment::sectorAlignment(diskDevice);
|
||||
}
|
||||
|
||||
qint64 PartitionTable::defaultLastUsable(const Device& d, TableType t)
|
||||
{
|
||||
if (t == gpt)
|
||||
return d.totalSectors() - 1 - 32 - 1;
|
||||
return d.totalLogical() - 1 - 32 - 1;
|
||||
|
||||
return d.totalSectors() - 1;
|
||||
return d.totalLogical() - 1;
|
||||
}
|
||||
|
||||
static struct {
|
||||
|
@ -398,50 +438,51 @@ static struct {
|
|||
{ QStringLiteral("mac"), 0xffff, false, true, PartitionTable::mac },
|
||||
{ QStringLiteral("pc98"), 16, false, true, PartitionTable::pc98 },
|
||||
{ QStringLiteral("amiga"), 128, false, true, PartitionTable::amiga },
|
||||
{ QStringLiteral("sun"), 8, false, true, PartitionTable::sun }
|
||||
{ QStringLiteral("sun"), 8, false, true, PartitionTable::sun },
|
||||
{ QStringLiteral("vmd"), 0xffff, false, false, PartitionTable::vmd }
|
||||
};
|
||||
|
||||
PartitionTable::TableType PartitionTable::nameToTableType(const QString& n)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(tableTypes) / sizeof(tableTypes[0]); i++)
|
||||
if (n == tableTypes[i].name)
|
||||
return tableTypes[i].type;
|
||||
for (const auto &type : tableTypes)
|
||||
if (n == type.name)
|
||||
return type.type;
|
||||
|
||||
return PartitionTable::unknownTableType;
|
||||
}
|
||||
|
||||
QString PartitionTable::tableTypeToName(TableType l)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(tableTypes) / sizeof(tableTypes[0]); i++)
|
||||
if (l == tableTypes[i].type)
|
||||
return tableTypes[i].name;
|
||||
for (const auto &type : tableTypes)
|
||||
if (l == type.type)
|
||||
return type.name;
|
||||
|
||||
return xi18nc("@item partition table name", "unknown");
|
||||
}
|
||||
|
||||
qint64 PartitionTable::maxPrimariesForTableType(TableType l)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(tableTypes) / sizeof(tableTypes[0]); i++)
|
||||
if (l == tableTypes[i].type)
|
||||
return tableTypes[i].maxPrimaries;
|
||||
for (const auto &type : tableTypes)
|
||||
if (l == type.type)
|
||||
return type.maxPrimaries;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool PartitionTable::tableTypeSupportsExtended(TableType l)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(tableTypes) / sizeof(tableTypes[0]); i++)
|
||||
if (l == tableTypes[i].type)
|
||||
return tableTypes[i].canHaveExtended;
|
||||
for (const auto &type : tableTypes)
|
||||
if (l == type.type)
|
||||
return type.canHaveExtended;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PartitionTable::tableTypeIsReadOnly(TableType l)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(tableTypes) / sizeof(tableTypes[0]); i++)
|
||||
if (l == tableTypes[i].type)
|
||||
return tableTypes[i].isReadOnly;
|
||||
for (const auto &type : tableTypes)
|
||||
if (l == type.type)
|
||||
return type.isReadOnly;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -452,26 +493,32 @@ bool PartitionTable::tableTypeIsReadOnly(TableType l)
|
|||
*/
|
||||
bool PartitionTable::isSectorBased(const Device& d) const
|
||||
{
|
||||
if (type() == PartitionTable::msdos) {
|
||||
// the default for empty partition tables is sector based
|
||||
if (numPrimaries() == 0)
|
||||
return true;
|
||||
if (d.type() == Device::Disk_Device) {
|
||||
const DiskDevice& diskDevice = dynamic_cast<const DiskDevice&>(d);
|
||||
|
||||
quint32 numCylinderAligned = 0;
|
||||
quint32 numSectorAligned = 0;
|
||||
if (type() == PartitionTable::msdos) {
|
||||
// the default for empty partition tables is sector based
|
||||
if (numPrimaries() == 0)
|
||||
return true;
|
||||
|
||||
// see if we have more cylinder aligned partitions than sector
|
||||
// aligned ones.
|
||||
foreach(const Partition * p, children())
|
||||
if (p->firstSector() % PartitionAlignment::sectorAlignment(d) == 0)
|
||||
numSectorAligned++;
|
||||
else if (p->firstSector() % d.cylinderSize() == 0)
|
||||
numCylinderAligned++;
|
||||
quint32 numCylinderAligned = 0;
|
||||
quint32 numSectorAligned = 0;
|
||||
|
||||
return numSectorAligned >= numCylinderAligned;
|
||||
// see if we have more cylinder aligned partitions than sector
|
||||
// aligned ones.
|
||||
for (const auto &p : children()) {
|
||||
if (p->firstSector() % PartitionAlignment::sectorAlignment(diskDevice) == 0)
|
||||
numSectorAligned++;
|
||||
else if (p->firstSector() % diskDevice.cylinderSize() == 0)
|
||||
numCylinderAligned++;
|
||||
}
|
||||
|
||||
return numSectorAligned >= numCylinderAligned;
|
||||
}
|
||||
return type() == PartitionTable::msdos_sectorbased;
|
||||
}
|
||||
|
||||
return type() == PartitionTable::msdos_sectorbased;
|
||||
return false;
|
||||
}
|
||||
|
||||
void PartitionTable::setType(const Device& d, TableType t)
|
||||
|
@ -497,19 +544,21 @@ QTextStream& operator<<(QTextStream& stream, const PartitionTable& ptable)
|
|||
|
||||
QList<const Partition*> partitions;
|
||||
|
||||
foreach(const Partition * p, ptable.children())
|
||||
for (const auto &p : ptable.children()) {
|
||||
if (!p->roles().has(PartitionRole::Unallocated)) {
|
||||
partitions.append(p);
|
||||
|
||||
if (p->roles().has(PartitionRole::Extended))
|
||||
foreach(const Partition * child, p->children())
|
||||
if (!child->roles().has(PartitionRole::Unallocated))
|
||||
partitions.append(child);
|
||||
for (const auto &child : p->children()) {
|
||||
if (!child->roles().has(PartitionRole::Unallocated))
|
||||
partitions.append(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qSort(partitions.begin(), partitions.end(), isPartitionLessThan);
|
||||
|
||||
foreach(const Partition * p, partitions)
|
||||
foreach(const auto &p, partitions)
|
||||
stream << *p;
|
||||
|
||||
return stream;
|
||||
|
|
|
@ -64,7 +64,8 @@ public:
|
|||
mac,
|
||||
pc98,
|
||||
amiga,
|
||||
sun
|
||||
sun,
|
||||
vmd /* Volume Manager Device */
|
||||
};
|
||||
|
||||
/** Partition flags */
|
||||
|
@ -94,7 +95,7 @@ public:
|
|||
Q_FLAG(Flag)
|
||||
|
||||
public:
|
||||
PartitionTable(TableType type, qint64 first_usable, qint64 last_usable);
|
||||
PartitionTable(TableType type, qint64 firstUsable, qint64 lastUsable);
|
||||
~PartitionTable();
|
||||
|
||||
public:
|
||||
|
@ -125,6 +126,7 @@ public:
|
|||
|
||||
qint64 freeSectorsBefore(const Partition& p) const;
|
||||
qint64 freeSectorsAfter(const Partition& p) const;
|
||||
qint64 freeSectors() const;
|
||||
|
||||
bool hasExtended() const;
|
||||
Partition* extended() const;
|
||||
|
@ -150,12 +152,19 @@ public:
|
|||
return m_LastUsable;
|
||||
}
|
||||
|
||||
void setFirstUsableSector(qint64 s) {
|
||||
m_FirstUsable = s;
|
||||
}
|
||||
void setLastUsableSector(qint64 s) {
|
||||
m_LastUsable = s;
|
||||
}
|
||||
|
||||
void updateUnallocated(const Device& d);
|
||||
void insertUnallocated(const Device& d, PartitionNode* p, qint64 start) const;
|
||||
|
||||
bool isSectorBased(const Device& d) const;
|
||||
|
||||
static QList<Flag> flagList();
|
||||
static const QList<Flag> flagList();
|
||||
static QString flagName(Flag f);
|
||||
static QStringList flagNames(Flags f);
|
||||
|
||||
|
@ -177,12 +186,6 @@ protected:
|
|||
void setMaxPrimaries(qint32 n) {
|
||||
m_MaxPrimaries = n;
|
||||
}
|
||||
void setFirstUsableSector(qint64 s) {
|
||||
m_FirstUsable = s;
|
||||
}
|
||||
void setLastUsableSector(qint64 s) {
|
||||
m_LastUsable = s;
|
||||
}
|
||||
|
||||
private:
|
||||
Partitions m_Children;
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "core/volumemanagerdevice.h"
|
||||
|
||||
/** Constructs an abstract Volume Manager Device with an empty PartitionTable.
|
||||
*
|
||||
*/
|
||||
VolumeManagerDevice::VolumeManagerDevice(const QString& name,
|
||||
const QString& deviceNode,
|
||||
const qint32 logicalSize,
|
||||
const qint64 totalLogical,
|
||||
const QString& iconName,
|
||||
Device::Type type)
|
||||
: Device(name, deviceNode, logicalSize, totalLogical, iconName, type)
|
||||
{
|
||||
}
|
||||
|
||||
QString VolumeManagerDevice::prettyDeviceNodeList() const
|
||||
{
|
||||
QString rval;
|
||||
for (const auto &devNode : deviceNodes()) {
|
||||
rval += devNode + QStringLiteral(",");
|
||||
}
|
||||
|
||||
if (rval.size()) {
|
||||
//chop off the trailing colon
|
||||
rval.chop(1);
|
||||
}
|
||||
return rval;
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(VOLUMEMANAGERDEVICE__H)
|
||||
|
||||
#define VOLUMEMANAGERDEVICE__H
|
||||
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
#include "core/device.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QObject>
|
||||
#include <QtGlobal>
|
||||
|
||||
/** A Volume Manager of physical devices represented as an abstract device.
|
||||
*
|
||||
* VolumeManagerDevice is an abstract device class for volume manager. e.g: LVM, SoftRAID.
|
||||
* example of physical device: /dev/sda, /dev/sdb1.
|
||||
*
|
||||
* Devices are the outermost entity; they contain a PartitionTable that itself contains Partitions.
|
||||
*
|
||||
* @see Device, PartitionTable, Partition
|
||||
*/
|
||||
class LIBKPMCORE_EXPORT VolumeManagerDevice : public Device
|
||||
{
|
||||
Q_DISABLE_COPY(VolumeManagerDevice)
|
||||
|
||||
public:
|
||||
|
||||
VolumeManagerDevice(const QString& name, const QString& deviceNode, const qint32 logicalSize, const qint64 totalLogical, const QString& iconName = QString(), Device::Type type = Device::Unknown_Device);
|
||||
|
||||
/**
|
||||
* @return list of physical device's path that makes up volumeManagerDevice.(e.g: /dev/sda, /dev/sdb1)
|
||||
*/
|
||||
virtual const QStringList deviceNodes() const = 0;
|
||||
|
||||
/**
|
||||
* @return list of logical partition's path.
|
||||
*/
|
||||
virtual const QStringList partitionNodes() const = 0;
|
||||
|
||||
/**
|
||||
* @return size of logical partition at the given path in bytes.
|
||||
*/
|
||||
virtual qint64 partitionSize(QString& partitionPath) const = 0;
|
||||
|
||||
protected:
|
||||
|
||||
/** Initialize device's partition table and partitions.
|
||||
*
|
||||
*/
|
||||
virtual void initPartitions() = 0;
|
||||
|
||||
/** absolute sector as represented inside the device's partitionTable
|
||||
*
|
||||
* For VolumeMangerDevice to works with the rest of the codebase, partitions are stringed
|
||||
* one after another to create a representation of PartitionTable and partition just like
|
||||
* real disk device.
|
||||
*
|
||||
* @param partitionPath logical partition path
|
||||
* @sector sector value to be mapped (if 0, will return start sector of the partition)
|
||||
* @return absolute sector value as represented inside device's partitionTable
|
||||
*/
|
||||
virtual qint64 mappedSector(const QString& partitionPath, qint64 sector) const = 0;
|
||||
|
||||
public:
|
||||
|
||||
/** string deviceNodes together into comma-sperated list
|
||||
*
|
||||
* @return comma-seperated list of deviceNodes
|
||||
*/
|
||||
virtual QString prettyDeviceNodeList() const;
|
||||
|
||||
/** Resize device total number of logical sectors.
|
||||
*
|
||||
* @param n Number of sectors.
|
||||
*/
|
||||
void setTotalLogical(qint64 n) {
|
||||
Q_ASSERT(n > 0);
|
||||
m_TotalLogical = n;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,6 +1,6 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2008,2009 by Volker Lanz <vl@fidra.de> *
|
||||
* Copyright (C) 2016 by Andrius Štikonas <andrius@stikonas.eu> *
|
||||
* Copyright (C) 2016 by Andrius Štikonas <andrius@stikonas.eu> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
|
|
|
@ -154,8 +154,10 @@ bool fat16::updateUUID(Report& report, const QString& deviceNode) const
|
|||
qint32 t = time(nullptr);
|
||||
|
||||
char uuid[4];
|
||||
for (quint32 i = 0; i < sizeof(uuid); i++, t >>= 8)
|
||||
uuid[i] = t & 0xff;
|
||||
for (auto &u : uuid) {
|
||||
u = t & 0xff;
|
||||
t >>= 8;
|
||||
}
|
||||
|
||||
ExternalCommand cmd(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode , QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=39") });
|
||||
|
||||
|
|
|
@ -51,8 +51,10 @@ bool fat32::updateUUID(Report& report, const QString& deviceNode) const
|
|||
qint32 t = time(nullptr);
|
||||
|
||||
char uuid[4];
|
||||
for (quint32 i = 0; i < sizeof(uuid); i++, t >>= 8)
|
||||
uuid[i] = t & 0xff;
|
||||
for (auto &u : uuid) {
|
||||
u = t & 0xff;
|
||||
t >>= 8;
|
||||
}
|
||||
|
||||
ExternalCommand cmd(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode, QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=67") });
|
||||
|
||||
|
|
|
@ -84,9 +84,8 @@ void FileSystemFactory::init()
|
|||
m_FileSystems.insert(FileSystem::Xfs, new FS::xfs(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Zfs, new FS::zfs(-1, -1, -1, QString()));
|
||||
|
||||
foreach(FileSystem * fs, FileSystemFactory::map()) {
|
||||
for (const auto &fs : FileSystemFactory::map())
|
||||
fs->init();
|
||||
}
|
||||
|
||||
CoreBackendManager::self()->backend()->initFSSupport();
|
||||
}
|
||||
|
|
|
@ -69,18 +69,21 @@ luks::~luks()
|
|||
|
||||
void luks::init()
|
||||
{
|
||||
m_Create = findExternal(QStringLiteral("cryptsetup")) ? cmdSupportFileSystem : cmdSupportNone;
|
||||
CommandSupportType cryptsetupFound = findExternal(QStringLiteral("cryptsetup")) ? cmdSupportFileSystem : cmdSupportNone;
|
||||
|
||||
m_Create = cryptsetupFound;
|
||||
m_UpdateUUID = cryptsetupFound;
|
||||
m_GetUUID = cryptsetupFound;
|
||||
m_Grow = cryptsetupFound;
|
||||
m_Shrink = cryptsetupFound;
|
||||
|
||||
m_SetLabel = cmdSupportNone;
|
||||
m_GetLabel = cmdSupportFileSystem;
|
||||
m_UpdateUUID = findExternal(QStringLiteral("cryptsetup")) ? cmdSupportFileSystem : cmdSupportNone;
|
||||
m_Grow = findExternal(QStringLiteral("cryptsetup")) ? cmdSupportFileSystem : cmdSupportNone;
|
||||
m_Shrink = m_Grow;
|
||||
m_Check = cmdSupportCore;
|
||||
m_Copy = cmdSupportCore;
|
||||
m_Move = cmdSupportCore;
|
||||
m_Backup = cmdSupportCore;
|
||||
m_GetUsed = cmdSupportNone; // libparted does not support LUKS, we do this as a special case
|
||||
m_GetUUID = findExternal(QStringLiteral("cryptsetup")) ? cmdSupportFileSystem : cmdSupportNone;
|
||||
}
|
||||
|
||||
bool luks::supportToolFound() const
|
||||
|
@ -319,7 +322,7 @@ void luks::loadInnerFileSystem(const QString& deviceNode, const QString& mapperN
|
|||
setLabel(m_innerFs->readLabel(mapperNode));
|
||||
setUUID(m_innerFs->readUUID(mapperNode));
|
||||
if (m_innerFs->supportGetUsed() == FileSystem::cmdSupportFileSystem)
|
||||
setSectorsUsed(m_innerFs->readUsedCapacity(mapperNode)/m_logicalSectorSize + getPayloadOffset(deviceNode));
|
||||
setSectorsUsed((m_innerFs->readUsedCapacity(mapperNode) + getPayloadOffset(deviceNode)) / m_logicalSectorSize );
|
||||
}
|
||||
|
||||
void luks::createInnerFileSystem(FileSystem::Type type)
|
||||
|
@ -378,7 +381,7 @@ bool luks::mount(Report& report, const QString& deviceNode, const QString& mount
|
|||
|
||||
const KDiskFreeSpaceInfo freeSpaceInfo = KDiskFreeSpaceInfo::freeSpaceInfo(mountPoint);
|
||||
if (freeSpaceInfo.isValid() && mountPoint != QString())
|
||||
setSectorsUsed(freeSpaceInfo.used() / m_logicalSectorSize + getPayloadOffset(deviceNode));
|
||||
setSectorsUsed((freeSpaceInfo.used() + getPayloadOffset(deviceNode)) / m_logicalSectorSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -473,7 +476,7 @@ bool luks::resize(Report& report, const QString& deviceNode, qint64 newLength) c
|
|||
if (mapperNode.isEmpty())
|
||||
return false;
|
||||
|
||||
qint64 payloadLength = newLength - getPayloadOffset(deviceNode) * m_logicalSectorSize;
|
||||
qint64 payloadLength = newLength - getPayloadOffset(deviceNode);
|
||||
if ( newLength - length() * m_logicalSectorSize > 0 )
|
||||
{
|
||||
ExternalCommand cryptResizeCmd(report, QStringLiteral("cryptsetup"), { QStringLiteral("resize"), mapperNode });
|
||||
|
@ -481,12 +484,14 @@ bool luks::resize(Report& report, const QString& deviceNode, qint64 newLength) c
|
|||
|
||||
if (cryptResizeCmd.run(-1) && cryptResizeCmd.exitCode() == 0)
|
||||
{
|
||||
return m_innerFs->resize(report, mapperNode, newLength - getPayloadOffset(deviceNode) * m_logicalSectorSize);
|
||||
return m_innerFs->resize(report, mapperNode, payloadLength);
|
||||
}
|
||||
}
|
||||
else if (m_innerFs->resize(report, mapperNode, payloadLength))
|
||||
{
|
||||
ExternalCommand cryptResizeCmd(report, QStringLiteral("cryptsetup"), { QStringLiteral("--size"), QString::number(payloadLength / m_logicalSectorSize), QStringLiteral("resize"), mapperNode });
|
||||
ExternalCommand cryptResizeCmd(report, QStringLiteral("cryptsetup"),
|
||||
{ QStringLiteral("--size"), QString::number(payloadLength / /*m_logicalSectorSize*/ 512), // LUKS assume 512 bytes sector
|
||||
QStringLiteral("resize"), mapperNode });
|
||||
report.line() << xi18nc("@info:progress", "Resizing LUKS crypt on partition <filename>%1</filename>.", deviceNode);
|
||||
if (cryptResizeCmd.run(-1) && cryptResizeCmd.exitCode() == 0)
|
||||
{
|
||||
|
@ -596,6 +601,9 @@ qint64 luks::getKeySize(const QString& deviceNode) const
|
|||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* @return size of payload offset in bytes.
|
||||
*/
|
||||
qint64 luks::getPayloadOffset(const QString& deviceNode) const
|
||||
{
|
||||
ExternalCommand cmd(QStringLiteral("cryptsetup"),
|
||||
|
@ -604,7 +612,7 @@ qint64 luks::getPayloadOffset(const QString& deviceNode) const
|
|||
QRegularExpression re(QStringLiteral("Payload offset:\\s+(\\d+)"));
|
||||
QRegularExpressionMatch rePayloadOffset = re.match(cmd.output());
|
||||
if (rePayloadOffset.hasMatch())
|
||||
return rePayloadOffset.captured(1).toLongLong();
|
||||
return rePayloadOffset.captured(1).toLongLong() * 512; // assuming LUKS sector size is 512
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#include <QString>
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
namespace FS
|
||||
{
|
||||
FileSystem::CommandSupportType lvm2_pv::m_GetUsed = FileSystem::cmdSupportNone;
|
||||
|
@ -45,31 +47,36 @@ lvm2_pv::lvm2_pv(qint64 firstsector, qint64 lastsector, qint64 sectorsused, cons
|
|||
|
||||
void lvm2_pv::init()
|
||||
{
|
||||
m_Create = findExternal(QStringLiteral("lvm")) ? cmdSupportFileSystem : cmdSupportNone;
|
||||
m_Check = findExternal(QStringLiteral("lvm")) ? cmdSupportFileSystem : cmdSupportNone;
|
||||
CommandSupportType lvmFound = findExternal(QStringLiteral("lvm")) ? cmdSupportFileSystem : cmdSupportNone;
|
||||
|
||||
m_GetLabel = cmdSupportCore;
|
||||
m_UpdateUUID = findExternal(QStringLiteral("lvm")) ? cmdSupportFileSystem : cmdSupportNone;
|
||||
m_Create = lvmFound;
|
||||
m_Check = lvmFound;
|
||||
m_Grow = lvmFound;
|
||||
m_Shrink = lvmFound;
|
||||
m_UpdateUUID = lvmFound;
|
||||
m_GetUsed = lvmFound;
|
||||
|
||||
m_Copy = cmdSupportNone; // Copying PV can confuse LVM
|
||||
m_Move = (m_Check != cmdSupportNone) ? cmdSupportCore : cmdSupportNone;
|
||||
|
||||
m_GetLabel = cmdSupportCore;
|
||||
m_Backup = cmdSupportCore;
|
||||
m_GetUUID = cmdSupportCore;
|
||||
|
||||
m_GetLabel = cmdSupportNone;
|
||||
m_Backup = cmdSupportCore;
|
||||
m_GetUUID = cmdSupportCore;
|
||||
m_Copy = cmdSupportNone; // Copying PV can confuse LVM
|
||||
}
|
||||
|
||||
bool lvm2_pv::supportToolFound() const
|
||||
{
|
||||
return
|
||||
// m_GetUsed != cmdSupportNone &&
|
||||
m_GetUsed != cmdSupportNone &&
|
||||
// m_GetLabel != cmdSupportNone &&
|
||||
// m_SetLabel != cmdSupportNone &&
|
||||
m_Create != cmdSupportNone &&
|
||||
m_Check != cmdSupportNone &&
|
||||
m_UpdateUUID != cmdSupportNone &&
|
||||
// m_Grow != cmdSupportNone &&
|
||||
// m_Shrink != cmdSupportNone &&
|
||||
m_Grow != cmdSupportNone &&
|
||||
m_Shrink != cmdSupportNone &&
|
||||
// m_Copy != cmdSupportNone &&
|
||||
m_Move != cmdSupportNone &&
|
||||
m_Backup != cmdSupportNone &&
|
||||
|
@ -86,6 +93,13 @@ qint64 lvm2_pv::maxCapacity() const
|
|||
return Capacity::unitFactor(Capacity::Byte, Capacity::EiB);
|
||||
}
|
||||
|
||||
qint64 lvm2_pv::readUsedCapacity(const QString& deviceNode) const
|
||||
{
|
||||
QString val = getpvField(QStringLiteral("pv_used"), deviceNode);
|
||||
QString metadataOffset = getpvField(QStringLiteral("pe_start"), deviceNode);
|
||||
return val.isEmpty() ? -1 : val.toLongLong() + metadataOffset.toLongLong();
|
||||
}
|
||||
|
||||
bool lvm2_pv::check(Report& report, const QString& deviceNode) const
|
||||
{
|
||||
ExternalCommand cmd(report, QStringLiteral("lvm"), { QStringLiteral("pvck"), QStringLiteral("--verbose"), deviceNode });
|
||||
|
@ -94,7 +108,7 @@ bool lvm2_pv::check(Report& report, const QString& deviceNode) const
|
|||
|
||||
bool lvm2_pv::create(Report& report, const QString& deviceNode) const
|
||||
{
|
||||
ExternalCommand cmd(report, QStringLiteral("lvm"), { QStringLiteral("pvcreate"), deviceNode });
|
||||
ExternalCommand cmd(report, QStringLiteral("lvm"), { QStringLiteral("pvcreate"), QStringLiteral("--force"), deviceNode });
|
||||
return cmd.run(-1) && cmd.exitCode() == 0;
|
||||
}
|
||||
|
||||
|
@ -105,16 +119,222 @@ bool lvm2_pv::remove(Report& report, const QString& deviceNode) const
|
|||
return cmd.run(-1) && cmd.exitCode() == 0;
|
||||
}
|
||||
|
||||
bool lvm2_pv::resize(Report& report, const QString& deviceNode, qint64 length) const
|
||||
{
|
||||
bool rval = true;
|
||||
|
||||
qint64 metadataOffset = getpvField(QStringLiteral("pe_start"), deviceNode).toLongLong();
|
||||
|
||||
qint64 lastPE = getTotalPE(deviceNode) - 1; // starts from 0
|
||||
if (lastPE > 0) { // make sure that the PV is already in a VG
|
||||
qint64 targetPE = (length - metadataOffset)/ getPESize(deviceNode) - 1; // starts from 0
|
||||
if (targetPE < lastPE) { //shrinking FS
|
||||
qint64 firstMovedPE = qMax(targetPE + 1, getAllocatedPE(deviceNode)); // starts from 1
|
||||
ExternalCommand moveCmd(report,
|
||||
QStringLiteral("lvm"), {
|
||||
QStringLiteral("pvmove"),
|
||||
QStringLiteral("--alloc"),
|
||||
QStringLiteral("anywhere"),
|
||||
deviceNode + QStringLiteral(":") + QString::number(firstMovedPE) + QStringLiteral("-") + QString::number(lastPE),
|
||||
deviceNode + QStringLiteral(":") + QStringLiteral("0-") + QString::number(firstMovedPE - 1)
|
||||
});
|
||||
rval = moveCmd.run(-1) && (moveCmd.exitCode() == 0 || moveCmd.exitCode() == 5); // FIXME: exit code 5: NO data to move
|
||||
}
|
||||
}
|
||||
|
||||
ExternalCommand cmd(report, QStringLiteral("lvm"), {
|
||||
QStringLiteral("pvresize"),
|
||||
QStringLiteral("--yes"),
|
||||
QStringLiteral("--setphysicalvolumesize"),
|
||||
QString::number(length) + QStringLiteral("B"),
|
||||
deviceNode });
|
||||
return rval && cmd.run(-1) && cmd.exitCode() == 0;
|
||||
}
|
||||
|
||||
bool lvm2_pv::updateUUID(Report& report, const QString& deviceNode) const
|
||||
{
|
||||
ExternalCommand cmd(report, QStringLiteral("lvm"), { QStringLiteral("pvchange"), QStringLiteral("--uuid"), deviceNode });
|
||||
return cmd.run(-1) && cmd.exitCode() == 0;
|
||||
}
|
||||
|
||||
bool lvm2_pv::canMount(const QString & deviceNode, const QString & mountPoint) const
|
||||
QString lvm2_pv::readUUID(const QString& deviceNode) const
|
||||
{
|
||||
Q_UNUSED(deviceNode)
|
||||
Q_UNUSED(mountPoint)
|
||||
return getpvField(QStringLiteral("pv_uuid"), deviceNode);
|
||||
}
|
||||
|
||||
bool lvm2_pv::mount(Report& report, const QString& deviceNode, const QString& mountPoint)
|
||||
{
|
||||
Q_UNUSED(report);
|
||||
Q_UNUSED(deviceNode);
|
||||
Q_UNUSED(mountPoint);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool lvm2_pv::unmount(Report& report, const QString& deviceNode)
|
||||
{
|
||||
Q_UNUSED(deviceNode);
|
||||
Q_UNUSED(report);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool lvm2_pv::canMount(const QString & deviceNode, const QString & mountPoint) const
|
||||
{
|
||||
Q_UNUSED(mountPoint);
|
||||
QString rval = getpvField(QStringLiteral("pv_in_use"), deviceNode); // this field return "used" when in use otherwise empty string
|
||||
if (rval.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool lvm2_pv::canUnmount(const QString& deviceNode) const
|
||||
{
|
||||
QString rval = getpvField(QStringLiteral("pv_in_use"), deviceNode);
|
||||
if (rval.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
qint64 lvm2_pv::getTotalPE(const QString& deviceNode)
|
||||
{
|
||||
QString val = getpvField(QStringLiteral("pv_pe_count"), deviceNode);
|
||||
return val.isEmpty() ? -1 : val.toLongLong();
|
||||
}
|
||||
|
||||
qint64 lvm2_pv::getTotalPE(const QStringList& deviceNodeList)
|
||||
{
|
||||
qint64 sum = 0;
|
||||
for (const auto &deviceNode : deviceNodeList) {
|
||||
qint64 totalPE = getTotalPE(deviceNode);
|
||||
if (totalPE < 0) {
|
||||
sum = -1;
|
||||
break;
|
||||
}
|
||||
sum += totalPE;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
qint64 lvm2_pv::getFreePE(const QString& deviceNode)
|
||||
{
|
||||
return getTotalPE(deviceNode) - getAllocatedPE(deviceNode);
|
||||
}
|
||||
|
||||
qint64 lvm2_pv::getFreePE(const QStringList& deviceNodeList)
|
||||
{
|
||||
qint64 sum = 0;
|
||||
for (QString deviceNode :deviceNodeList) {
|
||||
qint64 freePE = getFreePE(deviceNode);
|
||||
if (freePE < 0) {
|
||||
sum = -1;
|
||||
break;
|
||||
}
|
||||
sum += freePE;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
qint64 lvm2_pv::getAllocatedPE(const QString& deviceNode)
|
||||
{
|
||||
QString val = getpvField(QStringLiteral("pv_pe_alloc_count"), deviceNode);
|
||||
return val.isEmpty() ? -1 : val.toLongLong();
|
||||
}
|
||||
|
||||
qint64 lvm2_pv::getAllocatedPE(const QStringList& deviceNodeList)
|
||||
{
|
||||
qint64 sum = 0;
|
||||
for (QString deviceNode : deviceNodeList) {
|
||||
qint64 allocatedPE = getAllocatedPE(deviceNode);
|
||||
if (allocatedPE < 0) {
|
||||
sum = -1;
|
||||
break;
|
||||
}
|
||||
sum += allocatedPE;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
qint64 lvm2_pv::getPVSize(const QString& deviceNode)
|
||||
{
|
||||
QString val = getpvField(QStringLiteral("pv_size"), deviceNode);
|
||||
return val.isEmpty() ? -1 : val.toLongLong();
|
||||
}
|
||||
|
||||
qint64 lvm2_pv::getPVSize(const QStringList& deviceNodeList)
|
||||
{
|
||||
qint64 sum = 0;
|
||||
for (QString deviceNode : deviceNodeList) {
|
||||
qint64 pvsize = getPVSize(deviceNode);
|
||||
if (pvsize < 0) {
|
||||
sum = -1;
|
||||
break;
|
||||
}
|
||||
sum += pvsize;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
qint64 lvm2_pv::getPESize(const QString& deviceNode)
|
||||
{
|
||||
QString val = getpvField(QStringLiteral("vg_extent_size"), deviceNode);
|
||||
return val.isEmpty() ? -1 : val.toLongLong();
|
||||
}
|
||||
|
||||
/** Get pvs command output with field name
|
||||
*
|
||||
* @param fieldName LVM field name
|
||||
* @param deviceNode path to PV
|
||||
* @return raw output of pvs command, usually with many spaces
|
||||
*/
|
||||
QString lvm2_pv::getpvField(const QString& fieldName, const QString& deviceNode)
|
||||
{
|
||||
QStringList args = { QStringLiteral("pvs"),
|
||||
QStringLiteral("--foreign"),
|
||||
QStringLiteral("--readonly"),
|
||||
QStringLiteral("--noheadings"),
|
||||
QStringLiteral("--units"),
|
||||
QStringLiteral("B"),
|
||||
QStringLiteral("--nosuffix"),
|
||||
QStringLiteral("--options"),
|
||||
fieldName };
|
||||
if (!deviceNode.isEmpty()) {
|
||||
args << deviceNode;
|
||||
}
|
||||
ExternalCommand cmd(QStringLiteral("lvm"), args);
|
||||
if (cmd.run(-1) && cmd.exitCode() == 0) {
|
||||
return cmd.output().trimmed();
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString lvm2_pv::getVGName(const QString& deviceNode)
|
||||
{
|
||||
return getpvField(QStringLiteral("vg_name"), deviceNode);
|
||||
}
|
||||
|
||||
const QStringList lvm2_pv::getFreePV()
|
||||
{
|
||||
QStringList rlist;
|
||||
|
||||
QString output = getpvField(QStringLiteral("pv_name"));
|
||||
const QStringList pvList = output.split(QStringLiteral("\n"), QString::SkipEmptyParts);
|
||||
for (QString pvnode : pvList) {
|
||||
if (!isUsed(pvnode.trimmed())) {
|
||||
rlist.append(pvnode.trimmed());
|
||||
}
|
||||
}
|
||||
|
||||
return rlist;
|
||||
}
|
||||
|
||||
bool lvm2_pv::isUsed(const QString& deviceNode)
|
||||
{
|
||||
QString output = getpvField(QStringLiteral("pv_in_use"), deviceNode.trimmed());
|
||||
if (output.trimmed() == QStringLiteral("used")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -43,14 +43,21 @@ public:
|
|||
public:
|
||||
void init() override;
|
||||
|
||||
// qint64 readUsedCapacity(const QString& deviceNode) const override;
|
||||
qint64 readUsedCapacity(const QString& deviceNode) const override;
|
||||
bool check(Report& report, const QString& deviceNode) const override;
|
||||
bool create(Report& report, const QString& deviceNode) const override;
|
||||
bool remove(Report& report, const QString& deviceNode) const override;
|
||||
// bool resize(Report& report, const QString& deviceNode, qint64 length) const override;
|
||||
bool resize(Report& report, const QString& deviceNode, qint64 length) const override;
|
||||
// bool writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) override;
|
||||
bool updateUUID(Report& report, const QString& deviceNode) const override;
|
||||
QString readUUID(const QString& deviceNode) const override;
|
||||
|
||||
bool canMount(const QString & deviceNode, const QString & mountPoint) const override;
|
||||
bool canUnmount(const QString& deviceNode) const override;
|
||||
|
||||
bool mount(Report& report, const QString& deviceNode, const QString& mountPoint) override; // mountPoint == VG name
|
||||
bool unmount(Report& report, const QString& deviceNode) override;
|
||||
|
||||
|
||||
CommandSupportType supportGetUsed() const override {
|
||||
return m_GetUsed;
|
||||
|
@ -93,6 +100,23 @@ public:
|
|||
SupportTool supportToolName() const override;
|
||||
bool supportToolFound() const override;
|
||||
|
||||
static qint64 getTotalPE(const QString& deviceNode);
|
||||
static qint64 getTotalPE(const QStringList& deviceNodeList);
|
||||
static qint64 getFreePE(const QString& deviceNode);
|
||||
static qint64 getFreePE(const QStringList& deviceNodeList);
|
||||
static qint64 getAllocatedPE(const QString& deviceNode);
|
||||
static qint64 getAllocatedPE(const QStringList& deviceNodeList);
|
||||
static qint64 getPESize(const QString& deviceNode); // return PE size in bytes
|
||||
static qint64 getPVSize(const QString& deviceNode); // return PV size in bytes
|
||||
static qint64 getPVSize(const QStringList& deviceNodeList);
|
||||
|
||||
static bool isUsed(const QString& pvNode);
|
||||
|
||||
static QString getVGName(const QString& deviceNode);
|
||||
static QString getpvField(const QString& fieldName, const QString& deviceNode = QString());
|
||||
|
||||
static const QStringList getFreePV();
|
||||
|
||||
public:
|
||||
static CommandSupportType m_GetUsed;
|
||||
static CommandSupportType m_GetLabel;
|
||||
|
|
|
@ -133,9 +133,9 @@ qint32 PartResizerWidget::handleWidth() const
|
|||
return style()->pixelMetric(QStyle::PM_SplitterWidth);
|
||||
}
|
||||
|
||||
qint64 PartResizerWidget::sectorsPerPixel() const
|
||||
long double PartResizerWidget::sectorsPerPixel() const
|
||||
{
|
||||
return totalSectors() / (width() - 2 * handleWidth());
|
||||
return totalSectors() / (width() - 2.0L * handleWidth());
|
||||
}
|
||||
|
||||
int PartResizerWidget::partWidgetStart() const
|
||||
|
@ -285,13 +285,13 @@ void PartResizerWidget::mouseMoveEvent(QMouseEvent* event)
|
|||
int x = event->pos().x() - m_Hotspot;
|
||||
|
||||
if (draggedWidget() == &leftHandle()) {
|
||||
const qint64 newFirstSector = qMax(minimumFirstSector() + x * sectorsPerPixel(), 0LL);
|
||||
const qint64 newFirstSector = qMax(minimumFirstSector() + x * sectorsPerPixel(), 0.0L);
|
||||
updateFirstSector(newFirstSector);
|
||||
} else if (draggedWidget() == &rightHandle()) {
|
||||
const qint64 newLastSector = qMin(minimumFirstSector() + (x - rightHandle().width()) * sectorsPerPixel(), maximumLastSector());
|
||||
const qint64 newLastSector = qMin(static_cast<qint64>(minimumFirstSector() + (x - rightHandle().width()) * sectorsPerPixel()), maximumLastSector());
|
||||
updateLastSector(newLastSector);
|
||||
} else if (draggedWidget() == &partWidget() && moveAllowed()) {
|
||||
const qint64 newFirstSector = qMax(minimumFirstSector() + (x - handleWidth()) * sectorsPerPixel(), 0LL);
|
||||
const qint64 newFirstSector = qMax(minimumFirstSector() + (x - handleWidth()) * sectorsPerPixel(), 0.0L);
|
||||
movePartition(newFirstSector);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,7 +169,7 @@ protected:
|
|||
return m_RightHandle;
|
||||
}
|
||||
|
||||
qint64 sectorsPerPixel() const;
|
||||
long double sectorsPerPixel() const;
|
||||
|
||||
void set(qint64 newCap, qint64 newFreeBefore, qint64 newFreeAfter);
|
||||
|
||||
|
|
|
@ -56,13 +56,13 @@ void PartWidget::init(const Partition* p)
|
|||
void PartWidget::updateChildren()
|
||||
{
|
||||
if (partition()) {
|
||||
foreach(QWidget * w, childWidgets()) {
|
||||
for (const auto &w : childWidgets()) {
|
||||
w->setVisible(false);
|
||||
w->deleteLater();
|
||||
w->setParent(nullptr);
|
||||
}
|
||||
|
||||
foreach(const Partition * child, partition()->children()) {
|
||||
for (const auto &child : partition()->children()) {
|
||||
QWidget* w = new PartWidget(this, child);
|
||||
w->setVisible(true);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ template<typename T>
|
|||
T sum(const QList<T>& list)
|
||||
{
|
||||
T rval = 0;
|
||||
foreach(const T & val, list)
|
||||
for (const T & val : list)
|
||||
rval += val;
|
||||
return rval;
|
||||
}
|
||||
|
@ -107,21 +107,21 @@ void PartWidgetBase::positionChildren(const QWidget* destWidget, const Partition
|
|||
return;
|
||||
|
||||
qint64 totalLength = 0;
|
||||
foreach(const Partition * p, partitions)
|
||||
for (const auto &p : partitions)
|
||||
totalLength += p->length();
|
||||
|
||||
if (totalLength < 1)
|
||||
return;
|
||||
|
||||
// calculate unleveled width for each child and store it
|
||||
for (int i = 0; i < partitions.size(); i++) {
|
||||
childrenWidth.append(partitions[i]->length() * destWidgetWidth / totalLength);
|
||||
for (const auto &p : partitions) {
|
||||
childrenWidth.append(p->length() * destWidgetWidth / totalLength);
|
||||
|
||||
// Calculate the minimum width for the widget. This is easy for primary and logical partitions: they
|
||||
// just have a fixed min width (configured in m_MinWidth). But for extended partitions things
|
||||
// are not quite as simple. We need to calc the sum of the min widths for each child, taking
|
||||
// spacing and borders into account, and add our own min width.
|
||||
qint32 min = (minWidth() + 2 * borderWidth() + spacing()) * partitions[i]->children().size() - spacing() + 2 * borderWidth();
|
||||
qint32 min = (minWidth() + 2 * borderWidth() + spacing()) * p->children().size() - spacing() + 2 * borderWidth();
|
||||
|
||||
// if it's too small, this partition is a primary or logical so just use the configured value
|
||||
if (min < minWidth())
|
||||
|
@ -142,11 +142,11 @@ void PartWidgetBase::positionChildren(const QWidget* destWidget, const Partition
|
|||
}
|
||||
}
|
||||
|
||||
QList<PartWidget*> PartWidgetBase::childWidgets()
|
||||
const QList<PartWidget*> PartWidgetBase::childWidgets() const
|
||||
{
|
||||
QList<PartWidget*> rval;
|
||||
|
||||
foreach(QObject * o, children())
|
||||
for (auto &o : children())
|
||||
if (PartWidget* w = qobject_cast<PartWidget*>(o))
|
||||
rval.append(w);
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ public:
|
|||
return m_MinWidth; /**< @return minimum width for a Partition widget */
|
||||
}
|
||||
|
||||
virtual QList<PartWidget*> childWidgets();
|
||||
virtual const QList<PartWidget*> childWidgets() const;
|
||||
|
||||
protected:
|
||||
virtual void positionChildren(const QWidget* destWidget, const PartitionNode::Partitions& partitions, QList<PartWidget*> widgets) const;
|
||||
|
|
|
@ -6,6 +6,12 @@ set(JOBS_SRC
|
|||
jobs/shredfilesystemjob.cpp
|
||||
jobs/createpartitionjob.cpp
|
||||
jobs/createpartitiontablejob.cpp
|
||||
jobs/createvolumegroupjob.cpp
|
||||
jobs/removevolumegroupjob.cpp
|
||||
jobs/deactivatevolumegroupjob.cpp
|
||||
jobs/deactivatelogicalvolumejob.cpp
|
||||
jobs/resizevolumegroupjob.cpp
|
||||
jobs/movephysicalvolumejob.cpp
|
||||
jobs/setfilesystemlabeljob.cpp
|
||||
jobs/deletepartitionjob.cpp
|
||||
jobs/restorefilesystemjob.cpp
|
||||
|
|
|
@ -57,7 +57,7 @@ bool BackupFileSystemJob::run(Report& parent)
|
|||
rval = sourcePartition().fileSystem().backup(*report, sourceDevice(), sourcePartition().deviceNode(), fileName());
|
||||
else if (sourcePartition().fileSystem().supportBackup() == FileSystem::cmdSupportCore) {
|
||||
CopySourceDevice copySource(sourceDevice(), sourcePartition().fileSystem().firstSector(), sourcePartition().fileSystem().lastSector());
|
||||
CopyTargetFile copyTarget(fileName(), sourceDevice().logicalSectorSize());
|
||||
CopyTargetFile copyTarget(fileName(), sourceDevice().logicalSize());
|
||||
|
||||
if (!copySource.open())
|
||||
report->line() << xi18nc("@info:progress", "Could not open file system on source partition <filename>%1</filename> for backup.", sourcePartition().deviceNode());
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "core/partition.h"
|
||||
#include "core/device.h"
|
||||
#include "core/lvmdevice.h"
|
||||
|
||||
#include "util/report.h"
|
||||
|
||||
|
@ -49,29 +50,38 @@ bool CreatePartitionJob::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) {
|
||||
QString partitionPath = backendPartitionTable->createPartition(*report, partition());
|
||||
if (backendPartitionTable) {
|
||||
QString partitionPath = backendPartitionTable->createPartition(*report, partition());
|
||||
|
||||
if (partitionPath != QString()) {
|
||||
rval = true;
|
||||
partition().setPartitionPath(partitionPath);
|
||||
partition().setState(Partition::StateNone);
|
||||
backendPartitionTable->commit();
|
||||
if (partitionPath != QString()) {
|
||||
rval = true;
|
||||
partition().setPartitionPath(partitionPath);
|
||||
partition().setState(Partition::StateNone);
|
||||
backendPartitionTable->commit();
|
||||
} else
|
||||
report->line() << xi18nc("@info/plain", "Failed to add partition <filename>%1</filename> to device <filename>%2</filename>.", partition().deviceNode(), device().deviceNode());
|
||||
|
||||
delete backendPartitionTable;
|
||||
} else
|
||||
report->line() << xi18nc("@info:progress", "Failed to add partition <filename>%1</filename> to device <filename>%2</filename>.", partition().deviceNode(), device().deviceNode());
|
||||
report->line() << xi18nc("@info:progress", "Could not open partition table on device <filename>%1</filename> to create new 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 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) {
|
||||
LvmDevice& dev = dynamic_cast<LvmDevice&>(device());
|
||||
partition().setState(Partition::StateNone);
|
||||
|
||||
delete backendDevice;
|
||||
} else
|
||||
report->line() << xi18nc("@info:progress", "Could not open device <filename>%1</filename> to create new partition <filename>%2</filename>.", device().deviceNode(), partition().deviceNode());
|
||||
QString partPath = partition().partitionPath();
|
||||
QString lvname = partPath.right(partPath.length() - partPath.lastIndexOf(QStringLiteral("/")) - 1);
|
||||
rval = LvmDevice::createLV(*report, dev, partition(), lvname);
|
||||
}
|
||||
|
||||
jobFinished(*report, rval);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "jobs/createvolumegroupjob.h"
|
||||
|
||||
#include "core/lvmdevice.h"
|
||||
|
||||
#include "util/report.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
/** Creates a new CreateVolumeGroupJob
|
||||
* @param vgName LVM Volume Group name
|
||||
* @param pvList List of LVM Physical Volumes used to create Volume Group
|
||||
* @param peSize LVM Physical Extent size in MiB
|
||||
*/
|
||||
CreateVolumeGroupJob::CreateVolumeGroupJob(const QString& vgName, const QStringList& pvList, const qint32 peSize) :
|
||||
Job(),
|
||||
m_vgName(vgName),
|
||||
m_pvList(pvList),
|
||||
m_PESize(peSize)
|
||||
{
|
||||
}
|
||||
|
||||
bool CreateVolumeGroupJob::run(Report& parent)
|
||||
{
|
||||
bool rval = false;
|
||||
|
||||
Report* report = jobStarted(parent);
|
||||
|
||||
rval = LvmDevice::createVG(*report, vgName(), pvList(), peSize());
|
||||
|
||||
jobFinished(*report, rval);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
QString CreateVolumeGroupJob::description() const
|
||||
{
|
||||
QString tmp = QString();
|
||||
for (const auto &name : pvList()) {
|
||||
tmp += QStringLiteral("\n") + name;
|
||||
}
|
||||
return xi18nc("@info/plain", "Create new Volume Group: <filename>%1</filename> with PV: %2", vgName(), tmp);
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(CREATEVOLUMEGROUPJOB_H)
|
||||
|
||||
#define CREATEVOLUMEGROUPJOB_H
|
||||
|
||||
#include "jobs/job.h"
|
||||
|
||||
class LvmDevice;
|
||||
class Partition;
|
||||
class Report;
|
||||
|
||||
class QString;
|
||||
|
||||
class CreateVolumeGroupJob : public Job
|
||||
{
|
||||
public:
|
||||
CreateVolumeGroupJob(const QString& vgName, const QStringList& pvList, const qint32 peSize);
|
||||
|
||||
public:
|
||||
bool run(Report& parent) override;
|
||||
QString description() const override;
|
||||
|
||||
protected:
|
||||
QString vgName() {
|
||||
return m_vgName;
|
||||
}
|
||||
const QString vgName() const {
|
||||
return m_vgName;
|
||||
}
|
||||
QStringList pvList() {
|
||||
return m_pvList;
|
||||
}
|
||||
const QStringList pvList() const {
|
||||
return m_pvList;
|
||||
}
|
||||
|
||||
qint32 peSize() {
|
||||
return m_PESize;
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_vgName;
|
||||
QStringList m_pvList;
|
||||
qint32 m_PESize;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,61 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "jobs/deactivatelogicalvolumejob.h"
|
||||
|
||||
#include "core/lvmdevice.h"
|
||||
#include "core/partition.h"
|
||||
#include "core/partitiontable.h"
|
||||
|
||||
#include "util/report.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
/** Creates a new DeactivateLogicalVolumeJob
|
||||
*/
|
||||
DeactivateLogicalVolumeJob::DeactivateLogicalVolumeJob(const VolumeManagerDevice& d, const QStringList lvPaths) :
|
||||
Job(),
|
||||
m_Device(d),
|
||||
m_LVList(lvPaths)
|
||||
{
|
||||
}
|
||||
|
||||
bool DeactivateLogicalVolumeJob::run(Report& parent)
|
||||
{
|
||||
bool rval = true;
|
||||
|
||||
Report* report = jobStarted(parent);
|
||||
|
||||
if (device().type() == Device::LVM_Device) {
|
||||
for (const auto &p : device().partitionTable()->children()) {
|
||||
if (!p->roles().has(PartitionRole::Unallocated)) {
|
||||
if (!LvmDevice::deactivateLV(*report, *p)) {
|
||||
rval = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jobFinished(*report, rval);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
QString DeactivateLogicalVolumeJob::description() const
|
||||
{
|
||||
return xi18nc("@info/plain", "Deactivate Logical Volumes: <filename>%1</filename>", device().prettyDeviceNodeList());
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(DEACTIVATELOGICALVOLUMEJOB_H)
|
||||
|
||||
#define DEACTIVATELOGICALVOLUMEJOB_H
|
||||
|
||||
#include "jobs/job.h"
|
||||
|
||||
class VolumeManagerDevice;
|
||||
class Partition;
|
||||
class Report;
|
||||
|
||||
class QString;
|
||||
|
||||
class DeactivateLogicalVolumeJob : public Job
|
||||
{
|
||||
public:
|
||||
DeactivateLogicalVolumeJob(const VolumeManagerDevice& dev, const QStringList lvPaths = {});
|
||||
|
||||
public:
|
||||
bool run(Report& parent) override;
|
||||
QString description() const override;
|
||||
|
||||
protected:
|
||||
const VolumeManagerDevice& device() const {
|
||||
return m_Device;
|
||||
}
|
||||
|
||||
QStringList LVList() const {
|
||||
return m_LVList;
|
||||
}
|
||||
|
||||
private:
|
||||
const VolumeManagerDevice& m_Device;
|
||||
const QStringList m_LVList;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,52 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "jobs/deactivatevolumegroupjob.h"
|
||||
|
||||
#include "core/lvmdevice.h"
|
||||
|
||||
#include "util/report.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
/** Deactivate LVM Volume Group
|
||||
*/
|
||||
DeactivateVolumeGroupJob::DeactivateVolumeGroupJob(VolumeManagerDevice& d) :
|
||||
Job(),
|
||||
m_Device(d)
|
||||
{
|
||||
}
|
||||
|
||||
bool DeactivateVolumeGroupJob::run(Report& parent)
|
||||
{
|
||||
bool rval = false;
|
||||
|
||||
Report* report = jobStarted(parent);
|
||||
|
||||
if (device().type() == Device::LVM_Device) {
|
||||
rval = LvmDevice::deactivateVG(*report, dynamic_cast<LvmDevice&>(device()));
|
||||
}
|
||||
|
||||
jobFinished(*report, rval);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
QString DeactivateVolumeGroupJob::description() const
|
||||
{
|
||||
return xi18nc("@info/plain", "Deactivate Volume Group: <filename>%1</filename>", device().name());
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(DEACTIVATEVOLUMEGROUPJOB_H)
|
||||
|
||||
#define DEACTIVATEVOLUMEGROUPJOB_H
|
||||
|
||||
#include "jobs/job.h"
|
||||
|
||||
class VolumeManagerDevice;
|
||||
class Partition;
|
||||
class Report;
|
||||
|
||||
class QString;
|
||||
|
||||
class DeactivateVolumeGroupJob : public Job
|
||||
{
|
||||
public:
|
||||
DeactivateVolumeGroupJob(VolumeManagerDevice& dev);
|
||||
|
||||
public:
|
||||
bool run(Report& parent) override;
|
||||
QString description() const override;
|
||||
|
||||
protected:
|
||||
VolumeManagerDevice& device() {
|
||||
return m_Device;
|
||||
}
|
||||
const VolumeManagerDevice& device() const {
|
||||
return m_Device;
|
||||
}
|
||||
|
||||
private:
|
||||
VolumeManagerDevice& m_Device;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -63,8 +63,11 @@ bool DeleteFileSystemJob::run(Report& parent)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (partition().roles().has(PartitionRole::Extended))
|
||||
if (partition().roles().has(PartitionRole::Extended)) {
|
||||
rval = true;
|
||||
} else if (device().type() == Device::LVM_Device) {
|
||||
rval = true;
|
||||
}
|
||||
else {
|
||||
if (!partition().fileSystem().remove(*report, partition().deviceNode())) {
|
||||
jobFinished(*report, rval);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "core/partition.h"
|
||||
#include "core/device.h"
|
||||
#include "core/lvmdevice.h"
|
||||
|
||||
#include "util/report.h"
|
||||
|
||||
|
@ -56,27 +57,32 @@ bool DeletePartitionJob::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->deletePartition(*report, partition());
|
||||
if (backendPartitionTable) {
|
||||
rval = backendPartitionTable->deletePartition(*report, partition());
|
||||
|
||||
if (!rval)
|
||||
report->line() << xi18nc("@info:progress", "Could not delete partition <filename>%1</filename>.", partition().deviceNode());
|
||||
else
|
||||
backendPartitionTable->commit();
|
||||
if (!rval)
|
||||
report->line() << xi18nc("@info:progress", "Could not delete partition <filename>%1</filename>.", partition().deviceNode());
|
||||
else
|
||||
backendPartitionTable->commit();
|
||||
|
||||
delete backendPartitionTable;
|
||||
delete backendPartitionTable;
|
||||
|
||||
} else
|
||||
report->line() << xi18nc("@info:progress", "Could not open partition table on device <filename>%1</filename> to delete partition <filename>%2</filename>.", device().deviceNode(), partition().deviceNode());
|
||||
|
||||
delete backendDevice;
|
||||
} else
|
||||
report->line() << xi18nc("@info:progress", "Could not open partition table on device <filename>%1</filename> to delete partition <filename>%2</filename>.", device().deviceNode(), partition().deviceNode());
|
||||
|
||||
delete backendDevice;
|
||||
} 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) {
|
||||
LvmDevice& dev = dynamic_cast<LvmDevice&>(device());
|
||||
rval = LvmDevice::removeLV(*report, dev, partition());
|
||||
}
|
||||
|
||||
jobFinished(*report, rval);
|
||||
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "jobs/movephysicalvolumejob.h"
|
||||
|
||||
#include "core/lvmdevice.h"
|
||||
|
||||
#include "util/report.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
/** Creates a new MovePhysicalVolumeJob
|
||||
* @param d Device representing LVM Volume Group
|
||||
*/
|
||||
MovePhysicalVolumeJob::MovePhysicalVolumeJob(LvmDevice& d, const QStringList partList) :
|
||||
Job(),
|
||||
m_Device(d),
|
||||
m_PartList(partList)
|
||||
{
|
||||
}
|
||||
|
||||
bool MovePhysicalVolumeJob::run(Report& parent)
|
||||
{
|
||||
bool rval = false;
|
||||
|
||||
Report* report = jobStarted(parent);
|
||||
|
||||
QStringList destinations = LvmDevice::getPVs(device().name());
|
||||
for (const auto &partPath : partList()) {
|
||||
if (destinations.contains(partPath)) {
|
||||
destinations.removeAll(partPath);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &partPath : partList()) {
|
||||
rval = LvmDevice::movePV(*report, partPath, destinations);
|
||||
if (rval == false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
jobFinished(*report, rval);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
QString MovePhysicalVolumeJob::description() const
|
||||
{
|
||||
return xi18nc("@info/plain", "Move used PE in %1 on %2 to other available Physical Volumes", partList().join(QStringLiteral(", ")), device().name());
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(MOVEPHYSICALVOLUMEJOB_H)
|
||||
|
||||
#define MOVEPHYSICALVOLUMEJOB_H
|
||||
|
||||
#include "jobs/job.h"
|
||||
|
||||
class LvmDevice;
|
||||
class Report;
|
||||
|
||||
class QString;
|
||||
|
||||
class MovePhysicalVolumeJob : public Job
|
||||
{
|
||||
public:
|
||||
MovePhysicalVolumeJob(LvmDevice& dev, const QStringList partlist);
|
||||
|
||||
public:
|
||||
bool run(Report& parent) override;
|
||||
QString description() const override;
|
||||
|
||||
|
||||
protected:
|
||||
LvmDevice& device() {
|
||||
return m_Device;
|
||||
}
|
||||
const LvmDevice& device() const {
|
||||
return m_Device;
|
||||
}
|
||||
const QStringList partList() const {
|
||||
return m_PartList;
|
||||
}
|
||||
|
||||
private:
|
||||
LvmDevice& m_Device;
|
||||
const QStringList m_PartList;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,52 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "jobs/removevolumegroupjob.h"
|
||||
|
||||
#include "core/lvmdevice.h"
|
||||
|
||||
#include "util/report.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
/** Creates a new RemoveVolumeGroupJob
|
||||
*/
|
||||
RemoveVolumeGroupJob::RemoveVolumeGroupJob(VolumeManagerDevice& d) :
|
||||
Job(),
|
||||
m_Device(d)
|
||||
{
|
||||
}
|
||||
|
||||
bool RemoveVolumeGroupJob::run(Report& parent)
|
||||
{
|
||||
bool rval = false;
|
||||
|
||||
Report* report = jobStarted(parent);
|
||||
|
||||
if (device().type() == Device::LVM_Device) {
|
||||
rval = LvmDevice::removeVG(*report, dynamic_cast<LvmDevice&>(device()));
|
||||
}
|
||||
|
||||
jobFinished(*report, rval);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
QString RemoveVolumeGroupJob::description() const
|
||||
{
|
||||
return xi18nc("@info/plain", "Remove Volume Group: <filename>%1</filename>", device().name());
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(REMOVEVOLUMEGROUPJOB_H)
|
||||
|
||||
#define REMOVEVOLUMEGROUPJOB_H
|
||||
|
||||
#include "jobs/job.h"
|
||||
|
||||
class VolumeManagerDevice;
|
||||
class Partition;
|
||||
class Report;
|
||||
|
||||
class QString;
|
||||
|
||||
class RemoveVolumeGroupJob : public Job
|
||||
{
|
||||
public:
|
||||
RemoveVolumeGroupJob(VolumeManagerDevice& dev);
|
||||
|
||||
public:
|
||||
bool run(Report& parent) override;
|
||||
QString description() const override;
|
||||
|
||||
protected:
|
||||
VolumeManagerDevice& device() {
|
||||
return m_Device;
|
||||
}
|
||||
const VolumeManagerDevice& device() const {
|
||||
return m_Device;
|
||||
}
|
||||
|
||||
private:
|
||||
VolumeManagerDevice& m_Device;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -86,7 +86,7 @@ bool ResizeFileSystemJob::run(Report& parent)
|
|||
}
|
||||
|
||||
case FileSystem::cmdSupportFileSystem: {
|
||||
const qint64 newLengthInByte = Capacity(newLength() * device().logicalSectorSize()).toInt(Capacity::Byte);
|
||||
const qint64 newLengthInByte = Capacity(newLength() * device().logicalSize()).toInt(Capacity::Byte);
|
||||
rval = partition().fileSystem().resize(*report, partition().deviceNode(), newLengthInByte);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "jobs/resizevolumegroupjob.h"
|
||||
|
||||
#include "core/lvmdevice.h"
|
||||
|
||||
#include "util/report.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
/** Creates a new ResizeVolumeGroupJob
|
||||
*/
|
||||
ResizeVolumeGroupJob::ResizeVolumeGroupJob(LvmDevice& dev, const QStringList partlist, const Type type) :
|
||||
Job(),
|
||||
m_Device(dev),
|
||||
m_PartList(partlist),
|
||||
m_Type(type)
|
||||
{
|
||||
}
|
||||
|
||||
bool ResizeVolumeGroupJob::run(Report& parent)
|
||||
{
|
||||
bool rval = false;
|
||||
|
||||
Report* report = jobStarted(parent);
|
||||
|
||||
for (const auto &pvpath : partList()) {
|
||||
if (type() == ResizeVolumeGroupJob::Grow) {
|
||||
rval = LvmDevice::insertPV(*report, device(), pvpath);
|
||||
} else if (type() == ResizeVolumeGroupJob::Shrink) {
|
||||
rval = LvmDevice::removePV(*report, device(), pvpath);
|
||||
}
|
||||
if (rval == false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
jobFinished(*report, rval);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
QString ResizeVolumeGroupJob::description() const
|
||||
{
|
||||
const QString partitionList = partList().join(QStringLiteral(", "));
|
||||
|
||||
if (type() == ResizeVolumeGroupJob::Grow) {
|
||||
return xi18nc("@info/plain", "Inserting Volume: %1 to %2.", partitionList, device().name());
|
||||
}
|
||||
if (type() == ResizeVolumeGroupJob::Shrink) {
|
||||
return xi18nc("@info/plain", "Removing Volume: %1 from %2.", partitionList, device().name());
|
||||
}
|
||||
return xi18nc("@info/plain", "Resizing Volume: %1 to %2.", device().name(), partitionList);
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(RESIZEVOLUMEGROUPJOB_H)
|
||||
|
||||
#define RESIZEVOLUMEGROUPJOB_H
|
||||
|
||||
#include "jobs/job.h"
|
||||
|
||||
class LvmDevice;
|
||||
class Report;
|
||||
|
||||
class QString;
|
||||
|
||||
class ResizeVolumeGroupJob : public Job
|
||||
{
|
||||
|
||||
public:
|
||||
enum Type {
|
||||
Grow = 0,
|
||||
Shrink = 1
|
||||
};
|
||||
|
||||
public:
|
||||
ResizeVolumeGroupJob(LvmDevice& dev, const QStringList partlist, const Type type);
|
||||
|
||||
public:
|
||||
bool run(Report& parent) override;
|
||||
QString description() const override;
|
||||
|
||||
protected:
|
||||
LvmDevice& device() {
|
||||
return m_Device;
|
||||
}
|
||||
const LvmDevice& device() const {
|
||||
return m_Device;
|
||||
}
|
||||
|
||||
const QStringList partList() const {
|
||||
return m_PartList;
|
||||
}
|
||||
|
||||
ResizeVolumeGroupJob::Type type() const {
|
||||
return m_Type;
|
||||
}
|
||||
|
||||
private:
|
||||
LvmDevice& m_Device;
|
||||
const QStringList m_PartList;
|
||||
ResizeVolumeGroupJob::Type m_Type;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -70,7 +70,7 @@ bool SetPartFlagsJob::run(Report& parent)
|
|||
if (backendPartition) {
|
||||
quint32 count = 0;
|
||||
|
||||
foreach(const PartitionTable::Flag & f, PartitionTable::flagList()) {
|
||||
for (const auto &f : PartitionTable::flagList()) {
|
||||
emit progress(++count);
|
||||
|
||||
const bool state = (flags() & f) ? true : false;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "core/partition.h"
|
||||
#include "core/device.h"
|
||||
#include "core/lvmdevice.h"
|
||||
|
||||
#include "util/report.h"
|
||||
|
||||
|
@ -54,26 +55,35 @@ 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) {
|
||||
|
||||
partition().setFirstSector(newStart());
|
||||
partition().setLastSector(newStart() + newLength() - 1);
|
||||
|
||||
rval = LvmDevice::resizeLV(*report, partition());
|
||||
}
|
||||
|
||||
jobFinished(*report, rval);
|
||||
|
||||
|
|
|
@ -6,6 +6,10 @@ set(OPS_SRC
|
|||
ops/newoperation.cpp
|
||||
ops/createfilesystemoperation.cpp
|
||||
ops/createpartitiontableoperation.cpp
|
||||
ops/createvolumegroupoperation.cpp
|
||||
ops/removevolumegroupoperation.cpp
|
||||
ops/deactivatevolumegroupoperation.cpp
|
||||
ops/resizevolumegroupoperation.cpp
|
||||
ops/setfilesystemlabeloperation.cpp
|
||||
ops/setpartflagsoperation.cpp
|
||||
ops/checkoperation.cpp
|
||||
|
@ -19,6 +23,10 @@ set(OPS_LIB_HDRS
|
|||
ops/copyoperation.h
|
||||
ops/createfilesystemoperation.h
|
||||
ops/createpartitiontableoperation.h
|
||||
ops/createvolumegroupoperation.h
|
||||
ops/removevolumegroupoperation.h
|
||||
ops/deactivatevolumegroupoperation.h
|
||||
ops/resizevolumegroupoperation.h
|
||||
ops/deleteoperation.h
|
||||
ops/newoperation.h
|
||||
ops/operation.h
|
||||
|
|
|
@ -211,7 +211,7 @@ QString CopyOperation::updateDescription() const
|
|||
sourcePartition().deviceNode(),
|
||||
Capacity::formatByteSize(sourcePartition().capacity()),
|
||||
sourcePartition().fileSystem().name(),
|
||||
Capacity::formatByteSize(copiedPartition().firstSector() * targetDevice().logicalSectorSize()),
|
||||
Capacity::formatByteSize(copiedPartition().firstSector() * targetDevice().logicalSize()),
|
||||
targetDevice().deviceNode()
|
||||
);
|
||||
|
||||
|
@ -219,7 +219,7 @@ QString CopyOperation::updateDescription() const
|
|||
sourcePartition().deviceNode(),
|
||||
Capacity::formatByteSize(sourcePartition().capacity()),
|
||||
sourcePartition().fileSystem().name(),
|
||||
Capacity::formatByteSize(copiedPartition().firstSector() * targetDevice().logicalSectorSize()),
|
||||
Capacity::formatByteSize(copiedPartition().firstSector() * targetDevice().logicalSize()),
|
||||
targetDevice().deviceNode(),
|
||||
Capacity::formatByteSize(copiedPartition().capacity())
|
||||
);
|
||||
|
|
|
@ -93,7 +93,7 @@ bool CreatePartitionTableOperation::execute(Report& parent)
|
|||
*/
|
||||
bool CreatePartitionTableOperation::canCreate(const Device* device)
|
||||
{
|
||||
return device != nullptr && (device->partitionTable() == nullptr || !device->partitionTable()->isChildMounted());
|
||||
return (device != nullptr) && (device->partitionTable() == nullptr || !device->partitionTable()->isChildMounted()) && (device->type() != Device::LVM_Device);
|
||||
}
|
||||
|
||||
QString CreatePartitionTableOperation::description() const
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "ops/createvolumegroupoperation.h"
|
||||
|
||||
#include "core/lvmdevice.h"
|
||||
#include "fs/lvm2_pv.h"
|
||||
|
||||
#include "jobs/createvolumegroupjob.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
/** Creates a new CreateVolumeGroupOperation.
|
||||
* @param vgName LVM Volume Group name
|
||||
* @param pvList List of LVM Physical Volumes used to create Volume Group
|
||||
* @param peSize LVM Physical Extent size in MiB
|
||||
*/
|
||||
CreateVolumeGroupOperation::CreateVolumeGroupOperation(const QString& vgName, const QStringList& pvList, const qint32 peSize) :
|
||||
Operation(),
|
||||
m_CreateVolumeGroupJob(new CreateVolumeGroupJob(vgName, pvList, peSize)),
|
||||
m_PVList(pvList)
|
||||
{
|
||||
addJob(createVolumeGroupJob());
|
||||
}
|
||||
|
||||
QString CreateVolumeGroupOperation::description() const
|
||||
{
|
||||
return xi18nc("@info/plain", "Create a new LVM volume group.");
|
||||
}
|
||||
|
||||
bool CreateVolumeGroupOperation::targets(const Partition&) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void CreateVolumeGroupOperation::preview()
|
||||
{
|
||||
LvmDevice::s_DirtyPVs << PVList();
|
||||
}
|
||||
|
||||
void CreateVolumeGroupOperation::undo()
|
||||
{
|
||||
for (const auto &pvPath : PVList()) {
|
||||
if (LvmDevice::s_DirtyPVs.contains(pvPath)) {
|
||||
LvmDevice::s_DirtyPVs.removeAll(pvPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CreateVolumeGroupOperation::canCreate()
|
||||
{
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(CREATEVOLUMEGROUPOPERATION_H)
|
||||
|
||||
#define CREATEVOLUMEGROUPOPERATION_H
|
||||
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
|
||||
#include "ops/operation.h"
|
||||
|
||||
#include "core/lvmdevice.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
class CreateVolumeGroupJob;
|
||||
class OperationStack;
|
||||
|
||||
class LIBKPMCORE_EXPORT CreateVolumeGroupOperation : public Operation
|
||||
{
|
||||
Q_DISABLE_COPY(CreateVolumeGroupOperation)
|
||||
|
||||
friend class OperationStack;
|
||||
|
||||
public:
|
||||
CreateVolumeGroupOperation(const QString& vgName, const QStringList& pvList, const qint32 peSize = 4);
|
||||
|
||||
public:
|
||||
QString iconName() const override {
|
||||
return QStringLiteral("document-new");
|
||||
}
|
||||
|
||||
QString description() const override;
|
||||
|
||||
virtual bool targets(const Device&) const override {
|
||||
return true;
|
||||
}
|
||||
virtual bool targets(const Partition&) const override;
|
||||
|
||||
virtual void preview() override;
|
||||
virtual void undo() override;
|
||||
|
||||
static bool canCreate();
|
||||
|
||||
protected:
|
||||
CreateVolumeGroupJob* createVolumeGroupJob() {
|
||||
return m_CreateVolumeGroupJob;
|
||||
}
|
||||
|
||||
const QStringList PVList() {
|
||||
return m_PVList;
|
||||
}
|
||||
|
||||
private:
|
||||
CreateVolumeGroupJob* m_CreateVolumeGroupJob;
|
||||
QStringList m_PVList;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,79 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "ops/deactivatevolumegroupoperation.h"
|
||||
#include "jobs/deactivatevolumegroupjob.h"
|
||||
#include "jobs/deactivatelogicalvolumejob.h"
|
||||
|
||||
#include "core/volumemanagerdevice.h"
|
||||
#include "core/partitiontable.h"
|
||||
#include "core/partition.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
/** Creates a new RemoveVolumeGroupOperation.
|
||||
*/
|
||||
DeactivateVolumeGroupOperation::DeactivateVolumeGroupOperation(VolumeManagerDevice& d) :
|
||||
Operation(),
|
||||
m_DeactivateVolumeGroupJob(new DeactivateVolumeGroupJob(d)),
|
||||
m_DeactivateLogicalVolumeJob(new DeactivateLogicalVolumeJob(d)),
|
||||
m_Device(d),
|
||||
m_PartitionTable(d.partitionTable())
|
||||
{
|
||||
addJob(deactivateLogicalVolumeJob());
|
||||
addJob(deactivateVolumeGroupJob());
|
||||
}
|
||||
|
||||
QString DeactivateVolumeGroupOperation::description() const
|
||||
{
|
||||
return xi18nc("@info/plain", "Deactivate volume group.");
|
||||
}
|
||||
|
||||
void DeactivateVolumeGroupOperation::preview()
|
||||
{
|
||||
device().setPartitionTable(new PartitionTable(PartitionTable::vmd, 0, device().totalLogical() - 1));
|
||||
}
|
||||
|
||||
void DeactivateVolumeGroupOperation::undo()
|
||||
{
|
||||
PartitionTable* tmp = device().partitionTable();
|
||||
if (tmp != partitionTable()) {
|
||||
device().setPartitionTable(partitionTable());
|
||||
delete tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/** loop through given device's partitions to check if any is mounted.
|
||||
*
|
||||
* @dev VolumeManagerDevice with initialized partitions
|
||||
* @return false if any of the device's partition is mounted.
|
||||
*/
|
||||
bool DeactivateVolumeGroupOperation::isDeactivatable(const VolumeManagerDevice* dev)
|
||||
{
|
||||
if (dev->type() == Device::LVM_Device) {
|
||||
for (const auto &p : dev->partitionTable()->children()) {
|
||||
if (p->isMounted()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(DEACTIVATEVOLUMEGROUPOPERATION_H)
|
||||
|
||||
#define DEACTIVATEVOLUMEGROUPOPERATION_H
|
||||
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
|
||||
#include "ops/operation.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
|
||||
class DeactivateLogicalVolumeJob;
|
||||
class DeactivateVolumeGroupJob;
|
||||
class VolumeManagerDevice;
|
||||
class OperationStack;
|
||||
class PartitionTable;
|
||||
|
||||
class LIBKPMCORE_EXPORT DeactivateVolumeGroupOperation : public Operation
|
||||
{
|
||||
Q_DISABLE_COPY(DeactivateVolumeGroupOperation)
|
||||
|
||||
friend class OperationStack;
|
||||
|
||||
public:
|
||||
DeactivateVolumeGroupOperation(VolumeManagerDevice& d);
|
||||
|
||||
public:
|
||||
QString iconName() const override {
|
||||
return QStringLiteral("edit-delete");
|
||||
}
|
||||
|
||||
QString description() const override;
|
||||
|
||||
virtual bool targets(const Device&) const override {
|
||||
return true;
|
||||
}
|
||||
virtual bool targets(const Partition&) const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void preview() override;
|
||||
virtual void undo() override;
|
||||
|
||||
static bool isDeactivatable(const VolumeManagerDevice* dev);
|
||||
|
||||
protected:
|
||||
DeactivateVolumeGroupJob* deactivateVolumeGroupJob() {
|
||||
return m_DeactivateVolumeGroupJob;
|
||||
}
|
||||
|
||||
DeactivateLogicalVolumeJob* deactivateLogicalVolumeJob() {
|
||||
return m_DeactivateLogicalVolumeJob;
|
||||
}
|
||||
|
||||
VolumeManagerDevice& device() {
|
||||
return m_Device;
|
||||
}
|
||||
|
||||
PartitionTable* partitionTable() {
|
||||
return m_PartitionTable;
|
||||
}
|
||||
|
||||
private:
|
||||
DeactivateVolumeGroupJob* m_DeactivateVolumeGroupJob;
|
||||
DeactivateLogicalVolumeJob* m_DeactivateLogicalVolumeJob;
|
||||
VolumeManagerDevice& m_Device;
|
||||
PartitionTable* m_PartitionTable;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -146,7 +146,7 @@ qint32 Operation::totalProgress() const
|
|||
{
|
||||
qint32 result = 0;
|
||||
|
||||
foreach(const Job * job, jobs())
|
||||
for (const auto &job : jobs())
|
||||
result += job->numSteps();
|
||||
|
||||
return result;
|
||||
|
@ -162,7 +162,8 @@ bool Operation::execute(Report& parent)
|
|||
|
||||
Report* report = parent.newChild(description());
|
||||
|
||||
foreach(Job * job, jobs())
|
||||
const auto Jobs = jobs();
|
||||
for (const auto &job : Jobs)
|
||||
if (!(rval = job->run(*report)))
|
||||
break;
|
||||
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "ops/removevolumegroupoperation.h"
|
||||
#include "jobs/removevolumegroupjob.h"
|
||||
|
||||
#include "core/volumemanagerdevice.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
/** Creates a new RemoveVolumeGroupOperation.
|
||||
*/
|
||||
RemoveVolumeGroupOperation::RemoveVolumeGroupOperation(VolumeManagerDevice& d) :
|
||||
Operation(),
|
||||
m_RemoveVolumeGroupJob(new RemoveVolumeGroupJob(d)),
|
||||
m_Device(d)
|
||||
{
|
||||
addJob(removeVolumeGroupJob());
|
||||
}
|
||||
|
||||
QString RemoveVolumeGroupOperation::description() const
|
||||
{
|
||||
return xi18nc("@info/plain", "Remove a new LVM volume group.");
|
||||
}
|
||||
|
||||
void RemoveVolumeGroupOperation::preview()
|
||||
{
|
||||
}
|
||||
|
||||
void RemoveVolumeGroupOperation::undo()
|
||||
{
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(REMOVEVOLUMEGROUPOPERATION_H)
|
||||
|
||||
#define REMOVEVOLUMEGROUPOPERATION_H
|
||||
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
|
||||
#include "ops/operation.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
class RemoveVolumeGroupJob;
|
||||
class VolumeManagerDevice;
|
||||
class OperationStack;
|
||||
|
||||
class LIBKPMCORE_EXPORT RemoveVolumeGroupOperation : public Operation
|
||||
{
|
||||
Q_DISABLE_COPY(RemoveVolumeGroupOperation)
|
||||
|
||||
friend class OperationStack;
|
||||
|
||||
public:
|
||||
RemoveVolumeGroupOperation(VolumeManagerDevice& d);
|
||||
|
||||
public:
|
||||
QString iconName() const override {
|
||||
return QStringLiteral("edit-delete");
|
||||
}
|
||||
|
||||
QString description() const override;
|
||||
|
||||
virtual bool targets(const Device&) const override {
|
||||
return true;
|
||||
}
|
||||
virtual bool targets(const Partition&) const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void preview() override;
|
||||
virtual void undo() override;
|
||||
|
||||
protected:
|
||||
RemoveVolumeGroupJob* removeVolumeGroupJob() {
|
||||
return m_RemoveVolumeGroupJob;
|
||||
}
|
||||
|
||||
VolumeManagerDevice& device() {
|
||||
return m_Device;
|
||||
}
|
||||
|
||||
private:
|
||||
RemoveVolumeGroupJob* m_RemoveVolumeGroupJob;
|
||||
VolumeManagerDevice& m_Device;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -187,10 +187,10 @@ QString ResizeOperation::description() const
|
|||
// Each of these needs a different description. And for reasons of i18n, we cannot
|
||||
// just concatenate strings together...
|
||||
|
||||
const QString moveDelta = Capacity::formatByteSize(qAbs(newFirstSector() - origFirstSector()) * targetDevice().logicalSectorSize());
|
||||
const QString moveDelta = Capacity::formatByteSize(qAbs(newFirstSector() - origFirstSector()) * targetDevice().logicalSize());
|
||||
|
||||
const QString origCapacity = Capacity::formatByteSize(origLength() * targetDevice().logicalSectorSize());
|
||||
const QString newCapacity = Capacity::formatByteSize(newLength() * targetDevice().logicalSectorSize());
|
||||
const QString origCapacity = Capacity::formatByteSize(origLength() * targetDevice().logicalSize());
|
||||
const QString newCapacity = Capacity::formatByteSize(newLength() * targetDevice().logicalSize());
|
||||
|
||||
switch (resizeAction()) {
|
||||
case MoveLeft:
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "ops/resizevolumegroupoperation.h"
|
||||
|
||||
#include "core/lvmdevice.h"
|
||||
#include "fs/lvm2_pv.h"
|
||||
#include "core/partition.h"
|
||||
|
||||
#include "jobs/resizevolumegroupjob.h"
|
||||
#include "jobs/movephysicalvolumejob.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
/** Creates a new ResizeVolumeGroupOperation.
|
||||
@param d the Device to create the new PartitionTable on
|
||||
@param partlist list of LVM Physical Volumes that should be in LVM Volume Group
|
||||
*/
|
||||
ResizeVolumeGroupOperation::ResizeVolumeGroupOperation(LvmDevice& d, const QStringList partlist) :
|
||||
Operation(),
|
||||
m_Device(d),
|
||||
m_TargetList(partlist),
|
||||
m_CurrentList(LvmDevice::getPVs(d.name())),
|
||||
m_GrowVolumeGroupJob(nullptr),
|
||||
m_ShrinkVolumeGroupJob(nullptr),
|
||||
m_MovePhysicalVolumeJob(nullptr)
|
||||
{
|
||||
const QStringList curList = currentList();
|
||||
m_TargetSize = FS::lvm2_pv::getPVSize(targetList());
|
||||
m_CurrentSize = FS::lvm2_pv::getPVSize(currentList());
|
||||
|
||||
QStringList toRemoveList = curList;
|
||||
for (QString path : partlist) {
|
||||
if (toRemoveList.contains(path)) {
|
||||
toRemoveList.removeAll(path);
|
||||
}
|
||||
}
|
||||
|
||||
QStringList toInsertList = partlist;
|
||||
for (QString path : curList) {
|
||||
if (toInsertList.contains(path)) {
|
||||
toInsertList.removeAll(path);
|
||||
}
|
||||
}
|
||||
|
||||
qint64 freePE = FS::lvm2_pv::getFreePE(curList) - FS::lvm2_pv::getFreePE(toRemoveList);
|
||||
qint64 movePE = FS::lvm2_pv::getAllocatedPE(toRemoveList);
|
||||
qint64 growPE = FS::lvm2_pv::getPVSize(toInsertList) / LvmDevice::getPeSize(d.name());
|
||||
|
||||
if ( movePE > (freePE + growPE)) {
|
||||
// *ABORT* can't move
|
||||
} else if (partlist == curList) {
|
||||
// *DO NOTHING*
|
||||
} else {
|
||||
if (!toInsertList.isEmpty()) {
|
||||
m_GrowVolumeGroupJob = new ResizeVolumeGroupJob(d, toInsertList, ResizeVolumeGroupJob::Grow);
|
||||
addJob(growVolumeGroupJob());
|
||||
}
|
||||
if (!toRemoveList.isEmpty()) {
|
||||
m_MovePhysicalVolumeJob = new MovePhysicalVolumeJob(d, toRemoveList);
|
||||
m_ShrinkVolumeGroupJob = new ResizeVolumeGroupJob(d, toRemoveList, ResizeVolumeGroupJob::Shrink);
|
||||
addJob(movePhysicalVolumeJob());
|
||||
addJob(shrinkvolumegroupjob());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString ResizeVolumeGroupOperation::description() const
|
||||
{
|
||||
QString tList = targetList().join(QStringLiteral(", "));
|
||||
QString curList = currentList().join(QStringLiteral(", "));
|
||||
|
||||
return xi18nc("@info/plain", "Resize volume %1 from %2 to %3", device().name(), curList, tList);
|
||||
}
|
||||
|
||||
bool ResizeVolumeGroupOperation::targets(const Device& d) const
|
||||
{
|
||||
return d == device();
|
||||
}
|
||||
|
||||
bool ResizeVolumeGroupOperation::targets(const Partition& p) const
|
||||
{
|
||||
for (QString partPath : targetList()) {
|
||||
if (partPath == p.partitionPath()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ResizeVolumeGroupOperation::preview()
|
||||
{
|
||||
//asumming that targetSize is larger than the allocated space.
|
||||
device().setTotalLogical(targetSize() / device().logicalSize());
|
||||
device().partitionTable()->setFirstUsableSector(PartitionTable::defaultFirstUsable(device(), PartitionTable::vmd));
|
||||
device().partitionTable()->setLastUsableSector(PartitionTable::defaultLastUsable(device(), PartitionTable::vmd));
|
||||
device().partitionTable()->updateUnallocated(device());
|
||||
}
|
||||
|
||||
void ResizeVolumeGroupOperation::undo()
|
||||
{
|
||||
device().setTotalLogical(currentSize() / device().logicalSize());
|
||||
device().partitionTable()->setFirstUsableSector(PartitionTable::defaultFirstUsable(device(), PartitionTable::vmd));
|
||||
device().partitionTable()->setLastUsableSector(PartitionTable::defaultLastUsable(device(), PartitionTable::vmd));
|
||||
device().partitionTable()->updateUnallocated(device());
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* *
|
||||
* 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 <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(RESIZEVOLUMEGROUPOPERATION_H)
|
||||
|
||||
#define RESIZEVOLUMEGROUPOPERATION_H
|
||||
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
|
||||
#include "ops/operation.h"
|
||||
|
||||
#include "core/lvmdevice.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
class ResizeVolumeGroupJob;
|
||||
class MovePhysicalVolumeJob;
|
||||
class OperationStack;
|
||||
class LvmDevice;
|
||||
|
||||
class LIBKPMCORE_EXPORT ResizeVolumeGroupOperation : public Operation
|
||||
{
|
||||
Q_DISABLE_COPY(ResizeVolumeGroupOperation)
|
||||
|
||||
friend class OperationStack;
|
||||
|
||||
public:
|
||||
ResizeVolumeGroupOperation(LvmDevice& dev, const QStringList partlist);
|
||||
|
||||
public:
|
||||
QString iconName() const override {
|
||||
return QStringLiteral("arrow-right-double");
|
||||
}
|
||||
|
||||
QString description() const override;
|
||||
|
||||
virtual bool targets(const Device&) const override;
|
||||
virtual bool targets(const Partition&) const override;
|
||||
|
||||
virtual void preview() override;
|
||||
virtual void undo() override;
|
||||
|
||||
QStringList getToRemoveList();
|
||||
QStringList getToInsertList();
|
||||
|
||||
protected:
|
||||
LvmDevice& device() {
|
||||
return m_Device;
|
||||
}
|
||||
const LvmDevice& device() const {
|
||||
return m_Device;
|
||||
}
|
||||
const QStringList targetList() const {
|
||||
return m_TargetList;
|
||||
}
|
||||
|
||||
const QStringList currentList() const {
|
||||
return m_CurrentList;
|
||||
}
|
||||
|
||||
qint64 targetSize() const {
|
||||
return m_TargetSize;
|
||||
}
|
||||
|
||||
qint64 currentSize() const {
|
||||
return m_CurrentSize;
|
||||
}
|
||||
|
||||
ResizeVolumeGroupJob* growVolumeGroupJob() {
|
||||
return m_GrowVolumeGroupJob;
|
||||
}
|
||||
|
||||
ResizeVolumeGroupJob* shrinkvolumegroupjob() {
|
||||
return m_ShrinkVolumeGroupJob;
|
||||
}
|
||||
|
||||
MovePhysicalVolumeJob* movePhysicalVolumeJob() {
|
||||
return m_MovePhysicalVolumeJob;
|
||||
}
|
||||
|
||||
private:
|
||||
LvmDevice& m_Device;
|
||||
|
||||
const QStringList m_TargetList;
|
||||
const QStringList m_CurrentList;
|
||||
qint64 m_TargetSize;
|
||||
qint64 m_CurrentSize;
|
||||
|
||||
ResizeVolumeGroupJob *m_GrowVolumeGroupJob;
|
||||
ResizeVolumeGroupJob *m_ShrinkVolumeGroupJob;
|
||||
MovePhysicalVolumeJob *m_MovePhysicalVolumeJob;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -164,7 +164,7 @@ QString RestoreOperation::description() const
|
|||
if (overwrittenPartition())
|
||||
return xi18nc("@info:status", "Restore partition from <filename>%1</filename> to <filename>%2</filename>", fileName(), overwrittenPartition()->deviceNode());
|
||||
|
||||
return xi18nc("@info:status", "Restore partition on <filename>%1</filename> at %2 from <filename>%3</filename>", targetDevice().deviceNode(), Capacity::formatByteSize(restorePartition().firstSector() * targetDevice().logicalSectorSize()), fileName());
|
||||
return xi18nc("@info:status", "Restore partition on <filename>%1</filename> at %2 from <filename>%3</filename>", targetDevice().deviceNode(), Capacity::formatByteSize(restorePartition().firstSector() * targetDevice().logicalSize()), fileName());
|
||||
}
|
||||
|
||||
void RestoreOperation::setOverwrittenPartition(Partition* p)
|
||||
|
@ -222,7 +222,7 @@ Partition* RestoreOperation::createRestorePartition(const Device& device, Partit
|
|||
if (!fileInfo.exists())
|
||||
return nullptr;
|
||||
|
||||
const qint64 end = start + fileInfo.size() / device.logicalSectorSize() - 1;
|
||||
const qint64 end = start + fileInfo.size() / device.logicalSize() - 1;
|
||||
Partition* p = new Partition(&parent, device, PartitionRole(r), FileSystemFactory::create(FileSystem::Unknown, start, end), start, end, QString());
|
||||
|
||||
p->setState(Partition::StateRestore);
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "plugins/dummy/dummybackend.h"
|
||||
#include "plugins/dummy/dummydevice.h"
|
||||
|
||||
#include "core/device.h"
|
||||
#include "core/diskdevice.h"
|
||||
#include "core/partition.h"
|
||||
#include "core/partitiontable.h"
|
||||
|
||||
|
@ -59,7 +59,7 @@ QList<Device*> DummyBackend::scanDevices(bool excludeLoop)
|
|||
|
||||
Device* DummyBackend::scanDevice(const QString& device_node)
|
||||
{
|
||||
Device* d = new Device(QStringLiteral("Dummy Device"), QStringLiteral("/tmp") + device_node, 255, 30, 63, 512);
|
||||
DiskDevice* d = new DiskDevice(QStringLiteral("Dummy Device"), QStringLiteral("/tmp") + device_node, 255, 30, 63, 512);
|
||||
CoreBackend::setPartitionTableForDevice(*d, new PartitionTable(PartitionTable::msdos_sectorbased, 2048, d->totalSectors() - 2048));
|
||||
CoreBackend::setPartitionTableMaxPrimaries(*d->partitionTable(), 128);
|
||||
d->partitionTable()->updateUnallocated(*d);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
add_executable(kpmcore_scan scan.cpp)
|
||||
target_link_libraries(kpmcore_scan ${LIBPARTED_LIBS} ${BLKID_LIBRARIES} KF5::Auth)
|
||||
target_link_libraries(kpmcore_scan ${LIBPARTED_LIBS} KF5::Auth)
|
||||
install(TARGETS kpmcore_scan DESTINATION ${KAUTH_HELPER_INSTALL_DIR})
|
||||
|
||||
kauth_install_helper_files(kpmcore_scan org.kde.kpmcore.scan root)
|
||||
|
|
|
@ -45,23 +45,3 @@ Description[uk]=Читання даних щодо використаних се
|
|||
Description[x-test]=xxRead used sectorsxx
|
||||
Policy=yes
|
||||
Persistence=session
|
||||
|
||||
[org.kde.kpmcore.scan.detectfilesystem]
|
||||
Name=Detect file system type action
|
||||
Name[ca]=Acció de detecció del tipus de sistema de fitxers
|
||||
Name[nl]=Actie voor type bestandssysteem detecteren
|
||||
Name[pt]=Acção de detecção do tipo de sistema de ficheiros
|
||||
Name[sl]=Dejanje zaznavanja vrste datotečnega sistema
|
||||
Name[sv]=Åtgärd för att detektera typ av filsystem
|
||||
Name[uk]=Дія із визначення типу файлової системи
|
||||
Name[x-test]=xxDetect file system type actionxx
|
||||
Description=Detect file system type
|
||||
Description[ca]=Detecta el tipus de sistema de fitxers
|
||||
Description[nl]=Type bestandssysteem detecteren
|
||||
Description[pt]=Detectar o tipo de sistema de ficheiros
|
||||
Description[sl]=Zaznaj vrsto datotečnega sistema
|
||||
Description[sv]=Detektera typ av filsystem
|
||||
Description[uk]=Визначення типу файлової системи
|
||||
Description[x-test]=xxDetect file system typexx
|
||||
Policy=yes
|
||||
Persistence=session
|
||||
|
|
|
@ -19,34 +19,28 @@
|
|||
#include "core/partitiontable.h"
|
||||
#include "plugins/libparted/pedflags.h"
|
||||
|
||||
#include <blkid/blkid.h>
|
||||
|
||||
ActionReply Scan::scandevice(const QVariantMap& args)
|
||||
{
|
||||
ActionReply reply;
|
||||
|
||||
QString deviceNode = args[QLatin1String("deviceNode")].toString();
|
||||
PedDevice* pedDevice = ped_device_get(deviceNode.toLocal8Bit().constData());
|
||||
PedDevice* pedDevice = ped_device_get(args[QStringLiteral("deviceNode")].toString().toLocal8Bit().constData());
|
||||
|
||||
QVariantMap returnArgs;
|
||||
if (!pedDevice) {
|
||||
returnArgs[QLatin1String("pedDeviceError")] = true;
|
||||
reply.setData(returnArgs);
|
||||
reply.addData(QStringLiteral("pedDeviceError"), true);
|
||||
return reply;
|
||||
}
|
||||
|
||||
returnArgs[QLatin1String("model")] = QString::fromUtf8(pedDevice->model);
|
||||
returnArgs[QLatin1String("path")] = QString::fromUtf8(pedDevice->path);
|
||||
returnArgs[QLatin1String("heads")] = pedDevice->bios_geom.heads;
|
||||
returnArgs[QLatin1String("sectors")] = pedDevice->bios_geom.sectors;
|
||||
returnArgs[QLatin1String("cylinders")] = pedDevice->bios_geom.cylinders;
|
||||
returnArgs[QLatin1String("sectorSize")] = pedDevice->sector_size;
|
||||
reply.addData(QStringLiteral("model"), QString::fromUtf8(pedDevice->model));
|
||||
reply.addData(QStringLiteral("path"), QString::fromUtf8(pedDevice->path));
|
||||
reply.addData(QStringLiteral("heads"), pedDevice->bios_geom.heads);
|
||||
reply.addData(QStringLiteral("sectors"), pedDevice->bios_geom.sectors);
|
||||
reply.addData(QStringLiteral("cylinders"), pedDevice->bios_geom.cylinders);
|
||||
reply.addData(QStringLiteral("sectorSize"), pedDevice->sector_size);
|
||||
|
||||
PedDisk* pedDisk = ped_disk_new(pedDevice);
|
||||
|
||||
if (!pedDisk) {
|
||||
returnArgs[QLatin1String("pedDiskError")] = true;
|
||||
reply.setData(returnArgs);
|
||||
reply.addData(QStringLiteral("pedDiskError"), true);
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
@ -77,13 +71,13 @@ ActionReply Scan::scandevice(const QVariantMap& args)
|
|||
lastUsableSector -= 32;
|
||||
}
|
||||
|
||||
returnArgs[QLatin1String("pedDeviceError")] = false;
|
||||
returnArgs[QLatin1String("pedDiskError")] = false;
|
||||
reply.addData(QStringLiteral("pedDeviceError"), false);
|
||||
reply.addData(QStringLiteral("pedDiskError"), false);
|
||||
|
||||
returnArgs[QLatin1String("typeName")] = QString::fromUtf8(pedDisk->type->name);
|
||||
returnArgs[QLatin1String("maxPrimaryPartitionCount")] = ped_disk_get_max_primary_partition_count(pedDisk);
|
||||
returnArgs[QLatin1String("firstUsableSector")] = firstUsableSector;
|
||||
returnArgs[QLatin1String("lastUsableSector")] = lastUsableSector;
|
||||
reply.addData(QStringLiteral("typeName"), QString::fromUtf8(pedDisk->type->name));
|
||||
reply.addData(QStringLiteral("maxPrimaryPartitionCount"), ped_disk_get_max_primary_partition_count(pedDisk));
|
||||
reply.addData(QStringLiteral("firstUsableSector"), firstUsableSector);
|
||||
reply.addData(QStringLiteral("lastUsableSector"), lastUsableSector);
|
||||
|
||||
PedPartition* pedPartition = nullptr;
|
||||
QList<QVariant> partitionPath;
|
||||
|
@ -98,7 +92,7 @@ ActionReply Scan::scandevice(const QVariantMap& args)
|
|||
if (pedPartition->num < 1)
|
||||
continue;
|
||||
|
||||
partitionPath.append(QLatin1String(ped_partition_get_path(pedPartition)));
|
||||
partitionPath.append(QString::fromLatin1(ped_partition_get_path(pedPartition)));
|
||||
partitionType.append(pedPartition->type);
|
||||
partitionStart.append(pedPartition->geom.start);
|
||||
partitionEnd.append(pedPartition->geom.end);
|
||||
|
@ -113,12 +107,12 @@ ActionReply Scan::scandevice(const QVariantMap& args)
|
|||
// unallocated. Libparted doesn't like it if we ask for flags for unallocated
|
||||
// space.
|
||||
if (pedPartition->num > 0)
|
||||
for (quint32 i = 0; i < sizeof(flagmap) / sizeof(flagmap[0]); i++)
|
||||
if (ped_partition_is_flag_available(pedPartition, flagmap[i].pedFlag))
|
||||
for (const auto &flag : flagmap)
|
||||
if (ped_partition_is_flag_available(pedPartition, flag.pedFlag))
|
||||
// Workaround: libparted claims the hidden flag is available for extended partitions, but
|
||||
// throws an error when we try to set or clear it. So skip this combination. Also see setFlag.
|
||||
if (pedPartition->type != PED_PARTITION_EXTENDED || flagmap[i].flag != PartitionTable::FlagHidden)
|
||||
flags |= flagmap[i].flag;
|
||||
if (pedPartition->type != PED_PARTITION_EXTENDED || flag.flag != PartitionTable::FlagHidden)
|
||||
flags |= flag.flag;
|
||||
|
||||
availableFlags.append(static_cast<qint32>(flags));
|
||||
// --------------------------------------------------------------------------
|
||||
|
@ -126,80 +120,38 @@ ActionReply Scan::scandevice(const QVariantMap& args)
|
|||
|
||||
flags = PartitionTable::FlagNone;
|
||||
if (pedPartition->num > 0)
|
||||
for (quint32 i = 0; i < sizeof(flagmap) / sizeof(flagmap[0]); i++)
|
||||
if (ped_partition_is_flag_available(pedPartition, flagmap[i].pedFlag) && ped_partition_get_flag(pedPartition, flagmap[i].pedFlag))
|
||||
flags |= flagmap[i].flag;
|
||||
for (const auto &flag : flagmap)
|
||||
if (ped_partition_is_flag_available(pedPartition, flag.pedFlag) && ped_partition_get_flag(pedPartition, flag.pedFlag))
|
||||
flags |= flag.flag;
|
||||
|
||||
activeFlags.append(static_cast<qint32>(flags));
|
||||
// --------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
returnArgs[QLatin1String("availableFlags")] = availableFlags;
|
||||
returnArgs[QLatin1String("activeFlags")] = activeFlags;
|
||||
returnArgs[QLatin1String("partitionPath")] = partitionPath;
|
||||
returnArgs[QLatin1String("partitionType")] = partitionType;
|
||||
returnArgs[QLatin1String("partitionStart")] = partitionStart;
|
||||
returnArgs[QLatin1String("partitionEnd")] = partitionEnd;
|
||||
returnArgs[QLatin1String("partitionBusy")] = partitionBusy;
|
||||
reply.addData(QStringLiteral("availableFlags"), availableFlags);
|
||||
reply.addData(QStringLiteral("activeFlags"), activeFlags);
|
||||
reply.addData(QStringLiteral("partitionPath"), partitionPath);
|
||||
reply.addData(QStringLiteral("partitionType"), partitionType);
|
||||
reply.addData(QStringLiteral("partitionStart"), partitionStart);
|
||||
reply.addData(QStringLiteral("partitionEnd"), partitionEnd);
|
||||
reply.addData(QStringLiteral("partitionBusy"), partitionBusy);
|
||||
|
||||
reply.setData(returnArgs);
|
||||
return reply;
|
||||
}
|
||||
|
||||
ActionReply Scan::readsectorsused(const QVariantMap& args)
|
||||
{
|
||||
ActionReply reply;
|
||||
|
||||
QString deviceNode = args[QLatin1String("deviceNode")].toString();
|
||||
qint64 firstSector = args[QLatin1String("firstSector")].toLongLong();
|
||||
qint64 rval = -1;
|
||||
|
||||
if (PedDevice* pedDevice = ped_device_get(deviceNode.toLocal8Bit().constData()))
|
||||
if (PedDevice* pedDevice = ped_device_get(args[QStringLiteral("deviceNode")].toString().toLocal8Bit().constData()))
|
||||
if (PedDisk* pedDisk = ped_disk_new(pedDevice))
|
||||
if (PedPartition* pedPartition = ped_disk_get_partition_by_sector(pedDisk, firstSector))
|
||||
if (PedPartition* pedPartition = ped_disk_get_partition_by_sector(pedDisk, args[QStringLiteral("firstSector")].toLongLong()))
|
||||
if (PedFileSystem* pedFileSystem = ped_file_system_open(&pedPartition->geom))
|
||||
if (PedConstraint* pedConstraint = ped_file_system_get_resize_constraint(pedFileSystem))
|
||||
rval = pedConstraint->min_size;
|
||||
|
||||
QVariantMap returnArgs;
|
||||
returnArgs[QLatin1String("sectorsUsed")] = rval;
|
||||
|
||||
reply.setData(returnArgs);
|
||||
return reply;
|
||||
}
|
||||
|
||||
ActionReply Scan::detectfilesystem(const QVariantMap& args)
|
||||
{
|
||||
ActionReply reply;
|
||||
QVariantMap returnArgs;
|
||||
QString deviceNode = args[QLatin1String("deviceNode")].toString();
|
||||
|
||||
blkid_cache cache;
|
||||
if (blkid_get_cache(&cache, nullptr) == 0) {
|
||||
blkid_dev dev;
|
||||
|
||||
if ((dev = blkid_get_dev(cache, deviceNode.toLocal8Bit().constData(), BLKID_DEV_NORMAL)) != nullptr) {
|
||||
char *string = blkid_get_tag_value(cache, "TYPE", deviceNode.toLocal8Bit().constData());
|
||||
QString s = QString::fromUtf8(string);
|
||||
free(string);
|
||||
|
||||
if (s == QStringLiteral("vfat")) {
|
||||
// libblkid uses SEC_TYPE to distinguish between FAT16 and FAT32
|
||||
string = blkid_get_tag_value(cache, "SEC_TYPE", deviceNode.toLocal8Bit().constData());
|
||||
QString st = QString::fromUtf8(string);
|
||||
free(string);
|
||||
if (st == QStringLiteral("msdos"))
|
||||
returnArgs[QLatin1String("fileSystem")] = QStringLiteral("fat16");
|
||||
else
|
||||
returnArgs[QLatin1String("fileSystem")] = QStringLiteral("fat32");
|
||||
}
|
||||
else
|
||||
returnArgs[QLatin1String("fileSystem")] = s;
|
||||
}
|
||||
blkid_put_cache(cache);
|
||||
}
|
||||
|
||||
reply.setData(returnArgs);
|
||||
reply.addData(QStringLiteral("sectorsUsed"), rval);
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ class Scan : public QObject
|
|||
public Q_SLOTS:
|
||||
ActionReply scandevice(const QVariantMap& args);
|
||||
ActionReply readsectorsused(const QVariantMap& args);
|
||||
ActionReply detectfilesystem(const QVariantMap& args);
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "plugins/libparted/libparteddevice.h"
|
||||
#include "plugins/libparted/pedflags.h"
|
||||
|
||||
#include "core/device.h"
|
||||
#include "core/diskdevice.h"
|
||||
#include "core/partition.h"
|
||||
#include "core/partitiontable.h"
|
||||
#include "core/partitionalignment.h"
|
||||
|
@ -36,11 +36,14 @@
|
|||
#include "fs/hfs.h"
|
||||
#include "fs/hfsplus.h"
|
||||
#include "fs/luks.h"
|
||||
#include "fs/lvm2_pv.h"
|
||||
|
||||
#include "util/globallog.h"
|
||||
#include "util/externalcommand.h"
|
||||
#include "util/helpers.h"
|
||||
|
||||
#include <blkid/blkid.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
@ -75,12 +78,12 @@ static PedExceptionOption pedExceptionHandler(PedException* e)
|
|||
#if defined LIBPARTED_FS_RESIZE_LIBRARY_SUPPORT
|
||||
static qint64 readSectorsUsedLibParted(const Partition& p)
|
||||
{
|
||||
QVariantMap args;
|
||||
args[QLatin1String("deviceNode")] = p.deviceNode();
|
||||
args[QLatin1String("firstSector")] = p.firstSector();
|
||||
|
||||
KAuth::Action action = QStringLiteral("org.kde.kpmcore.scan.readsectorsused");
|
||||
action.setHelperId(QStringLiteral("org.kde.kpmcore.scan"));
|
||||
QVariantMap args = {
|
||||
{ QStringLiteral("deviceNode"), p.deviceNode() },
|
||||
{ QStringLiteral("firstSector"), p.firstSector() }
|
||||
};
|
||||
action.setArguments(args);
|
||||
KAuth::ExecuteJob *job = action.execute();
|
||||
if (!job->exec()) {
|
||||
|
@ -96,7 +99,7 @@ static qint64 readSectorsUsedLibParted(const Partition& p)
|
|||
@param p the Partition the FileSystem is on
|
||||
@param mountPoint mount point of the partition in question
|
||||
*/
|
||||
static void readSectorsUsed(const Device& d, Partition& p, const QString& mountPoint)
|
||||
static void readSectorsUsed(const DiskDevice& d, Partition& p, const QString& mountPoint)
|
||||
{
|
||||
const KDiskFreeSpaceInfo freeSpaceInfo = KDiskFreeSpaceInfo::freeSpaceInfo(mountPoint);
|
||||
|
||||
|
@ -146,11 +149,9 @@ void LibPartedBackend::initFSSupport()
|
|||
*/
|
||||
Device* LibPartedBackend::scanDevice(const QString& deviceNode)
|
||||
{
|
||||
QVariantMap args;
|
||||
args[QLatin1String("deviceNode")] = deviceNode;
|
||||
|
||||
KAuth::Action scanAction = QStringLiteral("org.kde.kpmcore.scan.scandevice");
|
||||
scanAction.setHelperId(QStringLiteral("org.kde.kpmcore.scan"));
|
||||
QVariantMap args = {{ QStringLiteral("deviceNode"), deviceNode }};
|
||||
scanAction.setArguments(args);
|
||||
KAuth::ExecuteJob *job = scanAction.execute();
|
||||
if (!job->exec()) {
|
||||
|
@ -175,7 +176,7 @@ Device* LibPartedBackend::scanDevice(const QString& deviceNode)
|
|||
|
||||
Log(Log::information) << xi18nc("@info:status", "Device found: %1", model);
|
||||
|
||||
Device* d = new Device(model, path, heads, sectors, cylinders, sectorSize);
|
||||
DiskDevice* d = new DiskDevice(model, path, heads, sectors, cylinders, sectorSize);
|
||||
|
||||
if (pedDiskError)
|
||||
return d;
|
||||
|
@ -198,9 +199,6 @@ Device* LibPartedBackend::scanDevice(const QString& deviceNode)
|
|||
QList<QVariant> partitionEnd = job->data()[QLatin1String("partitionEnd")].toList();
|
||||
QList<QVariant> partitionBusy = job->data()[QLatin1String("partitionBusy")].toList();
|
||||
|
||||
QList<QVariant> availableFlags = job->data()[QLatin1String("availableFlags")].toList();
|
||||
QList<QVariant> activeFlags = job->data()[QLatin1String("activeFlags")].toList();
|
||||
|
||||
quint32 totalPartitions = partitionPath.size();
|
||||
QList<Partition*> partitions;
|
||||
for (quint32 i = 0; i < totalPartitions; ++i) {
|
||||
|
@ -255,22 +253,32 @@ Device* LibPartedBackend::scanDevice(const QString& deviceNode)
|
|||
if (isCryptOpen) {
|
||||
luksFs->loadInnerFileSystem(partitionNode, mapperNode);
|
||||
|
||||
mountPoint = mountPoints.findByDevice(mapperNode) ?
|
||||
mountPoints.findByDevice(mapperNode)->mountPoint() :
|
||||
QString();
|
||||
// We cannot use libparted to check the mounted status because
|
||||
// we don't have a PedPartition for the mapper device, so we use lsblk
|
||||
mounted = isMounted(mapperNode);
|
||||
if (luksFs->type() == FileSystem::Lvm2_PV) {
|
||||
mountPoint = FS::lvm2_pv::getVGName(mapperNode);
|
||||
mounted = false;
|
||||
} else {
|
||||
|
||||
mountPoint = mountPoints.findByDevice(mapperNode) ?
|
||||
mountPoints.findByDevice(mapperNode)->mountPoint() :
|
||||
QString();
|
||||
// We cannot use libparted to check the mounted status because
|
||||
// we don't have a PedPartition for the mapper device, so we use lsblk
|
||||
mounted = isMounted(mapperNode);
|
||||
}
|
||||
if (mounted) {
|
||||
const KDiskFreeSpaceInfo freeSpaceInfo = KDiskFreeSpaceInfo::freeSpaceInfo(mountPoint);
|
||||
if (freeSpaceInfo.isValid() && mountPoint != QString())
|
||||
luksFs->setSectorsUsed(freeSpaceInfo.used() / d->logicalSectorSize() + luksFs->getPayloadOffset(partitionNode));
|
||||
luksFs->setSectorsUsed((freeSpaceInfo.used() + luksFs->getPayloadOffset(partitionNode)) / d->logicalSectorSize());
|
||||
}
|
||||
} else {
|
||||
mounted = false;
|
||||
}
|
||||
|
||||
luksFs->setMounted(mounted);
|
||||
} else if (fsType == FileSystem::Lvm2_PV) {
|
||||
r |= PartitionRole::Lvm_Lv;
|
||||
mountPoint = FS::lvm2_pv::getVGName(partitionNode);
|
||||
mounted = false;
|
||||
} else {
|
||||
mountPoint = mountPoints.findByDevice(partitionNode) ?
|
||||
mountPoints.findByDevice(partitionNode)->mountPoint() :
|
||||
|
@ -278,7 +286,9 @@ Device* LibPartedBackend::scanDevice(const QString& deviceNode)
|
|||
mounted = busy;
|
||||
}
|
||||
|
||||
QList<QVariant> availableFlags = job->data()[QLatin1String("availableFlags")].toList();
|
||||
PartitionTable::Flags available = static_cast<PartitionTable::Flag>(availableFlags[i].toInt());
|
||||
QList<QVariant> activeFlags = job->data()[QLatin1String("activeFlags")].toList();
|
||||
PartitionTable::Flags active = static_cast<PartitionTable::Flag>(activeFlags[i].toInt());
|
||||
Partition* part = new Partition(parent, *d, PartitionRole(r), fs, start, end, partitionNode, available, mountPoint, mounted, active);
|
||||
|
||||
|
@ -310,7 +320,6 @@ Device* LibPartedBackend::scanDevice(const QString& deviceNode)
|
|||
QList<Device*> LibPartedBackend::scanDevices(bool excludeReadOnly)
|
||||
{
|
||||
QList<Device*> result;
|
||||
// FIXME: cat /sys/block/loop0/ro
|
||||
// linux.git/tree/Documentation/devices.txt
|
||||
QString blockDeviceMajorNumbers = QStringLiteral(
|
||||
"3,22,33,34,56,57,88,89,90,91,128,129,130,131,132,133,134,135," // MFM, RLL and IDE hard disk/CD-ROM interface
|
||||
|
@ -347,53 +356,61 @@ QList<Device*> LibPartedBackend::scanDevices(bool excludeReadOnly)
|
|||
}
|
||||
|
||||
/** Detects the type of a FileSystem given a PedDevice and a PedPartition
|
||||
@param deviceNode path to the partition
|
||||
@param partitionPath path to the partition
|
||||
@return the detected FileSystem type (FileSystem::Unknown if not detected)
|
||||
*/
|
||||
FileSystem::Type LibPartedBackend::detectFileSystem(const QString& deviceNode)
|
||||
FileSystem::Type LibPartedBackend::detectFileSystem(const QString& partitionPath)
|
||||
{
|
||||
FileSystem::Type rval = FileSystem::Unknown;
|
||||
|
||||
QVariantMap args;
|
||||
args[QLatin1String("deviceNode")] = deviceNode;
|
||||
blkid_cache cache;
|
||||
if (blkid_get_cache(&cache, nullptr) == 0) {
|
||||
blkid_dev dev;
|
||||
|
||||
KAuth::Action action = QStringLiteral("org.kde.kpmcore.scan.detectfilesystem");
|
||||
action.setHelperId(QStringLiteral("org.kde.kpmcore.scan"));
|
||||
action.setArguments(args);
|
||||
KAuth::ExecuteJob *job = action.execute();
|
||||
if (!job->exec()) {
|
||||
qWarning() << "KAuth returned an error code: " << job->errorString();
|
||||
return rval;
|
||||
if ((dev = blkid_get_dev(cache,
|
||||
partitionPath.toLocal8Bit().constData(),
|
||||
BLKID_DEV_NORMAL)) != nullptr) {
|
||||
char *string = blkid_get_tag_value(cache, "TYPE", partitionPath.toLocal8Bit().constData());
|
||||
QString s = QString::fromUtf8(string);
|
||||
free(string);
|
||||
|
||||
if (s == QStringLiteral("ext2")) rval = FileSystem::Ext2;
|
||||
else if (s == QStringLiteral("ext3")) rval = FileSystem::Ext3;
|
||||
else if (s.startsWith(QStringLiteral("ext4"))) rval = FileSystem::Ext4;
|
||||
else if (s == QStringLiteral("swap")) rval = FileSystem::LinuxSwap;
|
||||
else if (s == QStringLiteral("ntfs")) rval = FileSystem::Ntfs;
|
||||
else if (s == QStringLiteral("reiserfs")) rval = FileSystem::ReiserFS;
|
||||
else if (s == QStringLiteral("reiser4")) rval = FileSystem::Reiser4;
|
||||
else if (s == QStringLiteral("xfs")) rval = FileSystem::Xfs;
|
||||
else if (s == QStringLiteral("jfs")) rval = FileSystem::Jfs;
|
||||
else if (s == QStringLiteral("hfs")) rval = FileSystem::Hfs;
|
||||
else if (s == QStringLiteral("hfsplus")) rval = FileSystem::HfsPlus;
|
||||
else if (s == QStringLiteral("ufs")) rval = FileSystem::Ufs;
|
||||
else if (s == QStringLiteral("vfat")) {
|
||||
// libblkid uses SEC_TYPE to distinguish between FAT16 and FAT32
|
||||
string = blkid_get_tag_value(cache, "SEC_TYPE", partitionPath.toLocal8Bit().constData());
|
||||
QString st = QString::fromUtf8(string);
|
||||
free(string);
|
||||
if (st == QStringLiteral("msdos"))
|
||||
rval = FileSystem::Fat16;
|
||||
else
|
||||
rval = FileSystem::Fat32;
|
||||
} else if (s == QStringLiteral("btrfs")) rval = FileSystem::Btrfs;
|
||||
else if (s == QStringLiteral("ocfs2")) rval = FileSystem::Ocfs2;
|
||||
else if (s == QStringLiteral("zfs_member")) rval = FileSystem::Zfs;
|
||||
else if (s == QStringLiteral("hpfs")) rval = FileSystem::Hpfs;
|
||||
else if (s == QStringLiteral("crypto_LUKS")) rval = FileSystem::Luks;
|
||||
else if (s == QStringLiteral("exfat")) rval = FileSystem::Exfat;
|
||||
else if (s == QStringLiteral("nilfs2")) rval = FileSystem::Nilfs2;
|
||||
else if (s == QStringLiteral("LVM2_member")) rval = FileSystem::Lvm2_PV;
|
||||
else if (s == QStringLiteral("f2fs")) rval = FileSystem::F2fs;
|
||||
else
|
||||
qWarning() << "blkid: unknown file system type " << s << " on " << partitionPath;
|
||||
}
|
||||
|
||||
blkid_put_cache(cache);
|
||||
}
|
||||
|
||||
QString s = job->data()[QLatin1String("fileSystem")].toString();
|
||||
|
||||
if (s == QStringLiteral("ext2")) rval = FileSystem::Ext2;
|
||||
else if (s == QStringLiteral("ext3")) rval = FileSystem::Ext3;
|
||||
else if (s.startsWith(QStringLiteral("ext4"))) rval = FileSystem::Ext4;
|
||||
else if (s == QStringLiteral("swap")) rval = FileSystem::LinuxSwap;
|
||||
else if (s == QStringLiteral("ntfs")) rval = FileSystem::Ntfs;
|
||||
else if (s == QStringLiteral("reiserfs")) rval = FileSystem::ReiserFS;
|
||||
else if (s == QStringLiteral("reiser4")) rval = FileSystem::Reiser4;
|
||||
else if (s == QStringLiteral("xfs")) rval = FileSystem::Xfs;
|
||||
else if (s == QStringLiteral("jfs")) rval = FileSystem::Jfs;
|
||||
else if (s == QStringLiteral("hfs")) rval = FileSystem::Hfs;
|
||||
else if (s == QStringLiteral("hfsplus")) rval = FileSystem::HfsPlus;
|
||||
else if (s == QStringLiteral("ufs")) rval = FileSystem::Ufs;
|
||||
else if (s == QStringLiteral("fat16")) rval = FileSystem::Fat16;
|
||||
else if (s == QStringLiteral("fat32")) rval = FileSystem::Fat32;
|
||||
else if (s == QStringLiteral("btrfs")) rval = FileSystem::Btrfs;
|
||||
else if (s == QStringLiteral("ocfs2")) rval = FileSystem::Ocfs2;
|
||||
else if (s == QStringLiteral("zfs_member")) rval = FileSystem::Zfs;
|
||||
else if (s == QStringLiteral("hpfs")) rval = FileSystem::Hpfs;
|
||||
else if (s == QStringLiteral("crypto_LUKS")) rval = FileSystem::Luks;
|
||||
else if (s == QStringLiteral("exfat")) rval = FileSystem::Exfat;
|
||||
else if (s == QStringLiteral("nilfs2")) rval = FileSystem::Nilfs2;
|
||||
else if (s == QStringLiteral("LVM2_member")) rval = FileSystem::Lvm2_PV;
|
||||
else if (s == QStringLiteral("f2fs")) rval = FileSystem::F2fs;
|
||||
else
|
||||
qWarning() << "blkid: unknown file system type " << s << " on " << deviceNode;
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
@ -428,9 +445,9 @@ bool LibPartedBackend::closeDevice(CoreBackendDevice* core_device)
|
|||
|
||||
PedPartitionFlag LibPartedBackend::getPedFlag(PartitionTable::Flag flag)
|
||||
{
|
||||
for (quint32 i = 0; i < sizeof(flagmap) / sizeof(flagmap[0]); i++)
|
||||
if (flagmap[i].flag == flag)
|
||||
return flagmap[i].pedFlag;
|
||||
for (const auto &f : flagmap)
|
||||
if (f.flag == flag)
|
||||
return f.pedFlag;
|
||||
|
||||
return static_cast<PedPartitionFlag>(-1);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,6 @@ class LibPartedPartitionTable;
|
|||
class LibPartedPartition;
|
||||
class OperationStack;
|
||||
|
||||
class Device;
|
||||
class KPluginFactory;
|
||||
class QString;
|
||||
|
||||
|
@ -66,7 +65,7 @@ public:
|
|||
bool closeDevice(CoreBackendDevice* core_device) override;
|
||||
Device* scanDevice(const QString& deviceNode) override;
|
||||
QList<Device*> scanDevices(bool excludeReadOnly = true) override;
|
||||
FileSystem::Type detectFileSystem(const QString& deviceNode) override;
|
||||
FileSystem::Type detectFileSystem(const QString& partitionPath) override;
|
||||
|
||||
static QString lastPartedExceptionMessage();
|
||||
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
|
||||
#include <unistd.h>
|
||||
|
||||
LibPartedDevice::LibPartedDevice(const QString& device_node) :
|
||||
CoreBackendDevice(device_node),
|
||||
LibPartedDevice::LibPartedDevice(const QString& deviceNode) :
|
||||
CoreBackendDevice(deviceNode),
|
||||
m_PedDevice(nullptr)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ class LibPartedDevice : public CoreBackendDevice
|
|||
Q_DISABLE_COPY(LibPartedDevice);
|
||||
|
||||
public:
|
||||
LibPartedDevice(const QString& device_node);
|
||||
LibPartedDevice(const QString& deviceNode);
|
||||
~LibPartedDevice();
|
||||
|
||||
public:
|
||||
|
|
|
@ -51,4 +51,3 @@ bool LibPartedPartition::setFlag(Report& report, PartitionTable::Flag partitionM
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,5 +46,4 @@ private:
|
|||
PedPartition* m_PedPartition;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -60,8 +60,8 @@ ExternalCommand::ExternalCommand(Report& report, const QString& cmd, const QStri
|
|||
|
||||
void ExternalCommand::setup()
|
||||
{
|
||||
setEnvironment(QStringList() << QStringLiteral("LC_ALL=C") << QStringLiteral("PATH=") + QString::fromUtf8(getenv("PATH")));
|
||||
setProcessChannelMode(MergedChannels);
|
||||
setEnvironment(QStringList() << QStringLiteral("LC_ALL=C") << QStringLiteral("PATH=") + QString::fromUtf8(getenv("PATH")) << QStringLiteral("LVM_SUPPRESS_FD_WARNINGS=1"));
|
||||
setProcessChannelMode(SeparateChannels);
|
||||
|
||||
connect(this, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this, &ExternalCommand::onFinished);
|
||||
connect(this, &ExternalCommand::readyReadStandardOutput, this, &ExternalCommand::onReadOutput);
|
||||
|
|
|
@ -80,7 +80,7 @@ QString Report::toHtml() const
|
|||
if (children().size() == 0)
|
||||
s += QStringLiteral("<br/>\n");
|
||||
else
|
||||
foreach(Report * child, children())
|
||||
for (const auto &child : children())
|
||||
s += child->toHtml();
|
||||
|
||||
if (!status().isEmpty())
|
||||
|
@ -109,7 +109,7 @@ QString Report::toText() const
|
|||
if (!output().isEmpty())
|
||||
s += output() + QStringLiteral("\n");
|
||||
|
||||
foreach(Report * child, children())
|
||||
for (const auto &child : children())
|
||||
s += child->toText();
|
||||
|
||||
return s;
|
||||
|
|
Loading…
Reference in New Issue