Remove libparted backend.
This commit is contained in:
parent
00cb2c85d9
commit
8fa1814f45
|
@ -15,7 +15,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(KPMCORE_COREBACKENDMANAGER_P_H)
|
||||
#ifndef KPMCORE_COREBACKENDMANAGER_P_H
|
||||
|
||||
#define KPMCORE_COREBACKENDMANAGER_P_H
|
||||
|
||||
|
|
|
@ -15,13 +15,6 @@
|
|||
|
||||
############################################
|
||||
|
||||
|
||||
#option(PARTMAN_LIBPARTEDBACKEND "Build the libparted backend plugin." ON)
|
||||
|
||||
#if (PARTMAN_LIBPARTEDBACKEND)
|
||||
# add_subdirectory(libparted)
|
||||
#endif (PARTMAN_LIBPARTEDBACKEND)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
option(PARTMAN_SFDISKBACKEND "Build the sfdisk backend plugin." ON)
|
||||
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
# Copyright (C) 2010 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/>.
|
||||
|
||||
find_package(LIBPARTED REQUIRED)
|
||||
|
||||
if (LIBPARTED_FILESYSTEM_SUPPORT)
|
||||
add_definitions(-DLIBPARTED_FILESYSTEM_SUPPORT)
|
||||
endif (LIBPARTED_FILESYSTEM_SUPPORT)
|
||||
|
||||
if (LIBPARTED_FS_RESIZE_LIBRARY_SUPPORT)
|
||||
add_definitions(-DLIBPARTED_FS_RESIZE_LIBRARY_SUPPORT)
|
||||
endif (LIBPARTED_FS_RESIZE_LIBRARY_SUPPORT)
|
||||
|
||||
include_directories(${LIBPARTED_INCLUDE_DIR})
|
||||
|
||||
set (pmlibpartedbackendplugin_SRCS
|
||||
libpartedbackend.cpp
|
||||
libparteddevice.cpp
|
||||
libpartedpartitiontable.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/backend/corebackenddevice.cpp
|
||||
)
|
||||
|
||||
add_library(pmlibpartedbackendplugin SHARED ${pmlibpartedbackendplugin_SRCS})
|
||||
|
||||
target_link_libraries(pmlibpartedbackendplugin kpmcore ${LIBPARTED_LIBS} KF5::I18n)
|
||||
|
||||
install(TARGETS pmlibpartedbackendplugin DESTINATION ${KDE_INSTALL_PLUGINDIR})
|
|
@ -1,601 +0,0 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2008-2012 by Volker Lanz <vl@fidra.de> *
|
||||
* Copyright (C) 2015-2016 by Teo Mrnjavac <teo@kde.org> *
|
||||
* Copyright (C) 2016-2017 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/>.*
|
||||
*************************************************************************/
|
||||
|
||||
/** @file
|
||||
*/
|
||||
|
||||
#include "plugins/libparted/libpartedbackend.h"
|
||||
#include "plugins/libparted/libparteddevice.h"
|
||||
#include "plugins/libparted/pedflags.h"
|
||||
|
||||
#include "core/lvmdevice.h"
|
||||
#include "core/partition.h"
|
||||
#include "core/partitiontable.h"
|
||||
#include "core/partitionalignment.h"
|
||||
|
||||
#include "fs/filesystem.h"
|
||||
#include "fs/filesystemfactory.h"
|
||||
|
||||
#include "fs/fat16.h"
|
||||
#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 <QFile>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QStorageInfo>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include <KLocalizedString>
|
||||
#include <KPluginFactory>
|
||||
|
||||
#include <parted/parted.h>
|
||||
|
||||
K_PLUGIN_FACTORY_WITH_JSON(LibPartedBackendFactory, "pmlibpartedbackendplugin.json", registerPlugin<LibPartedBackend>();)
|
||||
|
||||
static QString s_lastPartedExceptionMessage;
|
||||
|
||||
/** Callback to handle exceptions from libparted
|
||||
@param e the libparted exception to handle
|
||||
*/
|
||||
static PedExceptionOption pedExceptionHandler(PedException* e)
|
||||
{
|
||||
Log(Log::error) << xi18nc("@info:status", "LibParted Exception: %1", QString::fromLocal8Bit(e->message));
|
||||
s_lastPartedExceptionMessage = QString::fromLocal8Bit(e->message);
|
||||
return PED_EXCEPTION_UNHANDLED;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
// The following structs and the typedef come from libparted's internal gpt sources.
|
||||
// It's very unfortunate there is no public API to get at the first and last usable
|
||||
// sector for GPT a partition table, so this is the only (libparted) way to get that
|
||||
// information (another way would be to read the GPT header and parse the
|
||||
// information ourselves; if the libparted devs begin changing these internal
|
||||
// structs for each point release and break our code, we'll have to do just that).
|
||||
|
||||
typedef struct {
|
||||
uint32_t time_low;
|
||||
uint16_t time_mid;
|
||||
uint16_t time_hi_and_version;
|
||||
uint8_t clock_seq_hi_and_reserved;
|
||||
uint8_t clock_seq_low;
|
||||
uint8_t node[6];
|
||||
} /* __attribute__ ((packed)) */ efi_guid_t;
|
||||
|
||||
|
||||
struct __attribute__((packed)) _GPTDiskData {
|
||||
PedGeometry data_area;
|
||||
int entry_count;
|
||||
efi_guid_t uuid;
|
||||
};
|
||||
|
||||
typedef struct _GPTDiskData GPTDiskData;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
/** Get the first sector a Partition may cover on a given Device
|
||||
@param d the Device in question
|
||||
@return the first sector usable by a Partition
|
||||
*/
|
||||
static qint64 firstUsableSector(const Device& d)
|
||||
{
|
||||
PedDevice* pedDevice = ped_device_get(d.deviceNode().toLocal8Bit().constData());
|
||||
PedDisk* pedDisk = pedDevice ? ped_disk_new(pedDevice) : nullptr;
|
||||
|
||||
qint64 rval = 0;
|
||||
if (pedDisk)
|
||||
rval = static_cast<qint64>(pedDisk->dev->bios_geom.sectors);
|
||||
|
||||
if (pedDisk && strcmp(pedDisk->type->name, "gpt") == 0) {
|
||||
GPTDiskData* gpt_disk_data = reinterpret_cast<GPTDiskData*>(pedDisk->disk_specific);
|
||||
PedGeometry* geom = reinterpret_cast<PedGeometry*>(&gpt_disk_data->data_area);
|
||||
|
||||
if (geom)
|
||||
rval = static_cast<qint64>(geom->start);
|
||||
else
|
||||
rval += 32;
|
||||
}
|
||||
|
||||
ped_disk_destroy(pedDisk);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/** Get the last sector a Partition may cover on a given Device
|
||||
@param d the Device in question
|
||||
@return the last sector usable by a Partition
|
||||
*/
|
||||
static qint64 lastUsableSector(const Device& d)
|
||||
{
|
||||
PedDevice* pedDevice = ped_device_get(d.deviceNode().toLocal8Bit().constData());
|
||||
PedDisk* pedDisk = pedDevice ? ped_disk_new(pedDevice) : nullptr;
|
||||
|
||||
qint64 rval = 0;
|
||||
if (pedDisk)
|
||||
rval = static_cast< qint64 >( pedDisk->dev->bios_geom.sectors ) *
|
||||
static_cast< qint64 >( pedDisk->dev->bios_geom.heads ) *
|
||||
static_cast< qint64 >( pedDisk->dev->bios_geom.cylinders - 1 );
|
||||
|
||||
if (pedDisk && strcmp(pedDisk->type->name, "gpt") == 0) {
|
||||
GPTDiskData* gpt_disk_data = reinterpret_cast<GPTDiskData*>(pedDisk->disk_specific);
|
||||
PedGeometry* geom = reinterpret_cast<PedGeometry*>(&gpt_disk_data->data_area);
|
||||
|
||||
if (geom)
|
||||
rval = geom->end;
|
||||
else
|
||||
rval -= 32;
|
||||
}
|
||||
|
||||
ped_disk_destroy(pedDisk);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/** Reads sectors used on a FileSystem using libparted functions.
|
||||
@param pedDisk pointer to pedDisk where the Partition and its FileSystem are
|
||||
@param p the Partition the FileSystem is on
|
||||
@return the number of sectors used
|
||||
*/
|
||||
#if defined LIBPARTED_FS_RESIZE_LIBRARY_SUPPORT
|
||||
static qint64 readSectorsUsedLibParted(PedDisk* pedDisk, const Partition& p)
|
||||
{
|
||||
Q_ASSERT(pedDisk);
|
||||
|
||||
qint64 rval = -1;
|
||||
|
||||
PedPartition* pedPartition = ped_disk_get_partition_by_sector(pedDisk, p.firstSector());
|
||||
|
||||
if (pedPartition) {
|
||||
PedFileSystem* pedFileSystem = ped_file_system_open(&pedPartition->geom);
|
||||
|
||||
if (pedFileSystem) {
|
||||
if (PedConstraint* pedConstraint = ped_file_system_get_resize_constraint(pedFileSystem)) {
|
||||
rval = pedConstraint->min_size;
|
||||
ped_constraint_destroy(pedConstraint);
|
||||
}
|
||||
|
||||
ped_file_system_close(pedFileSystem);
|
||||
}
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Reads the sectors used in a FileSystem and stores the result in the Partition's FileSystem object.
|
||||
@param pedDisk pointer to pedDisk where the Partition and its FileSystem are
|
||||
@param p the Partition the FileSystem is on
|
||||
@param mountPoint mount point of the partition in question
|
||||
*/
|
||||
static void readSectorsUsed(PedDisk* pedDisk, const Device& d, Partition& p, const QString& mountPoint)
|
||||
{
|
||||
if (!mountPoint.isEmpty() && p.fileSystem().type() != FileSystem::LinuxSwap && p.fileSystem().type() != FileSystem::Lvm2_PV) {
|
||||
const QStorageInfo storage = QStorageInfo(mountPoint);
|
||||
if (p.isMounted() && storage.isValid())
|
||||
p.fileSystem().setSectorsUsed( (storage.bytesTotal() - storage.bytesFree()) / d.logicalSize());
|
||||
}
|
||||
else if (p.fileSystem().supportGetUsed() == FileSystem::cmdSupportFileSystem)
|
||||
p.fileSystem().setSectorsUsed(p.fileSystem().readUsedCapacity(p.deviceNode()) / d.logicalSize());
|
||||
#if defined LIBPARTED_FS_RESIZE_LIBRARY_SUPPORT
|
||||
else if (p.fileSystem().supportGetUsed() == FileSystem::cmdSupportCore)
|
||||
p.fileSystem().setSectorsUsed(readSectorsUsedLibParted(pedDisk, p));
|
||||
#else
|
||||
Q_UNUSED(pedDisk);
|
||||
#endif
|
||||
}
|
||||
|
||||
static PartitionTable::Flags activeFlags(PedPartition* p)
|
||||
{
|
||||
PartitionTable::Flags flags = PartitionTable::FlagNone;
|
||||
|
||||
// We might get here with a pedPartition just picked up from libparted that is
|
||||
// unallocated. Libparted doesn't like it if we ask for flags for unallocated
|
||||
// space.
|
||||
if (p->num <= 0)
|
||||
return flags;
|
||||
|
||||
for (const auto &flag : flagmap)
|
||||
if (ped_partition_is_flag_available(p, flag.pedFlag) && ped_partition_get_flag(p, flag.pedFlag))
|
||||
flags |= flag.flag;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static PartitionTable::Flags availableFlags(PedPartition* p)
|
||||
{
|
||||
PartitionTable::Flags flags;
|
||||
|
||||
// see above.
|
||||
if (p->num <= 0)
|
||||
return flags;
|
||||
|
||||
for (const auto &flag : flagmap) {
|
||||
if (ped_partition_is_flag_available(p, 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 (p->type != PED_PARTITION_EXTENDED || flag.flag != PartitionTable::FlagHidden)
|
||||
flags |= flag.flag;
|
||||
}
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
/** Constructs a LibParted object. */
|
||||
LibPartedBackend::LibPartedBackend(QObject*, const QList<QVariant>&) :
|
||||
CoreBackend()
|
||||
{
|
||||
ped_exception_set_handler(pedExceptionHandler);
|
||||
}
|
||||
|
||||
void LibPartedBackend::initFSSupport()
|
||||
{
|
||||
#if defined LIBPARTED_FS_RESIZE_LIBRARY_SUPPORT
|
||||
if (FS::fat16::m_Shrink == FileSystem::cmdSupportNone)
|
||||
FS::fat16::m_Shrink = FileSystem::cmdSupportBackend;
|
||||
|
||||
if (FS::fat16::m_Grow == FileSystem::cmdSupportNone)
|
||||
FS::fat16::m_Grow = FileSystem::cmdSupportBackend;
|
||||
|
||||
if (FS::hfs::m_Shrink == FileSystem::cmdSupportNone)
|
||||
FS::hfs::m_Shrink = FileSystem::cmdSupportBackend;
|
||||
|
||||
if (FS::hfsplus::m_Shrink == FileSystem::cmdSupportNone)
|
||||
FS::hfsplus::m_Shrink = FileSystem::cmdSupportBackend;
|
||||
|
||||
if (FS::hfs::m_GetUsed == FileSystem::cmdSupportNone)
|
||||
FS::hfs::m_GetUsed = FileSystem::cmdSupportBackend;
|
||||
|
||||
if (FS::hfsplus::m_GetUsed == FileSystem::cmdSupportNone)
|
||||
FS::hfsplus::m_GetUsed = FileSystem::cmdSupportBackend;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Scans a Device for Partitions.
|
||||
|
||||
This method will scan a Device for all Partitions on it, detect the FileSystem for each Partition,
|
||||
try to determine the FileSystem usage, read the FileSystem label and store it all in newly created
|
||||
objects that are in the end added to the Device's PartitionTable.
|
||||
|
||||
@param d Device
|
||||
@param pedDisk libparted pointer to the partition table
|
||||
*/
|
||||
void LibPartedBackend::scanDevicePartitions(Device& d, PedDisk* pedDisk)
|
||||
{
|
||||
Q_ASSERT(pedDisk);
|
||||
Q_ASSERT(d.partitionTable());
|
||||
|
||||
PedPartition* pedPartition = nullptr;
|
||||
|
||||
QList<Partition*> partitions;
|
||||
|
||||
while ((pedPartition = ped_disk_next_partition(pedDisk, pedPartition))) {
|
||||
if (pedPartition->num < 1)
|
||||
continue;
|
||||
|
||||
PartitionRole::Roles r = PartitionRole::None;
|
||||
|
||||
FileSystem::Type type = FileSystem::Unknown;
|
||||
char* pedPath = ped_partition_get_path(pedPartition);
|
||||
const QString partitionNode = pedPath ? QString::fromLocal8Bit(pedPath) : QString();
|
||||
free(pedPath);
|
||||
type = detectFileSystem(partitionNode);
|
||||
|
||||
switch (pedPartition->type) {
|
||||
case PED_PARTITION_NORMAL:
|
||||
r = PartitionRole::Primary;
|
||||
break;
|
||||
|
||||
case PED_PARTITION_EXTENDED:
|
||||
r = PartitionRole::Extended;
|
||||
type = FileSystem::Extended;
|
||||
break;
|
||||
|
||||
case PED_PARTITION_LOGICAL:
|
||||
r = PartitionRole::Logical;
|
||||
break;
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find an extended partition this partition is in.
|
||||
PartitionNode* parent = d.partitionTable()->findPartitionBySector(pedPartition->geom.start, PartitionRole(PartitionRole::Extended));
|
||||
|
||||
// None found, so it's a primary in the device's partition table.
|
||||
if (parent == nullptr)
|
||||
parent = d.partitionTable();
|
||||
|
||||
FileSystem* fs = FileSystemFactory::create(type, pedPartition->geom.start, pedPartition->geom.end, d.logicalSize());
|
||||
fs->scan(partitionNode);
|
||||
QString mountPoint;
|
||||
bool mounted;
|
||||
|
||||
// libparted does not handle LUKS partitions
|
||||
if (fs->type() == FileSystem::Luks) {
|
||||
r |= PartitionRole::Luks;
|
||||
FS::luks* luksFs = static_cast<FS::luks*>(fs);
|
||||
luksFs->initLUKS();
|
||||
QString mapperNode = luksFs->mapperName();
|
||||
mountPoint = FileSystem::detectMountPoint(fs, mapperNode);
|
||||
mounted = FileSystem::detectMountStatus(fs, mapperNode);
|
||||
} else {
|
||||
mountPoint = FileSystem::detectMountPoint(fs, partitionNode);
|
||||
mounted = FileSystem::detectMountStatus(fs, partitionNode);
|
||||
}
|
||||
|
||||
Partition* part = new Partition(parent, d, PartitionRole(r), fs, pedPartition->geom.start, pedPartition->geom.end, partitionNode, availableFlags(pedPartition), mountPoint, mounted, activeFlags(pedPartition));
|
||||
|
||||
if (!part->roles().has(PartitionRole::Luks))
|
||||
readSectorsUsed(pedDisk, d, *part, mountPoint);
|
||||
|
||||
if (fs->supportGetLabel() != FileSystem::cmdSupportNone)
|
||||
fs->setLabel(fs->readLabel(part->deviceNode()));
|
||||
|
||||
// GPT partitions support partition labels and partition UUIDs
|
||||
if(d.partitionTable()->type() == PartitionTable::TableType::gpt)
|
||||
part->setLabel(QLatin1String(ped_partition_get_name(pedPartition)));
|
||||
|
||||
if (fs->supportGetUUID() != FileSystem::cmdSupportNone)
|
||||
fs->setUUID(fs->readUUID(part->deviceNode()));
|
||||
|
||||
parent->append(part);
|
||||
partitions.append(part);
|
||||
}
|
||||
|
||||
d.partitionTable()->updateUnallocated(d);
|
||||
|
||||
if (d.partitionTable()->isSectorBased(d))
|
||||
d.partitionTable()->setType(d, PartitionTable::msdos_sectorbased);
|
||||
|
||||
for (const Partition * part : qAsConst(partitions))
|
||||
PartitionAlignment::isAligned(d, *part);
|
||||
}
|
||||
|
||||
/** Create a Device for the given device_node and scan it for partitions.
|
||||
@param deviceNode the device node (e.g. "/dev/sda")
|
||||
@return the created Device object. callers need to free this.
|
||||
*/
|
||||
DiskDevice* LibPartedBackend::scanDevice(const QString& deviceNode)
|
||||
{
|
||||
PedDevice* pedDevice = ped_device_get(deviceNode.toLocal8Bit().constData());
|
||||
|
||||
if (pedDevice == nullptr) {
|
||||
Log(Log::warning) << xi18nc("@info:status", "Could not access device <filename>%1</filename>", deviceNode);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Log(Log::information) << xi18nc("@info:status", "Device found: %1", QString::fromLocal8Bit(pedDevice->model));
|
||||
|
||||
DiskDevice* d = new DiskDevice(QString::fromLocal8Bit(pedDevice->model), QString::fromLocal8Bit(pedDevice->path), pedDevice->bios_geom.heads, pedDevice->bios_geom.sectors, pedDevice->bios_geom.cylinders, pedDevice->sector_size);
|
||||
|
||||
PedDisk* pedDisk = ped_disk_new(pedDevice);
|
||||
|
||||
if (pedDisk) {
|
||||
const PartitionTable::TableType type = PartitionTable::nameToTableType(QString::fromLocal8Bit(pedDisk->type->name));
|
||||
CoreBackend::setPartitionTableForDevice(*d, new PartitionTable(type, firstUsableSector(*d), lastUsableSector(*d)));
|
||||
CoreBackend::setPartitionTableMaxPrimaries(*d->partitionTable(), ped_disk_get_max_primary_partition_count(pedDisk));
|
||||
|
||||
scanDevicePartitions(*d, pedDisk);
|
||||
}
|
||||
|
||||
ped_device_destroy(pedDevice);
|
||||
return d;
|
||||
}
|
||||
|
||||
QList<Device*> LibPartedBackend::scanDevices(bool excludeReadOnly)
|
||||
{
|
||||
// TODO: add another bool option for loopDevices
|
||||
QList<Device*> result;
|
||||
QStringList deviceNodes;
|
||||
|
||||
ExternalCommand cmd(QStringLiteral("lsblk"),
|
||||
{ QStringLiteral("--nodeps"),
|
||||
QStringLiteral("--paths"),
|
||||
QStringLiteral("--sort"), QStringLiteral("name"),
|
||||
QStringLiteral("--json"),
|
||||
QStringLiteral("--output"),
|
||||
QStringLiteral("type,name") });
|
||||
|
||||
if (cmd.run(-1) && cmd.exitCode() == 0) {
|
||||
const QJsonDocument jsonDocument = QJsonDocument::fromJson(cmd.rawOutput());
|
||||
QJsonObject jsonObject = jsonDocument.object();
|
||||
const QJsonArray jsonArray = jsonObject[QLatin1String("blockdevices")].toArray();
|
||||
for (const auto &deviceLine : jsonArray) {
|
||||
QJsonObject deviceObject = deviceLine.toObject();
|
||||
if (deviceObject[QLatin1String("type")].toString() != QLatin1String("disk"))
|
||||
continue;
|
||||
|
||||
const QString deviceNode = deviceObject[QLatin1String("name")].toString();
|
||||
if (excludeReadOnly) {
|
||||
QString deviceName = deviceNode;
|
||||
deviceName.remove(QStringLiteral("/dev/"));
|
||||
QFile f(QStringLiteral("/sys/block/%1/ro").arg(deviceName));
|
||||
if (f.open(QIODevice::ReadOnly))
|
||||
if (f.readLine().trimmed().toInt() == 1)
|
||||
continue;
|
||||
}
|
||||
deviceNodes << deviceNode;
|
||||
}
|
||||
|
||||
int totalDevices = deviceNodes.length();
|
||||
for (int i = 0; i < totalDevices; ++i) {
|
||||
const QString deviceNode = deviceNodes[i];
|
||||
|
||||
emitScanProgress(deviceNode, i * 100 / totalDevices);
|
||||
Device* device = scanDevice(deviceNode);
|
||||
if(device != nullptr) {
|
||||
result.append(device);
|
||||
}
|
||||
}
|
||||
|
||||
LvmDevice::scanSystemLVM(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Detects the type of a FileSystem given a PedDevice and a PedPartition
|
||||
@param partitionPath path to the partition
|
||||
@return the detected FileSystem type (FileSystem::Unknown if not detected)
|
||||
*/
|
||||
FileSystem::Type LibPartedBackend::detectFileSystem(const QString& partitionPath)
|
||||
{
|
||||
FileSystem::Type rval = FileSystem::Unknown;
|
||||
|
||||
blkid_cache cache;
|
||||
if (blkid_get_cache(&cache, nullptr) == 0) {
|
||||
blkid_dev dev;
|
||||
|
||||
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::fromLocal8Bit(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::fromLocal8Bit(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 if (s == QStringLiteral("udf")) rval = FileSystem::Udf;
|
||||
else if (s == QStringLiteral("iso9660")) rval = FileSystem::Iso9660;
|
||||
else
|
||||
qWarning() << "blkid: unknown file system type " << s << " on " << partitionPath;
|
||||
}
|
||||
|
||||
blkid_put_cache(cache);
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
static QString readBlkIdValue(const QString& deviceNode, const QString& tag)
|
||||
{
|
||||
blkid_cache cache;
|
||||
QString rval;
|
||||
|
||||
if (blkid_get_cache(&cache, nullptr) == 0) {
|
||||
blkid_dev dev;
|
||||
|
||||
char* label = nullptr;
|
||||
if ((dev = blkid_get_dev(cache, deviceNode.toLocal8Bit().constData(), BLKID_DEV_NORMAL)) != nullptr &&
|
||||
(label = blkid_get_tag_value(cache, tag.toLocal8Bit().constData(), deviceNode.toLocal8Bit().constData()))) {
|
||||
rval = QString::fromLocal8Bit(label);
|
||||
free(label);
|
||||
}
|
||||
|
||||
blkid_put_cache(cache);
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
QString LibPartedBackend::readLabel(const QString& deviceNode) const
|
||||
{
|
||||
return readBlkIdValue(deviceNode, QStringLiteral("LABEL"));
|
||||
}
|
||||
|
||||
QString LibPartedBackend::readUUID(const QString& deviceNode) const
|
||||
{
|
||||
return readBlkIdValue(deviceNode, QStringLiteral("UUID"));
|
||||
}
|
||||
|
||||
CoreBackendDevice* LibPartedBackend::openDevice(const Device& d)
|
||||
{
|
||||
LibPartedDevice* device = new LibPartedDevice(d.deviceNode());
|
||||
|
||||
if (device == nullptr || !device->open()) {
|
||||
delete device;
|
||||
device = nullptr;
|
||||
}
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
CoreBackendDevice* LibPartedBackend::openDeviceExclusive(const Device& d)
|
||||
{
|
||||
LibPartedDevice* device = new LibPartedDevice(d.deviceNode());
|
||||
|
||||
if (device == nullptr || !device->openExclusive()) {
|
||||
delete device;
|
||||
device = nullptr;
|
||||
}
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
bool LibPartedBackend::closeDevice(CoreBackendDevice* core_device)
|
||||
{
|
||||
return core_device->close();
|
||||
}
|
||||
|
||||
PedPartitionFlag LibPartedBackend::getPedFlag(PartitionTable::Flag flag)
|
||||
{
|
||||
for (const auto &f : flagmap)
|
||||
if (f.flag == flag)
|
||||
return f.pedFlag;
|
||||
|
||||
return static_cast<PedPartitionFlag>(-1);
|
||||
}
|
||||
|
||||
QString LibPartedBackend::lastPartedExceptionMessage()
|
||||
{
|
||||
return s_lastPartedExceptionMessage;
|
||||
}
|
||||
|
||||
#include "libpartedbackend.moc"
|
|
@ -1,80 +0,0 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2008, 2010 by Volker Lanz <vl@fidra.de> *
|
||||
* Copyright (C) 2015 by Teo Mrnjavac <teo@kde.org> *
|
||||
* *
|
||||
* 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(KPMCORE_LIBPARTED_H)
|
||||
|
||||
#define KPMCORE_LIBPARTED_H
|
||||
|
||||
#include "backend/corebackend.h"
|
||||
|
||||
#include "core/partitiontable.h"
|
||||
#include "core/diskdevice.h"
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
|
||||
#include "fs/filesystem.h"
|
||||
|
||||
#include <parted/parted.h>
|
||||
|
||||
#include <QList>
|
||||
#include <QVariant>
|
||||
#include <QtGlobal>
|
||||
|
||||
class LibPartedDevice;
|
||||
class LibPartedPartitionTable;
|
||||
class LibPartedPartition;
|
||||
class OperationStack;
|
||||
|
||||
class KPluginFactory;
|
||||
class QString;
|
||||
|
||||
/** Backend plugin for libparted.
|
||||
|
||||
@author Volker Lanz <vl@fidra.de>
|
||||
*/
|
||||
class LibPartedBackend : public CoreBackend
|
||||
{
|
||||
friend class KPluginFactory;
|
||||
friend class LibPartedPartition;
|
||||
friend class LibPartedDevice;
|
||||
friend class LibPartedPartitionTable;
|
||||
|
||||
Q_DISABLE_COPY(LibPartedBackend)
|
||||
|
||||
private:
|
||||
LibPartedBackend(QObject* parent, const QList<QVariant>& args);
|
||||
|
||||
public:
|
||||
void initFSSupport() override;
|
||||
|
||||
CoreBackendDevice* openDevice(const Device& d) override;
|
||||
CoreBackendDevice* openDeviceExclusive(const Device& d) override;
|
||||
bool closeDevice(CoreBackendDevice* core_device) override;
|
||||
DiskDevice* scanDevice(const QString& deviceNode) override;
|
||||
QList<Device*> scanDevices(bool excludeReadOnly = false) override;
|
||||
FileSystem::Type detectFileSystem(const QString& partitionPath) override;
|
||||
QString readLabel(const QString& deviceNode) const override;
|
||||
QString readUUID(const QString& deviceNode) const override;
|
||||
|
||||
static QString lastPartedExceptionMessage();
|
||||
|
||||
private:
|
||||
static PedPartitionFlag getPedFlag(PartitionTable::Flag flag);
|
||||
void scanDevicePartitions(Device& d, PedDisk* pedDisk);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,112 +0,0 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2010 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 "plugins/libparted/libparteddevice.h"
|
||||
#include "plugins/libparted/libpartedpartitiontable.h"
|
||||
|
||||
#include "core/partitiontable.h"
|
||||
|
||||
#include "util/globallog.h"
|
||||
#include "util/report.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
LibPartedDevice::LibPartedDevice(const QString& deviceNode) :
|
||||
CoreBackendDevice(deviceNode),
|
||||
m_PedDevice(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
LibPartedDevice::~LibPartedDevice()
|
||||
{
|
||||
if (pedDevice())
|
||||
close();
|
||||
}
|
||||
|
||||
bool LibPartedDevice::open()
|
||||
{
|
||||
Q_ASSERT(pedDevice() == nullptr);
|
||||
|
||||
if (pedDevice())
|
||||
return false;
|
||||
|
||||
m_PedDevice = ped_device_get(deviceNode().toLocal8Bit().constData());
|
||||
|
||||
return m_PedDevice != nullptr;
|
||||
}
|
||||
|
||||
bool LibPartedDevice::openExclusive()
|
||||
{
|
||||
bool rval = open() && ped_device_open(pedDevice());
|
||||
|
||||
if (rval)
|
||||
setExclusive(true);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool LibPartedDevice::close()
|
||||
{
|
||||
Q_ASSERT(pedDevice());
|
||||
|
||||
if (pedDevice() && isExclusive()) {
|
||||
ped_device_close(pedDevice());
|
||||
setExclusive(false);
|
||||
}
|
||||
|
||||
m_PedDevice = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
CoreBackendPartitionTable* LibPartedDevice::openPartitionTable()
|
||||
{
|
||||
CoreBackendPartitionTable* ptable = new LibPartedPartitionTable(pedDevice());
|
||||
|
||||
if (ptable == nullptr || !ptable->open()) {
|
||||
delete ptable;
|
||||
ptable = nullptr;
|
||||
}
|
||||
|
||||
return ptable;
|
||||
}
|
||||
|
||||
bool LibPartedDevice::createPartitionTable(Report& report, const PartitionTable& ptable)
|
||||
{
|
||||
PedDiskType* pedDiskType = ped_disk_type_get(ptable.typeName().toLocal8Bit().constData());
|
||||
|
||||
if (pedDiskType == nullptr) {
|
||||
report.line() << xi18nc("@info:progress", "Creating partition table failed: Could not retrieve partition table type \"%1\" for <filename>%2</filename>.", ptable.typeName(), deviceNode());
|
||||
return false;
|
||||
}
|
||||
|
||||
PedDevice* dev = ped_device_get(deviceNode().toLocal8Bit().constData());
|
||||
|
||||
if (dev == nullptr) {
|
||||
report.line() << xi18nc("@info:progress", "Creating partition table failed: Could not open backend device <filename>%1</filename>.", deviceNode());
|
||||
return false;
|
||||
}
|
||||
|
||||
PedDisk* disk = ped_disk_new_fresh(dev, pedDiskType);
|
||||
|
||||
if (disk == nullptr) {
|
||||
report.line() << xi18nc("@info:progress", "Creating partition table failed: Could not create a new partition table in the backend for device <filename>%1</filename>.", deviceNode());
|
||||
return false;
|
||||
}
|
||||
|
||||
return LibPartedPartitionTable::commit(disk);
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2010 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(KPMCORE_LIBPARTEDDEVICE_H)
|
||||
|
||||
#define KPMCORE_LIBPARTEDDEVICE_H
|
||||
|
||||
#include "backend/corebackenddevice.h"
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#include <parted/parted.h>
|
||||
|
||||
class Partition;
|
||||
class PartitionTable;
|
||||
class Report;
|
||||
class CoreBackendPartitionTable;
|
||||
|
||||
class LibPartedDevice : public CoreBackendDevice
|
||||
{
|
||||
Q_DISABLE_COPY(LibPartedDevice)
|
||||
|
||||
public:
|
||||
LibPartedDevice(const QString& deviceNode);
|
||||
~LibPartedDevice();
|
||||
|
||||
public:
|
||||
bool open() override;
|
||||
bool openExclusive() override;
|
||||
bool close() override;
|
||||
|
||||
CoreBackendPartitionTable* openPartitionTable() override;
|
||||
|
||||
bool createPartitionTable(Report& report, const PartitionTable& ptable) override;
|
||||
|
||||
protected:
|
||||
PedDevice* pedDevice() {
|
||||
return m_PedDevice;
|
||||
}
|
||||
|
||||
private:
|
||||
PedDevice* m_PedDevice;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,356 +0,0 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2010, 2011, 2012 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 "plugins/libparted/libpartedpartitiontable.h"
|
||||
#include "plugins/libparted/libpartedbackend.h"
|
||||
|
||||
#include "backend/corebackend.h"
|
||||
#include "backend/corebackendmanager.h"
|
||||
|
||||
#include "core/partition.h"
|
||||
#include "core/device.h"
|
||||
|
||||
#include "fs/filesystem.h"
|
||||
|
||||
#include "util/report.h"
|
||||
#include "util/externalcommand.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
LibPartedPartitionTable::LibPartedPartitionTable(PedDevice* device) :
|
||||
CoreBackendPartitionTable(),
|
||||
m_PedDevice(device),
|
||||
m_PedDisk(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
LibPartedPartitionTable::~LibPartedPartitionTable()
|
||||
{
|
||||
ped_disk_destroy(m_PedDisk);
|
||||
}
|
||||
|
||||
bool LibPartedPartitionTable::open()
|
||||
{
|
||||
m_PedDisk = ped_disk_new(pedDevice());
|
||||
|
||||
return m_PedDisk != nullptr;
|
||||
}
|
||||
|
||||
bool LibPartedPartitionTable::commit(quint32 timeout)
|
||||
{
|
||||
return commit(pedDisk(), timeout);
|
||||
}
|
||||
|
||||
bool LibPartedPartitionTable::commit(PedDisk* pd, quint32 timeout)
|
||||
{
|
||||
if (pd == nullptr)
|
||||
return false;
|
||||
|
||||
bool rval = ped_disk_commit_to_dev(pd);
|
||||
|
||||
if (rval)
|
||||
rval = ped_disk_commit_to_os(pd);
|
||||
|
||||
if (!ExternalCommand(QStringLiteral("udevadm"), QStringList() << QStringLiteral("settle") << QStringLiteral("--timeout=") + QString::number(timeout)).run() &&
|
||||
!ExternalCommand(QStringLiteral("udevsettle"), QStringList() << QStringLiteral("--timeout=") + QString::number(timeout)).run())
|
||||
sleep(timeout);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
FileSystem::Type type;
|
||||
QString name;
|
||||
} mapFileSystemTypeToLibPartedName[] = {
|
||||
{ FileSystem::Btrfs, QStringLiteral("btrfs") },
|
||||
{ FileSystem::Ext2, QStringLiteral("ext2") },
|
||||
{ FileSystem::Ext3, QStringLiteral("ext3") },
|
||||
{ FileSystem::Ext4, QStringLiteral("ext4") },
|
||||
{ FileSystem::LinuxSwap, QStringLiteral("linux-swap") },
|
||||
{ FileSystem::Fat16, QStringLiteral("fat16") },
|
||||
{ FileSystem::Fat32, QStringLiteral("fat32") },
|
||||
{ FileSystem::Nilfs2, QStringLiteral("nilfs2") },
|
||||
{ FileSystem::Ntfs, QStringLiteral("ntfs") },
|
||||
{ FileSystem::Exfat, QStringLiteral("ntfs") },
|
||||
{ FileSystem::ReiserFS, QStringLiteral("reiserfs") },
|
||||
{ FileSystem::Reiser4, QStringLiteral("reiserfs") },
|
||||
{ FileSystem::Xfs, QStringLiteral("xfs") },
|
||||
{ FileSystem::Jfs, QStringLiteral("jfs") },
|
||||
{ FileSystem::Hfs, QStringLiteral("hfs") },
|
||||
{ FileSystem::HfsPlus, QStringLiteral("hfs+") },
|
||||
{ FileSystem::Ufs, QStringLiteral("ufs") },
|
||||
{ FileSystem::Udf, QStringLiteral("ntfs") },
|
||||
{ FileSystem::Iso9660, QStringLiteral("iso9660") }
|
||||
};
|
||||
|
||||
static PedFileSystemType* getPedFileSystemType(FileSystem::Type t)
|
||||
{
|
||||
for (quint32 i = 0; i < sizeof(mapFileSystemTypeToLibPartedName) / sizeof(mapFileSystemTypeToLibPartedName[0]); i++)
|
||||
if (mapFileSystemTypeToLibPartedName[i].type == t)
|
||||
return ped_file_system_type_get(mapFileSystemTypeToLibPartedName[i].name.toLocal8Bit().constData());
|
||||
|
||||
// if we didn't find anything, go with ext2 as a safe fallback
|
||||
return ped_file_system_type_get("ext2");
|
||||
}
|
||||
|
||||
QString LibPartedPartitionTable::createPartition(Report& report, const Partition& partition)
|
||||
{
|
||||
Q_ASSERT(partition.devicePath() == QString::fromLocal8Bit(pedDevice()->path));
|
||||
|
||||
QString rval = QString();
|
||||
|
||||
// According to libParted docs, PedPartitionType can be "nullptr if unknown". That's obviously wrong,
|
||||
// it's a typedef for an enum. So let's use something the libparted devs will hopefully never
|
||||
// use...
|
||||
PedPartitionType pedType = static_cast<PedPartitionType>(0xffffffff);
|
||||
|
||||
if (partition.roles().has(PartitionRole::Extended))
|
||||
pedType = PED_PARTITION_EXTENDED;
|
||||
else if (partition.roles().has(PartitionRole::Logical))
|
||||
pedType = PED_PARTITION_LOGICAL;
|
||||
else if (partition.roles().has(PartitionRole::Primary))
|
||||
pedType = PED_PARTITION_NORMAL;
|
||||
|
||||
if (pedType == static_cast<int>(0xffffffff)) {
|
||||
report.line() << xi18nc("@info:progress", "Unknown partition role for new partition <filename>%1</filename> (roles: %2)", partition.deviceNode(), partition.roles().toString());
|
||||
return QString();
|
||||
}
|
||||
|
||||
PedFileSystemType* pedFsType = (partition.roles().has(PartitionRole::Extended) || partition.fileSystem().type() == FileSystem::Unformatted) ? nullptr : getPedFileSystemType(partition.fileSystem().type());
|
||||
|
||||
PedPartition* pedPartition = ped_partition_new(pedDisk(), pedType, pedFsType, partition.firstSector(), partition.lastSector());
|
||||
|
||||
if (pedPartition == nullptr) {
|
||||
report.line() << xi18nc("@info:progress", "Failed to create new partition <filename>%1</filename>.", partition.deviceNode());
|
||||
return QString();
|
||||
}
|
||||
|
||||
PedConstraint* pedConstraint = nullptr;
|
||||
PedGeometry* pedGeometry = ped_geometry_new(pedDevice(), partition.firstSector(), partition.length());
|
||||
|
||||
if (pedGeometry)
|
||||
pedConstraint = ped_constraint_exact(pedGeometry);
|
||||
ped_geometry_destroy(pedGeometry);
|
||||
|
||||
if (pedConstraint == nullptr) {
|
||||
report.line() << i18nc("@info:progress", "Failed to create a new partition: could not get geometry for constraint.");
|
||||
return QString();
|
||||
}
|
||||
|
||||
if (ped_disk_add_partition(pedDisk(), pedPartition, pedConstraint)) {
|
||||
char *pedPath = ped_partition_get_path(pedPartition);
|
||||
rval = QString::fromLocal8Bit(pedPath);
|
||||
free(pedPath);
|
||||
}
|
||||
else {
|
||||
report.line() << xi18nc("@info:progress", "Failed to add partition <filename>%1</filename> to device <filename>%2</filename>.", partition.deviceNode(), QString::fromLocal8Bit(pedDisk()->dev->path));
|
||||
report.line() << LibPartedBackend::lastPartedExceptionMessage();
|
||||
}
|
||||
|
||||
ped_constraint_destroy(pedConstraint);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool LibPartedPartitionTable::deletePartition(Report& report, const Partition& partition)
|
||||
{
|
||||
Q_ASSERT(partition.devicePath() == QString::fromLocal8Bit(pedDevice()->path));
|
||||
|
||||
bool rval = false;
|
||||
|
||||
PedPartition* pedPartition = partition.roles().has(PartitionRole::Extended)
|
||||
? ped_disk_extended_partition(pedDisk())
|
||||
: ped_disk_get_partition_by_sector(pedDisk(), partition.firstSector());
|
||||
|
||||
if (pedPartition) {
|
||||
rval = ped_disk_delete_partition(pedDisk(), pedPartition);
|
||||
|
||||
if (!rval)
|
||||
report.line() << xi18nc("@info:progress", "Could not delete partition <filename>%1</filename>.", partition.deviceNode());
|
||||
} else
|
||||
report.line() << xi18nc("@info:progress", "Deleting partition failed: Partition to delete (<filename>%1</filename>) not found on disk.", partition.deviceNode());
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool LibPartedPartitionTable::updateGeometry(Report& report, const Partition& partition, qint64 sector_start, qint64 sector_end)
|
||||
{
|
||||
Q_ASSERT(partition.devicePath() == QString::fromLocal8Bit(pedDevice()->path));
|
||||
|
||||
bool rval = false;
|
||||
|
||||
PedPartition* pedPartition = (partition.roles().has(PartitionRole::Extended))
|
||||
? ped_disk_extended_partition(pedDisk())
|
||||
: ped_disk_get_partition_by_sector(pedDisk(), partition.firstSector());
|
||||
|
||||
if (pedPartition) {
|
||||
if (PedGeometry* pedGeometry = ped_geometry_new(pedDevice(), sector_start, sector_end - sector_start + 1)) {
|
||||
if (PedConstraint* pedConstraint = ped_constraint_exact(pedGeometry)) {
|
||||
if (ped_disk_set_partition_geom(pedDisk(), pedPartition, pedConstraint, sector_start, sector_end))
|
||||
rval = true;
|
||||
else
|
||||
report.line() << xi18nc("@info:progress", "Could not set geometry for partition <filename>%1</filename> while trying to resize/move it.", partition.deviceNode());
|
||||
ped_constraint_destroy(pedConstraint);
|
||||
} else
|
||||
report.line() << xi18nc("@info:progress", "Could not get constraint for partition <filename>%1</filename> while trying to resize/move it.", partition.deviceNode());
|
||||
ped_geometry_destroy(pedGeometry);
|
||||
} else
|
||||
report.line() << xi18nc("@info:progress", "Could not get geometry for partition <filename>%1</filename> while trying to resize/move it.", partition.deviceNode());
|
||||
} else
|
||||
report.line() << xi18nc("@info:progress", "Could not open partition <filename>%1</filename> while trying to resize/move it.", partition.deviceNode());
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool LibPartedPartitionTable::clobberFileSystem(Report& report, const Partition& partition)
|
||||
{
|
||||
bool rval = false;
|
||||
|
||||
if (PedPartition* pedPartition = ped_disk_get_partition_by_sector(pedDisk(), partition.firstSector())) {
|
||||
if (pedPartition->type == PED_PARTITION_NORMAL || pedPartition->type == PED_PARTITION_LOGICAL) {
|
||||
if (ped_device_open(pedDevice())) {
|
||||
//reiser4 stores "ReIsEr4" at sector 128 with a sector size of 512 bytes
|
||||
|
||||
// We need to use memset instead of = {0} because clang sucks.
|
||||
const long long zeroes_length = pedDevice()->sector_size*129;
|
||||
char* zeroes = new char[zeroes_length];
|
||||
memset(zeroes, 0, zeroes_length*sizeof(char));
|
||||
|
||||
rval = ped_geometry_write(&pedPartition->geom, zeroes, 0, 129);
|
||||
delete[] zeroes;
|
||||
|
||||
if (!rval)
|
||||
report.line() << xi18nc("@info:progress", "Failed to erase filesystem signature on partition <filename>%1</filename>.", partition.deviceNode());
|
||||
|
||||
ped_device_close(pedDevice());
|
||||
}
|
||||
} else
|
||||
rval = true;
|
||||
} else
|
||||
report.line() << xi18nc("@info:progress", "Could not delete file system on partition <filename>%1</filename>: Failed to get partition.", partition.deviceNode());
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
#if defined LIBPARTED_FS_RESIZE_LIBRARY_SUPPORT
|
||||
static void pedTimerHandler(PedTimer* pedTimer, void*)
|
||||
{
|
||||
CoreBackendManager::self()->backend()->emitProgress(pedTimer->frac * 100);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool LibPartedPartitionTable::resizeFileSystem(Report& report, const Partition& partition, qint64 newLength)
|
||||
{
|
||||
bool rval = false;
|
||||
|
||||
#if defined LIBPARTED_FS_RESIZE_LIBRARY_SUPPORT
|
||||
if (PedGeometry* originalGeometry = ped_geometry_new(pedDevice(), partition.fileSystem().firstSector(), partition.fileSystem().length())) {
|
||||
if (PedFileSystem* pedFileSystem = ped_file_system_open(originalGeometry)) {
|
||||
if (PedGeometry* resizedGeometry = ped_geometry_new(pedDevice(), partition.fileSystem().firstSector(), newLength)) {
|
||||
PedTimer* pedTimer = ped_timer_new(pedTimerHandler, nullptr);
|
||||
rval = ped_file_system_resize(pedFileSystem, resizedGeometry, pedTimer);
|
||||
ped_timer_destroy(pedTimer);
|
||||
|
||||
if (!rval)
|
||||
report.line() << xi18nc("@info:progress", "Could not resize file system on partition <filename>%1</filename>.", partition.deviceNode());
|
||||
ped_geometry_destroy(resizedGeometry);
|
||||
} else
|
||||
report.line() << xi18nc("@info:progress", "Could not get geometry for resized partition <filename>%1</filename> while trying to resize the file system.", partition.deviceNode());
|
||||
|
||||
ped_file_system_close(pedFileSystem);
|
||||
} else
|
||||
report.line() << xi18nc("@info:progress", "Could not open partition <filename>%1</filename> while trying to resize the file system.", partition.deviceNode());
|
||||
ped_geometry_destroy(originalGeometry);
|
||||
} else
|
||||
report.line() << xi18nc("@info:progress", "Could not read geometry for partition <filename>%1</filename> while trying to resize the file system.", partition.deviceNode());
|
||||
#else
|
||||
Q_UNUSED(report)
|
||||
Q_UNUSED(partition)
|
||||
Q_UNUSED(newLength)
|
||||
#endif
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
FileSystem::Type LibPartedPartitionTable::detectFileSystemBySector(Report& report, const Device& device, qint64 sector)
|
||||
{
|
||||
PedPartition* pedPartition = ped_disk_get_partition_by_sector(pedDisk(), sector);
|
||||
|
||||
char* pedPath = ped_partition_get_path(pedPartition);
|
||||
FileSystem::Type type = FileSystem::Unknown;
|
||||
if (pedPartition && pedPath)
|
||||
type = CoreBackendManager::self()->backend()->detectFileSystem(QString::fromLocal8Bit(pedPath));
|
||||
else
|
||||
report.line() << xi18nc("@info:progress", "Could not determine file system of partition at sector %1 on device <filename>%2</filename>.", sector, device.deviceNode());
|
||||
free(pedPath);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
bool LibPartedPartitionTable::setPartitionSystemType(Report& report, const Partition& partition)
|
||||
{
|
||||
PedFileSystemType* pedFsType = (partition.roles().has(PartitionRole::Extended) || partition.fileSystem().type() == FileSystem::Unformatted) ? nullptr : getPedFileSystemType(partition.fileSystem().type());
|
||||
if (pedFsType == nullptr) {
|
||||
report.line() << xi18nc("@info:progress", "Could not update the system type for partition <filename>%1</filename>.", partition.deviceNode());
|
||||
report.line() << xi18nc("@info:progress", "No file system defined.");
|
||||
return false;
|
||||
}
|
||||
|
||||
PedPartition* pedPartition = ped_disk_get_partition_by_sector(pedDisk(), partition.firstSector());
|
||||
if (pedPartition == nullptr) {
|
||||
report.line() << xi18nc("@info:progress", "Could not update the system type for partition <filename>%1</filename>.", partition.deviceNode());
|
||||
report.line() << xi18nc("@info:progress", "No partition found at sector %1.", partition.firstSector());
|
||||
return false;
|
||||
}
|
||||
|
||||
return ped_partition_set_system(pedPartition, pedFsType) != 0;
|
||||
}
|
||||
|
||||
bool LibPartedPartitionTable::setFlag(Report& report, const Partition& partition, PartitionTable::Flag flag, bool state)
|
||||
{
|
||||
PedPartition* pedPartition;
|
||||
if (partition.roles().has(PartitionRole::Extended))
|
||||
pedPartition = ped_disk_extended_partition(pedDisk());
|
||||
else
|
||||
pedPartition = ped_disk_get_partition_by_sector(pedDisk(), partition.firstSector());
|
||||
if (pedPartition == nullptr) {
|
||||
QString deviceNode = QString::fromUtf8(pedDevice()->path);
|
||||
report.line() << xi18nc("@info:progress", "Could not find partition <filename>%1</filename> on device <filename>%2</filename> to set partition flags.", partition.deviceNode(), deviceNode);
|
||||
return false;
|
||||
}
|
||||
|
||||
const PedPartitionFlag f = LibPartedBackend::getPedFlag(flag);
|
||||
|
||||
// ignore flags that don't exist for this partition
|
||||
if (!ped_partition_is_flag_available(pedPartition, f)) {
|
||||
report.line() << xi18nc("@info:progress", "The flag \"%1\" is not available on the partition's partition table.", PartitionTable::flagName(flag));
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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.
|
||||
if (pedPartition->type == PED_PARTITION_EXTENDED && flag == PartitionTable::FlagHidden)
|
||||
return true;
|
||||
|
||||
if (!ped_partition_set_flag(pedPartition, f, state ? 1 : 0))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2010, 2011 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(KPMCORE_LIBPARTEDPARTITIONTABLE_H)
|
||||
|
||||
#define KPMCORE_LIBPARTEDPARTITIONTABLE_H
|
||||
|
||||
#include "backend/corebackendpartitiontable.h"
|
||||
|
||||
#include "fs/filesystem.h"
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#include <parted/parted.h>
|
||||
|
||||
class CoreBackendPartition;
|
||||
class Report;
|
||||
class Partition;
|
||||
|
||||
class LibPartedPartitionTable : public CoreBackendPartitionTable
|
||||
{
|
||||
public:
|
||||
LibPartedPartitionTable(PedDevice* device);
|
||||
~LibPartedPartitionTable();
|
||||
|
||||
public:
|
||||
bool open() override;
|
||||
|
||||
bool commit(quint32 timeout = 10) override;
|
||||
static bool commit(PedDisk* pd, quint32 timeout = 10);
|
||||
|
||||
QString createPartition(Report& report, const Partition& partition) override;
|
||||
bool deletePartition(Report& report, const Partition& partition) override;
|
||||
bool updateGeometry(Report& report, const Partition& partition, qint64 sector_start, qint64 sector_end) override;
|
||||
bool clobberFileSystem(Report& report, const Partition& partition) override;
|
||||
bool resizeFileSystem(Report& report, const Partition& partition, qint64 newLength) override;
|
||||
FileSystem::Type detectFileSystemBySector(Report& report, const Device& device, qint64 sector) override;
|
||||
bool setPartitionSystemType(Report& report, const Partition& partition) override;
|
||||
bool setFlag(Report& report, const Partition& partition, PartitionTable::Flag flag, bool state) override;
|
||||
|
||||
private:
|
||||
PedDevice* pedDevice() {
|
||||
return m_PedDevice;
|
||||
}
|
||||
PedDisk* pedDisk() {
|
||||
return m_PedDisk;
|
||||
}
|
||||
|
||||
private:
|
||||
PedDevice* m_PedDevice;
|
||||
PedDisk* m_PedDisk;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,46 +0,0 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2008, 2010 by Volker Lanz <vl@fidra.de> *
|
||||
* Copyright (C) 2015 by Teo Mrnjavac <teo@kde.org> *
|
||||
* *
|
||||
* 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/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#ifndef KPMCORE_PEDFLAGS_H
|
||||
#define KPMCORE_PEDFLAGS_H
|
||||
|
||||
static struct {
|
||||
PedPartitionFlag pedFlag;
|
||||
PartitionTable::Flag flag;
|
||||
} flagmap[] = {
|
||||
{ PED_PARTITION_BOOT, PartitionTable::FlagBoot },
|
||||
{ PED_PARTITION_ROOT, PartitionTable::FlagRoot },
|
||||
{ PED_PARTITION_SWAP, PartitionTable::FlagSwap },
|
||||
{ PED_PARTITION_HIDDEN, PartitionTable::FlagHidden },
|
||||
{ PED_PARTITION_RAID, PartitionTable::FlagRaid },
|
||||
{ PED_PARTITION_LVM, PartitionTable::FlagLvm },
|
||||
{ PED_PARTITION_LBA, PartitionTable::FlagLba },
|
||||
{ PED_PARTITION_HPSERVICE, PartitionTable::FlagHpService },
|
||||
{ PED_PARTITION_PALO, PartitionTable::FlagPalo },
|
||||
{ PED_PARTITION_PREP, PartitionTable::FlagPrep },
|
||||
{ PED_PARTITION_MSFT_RESERVED, PartitionTable::FlagMsftReserved },
|
||||
{ PED_PARTITION_BIOS_GRUB, PartitionTable::FlagBiosGrub },
|
||||
{ PED_PARTITION_APPLE_TV_RECOVERY, PartitionTable::FlagAppleTvRecovery },
|
||||
{ PED_PARTITION_DIAG, PartitionTable::FlagDiag }, // generic diagnostics flag
|
||||
{ PED_PARTITION_LEGACY_BOOT, PartitionTable::FlagLegacyBoot },
|
||||
{ PED_PARTITION_MSFT_DATA, PartitionTable::FlagMsftData },
|
||||
{ PED_PARTITION_IRST, PartitionTable::FlagIrst }, // Intel Rapid Start partition
|
||||
{ PED_PARTITION_ESP, PartitionTable::FlagEsp } // EFI system
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,48 +0,0 @@
|
|||
{
|
||||
"KPlugin": {
|
||||
"Authors": [
|
||||
{
|
||||
"Email": "vl@fidra.de",
|
||||
"Name": "Volker Lanz",
|
||||
"Name[x-test]": "xxVolker Lanzxx"
|
||||
}
|
||||
],
|
||||
"Category": "BackendPlugin",
|
||||
"Description": "The LibParted backend for KDE Partition Manager",
|
||||
"Description[ca@valencia]": "Un dorsal pel LibParted del gestor de particions del KDE",
|
||||
"Description[ca]": "Un dorsal pel LibParted del gestor de particions del KDE",
|
||||
"Description[de]": "Das LibParted-Backend für die KDE-Partitionsverwaltung",
|
||||
"Description[es]": "El motor LibParted para el gestor de particiones de KDE",
|
||||
"Description[nl]": "De LibParted-backend voor de KDE-partitiebeheerder",
|
||||
"Description[pt]": "A infra-estrutura da LibParted para o Gestor de Partições do KDE",
|
||||
"Description[sk]": "LibParted - program v pozadí pre KDE Správcu partícií",
|
||||
"Description[sv]": "LibParted bakgrundsprogrammet till KDE:s partitionshanterare",
|
||||
"Description[uk]": "Сервер LibParted для Керування розділами KDE",
|
||||
"Description[x-test]": "xxThe LibParted backend for KDE Partition Managerxx",
|
||||
"EnabledByDefault": true,
|
||||
"Icon": "preferences-plugin",
|
||||
"Id": "pmlibpartedbackendplugin",
|
||||
"License": "GPL",
|
||||
"Name": "KDE Partition Manager LibParted Backend",
|
||||
"Name[ca@valencia]": "Dorsal pel LibParted del gestor de particions del KDE",
|
||||
"Name[ca]": "Dorsal pel LibParted del gestor de particions del KDE",
|
||||
"Name[de]": "KDE-Partitionsverwaltung LibParted-Backend",
|
||||
"Name[es]": "Motor LibParted para el gestor de particiones de KDE",
|
||||
"Name[fi]": "KDE:n osionhallinnan LibParted-taustaosa",
|
||||
"Name[fr]": "Moteur LibParted pour le gestionnaire de partitions de KDE",
|
||||
"Name[id]": "Backend LibParted Pengelola Parisi KDE",
|
||||
"Name[it]": "Motore LibParted del gestore delle partizioni di KDE",
|
||||
"Name[nb]": "KDE partisjonsbehandler, bakgrunnsmotor for libparted",
|
||||
"Name[nl]": "KDE-partitiebeheerder LibParted-backend",
|
||||
"Name[pt]": "Infra-Estrutura da LibParted para o Gestor de Partições do KDE",
|
||||
"Name[sk]": "LibParted - program v pozadí pre KDE Správcu partícií",
|
||||
"Name[sv]": "KDE:s partitionshanterare LibParted bakgrundsprogram",
|
||||
"Name[uk]": "Сервер LibParted Керування розділами KDE",
|
||||
"Name[x-test]": "xxKDE Partition Manager LibParted Backendxx",
|
||||
"ServiceTypes": [
|
||||
"PartitionManager/Plugin"
|
||||
],
|
||||
"Version": "1",
|
||||
"Website": "http://www.partitionmanager.org"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue