From b97fd0eeaacb6386c4aa769b07db214ce5642bbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Fri, 2 Oct 2020 17:35:23 +0100 Subject: [PATCH 01/11] rename jsonCommand variable to sfdiskJsonCommand. --- src/plugins/sfdisk/sfdiskbackend.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/sfdisk/sfdiskbackend.cpp b/src/plugins/sfdisk/sfdiskbackend.cpp index 3240c95..9c7961e 100644 --- a/src/plugins/sfdisk/sfdiskbackend.cpp +++ b/src/plugins/sfdisk/sfdiskbackend.cpp @@ -187,11 +187,11 @@ Device* SfdiskBackend::scanDevice(const QString& deviceNode) deviceNode }); ExternalCommand sizeCommand(QStringLiteral("blockdev"), { QStringLiteral("--getsize64"), deviceNode }); ExternalCommand sizeCommand2(QStringLiteral("blockdev"), { QStringLiteral("--getss"), deviceNode }); - ExternalCommand jsonCommand(QStringLiteral("sfdisk"), { QStringLiteral("--json"), deviceNode }, QProcess::ProcessChannelMode::SeparateChannels ); + ExternalCommand sfdiskJsonCommand(QStringLiteral("sfdisk"), { QStringLiteral("--json"), deviceNode }, QProcess::ProcessChannelMode::SeparateChannels ); if ( sizeCommand.run(-1) && sizeCommand.exitCode() == 0 && sizeCommand2.run(-1) && sizeCommand2.exitCode() == 0 - && jsonCommand.run(-1) ) + && sfdiskJsonCommand.run(-1) ) { Device* d = nullptr; qint64 deviceSize = sizeCommand.output().trimmed().toLongLong(); @@ -251,10 +251,10 @@ Device* SfdiskBackend::scanDevice(const QString& deviceNode) if ( d ) { - if (jsonCommand.exitCode() != 0) + if (sfdiskJsonCommand.exitCode() != 0) return d; - auto s = jsonCommand.rawOutput(); + auto s = sfdiskJsonCommand.rawOutput(); fixInvalidJsonFromSFDisk(s); const QJsonObject jsonObject = QJsonDocument::fromJson(s).object(); From ba05f997204a24cdf5a975fd602aab73b26b0268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Fri, 2 Oct 2020 22:36:19 +0100 Subject: [PATCH 02/11] Split detectFileSystem function in sfdiskbackend into two smaller functions. --- src/plugins/sfdisk/sfdiskbackend.cpp | 103 ++++++++++++++------------- src/plugins/sfdisk/sfdiskbackend.h | 1 + 2 files changed, 56 insertions(+), 48 deletions(-) diff --git a/src/plugins/sfdisk/sfdiskbackend.cpp b/src/plugins/sfdisk/sfdiskbackend.cpp index 9c7961e..96bd299 100644 --- a/src/plugins/sfdisk/sfdiskbackend.cpp +++ b/src/plugins/sfdisk/sfdiskbackend.cpp @@ -307,8 +307,7 @@ void SfdiskBackend::scanDevicePartitions(Device& d, const QJsonArray& jsonPartit else if (partitionType == QStringLiteral("21686148-6449-6E6F-744E-656564454649")) activeFlags |= PartitionTable::Flag::BiosGrub; - FileSystem::Type type = FileSystem::Type::Unknown; - type = detectFileSystem(partitionNode); + FileSystem::Type type = detectFileSystem(partitionNode); PartitionRole::Roles r = PartitionRole::Primary; if ( (d.partitionTable()->type() == PartitionTable::msdos || d.partitionTable()->type() == PartitionTable::msdos_sectorbased) && @@ -471,60 +470,68 @@ FileSystem::Type SfdiskBackend::detectFileSystem(const QString& partitionPath) QRegularExpressionMatch reFileSystemType = re.match(udevCommand.output()); QRegularExpressionMatch reFileSystemVersion = re2.match(udevCommand.output()); - QString s; + QString name = {}; if (reFileSystemType.hasMatch()) { - s = reFileSystemType.captured(1); + name = reFileSystemType.captured(1); } - QString version; + QString version = {}; if (reFileSystemVersion.hasMatch()) { version = reFileSystemVersion.captured(1); } - - if (s == QStringLiteral("ext2")) rval = FileSystem::Type::Ext2; - else if (s == QStringLiteral("ext3")) rval = FileSystem::Type::Ext3; - else if (s.startsWith(QStringLiteral("ext4"))) rval = FileSystem::Type::Ext4; - else if (s == QStringLiteral("swap")) rval = FileSystem::Type::LinuxSwap; - else if (s == QStringLiteral("ntfs")) rval = FileSystem::Type::Ntfs; - else if (s == QStringLiteral("reiserfs")) rval = FileSystem::Type::ReiserFS; - else if (s == QStringLiteral("reiser4")) rval = FileSystem::Type::Reiser4; - else if (s == QStringLiteral("xfs")) rval = FileSystem::Type::Xfs; - else if (s == QStringLiteral("jfs")) rval = FileSystem::Type::Jfs; - else if (s == QStringLiteral("hfs")) rval = FileSystem::Type::Hfs; - else if (s == QStringLiteral("hfsplus")) rval = FileSystem::Type::HfsPlus; - else if (s == QStringLiteral("ufs")) rval = FileSystem::Type::Ufs; - else if (s == QStringLiteral("vfat")) { - if (version == QStringLiteral("FAT32")) - rval = FileSystem::Type::Fat32; - else if (version == QStringLiteral("FAT16")) - rval = FileSystem::Type::Fat16; - else if (version == QStringLiteral("FAT12")) - rval = FileSystem::Type::Fat12; + rval = fileSystemNameToType(name, version); + if (rval == FileSystem::Type::Unknown) { + qWarning() << "unknown file system type " << name << " on " << partitionPath; } - else if (s == QStringLiteral("btrfs")) rval = FileSystem::Type::Btrfs; - else if (s == QStringLiteral("ocfs2")) rval = FileSystem::Type::Ocfs2; - else if (s == QStringLiteral("zfs_member")) rval = FileSystem::Type::Zfs; - else if (s == QStringLiteral("hpfs")) rval = FileSystem::Type::Hpfs; - else if (s == QStringLiteral("crypto_LUKS")) { - if (version == QStringLiteral("1")) - rval = FileSystem::Type::Luks; - else if (version == QStringLiteral("2")) { - rval = FileSystem::Type::Luks2; - } - } - else if (s == QStringLiteral("exfat")) rval = FileSystem::Type::Exfat; - else if (s == QStringLiteral("nilfs2")) rval = FileSystem::Type::Nilfs2; - else if (s == QStringLiteral("LVM2_member")) rval = FileSystem::Type::Lvm2_PV; - else if (s == QStringLiteral("f2fs")) rval = FileSystem::Type::F2fs; - else if (s == QStringLiteral("udf")) rval = FileSystem::Type::Udf; - else if (s == QStringLiteral("iso9660")) rval = FileSystem::Type::Iso9660; - else if (s == QStringLiteral("linux_raid_member")) rval = FileSystem::Type::LinuxRaidMember; - else if (s == QStringLiteral("BitLocker")) rval = FileSystem::Type::BitLocker; - else if (s == QStringLiteral("apfs")) rval = FileSystem::Type::Apfs; - else if (s == QStringLiteral("minix")) rval = FileSystem::Type::Minix; - else - qWarning() << "unknown file system type " << s << " on " << partitionPath; } + return rval; +} + +FileSystem::Type SfdiskBackend::fileSystemNameToType(const QString& name, const QString& version) +{ + FileSystem::Type rval = FileSystem::Type::Unknown; + + if (name == QStringLiteral("ext2")) rval = FileSystem::Type::Ext2; + else if (name == QStringLiteral("ext3")) rval = FileSystem::Type::Ext3; + else if (name.startsWith(QStringLiteral("ext4"))) rval = FileSystem::Type::Ext4; + else if (name == QStringLiteral("swap")) rval = FileSystem::Type::LinuxSwap; + else if (name == QStringLiteral("ntfs")) rval = FileSystem::Type::Ntfs; + else if (name == QStringLiteral("reiserfs")) rval = FileSystem::Type::ReiserFS; + else if (name == QStringLiteral("reiser4")) rval = FileSystem::Type::Reiser4; + else if (name == QStringLiteral("xfs")) rval = FileSystem::Type::Xfs; + else if (name == QStringLiteral("jfs")) rval = FileSystem::Type::Jfs; + else if (name == QStringLiteral("hfs")) rval = FileSystem::Type::Hfs; + else if (name == QStringLiteral("hfsplus")) rval = FileSystem::Type::HfsPlus; + else if (name == QStringLiteral("ufs")) rval = FileSystem::Type::Ufs; + else if (name == QStringLiteral("vfat")) { + if (version == QStringLiteral("FAT32")) + rval = FileSystem::Type::Fat32; + else if (version == QStringLiteral("FAT16")) + rval = FileSystem::Type::Fat16; + else if (version == QStringLiteral("FAT12")) + rval = FileSystem::Type::Fat12; + } + else if (name == QStringLiteral("btrfs")) rval = FileSystem::Type::Btrfs; + else if (name == QStringLiteral("ocfs2")) rval = FileSystem::Type::Ocfs2; + else if (name == QStringLiteral("zfs_member")) rval = FileSystem::Type::Zfs; + else if (name == QStringLiteral("hpfs")) rval = FileSystem::Type::Hpfs; + else if (name == QStringLiteral("crypto_LUKS")) { + if (version == QStringLiteral("1")) + rval = FileSystem::Type::Luks; + else if (version == QStringLiteral("2")) { + rval = FileSystem::Type::Luks2; + } + } + else if (name == QStringLiteral("exfat")) rval = FileSystem::Type::Exfat; + else if (name == QStringLiteral("nilfs2")) rval = FileSystem::Type::Nilfs2; + else if (name == QStringLiteral("LVM2_member")) rval = FileSystem::Type::Lvm2_PV; + else if (name == QStringLiteral("f2fs")) rval = FileSystem::Type::F2fs; + else if (name == QStringLiteral("udf")) rval = FileSystem::Type::Udf; + else if (name == QStringLiteral("iso9660")) rval = FileSystem::Type::Iso9660; + else if (name == QStringLiteral("linux_raid_member")) rval = FileSystem::Type::LinuxRaidMember; + else if (name == QStringLiteral("BitLocker")) rval = FileSystem::Type::BitLocker; + else if (name == QStringLiteral("apfs")) rval = FileSystem::Type::Apfs; + else if (name == QStringLiteral("minix")) rval = FileSystem::Type::Minix; return rval; } diff --git a/src/plugins/sfdisk/sfdiskbackend.h b/src/plugins/sfdisk/sfdiskbackend.h index 8621a7f..e6fe88a 100644 --- a/src/plugins/sfdisk/sfdiskbackend.h +++ b/src/plugins/sfdisk/sfdiskbackend.h @@ -52,6 +52,7 @@ private: void setupPartitionInfo(const Device& d, Partition* partition, const QJsonObject& partitionObject, const QString mountPoint); bool updateDevicePartitionTable(Device& d, const QJsonObject& jsonPartitionTable); static PartitionTable::Flags availableFlags(PartitionTable::TableType type); + static FileSystem::Type fileSystemNameToType(const QString& fileSystemName, const QString& version); }; #endif From ae05c031b76813724c17abdf127d7577fb9e07af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Fri, 2 Oct 2020 23:00:40 +0100 Subject: [PATCH 03/11] Further splitting of detectFileSystem function. --- src/plugins/sfdisk/sfdiskbackend.cpp | 31 ++++++++++++++++++++-------- src/plugins/sfdisk/sfdiskbackend.h | 2 ++ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/plugins/sfdisk/sfdiskbackend.cpp b/src/plugins/sfdisk/sfdiskbackend.cpp index 96bd299..842d13f 100644 --- a/src/plugins/sfdisk/sfdiskbackend.cpp +++ b/src/plugins/sfdisk/sfdiskbackend.cpp @@ -464,13 +464,29 @@ FileSystem::Type SfdiskBackend::detectFileSystem(const QString& partitionPath) QStringLiteral("--query=property"), partitionPath }); - if (udevCommand.run(-1) && udevCommand.exitCode() == 0) { - QRegularExpression re(QStringLiteral("ID_FS_TYPE=(\\w+)")); - QRegularExpression re2(QStringLiteral("ID_FS_VERSION=(\\w+)")); - QRegularExpressionMatch reFileSystemType = re.match(udevCommand.output()); - QRegularExpressionMatch reFileSystemVersion = re2.match(udevCommand.output()); + QString udevTypeRegExp = QStringLiteral("ID_FS_TYPE=(\\w+)"); + QString udevVersionRegExp = QStringLiteral("ID_FS_VERSION=(\\w+)"); + + QString name = {}; + + rval = runDetectFileSystemCommand(udevCommand, udevTypeRegExp, udevVersionRegExp, name); + + if (rval == FileSystem::Type::Unknown) { + qWarning() << "unknown file system type " << name << " on " << partitionPath; + } + return rval; +} + +FileSystem::Type SfdiskBackend::runDetectFileSystemCommand(ExternalCommand& command, QString& typeRegExp, QString& versionRegExp, QString& name) +{ + FileSystem::Type rval = FileSystem::Type::Unknown; + + if (command.run(-1) && command.exitCode() == 0) { + QRegularExpression re(typeRegExp); + QRegularExpression re2(versionRegExp); + QRegularExpressionMatch reFileSystemType = re.match(command.output()); + QRegularExpressionMatch reFileSystemVersion = re2.match(command.output()); - QString name = {}; if (reFileSystemType.hasMatch()) { name = reFileSystemType.captured(1); } @@ -480,9 +496,6 @@ FileSystem::Type SfdiskBackend::detectFileSystem(const QString& partitionPath) version = reFileSystemVersion.captured(1); } rval = fileSystemNameToType(name, version); - if (rval == FileSystem::Type::Unknown) { - qWarning() << "unknown file system type " << name << " on " << partitionPath; - } } return rval; } diff --git a/src/plugins/sfdisk/sfdiskbackend.h b/src/plugins/sfdisk/sfdiskbackend.h index e6fe88a..7da59d3 100644 --- a/src/plugins/sfdisk/sfdiskbackend.h +++ b/src/plugins/sfdisk/sfdiskbackend.h @@ -16,6 +16,7 @@ #include class Device; +class ExternalCommand; class Partition; class KPluginFactory; class QString; @@ -53,6 +54,7 @@ private: bool updateDevicePartitionTable(Device& d, const QJsonObject& jsonPartitionTable); static PartitionTable::Flags availableFlags(PartitionTable::TableType type); static FileSystem::Type fileSystemNameToType(const QString& fileSystemName, const QString& version); + static FileSystem::Type runDetectFileSystemCommand(ExternalCommand& command, QString& typeRegExp, QString& versionRegExp, QString& name); }; #endif From 30bd4d62a9a0effbc8fca7a9f7bab12cda104c4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Fri, 2 Oct 2020 23:12:33 +0100 Subject: [PATCH 04/11] Add blkid fallback for file system detection if udev method fails. --- src/plugins/sfdisk/sfdiskbackend.cpp | 14 +++++++++++--- src/util/externalcommand_whitelist.h | 3 ++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/plugins/sfdisk/sfdiskbackend.cpp b/src/plugins/sfdisk/sfdiskbackend.cpp index 842d13f..3a859fd 100644 --- a/src/plugins/sfdisk/sfdiskbackend.cpp +++ b/src/plugins/sfdisk/sfdiskbackend.cpp @@ -464,12 +464,20 @@ FileSystem::Type SfdiskBackend::detectFileSystem(const QString& partitionPath) QStringLiteral("--query=property"), partitionPath }); - QString udevTypeRegExp = QStringLiteral("ID_FS_TYPE=(\\w+)"); - QString udevVersionRegExp = QStringLiteral("ID_FS_VERSION=(\\w+)"); + QString typeRegExp = QStringLiteral("ID_FS_TYPE=(\\w+)"); + QString versionRegExp = QStringLiteral("ID_FS_VERSION=(\\w+)"); QString name = {}; - rval = runDetectFileSystemCommand(udevCommand, udevTypeRegExp, udevVersionRegExp, name); + rval = runDetectFileSystemCommand(udevCommand, typeRegExp, versionRegExp, name); + + // Fallback to blkid. blkid has slightly worse detection but it works on whole block device filesystems. + if (rval == FileSystem::Type::Unknown) { + ExternalCommand blkidCommand(QStringLiteral("blkid"), { partitionPath }); + typeRegExp = QStringLiteral("TYPE=\"(\\w+)\""); + versionRegExp = QStringLiteral("SEC_TYPE=\"(\\w+)\""); + rval = runDetectFileSystemCommand(blkidCommand, typeRegExp, versionRegExp, name); + } if (rval == FileSystem::Type::Unknown) { qWarning() << "unknown file system type " << name << " on " << partitionPath; diff --git a/src/util/externalcommand_whitelist.h b/src/util/externalcommand_whitelist.h index 7ebae8d..4c52ced 100644 --- a/src/util/externalcommand_whitelist.h +++ b/src/util/externalcommand_whitelist.h @@ -1,5 +1,5 @@ /* - SPDX-FileCopyrightText: 2018-2019 Andrius Štikonas + SPDX-FileCopyrightText: 2018-2020 Andrius Štikonas SPDX-FileCopyrightText: 2019 Shubham Jangra SPDX-License-Identifier: GPL-3.0-or-later @@ -15,6 +15,7 @@ QStringLiteral("udevadm"), //Core programs QStringLiteral("blockdev"), +QStringLiteral("blkid"), QStringLiteral("partx"), QStringLiteral("sfdisk"), QStringLiteral("wipefs"), From 26b352180b4f4f563dc7c54a52f5ac4463593860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Sat, 3 Oct 2020 12:38:40 +0100 Subject: [PATCH 05/11] Reword a comment. --- src/plugins/sfdisk/sfdiskbackend.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/sfdisk/sfdiskbackend.cpp b/src/plugins/sfdisk/sfdiskbackend.cpp index 3a859fd..1e05985 100644 --- a/src/plugins/sfdisk/sfdiskbackend.cpp +++ b/src/plugins/sfdisk/sfdiskbackend.cpp @@ -471,7 +471,7 @@ FileSystem::Type SfdiskBackend::detectFileSystem(const QString& partitionPath) rval = runDetectFileSystemCommand(udevCommand, typeRegExp, versionRegExp, name); - // Fallback to blkid. blkid has slightly worse detection but it works on whole block device filesystems. + // Fallback to blkid which has slightly worse detection but it works on whole block device filesystems. if (rval == FileSystem::Type::Unknown) { ExternalCommand blkidCommand(QStringLiteral("blkid"), { partitionPath }); typeRegExp = QStringLiteral("TYPE=\"(\\w+)\""); From 81f8939cb16a0955ce1f3c89d99d1ebda5eacbfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Sat, 3 Oct 2020 12:39:26 +0100 Subject: [PATCH 06/11] Add a new type of partition table "none". This would be useful for block devices without partition table. --- src/core/partitiontable.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/partitiontable.h b/src/core/partitiontable.h index e94a015..19bc21e 100644 --- a/src/core/partitiontable.h +++ b/src/core/partitiontable.h @@ -57,7 +57,8 @@ public: pc98, amiga, sun, - vmd /* Volume Manager Device */ + vmd, /* Volume Manager Device */ + none, /* Single FileSystem devices */ }; /** Partition flags */ From de346177b5be649c3a87cfcf7d3eaee7cde6e490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Sat, 3 Oct 2020 12:41:18 +0100 Subject: [PATCH 07/11] Do not allow moving partitions without partition table. --- src/core/partition.cpp | 9 +++++++++ src/core/partition.h | 4 +++- src/ops/resizeoperation.cpp | 14 +++++++++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/core/partition.cpp b/src/core/partition.cpp index 87d308d..61c59f4 100644 --- a/src/core/partition.cpp +++ b/src/core/partition.cpp @@ -261,6 +261,15 @@ bool Partition::hasChildren() const return false; } +/** @return returns the Partition Table which contains this Partition */ +const PartitionTable* Partition::partitionTable() const { + const PartitionNode *p = this; + while (p->parent() != nullptr) { + p = p->parent(); + } + return static_cast(p); +} + /** Sets an extended Partition to mounted if any of its children are mounted */ void Partition::checkChildrenMounted() { diff --git a/src/core/partition.h b/src/core/partition.h index 2074261..e25678b 100644 --- a/src/core/partition.h +++ b/src/core/partition.h @@ -1,7 +1,7 @@ /* SPDX-FileCopyrightText: 2008-2010 Volker Lanz SPDX-FileCopyrightText: 2008 Laurent Montel - SPDX-FileCopyrightText: 2013-2019 Andrius Štikonas + SPDX-FileCopyrightText: 2013-2020 Andrius Štikonas SPDX-FileCopyrightText: 2015 Chris Campbell SPDX-FileCopyrightText: 2015 Teo Mrnjavac SPDX-FileCopyrightText: 2020 Gaël PORTAY @@ -96,6 +96,8 @@ public: return false; /**< @return always false for Partition */ } + const PartitionTable* partitionTable() const; + PartitionNode* parent() override { return m_Parent; /**< @return the Partition's parent PartitionNode */ } diff --git a/src/ops/resizeoperation.cpp b/src/ops/resizeoperation.cpp index 0aedb66..5e99c40 100644 --- a/src/ops/resizeoperation.cpp +++ b/src/ops/resizeoperation.cpp @@ -1,6 +1,6 @@ /* SPDX-FileCopyrightText: 2008-2012 Volker Lanz - SPDX-FileCopyrightText: 2012-2018 Andrius Štikonas + SPDX-FileCopyrightText: 2012-2020 Andrius Štikonas SPDX-FileCopyrightText: 2015 Teo Mrnjavac SPDX-FileCopyrightText: 2016 Chantara Tith SPDX-FileCopyrightText: 2018 Caio Jordão Carvalho @@ -326,6 +326,10 @@ bool ResizeOperation::canGrow(const Partition* p) if (p == nullptr) return false; + // Whole block device filesystems cannot be resized + if (p->partitionTable()->type() == PartitionTable::TableType::none) + return false; + if (isLVMPVinNewlyVG(p)) return false; @@ -348,6 +352,10 @@ bool ResizeOperation::canShrink(const Partition* p) if (p == nullptr) return false; + // Whole block device filesystems cannot be resized + if (p->partitionTable()->type() == PartitionTable::TableType::none) + return false; + if (isLVMPVinNewlyVG(p)) return false; @@ -373,6 +381,10 @@ bool ResizeOperation::canMove(const Partition* p) if (p == nullptr) return false; + // Whole block device filesystems cannot be moved + if (p->partitionTable()->type() == PartitionTable::TableType::none) + return false; + if (isLVMPVinNewlyVG(p)) return false; From 779cc6cfb7e514ad196ed89f4d1d49105b3882db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Sat, 3 Oct 2020 13:25:05 +0100 Subject: [PATCH 08/11] Split scanPartition function from scanDevicePartitions. --- src/plugins/sfdisk/sfdiskbackend.cpp | 118 ++++++++++++++------------- src/plugins/sfdisk/sfdiskbackend.h | 3 +- 2 files changed, 65 insertions(+), 56 deletions(-) diff --git a/src/plugins/sfdisk/sfdiskbackend.cpp b/src/plugins/sfdisk/sfdiskbackend.cpp index 1e05985..55fa117 100644 --- a/src/plugins/sfdisk/sfdiskbackend.cpp +++ b/src/plugins/sfdisk/sfdiskbackend.cpp @@ -300,61 +300,13 @@ void SfdiskBackend::scanDevicePartitions(Device& d, const QJsonArray& jsonPartit const qint64 start = partitionObject[QLatin1String("start")].toVariant().toLongLong(); const qint64 size = partitionObject[QLatin1String("size")].toVariant().toLongLong(); const QString partitionType = partitionObject[QLatin1String("type")].toString(); - PartitionTable::Flags activeFlags = partitionObject[QLatin1String("bootable")].toBool() ? PartitionTable::Flag::Boot : PartitionTable::Flag::None; + const bool bootable = partitionObject[QLatin1String("bootable")].toBool(); + const auto lastSector = start + size - 1; - if (partitionType == QStringLiteral("C12A7328-F81F-11D2-BA4B-00A0C93EC93B")) - activeFlags |= PartitionTable::Flag::Boot; - else if (partitionType == QStringLiteral("21686148-6449-6E6F-744E-656564454649")) - activeFlags |= PartitionTable::Flag::BiosGrub; + Partition* part = scanPartition(d, partitionNode, start, lastSector, partitionType, bootable); - FileSystem::Type type = detectFileSystem(partitionNode); - PartitionRole::Roles r = PartitionRole::Primary; + setupPartitionInfo(d, part, partitionObject); - if ( (d.partitionTable()->type() == PartitionTable::msdos || d.partitionTable()->type() == PartitionTable::msdos_sectorbased) && - ( partitionType == QStringLiteral("5") || partitionType == QStringLiteral("f") ) ) { - r = PartitionRole::Extended; - type = FileSystem::Type::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; - - auto lastSector = start + size - 1; - FileSystem* fs = FileSystemFactory::create(type, start, lastSector, d.logicalSize()); - fs->scan(partitionNode); - - QString mountPoint; - bool mounted; - // sfdisk does not handle LUKS partitions - if (fs->type() == FileSystem::Type::Luks || fs->type() == FileSystem::Type::Luks2) { - r |= PartitionRole::Luks; - FS::luks* luksFs = static_cast(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, lastSector, partitionNode, availableFlags(d.partitionTable()->type()), mountPoint, mounted, activeFlags); - - setupPartitionInfo(d, part, partitionObject, mountPoint); - - if (fs->supportGetLabel() != FileSystem::cmdSupportNone) - fs->setLabel(fs->readLabel(part->deviceNode())); - - if (fs->supportGetUUID() != FileSystem::cmdSupportNone) - fs->setUUID(fs->readUUID(part->deviceNode())); - - parent->append(part); partitions.append(part); } @@ -363,14 +315,70 @@ void SfdiskBackend::scanDevicePartitions(Device& d, const QJsonArray& jsonPartit if (d.partitionTable()->isSectorBased(d)) d.partitionTable()->setType(d, PartitionTable::msdos_sectorbased); - for (const Partition * part : qAsConst(partitions)) + for (const Partition *part : qAsConst(partitions)) PartitionAlignment::isAligned(d, *part); } -void SfdiskBackend::setupPartitionInfo(const Device &d, Partition *partition, const QJsonObject& partitionObject, const QString mountPoint) +Partition* SfdiskBackend::scanPartition(Device& d, const QString& partitionNode, const qint64 firstSector, const qint64 lastSector, const QString& partitionType, const bool bootable) +{ + PartitionTable::Flags activeFlags = bootable ? PartitionTable::Flag::Boot : PartitionTable::Flag::None; + if (partitionType == QStringLiteral("C12A7328-F81F-11D2-BA4B-00A0C93EC93B")) + activeFlags |= PartitionTable::Flag::Boot; + else if (partitionType == QStringLiteral("21686148-6449-6E6F-744E-656564454649")) + activeFlags |= PartitionTable::Flag::BiosGrub; + + FileSystem::Type type = detectFileSystem(partitionNode); + PartitionRole::Roles r = PartitionRole::Primary; + + if ( (d.partitionTable()->type() == PartitionTable::msdos || d.partitionTable()->type() == PartitionTable::msdos_sectorbased) && + ( partitionType == QStringLiteral("5") || partitionType == QStringLiteral("f") ) ) { + r = PartitionRole::Extended; + type = FileSystem::Type::Extended; + } + + // Find an extended partition this partition is in. + PartitionNode* parent = d.partitionTable()->findPartitionBySector(firstSector, 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, firstSector, lastSector, d.logicalSize()); + fs->scan(partitionNode); + + QString mountPoint; + bool mounted; + // sfdisk does not handle LUKS partitions + if (fs->type() == FileSystem::Type::Luks || fs->type() == FileSystem::Type::Luks2) { + r |= PartitionRole::Luks; + FS::luks* luksFs = static_cast(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* partition = new Partition(parent, d, PartitionRole(r), fs, firstSector, lastSector, partitionNode, availableFlags(d.partitionTable()->type()), mountPoint, mounted, activeFlags); + + if (fs->supportGetLabel() != FileSystem::cmdSupportNone) + fs->setLabel(fs->readLabel(partition->deviceNode())); + + if (fs->supportGetUUID() != FileSystem::cmdSupportNone) + fs->setUUID(fs->readUUID(partition->deviceNode())); + + parent->append(partition); + return partition; +} + +void SfdiskBackend::setupPartitionInfo(const Device &d, Partition *partition, const QJsonObject& partitionObject) { if (!partition->roles().has(PartitionRole::Luks)) - readSectorsUsed(d, *partition, mountPoint); + readSectorsUsed(d, *partition, partition->mountPoint()); if (d.partitionTable()->type() == PartitionTable::TableType::gpt) { partition->setLabel(partitionObject[QLatin1String("name")].toString()); diff --git a/src/plugins/sfdisk/sfdiskbackend.h b/src/plugins/sfdisk/sfdiskbackend.h index 7da59d3..6ed0708 100644 --- a/src/plugins/sfdisk/sfdiskbackend.h +++ b/src/plugins/sfdisk/sfdiskbackend.h @@ -50,7 +50,8 @@ public: private: static void readSectorsUsed(const Device& d, Partition& p, const QString& mountPoint); void scanDevicePartitions(Device& d, const QJsonArray& jsonPartitions); - void setupPartitionInfo(const Device& d, Partition* partition, const QJsonObject& partitionObject, const QString mountPoint); + Partition* scanPartition(Device& d, const QString& partitionNode, const qint64 firstSector, const qint64 lastSector, const QString& partitionType, const bool bootable); + static void setupPartitionInfo(const Device& d, Partition* partition, const QJsonObject& partitionObject); bool updateDevicePartitionTable(Device& d, const QJsonObject& jsonPartitionTable); static PartitionTable::Flags availableFlags(PartitionTable::TableType type); static FileSystem::Type fileSystemNameToType(const QString& fileSystemName, const QString& version); From 9ca3a5740adbb6282b100cf417e3115cfd1cb63b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Sat, 3 Oct 2020 14:03:59 +0100 Subject: [PATCH 09/11] Add information about PartitionTable::TableType::none. --- src/core/partitiontable.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/partitiontable.cpp b/src/core/partitiontable.cpp index f33b059..f5f2b7a 100644 --- a/src/core/partitiontable.cpp +++ b/src/core/partitiontable.cpp @@ -475,7 +475,8 @@ static struct { { QLatin1String("pc98"), 16, false, true, PartitionTable::pc98 }, { QLatin1String("amiga"), 128, false, true, PartitionTable::amiga }, { QLatin1String("sun"), 8, false, true, PartitionTable::sun }, - { QLatin1String("vmd"), 0xffff, false, false, PartitionTable::vmd } + { QLatin1String("vmd"), 0xffff, false, false, PartitionTable::vmd }, + { QLatin1String("none"), 1, false, false, PartitionTable::none }, }; PartitionTable::TableType PartitionTable::nameToTableType(const QString& n) From 091087513798e9f5c4cd25f9cc404a083ec0c418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Sat, 3 Oct 2020 14:15:10 +0100 Subject: [PATCH 10/11] Do not delete partitions when we have no partition table. --- src/ops/deleteoperation.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ops/deleteoperation.cpp b/src/ops/deleteoperation.cpp index f0d97e5..d777eea 100644 --- a/src/ops/deleteoperation.cpp +++ b/src/ops/deleteoperation.cpp @@ -49,7 +49,8 @@ DeleteOperation::DeleteOperation(Device& d, Partition* p, ShredAction shred) : } addJob(deleteFileSystemJob()); - addJob(deletePartitionJob()); + if (d.partitionTable()->type() != PartitionTable::TableType::none) + addJob(deletePartitionJob()); } DeleteOperation::~DeleteOperation() From 034311a7cc158b9a2db1dfeb641594ce1bf4dacd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Sat, 3 Oct 2020 15:14:51 +0100 Subject: [PATCH 11/11] Add support for whole disk file systems. BUG: 400652 --- src/plugins/sfdisk/sfdiskbackend.cpp | 27 ++++++++++++++++++++++++++- src/plugins/sfdisk/sfdiskbackend.h | 1 + 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/plugins/sfdisk/sfdiskbackend.cpp b/src/plugins/sfdisk/sfdiskbackend.cpp index 55fa117..102cc90 100644 --- a/src/plugins/sfdisk/sfdiskbackend.cpp +++ b/src/plugins/sfdisk/sfdiskbackend.cpp @@ -251,8 +251,11 @@ Device* SfdiskBackend::scanDevice(const QString& deviceNode) if ( d ) { - if (sfdiskJsonCommand.exitCode() != 0) + if (sfdiskJsonCommand.exitCode() != 0) { + scanWholeDevicePartition(*d); + return d; + } auto s = sfdiskJsonCommand.rawOutput(); fixInvalidJsonFromSFDisk(s); @@ -283,6 +286,28 @@ Device* SfdiskBackend::scanDevice(const QString& deviceNode) return nullptr; } +/** Scans a Device for FileSystems spanning the whole block device + + This method will scan a Device for a FileSystem. + It tries to determine the FileSystem usage, reads the FileSystem label and creates + PartitionTable of type "none" and a single Partition object. +*/ +void SfdiskBackend::scanWholeDevicePartition(Device& d) { + const QString partitionNode = d.deviceNode(); + constexpr qint64 firstSector = 0; + const qint64 lastSector = d.totalLogical() - 1; + setPartitionTableForDevice(d, new PartitionTable(PartitionTable::TableType::none, firstSector, lastSector)); + Partition *partition = scanPartition(d, partitionNode, firstSector, lastSector, QString(), false); + + if (partition->fileSystem().type() == FileSystem::Type::Unknown) { + setPartitionTableForDevice(d, nullptr); + delete d.partitionTable(); + } + + if (!partition->roles().has(PartitionRole::Luks)) + readSectorsUsed(d, *partition, partition->mountPoint()); +} + /** Scans a Device for Partitions. This method will scan a Device for all Partitions on it, detect the FileSystem for each Partition, diff --git a/src/plugins/sfdisk/sfdiskbackend.h b/src/plugins/sfdisk/sfdiskbackend.h index 6ed0708..e709f61 100644 --- a/src/plugins/sfdisk/sfdiskbackend.h +++ b/src/plugins/sfdisk/sfdiskbackend.h @@ -51,6 +51,7 @@ private: static void readSectorsUsed(const Device& d, Partition& p, const QString& mountPoint); void scanDevicePartitions(Device& d, const QJsonArray& jsonPartitions); Partition* scanPartition(Device& d, const QString& partitionNode, const qint64 firstSector, const qint64 lastSector, const QString& partitionType, const bool bootable); + void scanWholeDevicePartition(Device& d); static void setupPartitionInfo(const Device& d, Partition* partition, const QJsonObject& partitionObject); bool updateDevicePartitionTable(Device& d, const QJsonObject& jsonPartitionTable); static PartitionTable::Flags availableFlags(PartitionTable::TableType type);