Add an experimental sfdisk backend.
This commit is contained in:
parent
a6415561ae
commit
0d88e26c8c
|
@ -455,6 +455,7 @@ static struct {
|
|||
{ QLatin1String("dasd"), 1, false, true, PartitionTable::dasd },
|
||||
{ QLatin1String("msdos"), 4, true, false, PartitionTable::msdos },
|
||||
{ QLatin1String("msdos"), 4, true, false, PartitionTable::msdos_sectorbased },
|
||||
{ QLatin1String("dos"), 4, true, false, PartitionTable::msdos_sectorbased },
|
||||
{ QLatin1String("dvh"), 16, true, true, PartitionTable::dvh },
|
||||
{ QLatin1String("gpt"), 128, false, false, PartitionTable::gpt },
|
||||
{ QLatin1String("loop"), 1, false, true, PartitionTable::loop },
|
||||
|
|
|
@ -29,3 +29,4 @@ if (PARTMAN_DUMMYBACKEND)
|
|||
add_subdirectory(dummy)
|
||||
endif (PARTMAN_DUMMYBACKEND)
|
||||
|
||||
add_subdirectory(sfdisk)
|
||||
|
|
|
@ -47,4 +47,3 @@ Name[uk]=Додаток Керування розділами KDE
|
|||
Name[x-test]=xxKDE Partition Manager Pluginxx
|
||||
Name[zh_CN]=KDE 分区管理器插件
|
||||
Name[zh_TW]=KDE 磁碟分割區管理員外掛程式
|
||||
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
# 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/>.
|
||||
|
||||
set (pmsfdiskbackendplugin_SRCS
|
||||
sfdiskbackend.cpp
|
||||
sfdiskdevice.cpp
|
||||
sfdiskpartition.cpp
|
||||
sfdiskpartitiontable.cpp
|
||||
)
|
||||
|
||||
add_library(pmsfdiskbackendplugin SHARED ${pmsfdiskbackendplugin_SRCS})
|
||||
|
||||
target_link_libraries(pmsfdiskbackendplugin kpmcore)
|
||||
|
||||
install(TARGETS pmsfdiskbackendplugin DESTINATION ${KDE_INSTALL_PLUGINDIR})
|
||||
kcoreaddons_desktop_to_json(pmsfdiskbackendplugin pmsfdiskbackendplugin.desktop)
|
||||
install(FILES pmsfdiskbackendplugin.desktop DESTINATION ${SERVICES_INSTALL_DIR})
|
|
@ -0,0 +1,17 @@
|
|||
[Desktop Entry]
|
||||
Encoding=UTF-8
|
||||
Name=KDE Partition Manager sfdisk Backend
|
||||
Comment=A KDE Partition Manager sfdisk backend.
|
||||
Type=Service
|
||||
ServiceTypes=PartitionManager/Plugin
|
||||
Icon=preferences-plugin
|
||||
|
||||
X-KDE-Library=pmsfdiskbackendplugin
|
||||
X-KDE-PluginInfo-Name=pmsfdiskbackendplugin
|
||||
X-KDE-PluginInfo-Author=Andrius Štikonas
|
||||
X-KDE-PluginInfo-Email=andrius@stikonas.eu
|
||||
X-KDE-PluginInfo-License=GPL
|
||||
X-KDE-PluginInfo-Category=BackendPlugin
|
||||
X-KDE-PluginInfo-EnabledByDefault=true
|
||||
X-KDE-PluginInfo-Version=1
|
||||
X-KDE-PluginInfo-Website=http://www.partitionmanager.org
|
|
@ -0,0 +1,395 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 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/sfdisk/sfdiskbackend.h"
|
||||
#include "plugins/sfdisk/sfdiskdevice.h"
|
||||
|
||||
#include "core/diskdevice.h"
|
||||
#include "core/lvmdevice.h"
|
||||
#include "core/partitiontable.h"
|
||||
#include "core/partitionalignment.h"
|
||||
|
||||
#include "fs/filesystemfactory.h"
|
||||
#include "fs/luks.h"
|
||||
|
||||
#include "util/globallog.h"
|
||||
#include "util/externalcommand.h"
|
||||
#include "util/helpers.h"
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QStorageInfo>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include <KLocalizedString>
|
||||
#include <KPluginFactory>
|
||||
|
||||
K_PLUGIN_FACTORY_WITH_JSON(SfdiskBackendFactory, "pmsfdiskbackendplugin.json", registerPlugin<SfdiskBackend>();)
|
||||
|
||||
SfdiskBackend::SfdiskBackend(QObject*, const QList<QVariant>&) :
|
||||
CoreBackend()
|
||||
{
|
||||
}
|
||||
|
||||
void SfdiskBackend::initFSSupport()
|
||||
{
|
||||
}
|
||||
|
||||
QList<Device*> SfdiskBackend::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.output().toUtf8());
|
||||
const 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;
|
||||
}
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
Device* SfdiskBackend::scanDevice(const QString& deviceNode)
|
||||
{
|
||||
ExternalCommand modelCommand(QStringLiteral("lsblk"),
|
||||
{ QStringLiteral("--nodeps"),
|
||||
QStringLiteral("--noheadings"),
|
||||
QStringLiteral("--output"), QStringLiteral("model"),
|
||||
deviceNode });
|
||||
ExternalCommand sizeCommand(QStringLiteral("blockdev"), { QStringLiteral("--getsize64"), deviceNode });
|
||||
ExternalCommand sizeCommand2(QStringLiteral("blockdev"), { QStringLiteral("--getss"), deviceNode });
|
||||
ExternalCommand jsonCommand(QStringLiteral("sfdisk"), { QStringLiteral("--json"), deviceNode } );
|
||||
|
||||
if ( modelCommand.run(-1) && modelCommand.exitCode() == 0
|
||||
&& sizeCommand.run(-1) && sizeCommand.exitCode() == 0
|
||||
&& sizeCommand2.run(-1) && sizeCommand2.exitCode() == 0
|
||||
&& jsonCommand.run(-1) )
|
||||
{
|
||||
QString modelName = modelCommand.output();
|
||||
modelName = modelName.left(modelName.length() - 1);
|
||||
qint64 deviceSize = sizeCommand.output().trimmed().toLongLong();
|
||||
|
||||
Log(Log::information) << xi18nc("@info:status", "Device found: %1", modelName);
|
||||
int logicalSectorSize = sizeCommand2.output().trimmed().toLongLong();
|
||||
DiskDevice* d = new DiskDevice(modelName, deviceNode, 255, 63, deviceSize / logicalSectorSize / 255 / 63, logicalSectorSize);
|
||||
|
||||
if (jsonCommand.exitCode() != 0)
|
||||
return d;
|
||||
|
||||
const QJsonObject jsonObject = QJsonDocument::fromJson(jsonCommand.output().toUtf8()).object();
|
||||
const QJsonObject partitionTable = jsonObject[QLatin1String("partitiontable")].toObject();
|
||||
|
||||
QString tableType = partitionTable[QLatin1String("label")].toString();
|
||||
const PartitionTable::TableType type = PartitionTable::nameToTableType(tableType);
|
||||
|
||||
qint64 firstUsableSector = 0, lastUsableSector = d->totalSectors();
|
||||
if (type == PartitionTable::gpt) {
|
||||
firstUsableSector = partitionTable[QLatin1String("firstlba")].toVariant().toLongLong();
|
||||
lastUsableSector = partitionTable[QLatin1String("lastlba")].toVariant().toLongLong();
|
||||
}
|
||||
if (lastUsableSector < firstUsableSector) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
setPartitionTableForDevice(*d, new PartitionTable(type, firstUsableSector, lastUsableSector));
|
||||
switch (type) {
|
||||
case PartitionTable::gpt:
|
||||
{
|
||||
// Read the maximum number of GPT partitions
|
||||
qint32 maxEntries;
|
||||
ExternalCommand ddCommand(QStringLiteral("dd"), { QStringLiteral("skip=1"), QStringLiteral("count=1"), QStringLiteral("if=") + deviceNode}, QProcess::SeparateChannels);
|
||||
if (ddCommand.run(-1) && ddCommand.exitCode() == 0 ) {
|
||||
QByteArray gptHeader = ddCommand.rawOutput();
|
||||
QByteArray gptMaxEntries = gptHeader.mid(80, 4);
|
||||
QDataStream stream(&gptMaxEntries, QIODevice::ReadOnly);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
stream >> maxEntries;
|
||||
}
|
||||
else
|
||||
maxEntries = 128;
|
||||
CoreBackend::setPartitionTableMaxPrimaries(*d->partitionTable(), maxEntries);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
scanDevicePartitions(*d, partitionTable[QLatin1String("partitions")].toArray());
|
||||
return d;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
void SfdiskBackend::scanDevicePartitions(Device& d, const QJsonArray& jsonPartitions)
|
||||
{
|
||||
Q_ASSERT(d.partitionTable());
|
||||
|
||||
QList<Partition*> partitions;
|
||||
for (const auto &partition : jsonPartitions) {
|
||||
const QJsonObject partitionObject = partition.toObject();
|
||||
const QString partitionNode = partitionObject[QLatin1String("node")].toString();
|
||||
const qint64 start = partitionObject[QLatin1String("start")].toVariant().toLongLong();
|
||||
const qint64 size = partitionObject[QLatin1String("size")].toVariant().toLongLong();
|
||||
const QString partitionType = partitionObject[QLatin1String("type")].toString();
|
||||
PartitionTable::Flag activeFlags = partitionObject[QLatin1String("bootable")].toBool() ? PartitionTable::FlagBoot : PartitionTable::FlagNone;
|
||||
|
||||
if (partitionType == QStringLiteral("C12A7328-F81F-11D2-BA4B-00A0C93EC93B"))
|
||||
activeFlags = PartitionTable::FlagEsp;
|
||||
else if (partitionType == QStringLiteral("21686148-6449-6E6F-744E-656564454649"))
|
||||
activeFlags = PartitionTable::FlagBiosGrub;
|
||||
|
||||
FileSystem::Type type = FileSystem::Unknown;
|
||||
type = detectFileSystem(partitionNode);
|
||||
PartitionRole::Roles r = PartitionRole::Primary;
|
||||
|
||||
if ( (d.partitionTable()->type() == PartitionTable::msdos || d.partitionTable()->type() == PartitionTable::msdos_sectorbased) && partitionType.toInt() == 5 ) {
|
||||
r = PartitionRole::Extended;
|
||||
type = FileSystem::Extended;
|
||||
}
|
||||
|
||||
// Find an extended partition this partition is in.
|
||||
PartitionNode* parent = d.partitionTable()->findPartitionBySector(start, PartitionRole(PartitionRole::Extended));
|
||||
|
||||
// None found, so it's a primary in the device's partition table.
|
||||
if (parent == nullptr)
|
||||
parent = d.partitionTable();
|
||||
else
|
||||
r = PartitionRole::Logical;
|
||||
|
||||
FileSystem* fs = FileSystemFactory::create(type, start, start + size - 1, d.logicalSize());
|
||||
fs->scan(partitionNode);
|
||||
|
||||
QString mountPoint;
|
||||
bool mounted;
|
||||
// sfdisk 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, start, start + size - 1, partitionNode, availableFlags(d.partitionTable()->type()), mountPoint, mounted, activeFlags);
|
||||
|
||||
if (!part->roles().has(PartitionRole::Luks))
|
||||
readSectorsUsed(d, *part, mountPoint);
|
||||
|
||||
if (fs->supportGetLabel() != FileSystem::cmdSupportNone)
|
||||
fs->setLabel(fs->readLabel(part->deviceNode()));
|
||||
|
||||
if (d.partitionTable()->type() == PartitionTable::TableType::gpt) {
|
||||
part->setLabel(partitionObject[QLatin1String("name")].toString());
|
||||
part->setUUID(partitionObject[QLatin1String("uuid")].toString());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/** Reads the sectors used in a FileSystem and stores the result in the Partition's FileSystem object.
|
||||
@param p the Partition the FileSystem is on
|
||||
@param mountPoint mount point of the partition in question
|
||||
*/
|
||||
void SfdiskBackend::readSectorsUsed(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());
|
||||
}
|
||||
|
||||
FileSystem::Type SfdiskBackend::detectFileSystem(const QString& partitionPath)
|
||||
{
|
||||
FileSystem::Type rval = FileSystem::Unknown;
|
||||
|
||||
ExternalCommand lsblkCommand(QStringLiteral("lsblk"), {
|
||||
QStringLiteral("--json"),
|
||||
QStringLiteral("--paths"),
|
||||
QStringLiteral("--output=name,fstype"),
|
||||
partitionPath });
|
||||
|
||||
if (lsblkCommand.run(-1) && lsblkCommand.exitCode() == 0) {
|
||||
const QJsonArray partitionArray = QJsonDocument::fromJson(lsblkCommand.output().toUtf8()).object()[QLatin1String("blockdevices")].toArray();
|
||||
|
||||
for (const auto &partition : partitionArray) {
|
||||
QJsonObject partitionObject = partition.toObject();
|
||||
QString node = partitionObject[QLatin1String("name")].toString();
|
||||
|
||||
QString s = partitionObject[QLatin1String("fstype")].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("vfat")) {
|
||||
ExternalCommand blkidCommand(QStringLiteral("blkid"), {
|
||||
QStringLiteral("--output=value"),
|
||||
QStringLiteral("--match-tag"),
|
||||
QStringLiteral("SEC_TYPE"),
|
||||
partitionPath });
|
||||
// blkid uses SEC_TYPE to distinguish between FAT16 and FAT32
|
||||
if (blkidCommand.run(-1) && blkidCommand.exitCode() == 0 && blkidCommand.output().trimmed() == 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() << "lsblk: unknown file system type " << s << " on " << partitionPath;
|
||||
}
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
PartitionTable::Flags SfdiskBackend::availableFlags(PartitionTable::TableType type)
|
||||
{
|
||||
PartitionTable::Flags flags;
|
||||
if (type == PartitionTable::gpt) {
|
||||
// These are not really flags but for now keep them for compatibility
|
||||
// We should implement changing partition type
|
||||
flags = PartitionTable::FlagBiosGrub |
|
||||
PartitionTable::FlagEsp;
|
||||
}
|
||||
else if (type == PartitionTable::msdos || type == PartitionTable::msdos_sectorbased)
|
||||
flags = PartitionTable::FlagBoot;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
CoreBackendDevice* SfdiskBackend::openDevice(const QString& deviceNode)
|
||||
{
|
||||
SfdiskDevice* device = new SfdiskDevice(deviceNode);
|
||||
|
||||
if (device == nullptr || !device->open()) {
|
||||
delete device;
|
||||
device = nullptr;
|
||||
}
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
CoreBackendDevice* SfdiskBackend::openDeviceExclusive(const QString& deviceNode)
|
||||
{
|
||||
SfdiskDevice* device = new SfdiskDevice(deviceNode);
|
||||
|
||||
if (device == nullptr || !device->openExclusive()) {
|
||||
delete device;
|
||||
device = nullptr;
|
||||
}
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
bool SfdiskBackend::closeDevice(CoreBackendDevice* coreDevice)
|
||||
{
|
||||
return coreDevice->close();
|
||||
}
|
||||
|
||||
#include "sfdiskbackend.moc"
|
|
@ -0,0 +1,62 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 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/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(SFDISKBACKEND__H)
|
||||
|
||||
#define SFDISKBACKEND__H
|
||||
|
||||
#include "backend/corebackend.h"
|
||||
#include "core/partition.h"
|
||||
#include "fs/filesystem.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QVariant>
|
||||
|
||||
class Device;
|
||||
class KPluginFactory;
|
||||
class QString;
|
||||
|
||||
/** Backend plugin for sfdisk
|
||||
|
||||
@author Andrius Štikonas <andrius@stikonas.eu>
|
||||
*/
|
||||
class SfdiskBackend : public CoreBackend
|
||||
{
|
||||
friend class KPluginFactory;
|
||||
|
||||
Q_DISABLE_COPY(SfdiskBackend)
|
||||
|
||||
private:
|
||||
SfdiskBackend(QObject* parent, const QList<QVariant>& args);
|
||||
|
||||
public:
|
||||
void initFSSupport() override;
|
||||
|
||||
QList<Device*> scanDevices(bool excludeReadOnly = false) override;
|
||||
CoreBackendDevice* openDevice(const QString& deviceNode) override;
|
||||
CoreBackendDevice* openDeviceExclusive(const QString& deviceNode) override;
|
||||
bool closeDevice(CoreBackendDevice* coreDevice) override;
|
||||
Device* scanDevice(const QString& deviceNode) override;
|
||||
FileSystem::Type detectFileSystem(const QString& partitionPath) override;
|
||||
|
||||
private:
|
||||
static void readSectorsUsed(const Device& d, Partition& p, const QString& mountPoint);
|
||||
void scanDevicePartitions(Device& d, const QJsonArray& jsonPartitions);
|
||||
static PartitionTable::Flags availableFlags(PartitionTable::TableType type);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,120 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 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/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "plugins/sfdisk/sfdiskdevice.h"
|
||||
#include "plugins/sfdisk/sfdiskpartitiontable.h"
|
||||
|
||||
#include "core/partitiontable.h"
|
||||
|
||||
#include "util/externalcommand.h"
|
||||
#include "util/report.h"
|
||||
|
||||
SfdiskDevice::SfdiskDevice(const QString& deviceNode) :
|
||||
CoreBackendDevice(deviceNode),
|
||||
m_deviceNode(deviceNode)
|
||||
{
|
||||
}
|
||||
|
||||
SfdiskDevice::~SfdiskDevice()
|
||||
{
|
||||
}
|
||||
|
||||
bool SfdiskDevice::open()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SfdiskDevice::openExclusive()
|
||||
{
|
||||
setExclusive(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SfdiskDevice::close()
|
||||
{
|
||||
if (isExclusive())
|
||||
setExclusive(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CoreBackendPartitionTable* SfdiskDevice::openPartitionTable()
|
||||
{
|
||||
CoreBackendPartitionTable* ptable = new SfdiskPartitionTable(m_deviceNode);
|
||||
|
||||
if (ptable == nullptr || !ptable->open()) {
|
||||
delete ptable;
|
||||
ptable = nullptr;
|
||||
}
|
||||
|
||||
return ptable;
|
||||
}
|
||||
|
||||
bool SfdiskDevice::createPartitionTable(Report& report, const PartitionTable& ptable)
|
||||
{
|
||||
QByteArray tableType;
|
||||
if (ptable.type() == PartitionTable::msdos || ptable.type() == PartitionTable::msdos_sectorbased)
|
||||
tableType = QByteArrayLiteral("dos");
|
||||
else
|
||||
tableType = ptable.typeName().toLatin1();
|
||||
|
||||
ExternalCommand createCommand(report, QStringLiteral("sfdisk"), { m_deviceNode } );
|
||||
if ( createCommand.start(-1) && createCommand.write(QByteArrayLiteral("label: ") + tableType +
|
||||
QByteArrayLiteral("\nwrite\n")) && createCommand.waitFor() ) {
|
||||
return createCommand.output().contains(QStringLiteral("Script header accepted."));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SfdiskDevice::readData(QByteArray& buffer, qint64 offset, qint64 size)
|
||||
{
|
||||
if (!isExclusive())
|
||||
return false;
|
||||
|
||||
ExternalCommand ddCommand(QStringLiteral("dd"), {
|
||||
QStringLiteral("skip=") + QString::number(offset),
|
||||
QStringLiteral("bs=") + QString::number(size),
|
||||
QStringLiteral("count=1"),
|
||||
QStringLiteral("iflag=skip_bytes"),
|
||||
QStringLiteral("if=") + m_deviceNode }, QProcess::SeparateChannels);
|
||||
if (ddCommand.run(-1) && ddCommand.exitCode() == 0) {
|
||||
buffer = ddCommand.rawOutput();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SfdiskDevice::writeData(QByteArray& buffer, qint64 offset)
|
||||
{
|
||||
if (!isExclusive())
|
||||
return false;
|
||||
|
||||
ExternalCommand ddCommand(QStringLiteral("dd"), {
|
||||
QStringLiteral("of=") + m_deviceNode,
|
||||
QStringLiteral("seek=") + QString::number(offset),
|
||||
QStringLiteral("bs=1M"),
|
||||
QStringLiteral("oflag=seek_bytes"),
|
||||
QStringLiteral("conv=fsync") }, QProcess::SeparateChannels);
|
||||
if ( ddCommand.start(-1) && ddCommand.write(buffer) == buffer.size() && ddCommand.waitFor() && ddCommand.exitCode() == 0 ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 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/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(SFDISKDEVICE__H)
|
||||
|
||||
#define SFDISKDEVICE__H
|
||||
|
||||
#include "backend/corebackenddevice.h"
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
class Partition;
|
||||
class PartitionTable;
|
||||
class Report;
|
||||
class CoreBackendPartitionTable;
|
||||
|
||||
class SfdiskDevice : public CoreBackendDevice
|
||||
{
|
||||
Q_DISABLE_COPY(SfdiskDevice);
|
||||
|
||||
public:
|
||||
SfdiskDevice(const QString& deviceNode);
|
||||
~SfdiskDevice();
|
||||
|
||||
public:
|
||||
bool open() override;
|
||||
bool openExclusive() override;
|
||||
bool close() override;
|
||||
|
||||
CoreBackendPartitionTable* openPartitionTable() override;
|
||||
|
||||
bool createPartitionTable(Report& report, const PartitionTable& ptable) override;
|
||||
|
||||
bool readData(QByteArray& buffer, qint64 offset, qint64 size) override;
|
||||
bool writeData(QByteArray& buffer, qint64 offset) override;
|
||||
|
||||
private:
|
||||
QString m_deviceNode;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,35 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 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/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "plugins/sfdisk/sfdiskpartition.h"
|
||||
#include "plugins/sfdisk/sfdiskbackend.h"
|
||||
|
||||
#include "util/report.h"
|
||||
|
||||
SfdiskPartition::SfdiskPartition() :
|
||||
CoreBackendPartition()
|
||||
{
|
||||
}
|
||||
|
||||
bool SfdiskPartition::setFlag(Report& report, PartitionTable::Flag partitionManagerFlag, bool state)
|
||||
{
|
||||
Q_UNUSED(report);
|
||||
Q_UNUSED(partitionManagerFlag);
|
||||
Q_UNUSED(state);
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 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/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(SFDISKPARTITION__H)
|
||||
|
||||
#define SFDISKPARTITION__H
|
||||
|
||||
#include "backend/corebackendpartition.h"
|
||||
|
||||
#include "core/partitiontable.h"
|
||||
|
||||
class Report;
|
||||
|
||||
class SfdiskPartition : public CoreBackendPartition
|
||||
{
|
||||
Q_DISABLE_COPY(SfdiskPartition);
|
||||
|
||||
public:
|
||||
SfdiskPartition();
|
||||
|
||||
public:
|
||||
bool setFlag(Report& report, PartitionTable::Flag flag, bool state) override;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,178 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 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/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "plugins/sfdisk/sfdiskpartitiontable.h"
|
||||
#include "plugins/sfdisk/sfdiskpartition.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 <unistd.h>
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
SfdiskPartitionTable::SfdiskPartitionTable(const QString& deviceNode) :
|
||||
CoreBackendPartitionTable(),
|
||||
m_deviceNode(deviceNode)
|
||||
{
|
||||
}
|
||||
|
||||
SfdiskPartitionTable::~SfdiskPartitionTable()
|
||||
{
|
||||
}
|
||||
|
||||
bool SfdiskPartitionTable::open()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SfdiskPartitionTable::commit(quint32 timeout)
|
||||
{
|
||||
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 true;
|
||||
}
|
||||
|
||||
CoreBackendPartition* SfdiskPartitionTable::getExtendedPartition()
|
||||
{
|
||||
return new SfdiskPartition();
|
||||
}
|
||||
|
||||
CoreBackendPartition* SfdiskPartitionTable::getPartitionBySector(qint64 sector)
|
||||
{
|
||||
Q_UNUSED(sector);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QString SfdiskPartitionTable::createPartition(Report& report, const Partition& partition)
|
||||
{
|
||||
if ( !(partition.roles().has(PartitionRole::Extended) || partition.roles().has(PartitionRole::Logical) || partition.roles().has(PartitionRole::Primary) ) ) {
|
||||
report.line() << xi18nc("@info:progress", "Unknown partition role for new partition <filename>%1</filename> (roles: %2)", partition.deviceNode(), partition.roles().toString());
|
||||
return QString();
|
||||
}
|
||||
|
||||
QByteArray type = QByteArray(); // FIXME add map between fs types and default partition types
|
||||
if (partition.roles().has(PartitionRole::Extended))
|
||||
type = QByteArrayLiteral(" type=5");
|
||||
|
||||
// NOTE: at least on GPT partition types "are" partition flags
|
||||
ExternalCommand createCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--force"), QStringLiteral("--append"), partition.devicePath() } );
|
||||
if ( createCommand.start(-1) && createCommand.write(QByteArrayLiteral("start=") + QByteArray::number(partition.firstSector()) +
|
||||
type +
|
||||
QByteArrayLiteral(" size=") + QByteArray::number(partition.length()) + QByteArrayLiteral("\nwrite\n")) && createCommand.waitFor() ) {
|
||||
QRegularExpression re(QStringLiteral("Created a new partition (\\d)"));
|
||||
QRegularExpressionMatch rem = re.match(createCommand.output());
|
||||
if (rem.hasMatch())
|
||||
return partition.devicePath() + rem.captured(1);
|
||||
}
|
||||
|
||||
report.line() << xi18nc("@info:progress", "Failed to add partition <filename>%1</filename> to device <filename>%2</filename>.", partition.deviceNode(), m_deviceNode);
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool SfdiskPartitionTable::deletePartition(Report& report, const Partition& partition)
|
||||
{
|
||||
ExternalCommand deleteCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--force"), QStringLiteral("--delete"), partition.devicePath(), QString::number(partition.number()) } );
|
||||
if (deleteCommand.run(-1) && deleteCommand.exitCode() == 0)
|
||||
return true;
|
||||
|
||||
report.line() << xi18nc("@info:progress", "Could not delete partition <filename>%1</filename>.", partition.devicePath());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SfdiskPartitionTable::updateGeometry(Report& report, const Partition& partition, qint64 sectorStart, qint64 sectorEnd)
|
||||
{
|
||||
ExternalCommand sfdiskCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--force"), partition.devicePath(), QStringLiteral("-N"), QString::number(partition.number()) } );
|
||||
if ( sfdiskCommand.start(-1) && sfdiskCommand.write(QByteArrayLiteral("start=") + QByteArray::number(sectorStart) +
|
||||
QByteArrayLiteral(" size=") + QByteArray::number(sectorEnd - sectorStart + 1) +
|
||||
QByteArrayLiteral("\nY\n"))
|
||||
&& sfdiskCommand.waitFor() && sfdiskCommand.exitCode() == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
report.line() << xi18nc("@info:progress", "Could not set geometry for partition <filename>%1</filename> while trying to resize/move it.", partition.devicePath());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SfdiskPartitionTable::clobberFileSystem(Report& report, const Partition& partition)
|
||||
{
|
||||
ExternalCommand wipeCommand(report, QStringLiteral("wipefs"), { QStringLiteral("--all"), partition.partitionPath() } );
|
||||
if (wipeCommand.run(-1) && wipeCommand.exitCode() == 0)
|
||||
return true;
|
||||
|
||||
report.line() << xi18nc("@info:progress", "Failed to erase filesystem signature on partition <filename>%1</filename>.", partition.partitionPath());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SfdiskPartitionTable::resizeFileSystem(Report& report, const Partition& partition, qint64 newLength)
|
||||
{
|
||||
// sfdisk does not have any partition resize capabilities
|
||||
Q_UNUSED(report);
|
||||
Q_UNUSED(partition);
|
||||
Q_UNUSED(newLength);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
FileSystem::Type SfdiskPartitionTable::detectFileSystemBySector(Report& report, const Device& device, qint64 sector)
|
||||
{
|
||||
FileSystem::Type type = FileSystem::Unknown;
|
||||
|
||||
ExternalCommand jsonCommand(QStringLiteral("sfdisk"), { QStringLiteral("--json"), device.deviceNode() } );
|
||||
if (jsonCommand.run(-1) && jsonCommand.exitCode() == 0) {
|
||||
const QJsonArray partitionTable = QJsonDocument::fromJson(jsonCommand.output().toUtf8()).object()[QLatin1String("partitiontable")].toObject()[QLatin1String("partitions")].toArray();
|
||||
for (const auto &partition : partitionTable) {
|
||||
const QJsonObject partitionObject = partition.toObject();
|
||||
const qint64 start = partitionObject[QLatin1String("start")].toVariant().toLongLong();
|
||||
if (start == sector) {
|
||||
const QString deviceNode = partitionObject[QLatin1String("node")].toString();
|
||||
type = CoreBackendManager::self()->backend()->detectFileSystem(deviceNode);
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
report.line() << xi18nc("@info:progress", "Could not determine file system of partition at sector %1 on device <filename>%2</filename>.", sector, device.deviceNode());
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
bool SfdiskPartitionTable::setPartitionSystemType(Report& report, const Partition& partition)
|
||||
{
|
||||
Q_UNUSED(report);
|
||||
Q_UNUSED(partition);
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 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/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(SFDISKPARTITIONTABLE__H)
|
||||
|
||||
#define SFDISKPARTITIONTABLE__H
|
||||
|
||||
#include "backend/corebackendpartitiontable.h"
|
||||
|
||||
#include "fs/filesystem.h"
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
class CoreBackendPartition;
|
||||
class Report;
|
||||
class Partition;
|
||||
|
||||
class SfdiskPartitionTable : public CoreBackendPartitionTable
|
||||
{
|
||||
public:
|
||||
SfdiskPartitionTable(const QString& deviceNode);
|
||||
~SfdiskPartitionTable();
|
||||
|
||||
public:
|
||||
bool open() override;
|
||||
|
||||
bool commit(quint32 timeout = 10) override;
|
||||
|
||||
CoreBackendPartition* getExtendedPartition() override;
|
||||
CoreBackendPartition* getPartitionBySector(qint64 sector) override;
|
||||
|
||||
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;
|
||||
|
||||
private:
|
||||
QString m_deviceNode;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue