From ba4e4432235d22ca3ebcc494d4ea4c3f96152329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Wed, 31 Jan 2018 15:04:55 +0000 Subject: [PATCH] Move file system label and UUID read code to backends. This allows to use different implementations on different platforms. E.g. libblkid is not available on FreeBSD. libparted backend still uses the same libblkid implementation sfdisk backend reads label and UUID from udev database --- src/backend/corebackend.h | 16 ++++++++++- src/fs/filesystem.cpp | 27 ++----------------- src/fs/filesystem.h | 2 +- src/plugins/dummy/dummybackend.cpp | 14 ++++++++++ src/plugins/dummy/dummybackend.h | 2 ++ src/plugins/libparted/libpartedbackend.cpp | 31 ++++++++++++++++++++++ src/plugins/libparted/libpartedbackend.h | 2 ++ src/plugins/sfdisk/sfdiskbackend.cpp | 29 ++++++++++++++++++++ src/plugins/sfdisk/sfdiskbackend.h | 2 ++ 9 files changed, 98 insertions(+), 27 deletions(-) diff --git a/src/backend/corebackend.h b/src/backend/corebackend.h index 59725a2..7829ce2 100644 --- a/src/backend/corebackend.h +++ b/src/backend/corebackend.h @@ -100,11 +100,25 @@ public: /** * Scan a single device in the system. - * @param deviceNode The path to the device that is to be scanned (e.g. /dev/sda) + * @param deviceNode The path to the device that is to be scanned (e.g. /dev/sda1) * @return FileSystem type of the device on deviceNode */ virtual FileSystem::Type detectFileSystem(const QString& deviceNode) = 0; + /** + * Read a file system label + * @param deviceNode The path to the device that is to be scanned (e.g. /dev/sda1) + * @return FileSystem label on deviceNode + */ + virtual QString readLabel(const QString& deviceNode) const = 0; + + /** + * Read a file system UUID + * @param deviceNode The path to the device that is to be scanned (e.g. /dev/sda1) + * @return FileSystem UUID on deviceNode + */ + virtual QString readUUID(const QString& deviceNode) const = 0; + /** * Scan a single device in the system. * @param deviceNode The path to the device that is to be scanned (e.g. /dev/sda) diff --git a/src/fs/filesystem.cpp b/src/fs/filesystem.cpp index 6676a0f..863a29e 100644 --- a/src/fs/filesystem.cpp +++ b/src/fs/filesystem.cpp @@ -29,8 +29,6 @@ #include "util/capacity.h" #include "util/helpers.h" -#include - #include #include @@ -101,27 +99,6 @@ qint64 FileSystem::readUsedCapacity(const QString& deviceNode) const return -1; } -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; -} - FileSystem::Type FileSystem::detectFileSystem(const QString& partitionPath) { return CoreBackendManager::self()->backend()->detectFileSystem(partitionPath); @@ -168,7 +145,7 @@ bool FileSystem::detectMountStatus(FileSystem* fs, const QString& partitionPath) */ QString FileSystem::readLabel(const QString& deviceNode) const { - return readBlkIdValue(deviceNode, QStringLiteral("LABEL")); + return CoreBackendManager::self()->backend()->readLabel(deviceNode); } /** Creates a new FileSystem @@ -363,7 +340,7 @@ bool FileSystem::updateUUID(Report& report, const QString& deviceNode) const */ QString FileSystem::readUUID(const QString& deviceNode) const { - return readBlkIdValue(deviceNode, QStringLiteral("UUID")); + return CoreBackendManager::self()->backend()->readUUID(deviceNode); } /** Give implementations of FileSystem a chance to update the boot sector after the diff --git a/src/fs/filesystem.h b/src/fs/filesystem.h index cdce228..27451a7 100644 --- a/src/fs/filesystem.h +++ b/src/fs/filesystem.h @@ -18,8 +18,8 @@ *************************************************************************/ #if !defined(KPMCORE_FILESYSTEM_H) - #define KPMCORE_FILESYSTEM_H + #include "util/libpartitionmanagerexport.h" #include diff --git a/src/plugins/dummy/dummybackend.cpp b/src/plugins/dummy/dummybackend.cpp index 7e54880..5abc6f2 100644 --- a/src/plugins/dummy/dummybackend.cpp +++ b/src/plugins/dummy/dummybackend.cpp @@ -77,6 +77,20 @@ FileSystem::Type DummyBackend::detectFileSystem(const QString& deviceNode) return FileSystem::Unknown; } +QString DummyBackend::readLabel(const QString& deviceNode) const +{ + Q_UNUSED(deviceNode) + + return QString(); +} + +QString DummyBackend::readUUID(const QString& deviceNode) const +{ + Q_UNUSED(deviceNode) + + return QString(); +} + CoreBackendDevice* DummyBackend::openDevice(const Device& d) { DummyDevice* device = new DummyDevice(d.deviceNode()); diff --git a/src/plugins/dummy/dummybackend.h b/src/plugins/dummy/dummybackend.h index d027171..12aad6b 100644 --- a/src/plugins/dummy/dummybackend.h +++ b/src/plugins/dummy/dummybackend.h @@ -50,6 +50,8 @@ public: bool closeDevice(CoreBackendDevice* coreDevice) override; Device* scanDevice(const QString& deviceNode) override; FileSystem::Type detectFileSystem(const QString& deviceNode) override; + QString readLabel(const QString& deviceNode) const override; + QString readUUID(const QString& deviceNode) const override; }; #endif diff --git a/src/plugins/libparted/libpartedbackend.cpp b/src/plugins/libparted/libpartedbackend.cpp index 582fa0f..7c0e59a 100644 --- a/src/plugins/libparted/libpartedbackend.cpp +++ b/src/plugins/libparted/libpartedbackend.cpp @@ -524,6 +524,37 @@ FileSystem::Type LibPartedBackend::detectFileSystem(const QString& partitionPath 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()); diff --git a/src/plugins/libparted/libpartedbackend.h b/src/plugins/libparted/libpartedbackend.h index a5d5450..93ed320 100644 --- a/src/plugins/libparted/libpartedbackend.h +++ b/src/plugins/libparted/libpartedbackend.h @@ -67,6 +67,8 @@ public: DiskDevice* scanDevice(const QString& deviceNode) override; QList 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(); diff --git a/src/plugins/sfdisk/sfdiskbackend.cpp b/src/plugins/sfdisk/sfdiskbackend.cpp index 9849628..33ef5ff 100644 --- a/src/plugins/sfdisk/sfdiskbackend.cpp +++ b/src/plugins/sfdisk/sfdiskbackend.cpp @@ -358,6 +358,35 @@ FileSystem::Type SfdiskBackend::detectFileSystem(const QString& partitionPath) return rval; } +QString SfdiskBackend::readLabel(const QString& deviceNode) const +{ + ExternalCommand udevCommand(QStringLiteral("udevadm"), { + QStringLiteral("info"), + QStringLiteral("--query=property"), + deviceNode }); + + QRegularExpression re(QStringLiteral("ID_FS_LABEL=(\\w+)")); + QRegularExpressionMatch reFileSystemLabel = re.match(udevCommand.output()); + if (reFileSystemLabel.hasMatch()) + return reFileSystemLabel.captured(1); + + return QString(); +} + +QString SfdiskBackend::readUUID(const QString& deviceNode) const +{ + ExternalCommand udevCommand(QStringLiteral("udevadm"), { + QStringLiteral("info"), + QStringLiteral("--query=property"), + deviceNode }); + QRegularExpression re(QStringLiteral("ID_FS_UUID=(\\w+)")); + QRegularExpressionMatch reFileSystemUUID = re.match(udevCommand.output()); + if (reFileSystemUUID.hasMatch()) + return reFileSystemUUID.captured(1); + + return QString(); +} + PartitionTable::Flags SfdiskBackend::availableFlags(PartitionTable::TableType type) { PartitionTable::Flags flags; diff --git a/src/plugins/sfdisk/sfdiskbackend.h b/src/plugins/sfdisk/sfdiskbackend.h index ad421f7..5cb3291 100644 --- a/src/plugins/sfdisk/sfdiskbackend.h +++ b/src/plugins/sfdisk/sfdiskbackend.h @@ -52,6 +52,8 @@ public: bool closeDevice(CoreBackendDevice* coreDevice) override; Device* scanDevice(const QString& deviceNode) override; FileSystem::Type detectFileSystem(const QString& partitionPath) override; + QString readLabel(const QString& deviceNode) const override; + QString readUUID(const QString& deviceNode) const override; private: static void readSectorsUsed(const Device& d, Partition& p, const QString& mountPoint);