Merge branch 'kauth'
This commit is contained in:
commit
24d9d1bd73
|
@ -16,14 +16,22 @@
|
|||
|
||||
project(kpmcore)
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
|
||||
cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
|
||||
|
||||
set(CMAKE_USE_RELATIVE_PATHS OFF)
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
|
||||
|
||||
set(QT_MIN_VERSION "5.7.0")
|
||||
# Dependencies
|
||||
set(QT_MIN_VERSION "5.10.0")
|
||||
set(KF5_MIN_VERSION "5.25")
|
||||
set(BLKID_MIN_VERSION "2.32")
|
||||
# Qca-qt5 (tested with botan and ossl backends)
|
||||
|
||||
# Runtime
|
||||
# smartmontools 6.7
|
||||
|
||||
set(VERSION_MAJOR "3")
|
||||
set(VERSION_MINOR "3")
|
||||
set(VERSION_MINOR "50")
|
||||
set(VERSION_RELEASE "0")
|
||||
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_RELEASE})
|
||||
set(SOVERSION "8")
|
||||
|
@ -32,7 +40,7 @@ add_definitions(-D'VERSION="${VERSION}"') #"
|
|||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
find_package(ECM 1.0.0 REQUIRED NO_MODULE)
|
||||
find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE)
|
||||
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/")
|
||||
|
||||
include(KDEInstallDirs)
|
||||
|
@ -41,7 +49,6 @@ include(KDECompilerSettings NO_POLICY_SCOPE)
|
|||
include(FeatureSummary)
|
||||
include(GenerateExportHeader)
|
||||
include(ECMSetupVersion)
|
||||
include(ECMPackageConfigHelpers)
|
||||
|
||||
ecm_setup_version(${VERSION} VARIABLE_PREFIX KPMCORE
|
||||
VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/kpmcore_version.h"
|
||||
|
@ -56,12 +63,15 @@ find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
|
|||
)
|
||||
|
||||
# Load the frameworks we need
|
||||
find_package(KF5 REQUIRED
|
||||
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED
|
||||
Auth
|
||||
I18n
|
||||
CoreAddons
|
||||
WidgetsAddons
|
||||
)
|
||||
|
||||
find_package(Qca-qt5 REQUIRED)
|
||||
|
||||
# use sane compile flags
|
||||
add_definitions(
|
||||
-DQT_USE_QSTRINGBUILDER
|
||||
|
@ -76,10 +86,10 @@ add_definitions(
|
|||
)
|
||||
kde_enable_exceptions()
|
||||
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(BLKID REQUIRED blkid>=2.30)
|
||||
pkg_check_modules(LIBATASMART REQUIRED libatasmart)
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(BLKID REQUIRED blkid>=${BLKID_MIN_VERSION})
|
||||
endif()
|
||||
|
||||
include_directories(${Qt5Core_INCLUDE_DIRS} ${UUID_INCLUDE_DIRS} ${BLKID_INCLUDE_DIRS} lib/ src/)
|
||||
|
||||
|
@ -89,7 +99,7 @@ add_subdirectory(src)
|
|||
set(INCLUDE_INSTALL_DIR "include/kpmcore/")
|
||||
set(CMAKECONFIG_INSTALL_DIR "${CMAKECONFIG_INSTALL_PREFIX}/KPMcore")
|
||||
|
||||
ecm_configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/KPMcoreConfig.cmake.in"
|
||||
configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/KPMcoreConfig.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/KPMcoreConfig.cmake"
|
||||
INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR}
|
||||
PATH_VARS INCLUDE_INSTALL_DIR
|
||||
|
|
12
INSTALL
12
INSTALL
|
@ -4,24 +4,16 @@ Building and installing KDE Partition Manager Core Library from source
|
|||
|
||||
1. Dependencies
|
||||
|
||||
libparted: Either get it from http://www.gnu.org/software/parted/download.shtml
|
||||
and build it yourself or, preferably, install your distribution's packages
|
||||
(don't forget the dev-package).
|
||||
|
||||
libblkid: Part of the util-linux project available at
|
||||
https://github.com/karelzak/util-linux
|
||||
|
||||
libatasmart: Available from http://0pointer.de/blog/projects/being-smart.html
|
||||
util-linux 2.32: available at https://github.com/karelzak/util-linux
|
||||
|
||||
KDE Frameworks: The minimum required version is 5.0.
|
||||
|
||||
|
||||
2. Configure
|
||||
|
||||
KPMcore is built with cmake. It is recommended to build out of tree:
|
||||
After unpacking the source, create a separate build directory and run cmake there:
|
||||
|
||||
$ tar xfj kpmcore-x.y.z.tar.bz2
|
||||
$ tar xf kpmcore-x.y.z.tar.xz
|
||||
$ cd kpmcore-x.y.z
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
|
|
|
@ -14,7 +14,7 @@ of storage devices on a system:
|
|||
There are multiple backends so that KPMcore can support different
|
||||
operating systems, although the only functional backend is the
|
||||
one for Linux systems:
|
||||
* libparted backend (Linux)
|
||||
* sfdisk backend (Linux)
|
||||
* null backend
|
||||
|
||||
## Using KPMcore
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
# Copyright (C) 2008,2010,2011 by Volker Lanz <vl@fidra.de>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
include(CheckCSourceCompiles)
|
||||
include(CheckFunctionExists)
|
||||
|
||||
if (LIBPARTED_INCLUDE_DIR AND LIBPARTED_LIBRARY)
|
||||
# Already in cache, be silent
|
||||
set(LIBPARTED_FIND_QUIETLY TRUE)
|
||||
endif (LIBPARTED_INCLUDE_DIR AND LIBPARTED_LIBRARY)
|
||||
|
||||
|
||||
FIND_PATH(LIBPARTED_INCLUDE_DIR parted.h PATH_SUFFIXES parted )
|
||||
|
||||
FIND_LIBRARY(LIBPARTED_LIBRARY NAMES parted)
|
||||
FIND_LIBRARY(LIBPARTED_FS_RESIZE_LIBRARY NAMES parted-fs-resize)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBPARTED DEFAULT_MSG LIBPARTED_LIBRARY LIBPARTED_INCLUDE_DIR)
|
||||
|
||||
if (LIBPARTED_FS_RESIZE_LIBRARY)
|
||||
set(LIBPARTED_LIBS ${LIBPARTED_FS_RESIZE_LIBRARY} ${LIBPARTED_LIBRARY})
|
||||
else (LIBPARTED_FS_RESIZE_LIBRARY)
|
||||
set(LIBPARTED_LIBS ${LIBPARTED_LIBRARY})
|
||||
endif (LIBPARTED_FS_RESIZE_LIBRARY)
|
||||
|
||||
# KDE adds -ansi to the C make flags, parted headers use GNU extensions, so
|
||||
# undo that
|
||||
unset(CMAKE_C_FLAGS)
|
||||
|
||||
set(CMAKE_REQUIRED_INCLUDES ${LIBPARTED_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${LIBPARTED_LIBS})
|
||||
|
||||
CHECK_FUNCTION_EXISTS("ped_file_system_clobber" LIBPARTED_FILESYSTEM_SUPPORT) # parted < 3.0
|
||||
CHECK_FUNCTION_EXISTS("ped_file_system_resize" LIBPARTED_FS_RESIZE_LIBRARY_SUPPORT) # parted != 3.0
|
||||
|
||||
MARK_AS_ADVANCED(LIBPARTED_LIBRARY LIBPARTED_INCLUDE_DIR LIBPARTED_FILESYSTEM_SUPPORT LIBPARTED_FS_RESIZE_LIBRARY LIBPARTED_FS_RESIZE_LIBRARY_SUPPORT)
|
|
@ -39,14 +39,17 @@ set(kpmcore_SRCS
|
|||
ki18n_wrap_ui(kpmcore_SRCS ${gui_UIFILES})
|
||||
|
||||
add_library(kpmcore SHARED ${kpmcore_SRCS})
|
||||
target_link_libraries( kpmcore
|
||||
${UUID_LIBRARIES}
|
||||
target_link_libraries( kpmcore PUBLIC
|
||||
Qt5::Core
|
||||
PRIVATE
|
||||
${BLKID_LIBRARIES}
|
||||
${LIBATASMART_LIBRARIES}
|
||||
Qt5::DBus
|
||||
Qt5::Gui
|
||||
qca-qt5
|
||||
KF5::I18n
|
||||
KF5::CoreAddons
|
||||
KF5::WidgetsAddons
|
||||
KF5::Auth
|
||||
)
|
||||
|
||||
install(TARGETS kpmcore EXPORT KPMcoreTargets ${INSTALL_TARGETS_DEFAULT_ARGS})
|
||||
|
|
|
@ -24,20 +24,18 @@
|
|||
|
||||
#include <QDebug>
|
||||
|
||||
class CoreBackend::CoreBackendPrivate
|
||||
struct CoreBackendPrivate
|
||||
{
|
||||
public:
|
||||
CoreBackendPrivate() {}
|
||||
QString m_id, m_version;
|
||||
};
|
||||
|
||||
CoreBackend::CoreBackend() :
|
||||
d(new CoreBackendPrivate())
|
||||
d(std::make_unique<CoreBackendPrivate>())
|
||||
{
|
||||
}
|
||||
|
||||
CoreBackend::~CoreBackend()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
void CoreBackend::emitProgress(int i)
|
||||
|
@ -59,3 +57,23 @@ void CoreBackend::setPartitionTableMaxPrimaries(PartitionTable& p, qint32 max_pr
|
|||
{
|
||||
p.setMaxPrimaries(max_primaries);
|
||||
}
|
||||
|
||||
QString CoreBackend::id()
|
||||
{
|
||||
return d->m_id;
|
||||
}
|
||||
|
||||
QString CoreBackend::version()
|
||||
{
|
||||
return d->m_version;
|
||||
}
|
||||
|
||||
void CoreBackend::setId(const QString& id)
|
||||
{
|
||||
d->m_id = id;
|
||||
}
|
||||
|
||||
void CoreBackend::setVersion(const QString& version)
|
||||
{
|
||||
d->m_version = version;
|
||||
}
|
||||
|
|
|
@ -23,11 +23,14 @@
|
|||
#include "util/libpartitionmanagerexport.h"
|
||||
#include "fs/filesystem.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
|
||||
class CoreBackendManager;
|
||||
class CoreBackendDevice;
|
||||
struct CoreBackendPrivate;
|
||||
class Device;
|
||||
class PartitionTable;
|
||||
|
||||
|
@ -68,17 +71,13 @@ public:
|
|||
* Return the plugin's unique Id from JSON metadata
|
||||
* @return the plugin's unique Id from JSON metadata
|
||||
*/
|
||||
QString id() {
|
||||
return m_id;
|
||||
}
|
||||
QString id();
|
||||
|
||||
/**
|
||||
* Return the plugin's version from JSON metadata
|
||||
* @return the plugin's version from JSON metadata
|
||||
*/
|
||||
QString version() {
|
||||
return m_version;
|
||||
}
|
||||
QString version();
|
||||
|
||||
/**
|
||||
* Initialize the plugin's FileSystem support
|
||||
|
@ -130,29 +129,23 @@ public:
|
|||
/**
|
||||
* Open a device for reading.
|
||||
* @param deviceNode The path of the device that is to be opened (e.g. /dev/sda)
|
||||
* @return a pointer to a CoreBackendDevice or nullptr if the open failed. If a pointer to
|
||||
* an instance is returned, it's the caller's responsibility to delete the
|
||||
* object.
|
||||
* @return a pointer to a CoreBackendDevice or nullptr if the open failed.
|
||||
*/
|
||||
virtual CoreBackendDevice* openDevice(const Device& d) = 0;
|
||||
virtual std::unique_ptr<CoreBackendDevice> openDevice(const Device& d) = 0;
|
||||
|
||||
/**
|
||||
* Open a device in exclusive mode for writing.
|
||||
* @param deviceNode The path of the device that is to be opened (e.g. /dev/sda)
|
||||
* @return a pointer to a CoreBackendDevice or nullptr if the open failed. If a pointer to
|
||||
* an instance is returned, it's the caller's responsibility to delete the
|
||||
* object.
|
||||
* @return a pointer to a CoreBackendDevice or nullptr if the open failed.
|
||||
*/
|
||||
virtual CoreBackendDevice* openDeviceExclusive(const Device& d) = 0;
|
||||
virtual std::unique_ptr<CoreBackendDevice> openDeviceExclusive(const Device& d) = 0;
|
||||
|
||||
/**
|
||||
* Close a CoreBackendDevice that has previously been opened.
|
||||
* @param core_device Pointer to the CoreBackendDevice to be closed. Must not be nullptr.
|
||||
* @return true if closing the CoreBackendDevice succeeded, otherwise false.
|
||||
*
|
||||
* This method does not delete the object.
|
||||
*/
|
||||
virtual bool closeDevice(CoreBackendDevice* core_device) = 0;
|
||||
virtual bool closeDevice(std::unique_ptr<CoreBackendDevice> coreDevice) = 0;
|
||||
|
||||
/**
|
||||
* Emit progress.
|
||||
|
@ -176,18 +169,11 @@ protected:
|
|||
static void setPartitionTableMaxPrimaries(PartitionTable& p, qint32 max_primaries);
|
||||
|
||||
private:
|
||||
void setId(const QString& id) {
|
||||
m_id = id;
|
||||
}
|
||||
void setVersion(const QString& version) {
|
||||
m_version = version;
|
||||
}
|
||||
void setId(const QString& id);
|
||||
void setVersion(const QString& version);
|
||||
|
||||
private:
|
||||
QString m_id, m_version;
|
||||
|
||||
class CoreBackendPrivate;
|
||||
CoreBackendPrivate* d;
|
||||
std::unique_ptr<CoreBackendPrivate> d;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#define KPMCORE_COREBACKENDDEVICE_H
|
||||
|
||||
#include <memory>
|
||||
#include <QString>
|
||||
|
||||
class CoreBackendPartition;
|
||||
|
@ -81,7 +82,7 @@ public:
|
|||
* @return a pointer to the CoreBackendPartitionTable for this device or nullptr in case
|
||||
* of errors
|
||||
*/
|
||||
virtual CoreBackendPartitionTable* openPartitionTable() = 0;
|
||||
virtual std::unique_ptr<CoreBackendPartitionTable> openPartitionTable() = 0;
|
||||
|
||||
/**
|
||||
* Create a new partition table on this device.
|
||||
|
@ -91,23 +92,6 @@ public:
|
|||
*/
|
||||
virtual bool createPartitionTable(Report& report, const PartitionTable& ptable) = 0;
|
||||
|
||||
/**
|
||||
* Read data from an opened device into a buffer.
|
||||
* @param buffer the buffer to write the read data to
|
||||
* @param offset offset byte where to start reading on the device
|
||||
* @param size the number of bytes to read
|
||||
* @return true on success
|
||||
*/
|
||||
virtual bool readData(QByteArray& buffer, qint64 offset, qint64 size) = 0;
|
||||
|
||||
/**
|
||||
* Write data from a buffer to an exclusively opened device.
|
||||
* @param buffer the buffer with the data
|
||||
* @param offset offset byte where to start writing to the device
|
||||
* @return true on success
|
||||
*/
|
||||
virtual bool writeData(QByteArray& buffer, qint64 offset) = 0;
|
||||
|
||||
protected:
|
||||
void setExclusive(bool b) {
|
||||
m_Exclusive = b;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de> *
|
||||
* Copyright (C) 2015 by Teo Mrnjavac <teo@kde.org> *
|
||||
* Copyright (C) 2016 by Andrius Štikonas <andrius@stikonas.eu> *
|
||||
* Copyright (C) 2016-2018 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 *
|
||||
|
@ -20,8 +20,8 @@
|
|||
#include "backend/corebackendmanager.h"
|
||||
#include "backend/corebackend.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
#include <QStringList>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
|
@ -30,8 +30,17 @@
|
|||
#include <KPluginLoader>
|
||||
#include <KPluginMetaData>
|
||||
|
||||
struct CoreBackendManagerPrivate
|
||||
{
|
||||
CoreBackend *m_Backend;
|
||||
};
|
||||
|
||||
CoreBackendManager::CoreBackendManager() :
|
||||
m_Backend(nullptr)
|
||||
d(std::make_unique<CoreBackendManagerPrivate>())
|
||||
{
|
||||
}
|
||||
|
||||
CoreBackendManager::~CoreBackendManager()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -45,6 +54,11 @@ CoreBackendManager* CoreBackendManager::self()
|
|||
return instance;
|
||||
}
|
||||
|
||||
CoreBackend* CoreBackendManager::backend()
|
||||
{
|
||||
return d->m_Backend;
|
||||
}
|
||||
|
||||
QVector<KPluginMetaData> CoreBackendManager::list() const
|
||||
{
|
||||
auto filter = [&](const KPluginMetaData &metaData) {
|
||||
|
@ -66,7 +80,7 @@ bool CoreBackendManager::load(const QString& name)
|
|||
KPluginFactory* factory = loader.factory();
|
||||
|
||||
if (factory != nullptr) {
|
||||
m_Backend = factory->create<CoreBackend>(nullptr);
|
||||
d->m_Backend = factory->create<CoreBackend>(nullptr);
|
||||
|
||||
QString id = loader.metaData().toVariantMap().value(QStringLiteral("MetaData"))
|
||||
.toMap().value(QStringLiteral("KPlugin")).toMap().value(QStringLiteral("Id")).toString();
|
||||
|
@ -78,6 +92,7 @@ bool CoreBackendManager::load(const QString& name)
|
|||
backend()->setId(id);
|
||||
backend()->setVersion(version);
|
||||
qDebug() << "Loaded backend plugin: " << backend()->id();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -87,6 +102,4 @@ bool CoreBackendManager::load(const QString& name)
|
|||
|
||||
void CoreBackendManager::unload()
|
||||
{
|
||||
delete m_Backend;
|
||||
m_Backend = nullptr;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de> *
|
||||
* Copyright (C) 2018 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 *
|
||||
|
@ -15,18 +16,20 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(KPMCORE_COREBACKENDMANAGER_H)
|
||||
|
||||
#ifndef KPMCORE_COREBACKENDMANAGER_H
|
||||
#define KPMCORE_COREBACKENDMANAGER_H
|
||||
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QVector>
|
||||
|
||||
class QString;
|
||||
class QStringList;
|
||||
class KPluginMetaData;
|
||||
class CoreBackend;
|
||||
struct CoreBackendManagerPrivate;
|
||||
|
||||
/**
|
||||
* The backend manager class.
|
||||
|
@ -37,8 +40,8 @@ class CoreBackend;
|
|||
*/
|
||||
class LIBKPMCORE_EXPORT CoreBackendManager
|
||||
{
|
||||
private:
|
||||
CoreBackendManager();
|
||||
~CoreBackendManager();
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -50,7 +53,7 @@ public:
|
|||
* @return the name of the default backend plugin
|
||||
*/
|
||||
static QString defaultBackendName() {
|
||||
return QStringLiteral("pmlibpartedbackendplugin");
|
||||
return QStringLiteral("pmsfdiskbackendplugin");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,12 +76,10 @@ public:
|
|||
/**
|
||||
* @return a pointer to the currently loaded backend
|
||||
*/
|
||||
CoreBackend* backend() {
|
||||
return m_Backend;
|
||||
}
|
||||
CoreBackend* backend();
|
||||
|
||||
private:
|
||||
CoreBackend* m_Backend;
|
||||
std::unique_ptr<CoreBackendManagerPrivate> d;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
include(core/raid/CMakeLists.txt)
|
||||
|
||||
set(CORE_SRC
|
||||
core/copysource.cpp
|
||||
core/copysourcedevice.cpp
|
||||
|
@ -20,7 +22,11 @@ set(CORE_SRC
|
|||
core/partitiontable.cpp
|
||||
core/smartstatus.cpp
|
||||
core/smartattribute.cpp
|
||||
core/smartparser.cpp
|
||||
core/smartattributeparseddata.cpp
|
||||
core/smartdiskinformation.cpp
|
||||
core/volumemanagerdevice.cpp
|
||||
${RAID_SRC}
|
||||
)
|
||||
|
||||
set(CORE_LIB_HDRS
|
||||
|
@ -39,5 +45,5 @@ set(CORE_LIB_HDRS
|
|||
core/smartattribute.h
|
||||
core/smartstatus.h
|
||||
core/volumemanagerdevice.h
|
||||
${RAID_LIB_HDRS}
|
||||
)
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <QtGlobal>
|
||||
|
||||
class CopyTarget;
|
||||
class QString;
|
||||
|
||||
/** Base class for something to copy from.
|
||||
|
||||
|
@ -41,14 +42,12 @@ protected:
|
|||
|
||||
public:
|
||||
virtual bool open() = 0;
|
||||
virtual bool readData(QByteArray& buffer, qint64 readOffset, qint64 size) = 0;
|
||||
virtual QString path() const = 0;
|
||||
virtual qint64 length() const = 0;
|
||||
virtual bool overlaps(const CopyTarget& target) const = 0;
|
||||
|
||||
virtual qint64 firstByte() const = 0;
|
||||
virtual qint64 lastByte() const = 0;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
#include "backend/corebackend.h"
|
||||
#include "backend/corebackendmanager.h"
|
||||
#include "backend/corebackenddevice.h"
|
||||
|
||||
#include "core/copytarget.h"
|
||||
#include "core/copytargetdevice.h"
|
||||
|
@ -40,12 +39,6 @@ CopySourceDevice::CopySourceDevice(Device& d, qint64 firstbyte, qint64 lastbyte)
|
|||
{
|
||||
}
|
||||
|
||||
/** Destructs a CopySourceDevice */
|
||||
CopySourceDevice::~CopySourceDevice()
|
||||
{
|
||||
delete m_BackendDevice;
|
||||
}
|
||||
|
||||
/** Opens the Device
|
||||
@return true if the Device could be successfully opened
|
||||
*/
|
||||
|
@ -63,22 +56,6 @@ qint64 CopySourceDevice::length() const
|
|||
return lastByte() - firstByte() + 1;
|
||||
}
|
||||
|
||||
/** Reads a given number of bytes from the Device into the given buffer.
|
||||
|
||||
Note that @p readOffset must be greater or equal than zero.
|
||||
|
||||
@param buffer the buffer to store the read bytes in
|
||||
@param readOffset the offset to begin reading
|
||||
@param size the number of bytes to read
|
||||
|
||||
@return true if successful
|
||||
*/
|
||||
bool CopySourceDevice::readData(QByteArray& buffer, qint64 readOffset, qint64 size)
|
||||
{
|
||||
Q_ASSERT(readOffset >= 0);
|
||||
return m_BackendDevice->readData(buffer, readOffset, size);
|
||||
}
|
||||
|
||||
/** Checks if this CopySourceDevice overlaps with the given CopyTarget
|
||||
@param target the CopyTarget to check overlapping with
|
||||
@return true if overlaps
|
||||
|
@ -103,3 +80,8 @@ bool CopySourceDevice::overlaps(const CopyTarget& target) const
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
QString CopySourceDevice::path() const
|
||||
{
|
||||
return m_Device.deviceNode();
|
||||
}
|
||||
|
|
|
@ -19,14 +19,18 @@
|
|||
|
||||
#define KPMCORE_COPYSOURCEDEVICE_H
|
||||
|
||||
#include "backend/corebackenddevice.h"
|
||||
#include "core/copysource.h"
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
class Device;
|
||||
class CopyTarget;
|
||||
class CoreBackendDevice;
|
||||
class QString;
|
||||
|
||||
/** A Device to copy from.
|
||||
|
||||
|
@ -40,11 +44,9 @@ class CopySourceDevice : public CopySource
|
|||
|
||||
public:
|
||||
CopySourceDevice(Device& d, qint64 firstbyte, qint64 lastbyte);
|
||||
~CopySourceDevice();
|
||||
|
||||
public:
|
||||
bool open() override;
|
||||
bool readData(QByteArray& buffer, qint64 readOffset, qint64 size) override;
|
||||
qint64 length() const override;
|
||||
bool overlaps(const CopyTarget& target) const override;
|
||||
|
||||
|
@ -62,12 +64,13 @@ public:
|
|||
return m_Device; /**< @return Device to copy from */
|
||||
}
|
||||
|
||||
QString path() const override;
|
||||
|
||||
protected:
|
||||
Device& m_Device;
|
||||
const qint64 m_FirstByte;
|
||||
const qint64 m_LastByte;
|
||||
CoreBackendDevice* m_BackendDevice
|
||||
;
|
||||
std::unique_ptr<CoreBackendDevice> m_BackendDevice;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -45,18 +45,3 @@ qint64 CopySourceFile::length() const
|
|||
{
|
||||
return QFileInfo(file()).size();
|
||||
}
|
||||
|
||||
/** Reads the given number of bytes from the file into the given buffer.
|
||||
@param buffer buffer to store the bytes read in
|
||||
@param readOffset offset where to begin reading
|
||||
@param size the number of bytes to read
|
||||
@return true on success
|
||||
*/
|
||||
bool CopySourceFile::readData(QByteArray& buffer, qint64 readOffset, qint64 size)
|
||||
{
|
||||
if (!file().seek(readOffset))
|
||||
return false;
|
||||
|
||||
buffer = file().read(size);
|
||||
return !buffer.isEmpty();
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@ public:
|
|||
|
||||
public:
|
||||
bool open() override;
|
||||
bool readData(QByteArray& buffer, qint64 readOffset, qint64 size) override;
|
||||
qint64 length() const override;
|
||||
|
||||
bool overlaps(const CopyTarget&) const override {
|
||||
|
@ -52,6 +51,9 @@ public:
|
|||
qint64 lastByte() const override {
|
||||
return length(); /**< @return equal to length for file. @see length() */
|
||||
}
|
||||
QString path() const override {
|
||||
return m_File.fileName();
|
||||
}
|
||||
|
||||
protected:
|
||||
QFile& file() {
|
||||
|
|
|
@ -43,17 +43,3 @@ qint64 CopySourceShred::length() const
|
|||
{
|
||||
return size();
|
||||
}
|
||||
|
||||
/** Reads the given number of bytes from the source into the given buffer.
|
||||
@param buffer buffer to store the data read in
|
||||
@param readOffset offset where to begin reading (unused)
|
||||
@param size the number of bytes to read
|
||||
@return true on success
|
||||
*/
|
||||
bool CopySourceShred::readData(QByteArray& buffer, qint64 readOffset, qint64 size)
|
||||
{
|
||||
Q_UNUSED(readOffset);
|
||||
|
||||
buffer = sourceFile().read(size);
|
||||
return !buffer.isEmpty();
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <QFile>
|
||||
|
||||
class CopyTarget;
|
||||
class QString;
|
||||
|
||||
/** A source for securely overwriting a partition (shredding).
|
||||
|
||||
|
@ -38,7 +39,6 @@ public:
|
|||
|
||||
public:
|
||||
bool open() override;
|
||||
bool readData(QByteArray& buffer, qint64 readOffset, qint64 size) override;
|
||||
qint64 length() const override;
|
||||
|
||||
bool overlaps(const CopyTarget&) const override {
|
||||
|
@ -50,6 +50,9 @@ public:
|
|||
qint64 lastByte() const override {
|
||||
return length(); /**< @return equal to length for shred source. @see length() */
|
||||
}
|
||||
QString path() const override {
|
||||
return m_SourceFile.fileName();
|
||||
}
|
||||
|
||||
protected:
|
||||
QFile& sourceFile() {
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include <QtGlobal>
|
||||
|
||||
class QString;
|
||||
|
||||
/** Base class for something to copy to.
|
||||
|
||||
|
@ -40,10 +41,9 @@ protected:
|
|||
|
||||
public:
|
||||
virtual bool open() = 0;
|
||||
virtual bool writeData(QByteArray& buffer, qint64 writeOffset) = 0;
|
||||
virtual qint64 firstByte() const = 0;
|
||||
virtual qint64 lastByte() const = 0;
|
||||
|
||||
virtual QString path() const = 0;
|
||||
qint64 bytesWritten() const {
|
||||
return m_BytesWritten;
|
||||
}
|
||||
|
|
|
@ -19,11 +19,9 @@
|
|||
|
||||
#include "backend/corebackend.h"
|
||||
#include "backend/corebackendmanager.h"
|
||||
#include "backend/corebackenddevice.h"
|
||||
|
||||
#include "core/device.h"
|
||||
|
||||
|
||||
/** Constructs a device to copy to.
|
||||
@param d the Device to copy to
|
||||
@param firstbyte the first byte on the Device to write to
|
||||
|
@ -38,12 +36,6 @@ CopyTargetDevice::CopyTargetDevice(Device& d, qint64 firstbyte, qint64 lastbyte)
|
|||
{
|
||||
}
|
||||
|
||||
/** Destructs a CopyTargetDevice */
|
||||
CopyTargetDevice::~CopyTargetDevice()
|
||||
{
|
||||
delete m_BackendDevice;
|
||||
}
|
||||
|
||||
/** Opens a CopyTargetDevice for writing to.
|
||||
@return true on success
|
||||
*/
|
||||
|
@ -53,21 +45,7 @@ bool CopyTargetDevice::open()
|
|||
return m_BackendDevice != nullptr;
|
||||
}
|
||||
|
||||
/** Writes the given number of bytes to the Device.
|
||||
|
||||
Note that @p writeOffset must be greater or equal than zero.
|
||||
|
||||
@param buffer the data to write
|
||||
@param writeOffset where to start writing on the Device
|
||||
@return true on success
|
||||
*/
|
||||
bool CopyTargetDevice::writeData(QByteArray& buffer, qint64 writeOffset)
|
||||
QString CopyTargetDevice::path() const
|
||||
{
|
||||
Q_ASSERT(writeOffset >= 0);
|
||||
bool rval = m_BackendDevice->writeData(buffer, writeOffset);
|
||||
|
||||
if (rval)
|
||||
setBytesWritten(bytesWritten() + buffer.size());
|
||||
|
||||
return rval;
|
||||
return m_Device.deviceNode();
|
||||
}
|
||||
|
|
|
@ -19,9 +19,12 @@
|
|||
|
||||
#define KPMCORE_COPYTARGETDEVICE_H
|
||||
|
||||
#include "backend/corebackenddevice.h"
|
||||
#include "core/copytarget.h"
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
class Device;
|
||||
|
@ -42,11 +45,9 @@ class CopyTargetDevice : public CopyTarget
|
|||
|
||||
public:
|
||||
CopyTargetDevice(Device& d, qint64 firstbyte, qint64 lastbyte);
|
||||
~CopyTargetDevice();
|
||||
|
||||
public:
|
||||
bool open() override;
|
||||
bool writeData(QByteArray& buffer, qint64 writeOffset) override;
|
||||
qint64 firstByte() const override {
|
||||
return m_FirstByte; /**< @return the first byte to write to */
|
||||
}
|
||||
|
@ -60,10 +61,11 @@ public:
|
|||
const Device& device() const {
|
||||
return m_Device; /**< @return the Device to write to */
|
||||
}
|
||||
QString path() const override;
|
||||
|
||||
protected:
|
||||
Device& m_Device;
|
||||
CoreBackendDevice* m_BackendDevice;
|
||||
std::unique_ptr<CoreBackendDevice> m_BackendDevice;
|
||||
const qint64 m_FirstByte;
|
||||
const qint64 m_LastByte;
|
||||
};
|
||||
|
|
|
@ -33,21 +33,3 @@ bool CopyTargetFile::open()
|
|||
{
|
||||
return file().open(QIODevice::WriteOnly | QIODevice::Truncate);
|
||||
}
|
||||
|
||||
/** Writes the given number of bytes from the given buffer to the file.
|
||||
@param buffer the data to write
|
||||
@param writeOffset where in the file to start writing
|
||||
@return true on success
|
||||
*/
|
||||
bool CopyTargetFile::writeData(QByteArray& buffer, qint64 writeOffset)
|
||||
{
|
||||
if (!file().seek(writeOffset))
|
||||
return false;
|
||||
|
||||
bool rval = file().write(buffer) == buffer.size();
|
||||
|
||||
if (rval)
|
||||
setBytesWritten(bytesWritten() + buffer.size());
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@ public:
|
|||
|
||||
public:
|
||||
bool open() override;
|
||||
bool writeData(QByteArray& buffer, qint64 writeOffset) override;
|
||||
|
||||
qint64 firstByte() const override {
|
||||
return 0; /**< @return always 0 for a file */
|
||||
|
@ -49,6 +48,10 @@ public:
|
|||
return bytesWritten(); /**< @return the number of bytes written so far */
|
||||
}
|
||||
|
||||
QString path() const override {
|
||||
return m_File.fileName();
|
||||
}
|
||||
|
||||
protected:
|
||||
QFile& file() {
|
||||
return m_File;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2008 by Volker Lanz <vl@fidra.de> *
|
||||
* Copyright (C) 2016 by Andrius Štikonas <andrius@stikonas.eu> *
|
||||
* Copyright (C) 2016-2018 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 *
|
||||
|
@ -17,6 +17,7 @@
|
|||
*************************************************************************/
|
||||
|
||||
#include "core/device.h"
|
||||
#include "core/device_p.h"
|
||||
#include "core/partitiontable.h"
|
||||
#include "core/smartstatus.h"
|
||||
|
||||
|
@ -28,22 +29,24 @@
|
|||
@param name the Device's name, usually some string defined by the manufacturer
|
||||
@param deviceNode the Device's node, for example "/dev/sda"
|
||||
*/
|
||||
Device::Device(const QString& name,
|
||||
Device::Device(std::shared_ptr<DevicePrivate> d_ptr,
|
||||
const QString& name,
|
||||
const QString& deviceNode,
|
||||
const qint64 logicalSize,
|
||||
const qint64 totalLogical,
|
||||
const qint64 logicalSectorSize,
|
||||
const qint64 totalLogicalSectors,
|
||||
const QString& iconName,
|
||||
Device::Type type)
|
||||
: QObject()
|
||||
, m_Name(name.length() > 0 ? name : i18n("Unknown Device"))
|
||||
, m_DeviceNode(deviceNode)
|
||||
, m_LogicalSize(logicalSize)
|
||||
, m_TotalLogical(totalLogical)
|
||||
, m_PartitionTable(nullptr)
|
||||
, m_IconName(iconName.isEmpty() ? QStringLiteral("drive-harddisk") : iconName)
|
||||
, m_SmartStatus(type == Device::Disk_Device ? new SmartStatus(deviceNode) : nullptr)
|
||||
, m_Type(type)
|
||||
, d(d_ptr)
|
||||
{
|
||||
d->m_Name = name.length() > 0 ? name : i18n("Unknown Device");
|
||||
d->m_DeviceNode = deviceNode;
|
||||
d->m_LogicalSectorSize = logicalSectorSize;
|
||||
d->m_TotalLogical = totalLogicalSectors;
|
||||
d->m_PartitionTable = nullptr;
|
||||
d->m_IconName = iconName.isEmpty() ? QStringLiteral("drive-harddisk") : iconName;
|
||||
d->m_SmartStatus = type == Device::Type::Disk_Device ? std::make_shared<SmartStatus>(deviceNode) : nullptr;
|
||||
d->m_Type = type;
|
||||
}
|
||||
|
||||
/** Copy constructor for Device.
|
||||
|
@ -51,30 +54,31 @@ Device::Device(const QString& name,
|
|||
*/
|
||||
Device::Device(const Device& other)
|
||||
: QObject()
|
||||
, m_Name(other.m_Name)
|
||||
, m_DeviceNode(other.m_DeviceNode)
|
||||
, m_LogicalSize(other.m_LogicalSize)
|
||||
, m_TotalLogical(other.m_TotalLogical)
|
||||
, m_PartitionTable(nullptr)
|
||||
, m_IconName(other.m_IconName)
|
||||
, m_SmartStatus(nullptr)
|
||||
, m_Type(other.m_Type)
|
||||
, d(std::make_shared<DevicePrivate>())
|
||||
{
|
||||
if (other.m_PartitionTable)
|
||||
m_PartitionTable = new PartitionTable(*other.m_PartitionTable);
|
||||
if (other.m_SmartStatus)
|
||||
m_SmartStatus = new SmartStatus(*other.m_SmartStatus);
|
||||
d->m_Name = other.d->m_Name;
|
||||
d->m_DeviceNode = other.d->m_DeviceNode;
|
||||
d->m_LogicalSectorSize = other.d->m_LogicalSectorSize;
|
||||
d->m_TotalLogical = other.d->m_TotalLogical;
|
||||
d->m_PartitionTable = nullptr;
|
||||
d->m_IconName = other.d->m_IconName;
|
||||
d->m_SmartStatus = nullptr;
|
||||
d->m_Type = other.d->m_Type;
|
||||
d->m_SmartStatus = other.d->m_SmartStatus;
|
||||
|
||||
if (other.d->m_PartitionTable)
|
||||
d->m_PartitionTable = new PartitionTable(*other.d->m_PartitionTable);
|
||||
}
|
||||
|
||||
/** Destructs a Device. */
|
||||
Device::~Device()
|
||||
{
|
||||
delete m_PartitionTable;
|
||||
delete d->m_PartitionTable;
|
||||
}
|
||||
|
||||
bool Device::operator==(const Device& other) const
|
||||
{
|
||||
return m_DeviceNode == other.m_DeviceNode;
|
||||
return d->m_DeviceNode == other.d->m_DeviceNode;
|
||||
}
|
||||
|
||||
bool Device::operator!=(const Device& other) const
|
||||
|
@ -86,3 +90,68 @@ QString Device::prettyName() const
|
|||
{
|
||||
return xi18nc("@item:inlistbox Device name – Capacity (device node)", "%1 – %2 (%3)", name(), Capacity::formatByteSize(capacity()), deviceNode());
|
||||
}
|
||||
|
||||
QString& Device::name()
|
||||
{
|
||||
return d->m_Name;
|
||||
}
|
||||
|
||||
const QString& Device::name() const
|
||||
{
|
||||
return d->m_Name;
|
||||
}
|
||||
|
||||
const QString& Device::deviceNode() const
|
||||
{
|
||||
return d->m_DeviceNode;
|
||||
}
|
||||
|
||||
qint64 Device::logicalSize() const
|
||||
{
|
||||
return d->m_LogicalSectorSize;
|
||||
}
|
||||
|
||||
qint64 Device::totalLogical() const
|
||||
{
|
||||
return d->m_TotalLogical;
|
||||
}
|
||||
|
||||
PartitionTable* Device::partitionTable()
|
||||
{
|
||||
return d->m_PartitionTable;
|
||||
}
|
||||
|
||||
const PartitionTable* Device::partitionTable() const
|
||||
{
|
||||
return d->m_PartitionTable;
|
||||
}
|
||||
|
||||
void Device::setPartitionTable(PartitionTable* ptable)
|
||||
{
|
||||
d->m_PartitionTable = ptable;
|
||||
}
|
||||
|
||||
const QString& Device::iconName() const
|
||||
{
|
||||
return d->m_IconName;
|
||||
}
|
||||
|
||||
void Device::setIconName(const QString& name)
|
||||
{
|
||||
d->m_IconName = name;
|
||||
}
|
||||
|
||||
SmartStatus& Device::smartStatus()
|
||||
{
|
||||
return *(d->m_SmartStatus);
|
||||
}
|
||||
|
||||
const SmartStatus& Device::smartStatus() const
|
||||
{
|
||||
return *(d->m_SmartStatus);
|
||||
}
|
||||
|
||||
Device::Type Device::type() const
|
||||
{
|
||||
return d->m_Type;
|
||||
}
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(KPMCORE_DEVICE_H)
|
||||
|
||||
#ifndef KPMCORE_DEVICE_H
|
||||
#define KPMCORE_DEVICE_H
|
||||
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
|
@ -24,10 +23,13 @@
|
|||
#include <QString>
|
||||
#include <QObject>
|
||||
|
||||
#include <memory>
|
||||
|
||||
class PartitionTable;
|
||||
class CreatePartitionTableOperation;
|
||||
class CoreBackend;
|
||||
class SmartStatus;
|
||||
class DevicePrivate;
|
||||
|
||||
/** A device description.
|
||||
|
||||
|
@ -48,96 +50,66 @@ class LIBKPMCORE_EXPORT Device : public QObject
|
|||
friend class CoreBackend;
|
||||
|
||||
public:
|
||||
enum Type {
|
||||
Disk_Device = 0,
|
||||
LVM_Device = 1, /* VG */
|
||||
RAID_Device = 2, /* software RAID device */
|
||||
Unknown_Device = 4
|
||||
enum class Type {
|
||||
Unknown_Device,
|
||||
Disk_Device,
|
||||
LVM_Device, /* VG */
|
||||
SoftwareRAID_Device, /* software RAID device, i.e. mdraid */
|
||||
FakeRAID_Device, /* fake RAID device, i.e. dmraid */
|
||||
};
|
||||
|
||||
protected:
|
||||
explicit Device(const QString& name, const QString& deviceNode, const qint64 logicalSize, const qint64 totalLogical, const QString& iconName = QString(), Device::Type type = Device::Disk_Device);
|
||||
explicit Device(std::shared_ptr<DevicePrivate> d_ptr, const QString& name, const QString& deviceNode, const qint64 logicalSectorSize, const qint64 totalLogicalSectors, const QString& iconName = QString(), Device::Type type = Device::Type::Disk_Device);
|
||||
|
||||
public:
|
||||
explicit Device(const Device& other);
|
||||
virtual ~Device();
|
||||
|
||||
public:
|
||||
virtual bool operator==(const Device& other) const;
|
||||
virtual bool operator!=(const Device& other) const;
|
||||
|
||||
virtual QString& name() {
|
||||
return m_Name; /**< @return the Device's name, usually some manufacturer string */
|
||||
}
|
||||
/**< @return the Device's name, usually some manufacturer string */
|
||||
virtual QString& name();
|
||||
virtual const QString& name() const;
|
||||
|
||||
virtual const QString& name() const {
|
||||
return m_Name; /**< @return the Device's name, usually some manufacturer string */
|
||||
}
|
||||
/**< @return the Device's node, for example "/dev/sda" */
|
||||
virtual const QString& deviceNode() const;
|
||||
|
||||
virtual const QString& deviceNode() const {
|
||||
return m_DeviceNode; /**< @return the Device's node, for example "/dev/sda" */
|
||||
}
|
||||
/**< @return the logical sector size the Device uses (would be extent size for e.g. LVM devices) */
|
||||
virtual qint64 logicalSize() const;
|
||||
|
||||
virtual PartitionTable* partitionTable() {
|
||||
return m_PartitionTable; /**< @return the Device's PartitionTable */
|
||||
}
|
||||
/**< @return the total number of logical sectors on the device */
|
||||
virtual qint64 totalLogical() const;
|
||||
|
||||
virtual const PartitionTable* partitionTable() const {
|
||||
return m_PartitionTable; /**< @return the Device's PartitionTable */
|
||||
}
|
||||
|
||||
virtual qint64 capacity() const { /**< @return the Device's capacity in bytes */
|
||||
return logicalSize() * totalLogical();
|
||||
}
|
||||
|
||||
virtual void setIconName(const QString& name) {
|
||||
m_IconName = name;
|
||||
}
|
||||
|
||||
virtual const QString& iconName() const {
|
||||
return m_IconName; /**< @return suggested icon name for this Device */
|
||||
}
|
||||
|
||||
virtual SmartStatus& smartStatus() {
|
||||
return *m_SmartStatus;
|
||||
}
|
||||
|
||||
virtual const SmartStatus& smartStatus() const {
|
||||
return *m_SmartStatus;
|
||||
}
|
||||
/**< @return the Device's PartitionTable */
|
||||
virtual PartitionTable* partitionTable();
|
||||
virtual const PartitionTable* partitionTable() const;
|
||||
|
||||
/**
|
||||
* Change the description of the partition table for different one.
|
||||
* The device itself is not changed; use CreatePartitionTableOperation
|
||||
* for that. The Device instance becomes the owner of @p ptable .
|
||||
*/
|
||||
virtual void setPartitionTable(PartitionTable* ptable) {
|
||||
m_PartitionTable = ptable;
|
||||
virtual void setPartitionTable(PartitionTable* ptable);
|
||||
|
||||
virtual qint64 capacity() const { /**< @return the Device's capacity in bytes */
|
||||
return logicalSize() * totalLogical();
|
||||
}
|
||||
|
||||
virtual qint64 logicalSize() const {
|
||||
return m_LogicalSize;
|
||||
}
|
||||
/**< @return suggested icon name for this Device */
|
||||
virtual const QString& iconName() const;
|
||||
|
||||
virtual qint64 totalLogical() const {
|
||||
return m_TotalLogical;
|
||||
}
|
||||
/**< @param name set the new Icon for this Device */
|
||||
virtual void setIconName(const QString& name);
|
||||
|
||||
virtual Device::Type type() const {
|
||||
return m_Type;
|
||||
}
|
||||
virtual SmartStatus& smartStatus();
|
||||
virtual const SmartStatus& smartStatus() const;
|
||||
|
||||
virtual Device::Type type() const;
|
||||
|
||||
virtual QString prettyName() const;
|
||||
|
||||
protected:
|
||||
QString m_Name;
|
||||
QString m_DeviceNode;
|
||||
qint64 m_LogicalSize;
|
||||
qint64 m_TotalLogical;
|
||||
PartitionTable* m_PartitionTable;
|
||||
QString m_IconName;
|
||||
SmartStatus* m_SmartStatus;
|
||||
Device::Type m_Type;
|
||||
std::shared_ptr<DevicePrivate> d;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2018 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/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#ifndef KPMCORE_DEVICE_P_H
|
||||
#define KPMCORE_DEVICE_P_H
|
||||
|
||||
#include "core/device.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <memory>
|
||||
|
||||
class PartitionTable;
|
||||
class SmartStatus;
|
||||
|
||||
class DevicePrivate
|
||||
{
|
||||
public:
|
||||
QString m_Name;
|
||||
QString m_DeviceNode;
|
||||
qint64 m_LogicalSectorSize;
|
||||
qint64 m_TotalLogical;
|
||||
PartitionTable* m_PartitionTable;
|
||||
QString m_IconName;
|
||||
std::shared_ptr<SmartStatus> m_SmartStatus;
|
||||
Device::Type m_Type;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,6 +1,6 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2008 by Volker Lanz <vl@fidra.de> *
|
||||
* Copyright (C) 2016 by Andrius Štikonas <andrius@stikonas.eu> *
|
||||
* Copyright (C) 2016-2018 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 *
|
||||
|
@ -17,6 +17,7 @@
|
|||
*************************************************************************/
|
||||
|
||||
#include "core/diskdevice.h"
|
||||
#include "core/device_p.h"
|
||||
|
||||
#include "core/partitiontable.h"
|
||||
#include "core/smartstatus.h"
|
||||
|
@ -39,14 +40,25 @@
|
|||
#define BLKPBSZGET _IO(0x12,123)/* get block physical sector size */
|
||||
#endif
|
||||
|
||||
#define d_ptr std::static_pointer_cast<DiskDevicePrivate>(d)
|
||||
|
||||
class DiskDevicePrivate : public DevicePrivate
|
||||
{
|
||||
public:
|
||||
qint32 m_Heads;
|
||||
qint32 m_SectorsPerTrack;
|
||||
qint32 m_Cylinders;
|
||||
qint64 m_LogicalSectorSize;
|
||||
qint64 m_PhysicalSectorSize;
|
||||
};
|
||||
|
||||
static qint64 getPhysicalSectorSize(const QString& device_node)
|
||||
{
|
||||
/*
|
||||
* possible ways of getting the physical sector size for a drive:
|
||||
* - ioctl(BLKPBSZGET) -- supported with Linux 2.6.32 and later
|
||||
* - /sys/block/sda/queue/physical_block_size
|
||||
* - libblkid from util-linux-ng 2.17 or later
|
||||
* TODO: implement the blkid method
|
||||
* - libblkid from util-linux 2.17 or later (not implemented)
|
||||
*/
|
||||
|
||||
#if defined(BLKPBSZGET)
|
||||
|
@ -87,11 +99,46 @@ DiskDevice::DiskDevice(const QString& name,
|
|||
qint32 cylinders,
|
||||
qint64 sectorSize,
|
||||
const QString& iconName)
|
||||
: Device(name, deviceNode, sectorSize, (static_cast<qint64>(heads) * cylinders * numSectors), iconName, Device::Disk_Device)
|
||||
, m_Heads(heads)
|
||||
, m_SectorsPerTrack(numSectors)
|
||||
, m_Cylinders(cylinders)
|
||||
, m_LogicalSectorSize(sectorSize)
|
||||
, m_PhysicalSectorSize(getPhysicalSectorSize(deviceNode))
|
||||
: Device(std::make_shared<DiskDevicePrivate>(), name, deviceNode, sectorSize, (static_cast<qint64>(heads) * cylinders * numSectors), iconName, Device::Type::Disk_Device)
|
||||
{
|
||||
d_ptr->m_Heads = heads;
|
||||
d_ptr->m_SectorsPerTrack = numSectors;
|
||||
d_ptr->m_Cylinders = cylinders;
|
||||
d_ptr->m_LogicalSectorSize = sectorSize;
|
||||
d_ptr->m_PhysicalSectorSize = getPhysicalSectorSize(deviceNode);
|
||||
}
|
||||
|
||||
qint32 DiskDevice::heads() const
|
||||
{
|
||||
return d_ptr->m_Heads;
|
||||
}
|
||||
|
||||
qint32 DiskDevice::cylinders() const
|
||||
{
|
||||
return d_ptr->m_Cylinders;
|
||||
}
|
||||
|
||||
qint32 DiskDevice::sectorsPerTrack() const
|
||||
{
|
||||
return d_ptr->m_SectorsPerTrack;
|
||||
}
|
||||
|
||||
qint64 DiskDevice::physicalSectorSize() const
|
||||
{
|
||||
return d_ptr->m_PhysicalSectorSize;
|
||||
}
|
||||
|
||||
qint64 DiskDevice::logicalSectorSize() const
|
||||
{
|
||||
return d_ptr->m_LogicalSectorSize;
|
||||
}
|
||||
|
||||
qint64 DiskDevice::totalSectors() const
|
||||
{
|
||||
return static_cast<qint64>(d_ptr->m_Heads) * d_ptr->m_Cylinders * d_ptr->m_SectorsPerTrack;
|
||||
}
|
||||
|
||||
qint64 DiskDevice::cylinderSize() const
|
||||
{
|
||||
return static_cast<qint64>(d_ptr->m_Heads) * d_ptr->m_SectorsPerTrack;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2008 by Volker Lanz <vl@fidra.de> *
|
||||
* Copyright (C) 2018 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 *
|
||||
|
@ -15,13 +16,14 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(KPMCORE_DISKDEVICE_H)
|
||||
|
||||
#ifndef KPMCORE_DISKDEVICE_H
|
||||
#define KPMCORE_DISKDEVICE_H
|
||||
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
#include "core/device.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QString>
|
||||
#include <QObject>
|
||||
#include <QtGlobal>
|
||||
|
@ -30,6 +32,7 @@ class PartitionTable;
|
|||
class CreatePartitionTableOperation;
|
||||
class CoreBackend;
|
||||
class SmartStatus;
|
||||
class DiskDevicePrivate;
|
||||
|
||||
/** A disk device.
|
||||
|
||||
|
@ -40,6 +43,7 @@ class SmartStatus;
|
|||
@see PartitionTable, Partition
|
||||
@author Volker Lanz <vl@fidra.de>
|
||||
*/
|
||||
|
||||
class LIBKPMCORE_EXPORT DiskDevice : public Device
|
||||
{
|
||||
Q_DISABLE_COPY(DiskDevice)
|
||||
|
@ -51,34 +55,42 @@ public:
|
|||
DiskDevice(const QString& name, const QString& deviceNode, qint32 heads, qint32 numSectors, qint32 cylinders, qint64 sectorSize, const QString& iconName = QString());
|
||||
|
||||
public:
|
||||
qint32 heads() const {
|
||||
return m_Heads; /**< @return the number of heads on the Device in CHS notation */
|
||||
}
|
||||
qint32 cylinders() const {
|
||||
return m_Cylinders; /**< @return the number of cylinders on the Device in CHS notation */
|
||||
}
|
||||
qint32 sectorsPerTrack() const {
|
||||
return m_SectorsPerTrack; /**< @return the number of sectors on the Device in CHS notation */
|
||||
}
|
||||
qint64 physicalSectorSize() const {
|
||||
return m_PhysicalSectorSize; /**< @return the physical sector size the Device uses or -1 if unknown */
|
||||
}
|
||||
qint64 logicalSectorSize() const {
|
||||
return m_LogicalSectorSize; /**< @return the logical sector size the Device uses */
|
||||
}
|
||||
qint64 totalSectors() const {
|
||||
return static_cast<qint64>(heads()) * cylinders() * sectorsPerTrack(); /**< @return the total number of sectors on the device */
|
||||
}
|
||||
qint64 cylinderSize() const {
|
||||
return static_cast<qint64>(heads()) * sectorsPerTrack(); /**< @return the size of a cylinder on this Device in sectors */
|
||||
}
|
||||
/**
|
||||
* @return the number of heads on the Device in CHS notation
|
||||
*/
|
||||
[[deprecated]]
|
||||
qint32 heads() const;
|
||||
|
||||
private:
|
||||
qint32 m_Heads;
|
||||
qint32 m_SectorsPerTrack;
|
||||
qint32 m_Cylinders;
|
||||
qint64 m_LogicalSectorSize;
|
||||
qint64 m_PhysicalSectorSize;
|
||||
/**
|
||||
* @return the number of cylinders on the Device in CHS notation
|
||||
*/
|
||||
[[deprecated]]
|
||||
qint32 cylinders() const;
|
||||
|
||||
/**
|
||||
* @return the number of sectors on the Device in CHS notation
|
||||
*/
|
||||
qint32 sectorsPerTrack() const;
|
||||
|
||||
/**
|
||||
* @return the physical sector size the Device uses or -1 if unknown
|
||||
*/
|
||||
qint64 physicalSectorSize() const;
|
||||
|
||||
/**
|
||||
* @return the logical sector size the Device uses
|
||||
*/
|
||||
qint64 logicalSectorSize() const;
|
||||
|
||||
/**
|
||||
* @return the total number of sectors on the device
|
||||
*/
|
||||
qint64 totalSectors() const;
|
||||
|
||||
/**
|
||||
* @return the size of a cylinder on this Device in sectors
|
||||
*/
|
||||
qint64 cylinderSize() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,38 +18,47 @@
|
|||
*************************************************************************/
|
||||
|
||||
#include "core/fstab.h"
|
||||
#include "util/externalcommand.h"
|
||||
|
||||
#include <blkid/blkid.h>
|
||||
#if defined(Q_OS_LINUX)
|
||||
#include <blkid/blkid.h>
|
||||
#endif
|
||||
|
||||
#include <QChar>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QRegularExpression>
|
||||
#include <QTemporaryFile>
|
||||
#include <QTextStream>
|
||||
|
||||
static void parseFsSpec(const QString& m_fsSpec, FstabEntryType& m_entryType, QString& m_deviceNode);
|
||||
static QString findBlkIdDevice(const QString& token, const QString& value);
|
||||
static void parseFsSpec(const QString& m_fsSpec, FstabEntry::Type& m_entryType, QString& m_deviceNode);
|
||||
static QString findBlkIdDevice(const char *token, const QString& value);
|
||||
|
||||
FstabEntry::FstabEntry(const QString& fsSpec, const QString& mountPoint, const QString& type, const QString& options, int dumpFreq, int passNumber, const QString& comment)
|
||||
: m_fsSpec(fsSpec)
|
||||
, m_mountPoint(mountPoint)
|
||||
, m_type(type)
|
||||
, m_dumpFreq(dumpFreq)
|
||||
, m_passNumber(passNumber)
|
||||
, m_comment(comment)
|
||||
struct FstabEntryPrivate
|
||||
{
|
||||
m_options = options.split(QLatin1Char(','));
|
||||
parseFsSpec(m_fsSpec, m_entryType, m_deviceNode);
|
||||
}
|
||||
QString m_fsSpec;
|
||||
QString m_deviceNode;
|
||||
QString m_mountPoint;
|
||||
QString m_type;
|
||||
QStringList m_options;
|
||||
int m_dumpFreq;
|
||||
int m_passNumber;
|
||||
QString m_comment;
|
||||
FstabEntry::Type m_entryType;
|
||||
};
|
||||
|
||||
/**
|
||||
@param s the new value for the fs_spec field of fstab entry
|
||||
*/
|
||||
void FstabEntry::setFsSpec(const QString& s)
|
||||
FstabEntry::FstabEntry(const QString& fsSpec, const QString& mountPoint, const QString& type, const QString& options, int dumpFreq, int passNumber, const QString& comment) :
|
||||
d(std::make_unique<FstabEntryPrivate>())
|
||||
{
|
||||
m_fsSpec = s;
|
||||
parseFsSpec(m_fsSpec, m_entryType, m_deviceNode);
|
||||
d->m_fsSpec = fsSpec;
|
||||
d->m_mountPoint = mountPoint;
|
||||
d->m_type = type;
|
||||
d->m_dumpFreq = dumpFreq;
|
||||
d->m_passNumber = passNumber;
|
||||
d->m_comment = comment;
|
||||
|
||||
d->m_options = options.split(QLatin1Char(','));
|
||||
parseFsSpec(d->m_fsSpec, d->m_entryType, d->m_deviceNode);
|
||||
}
|
||||
|
||||
FstabEntryList readFstabEntries( const QString& fstabPath )
|
||||
|
@ -63,7 +72,7 @@ FstabEntryList readFstabEntries( const QString& fstabPath )
|
|||
{
|
||||
QString line = rawLine.trimmed();
|
||||
if ( line.startsWith( QLatin1Char('#') ) || line.isEmpty()) {
|
||||
fstabEntries.append( { {}, {}, {}, {}, {}, {}, line } );
|
||||
fstabEntries.push_back( { {}, {}, {}, {}, {}, {}, line } );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -80,27 +89,98 @@ FstabEntryList readFstabEntries( const QString& fstabPath )
|
|||
// (#) comment (optional).
|
||||
switch (splitLine.length()) {
|
||||
case 4:
|
||||
fstabEntries.append( {splitLine.at(0), splitLine.at(1), splitLine.at(2), splitLine.at(3) } );
|
||||
fstabEntries.push_back( {splitLine.at(0), splitLine.at(1), splitLine.at(2), splitLine.at(3) } );
|
||||
break;
|
||||
case 5:
|
||||
fstabEntries.append( {splitLine.at(0), splitLine.at(1), splitLine.at(2), splitLine.at(3), splitLine.at(4).toInt() } );
|
||||
fstabEntries.push_back( {splitLine.at(0), splitLine.at(1), splitLine.at(2), splitLine.at(3), splitLine.at(4).toInt() } );
|
||||
break;
|
||||
case 6:
|
||||
fstabEntries.append( {splitLine.at(0), splitLine.at(1), splitLine.at(2), splitLine.at(3), splitLine.at(4).toInt(), splitLine.at(5).toInt(), comment.isEmpty() ? QString() : QLatin1Char('#') + comment } );
|
||||
fstabEntries.push_back( {splitLine.at(0), splitLine.at(1), splitLine.at(2), splitLine.at(3), splitLine.at(4).toInt(), splitLine.at(5).toInt(), comment.isEmpty() ? QString() : QLatin1Char('#') + comment } );
|
||||
break;
|
||||
default:
|
||||
fstabEntries.append( { {}, {}, {}, {}, {}, {}, QLatin1Char('#') + line } );
|
||||
fstabEntries.push_back( { {}, {}, {}, {}, {}, {}, QLatin1Char('#') + line } );
|
||||
}
|
||||
}
|
||||
|
||||
fstabFile.close();
|
||||
if (fstabEntries.last().entryType() == comment && fstabEntries.last().comment().isEmpty())
|
||||
fstabEntries.removeLast();
|
||||
if (fstabEntries.back().entryType() == FstabEntry::Type::comment && fstabEntries.back().comment().isEmpty())
|
||||
fstabEntries.pop_back();
|
||||
}
|
||||
|
||||
return fstabEntries;
|
||||
}
|
||||
|
||||
void FstabEntry::setFsSpec(const QString& s)
|
||||
{
|
||||
d->m_fsSpec = s;
|
||||
parseFsSpec(d->m_fsSpec, d->m_entryType, d->m_deviceNode);
|
||||
}
|
||||
|
||||
const QString& FstabEntry::fsSpec() const
|
||||
{
|
||||
return d->m_fsSpec;
|
||||
}
|
||||
|
||||
const QString& FstabEntry::deviceNode() const
|
||||
{
|
||||
return d->m_deviceNode;
|
||||
}
|
||||
|
||||
const QString& FstabEntry::mountPoint() const
|
||||
{
|
||||
return d->m_mountPoint;
|
||||
}
|
||||
|
||||
const QString& FstabEntry::type() const
|
||||
{
|
||||
return d->m_type;
|
||||
}
|
||||
|
||||
const QStringList& FstabEntry::options() const
|
||||
{
|
||||
return d->m_options;
|
||||
}
|
||||
|
||||
int FstabEntry::dumpFreq() const
|
||||
{
|
||||
return d->m_dumpFreq;
|
||||
}
|
||||
|
||||
int FstabEntry::passNumber() const
|
||||
{
|
||||
return d->m_passNumber;
|
||||
}
|
||||
|
||||
const QString& FstabEntry::comment() const
|
||||
{
|
||||
return d->m_comment;
|
||||
}
|
||||
|
||||
FstabEntry::Type FstabEntry::entryType() const
|
||||
{
|
||||
return d->m_entryType;
|
||||
}
|
||||
|
||||
void FstabEntry::setMountPoint(const QString& s)
|
||||
{
|
||||
d->m_mountPoint = s;
|
||||
}
|
||||
|
||||
void FstabEntry::setOptions(const QStringList& s)
|
||||
{
|
||||
d->m_options = s;
|
||||
}
|
||||
|
||||
void FstabEntry::setDumpFreq(int s)
|
||||
{
|
||||
d->m_dumpFreq = s;
|
||||
}
|
||||
|
||||
void FstabEntry::setPassNumber(int s)
|
||||
{
|
||||
d->m_passNumber = s;
|
||||
}
|
||||
|
||||
QStringList possibleMountPoints(const QString& deviceNode, const QString& fstabPath)
|
||||
{
|
||||
QStringList mountPoints;
|
||||
|
@ -113,40 +193,37 @@ QStringList possibleMountPoints(const QString& deviceNode, const QString& fstabP
|
|||
return mountPoints;
|
||||
}
|
||||
|
||||
static QString findBlkIdDevice(const QString& token, const QString& value)
|
||||
static QString findBlkIdDevice(const char *token, const QString& value)
|
||||
{
|
||||
blkid_cache cache;
|
||||
QString rval;
|
||||
|
||||
if (blkid_get_cache(&cache, nullptr) == 0) {
|
||||
if (char* c = blkid_evaluate_tag(token.toLocal8Bit().constData(), value.toLocal8Bit().constData(), &cache)) {
|
||||
#if defined(Q_OS_LINUX)
|
||||
if (char* c = blkid_evaluate_tag(token, value.toLocal8Bit().constData(), nullptr)) {
|
||||
rval = QString::fromLocal8Bit(c);
|
||||
free(c);
|
||||
}
|
||||
|
||||
blkid_put_cache(cache);
|
||||
}
|
||||
#endif
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
static void parseFsSpec(const QString& m_fsSpec, FstabEntryType& m_entryType, QString& m_deviceNode)
|
||||
static void parseFsSpec(const QString& m_fsSpec, FstabEntry::Type& m_entryType, QString& m_deviceNode)
|
||||
{
|
||||
m_entryType = FstabEntryType::comment;
|
||||
m_entryType = FstabEntry::Type::comment;
|
||||
if (m_fsSpec.startsWith(QStringLiteral("UUID="))) {
|
||||
m_entryType = FstabEntryType::uuid;
|
||||
m_deviceNode = findBlkIdDevice(QStringLiteral("UUID"), QString(m_fsSpec).remove(QStringLiteral("UUID=")));
|
||||
m_entryType = FstabEntry::Type::uuid;
|
||||
m_deviceNode = findBlkIdDevice("UUID", QString(m_fsSpec).remove(QStringLiteral("UUID=")));
|
||||
} else if (m_fsSpec.startsWith(QStringLiteral("LABEL="))) {
|
||||
m_entryType = FstabEntryType::label;
|
||||
m_deviceNode = findBlkIdDevice(QStringLiteral("LABEL"), QString(m_fsSpec).remove(QStringLiteral("LABEL=")));
|
||||
m_entryType = FstabEntry::Type::label;
|
||||
m_deviceNode = findBlkIdDevice("LABEL", QString(m_fsSpec).remove(QStringLiteral("LABEL=")));
|
||||
} else if (m_fsSpec.startsWith(QStringLiteral("PARTUUID="))) {
|
||||
m_entryType = FstabEntryType::uuid;
|
||||
m_deviceNode = findBlkIdDevice(QStringLiteral("PARTUUID"), QString(m_fsSpec).remove(QStringLiteral("PARTUUID=")));
|
||||
m_entryType = FstabEntry::Type::uuid;
|
||||
m_deviceNode = findBlkIdDevice("PARTUUID", QString(m_fsSpec).remove(QStringLiteral("PARTUUID=")));
|
||||
} else if (m_fsSpec.startsWith(QStringLiteral("PARTLABEL="))) {
|
||||
m_entryType = FstabEntryType::label;
|
||||
m_deviceNode = findBlkIdDevice(QStringLiteral("PARTLABEL"), QString(m_fsSpec).remove(QStringLiteral("PARTLABEL=")));
|
||||
m_entryType = FstabEntry::Type::label;
|
||||
m_deviceNode = findBlkIdDevice("PARTLABEL", QString(m_fsSpec).remove(QStringLiteral("PARTLABEL=")));
|
||||
} else if (m_fsSpec.startsWith(QStringLiteral("/"))) {
|
||||
m_entryType = FstabEntryType::deviceNode;
|
||||
m_entryType = FstabEntry::Type::deviceNode;
|
||||
m_deviceNode = m_fsSpec;
|
||||
}
|
||||
}
|
||||
|
@ -154,7 +231,7 @@ static void parseFsSpec(const QString& m_fsSpec, FstabEntryType& m_entryType, QS
|
|||
static void writeEntry(QFile& output, const FstabEntry& entry)
|
||||
{
|
||||
QTextStream s(&output);
|
||||
if (entry.entryType() == FstabEntryType::comment) {
|
||||
if (entry.entryType() == FstabEntry::Type::comment) {
|
||||
s << entry.comment() << "\n";
|
||||
return;
|
||||
}
|
||||
|
@ -177,34 +254,34 @@ static void writeEntry(QFile& output, const FstabEntry& entry)
|
|||
<< entry.comment() << "\n";
|
||||
}
|
||||
|
||||
bool writeMountpoints(const FstabEntryList fstabEntries, const QString& filename)
|
||||
bool writeMountpoints(const FstabEntryList& fstabEntries, const QString& filename)
|
||||
{
|
||||
bool rval = true;
|
||||
const QString newFilename = QStringLiteral("%1.new").arg(filename);
|
||||
QFile out(newFilename);
|
||||
QTemporaryFile out;
|
||||
out.setAutoRemove(false);
|
||||
|
||||
if (!out.open(QFile::ReadWrite | QFile::Truncate)) {
|
||||
qWarning() << "could not open output file " << newFilename;
|
||||
rval = false;
|
||||
if (!out.open()) {
|
||||
qWarning() << "could not open output file " << out.fileName();
|
||||
return false;
|
||||
} else {
|
||||
for (const auto &e : fstabEntries)
|
||||
writeEntry(out, e);
|
||||
|
||||
out.close();
|
||||
|
||||
const QString bakFilename = QStringLiteral("%1.bak").arg(filename);
|
||||
QFile::remove(bakFilename);
|
||||
ExternalCommand mvCmd(QStringLiteral("mv"), { filename, bakFilename } );
|
||||
|
||||
if (QFile::exists(filename) && !QFile::rename(filename, bakFilename)) {
|
||||
qWarning() << "could not rename " << filename << " to " << bakFilename;
|
||||
rval = false;
|
||||
if ( !(mvCmd.run(-1) && mvCmd.exitCode() == 0) ) {
|
||||
qWarning() << "could not backup " << filename << " to " << bakFilename;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rval && !QFile::rename(newFilename, filename)) {
|
||||
qWarning() << "could not rename " << newFilename << " to " << filename;
|
||||
rval = false;
|
||||
ExternalCommand mvCmd2(QStringLiteral("mv"), { out.fileName(), filename } );
|
||||
|
||||
if ( !(mvCmd2.run(-1) && mvCmd2.exitCode() == 0) ) {
|
||||
qWarning() << "could not move " << out.fileName() << " to " << filename;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return rval;
|
||||
return true;
|
||||
}
|
||||
|
|
127
src/core/fstab.h
127
src/core/fstab.h
|
@ -1,5 +1,5 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2017 by Andrius Štikonas <andrius@stikonas.eu> *
|
||||
* Copyright (C) 2017-2018 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 *
|
||||
|
@ -20,10 +20,12 @@
|
|||
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
|
||||
enum FstabEntryType { deviceNode, uuid, label, partlabel, partuuid, comment };
|
||||
struct FstabEntryPrivate;
|
||||
|
||||
/** Base class for fstab handling.
|
||||
|
||||
|
@ -35,65 +37,88 @@ enum FstabEntryType { deviceNode, uuid, label, partlabel, partuuid, comment };
|
|||
class LIBKPMCORE_EXPORT FstabEntry
|
||||
{
|
||||
public:
|
||||
enum class Type { deviceNode, uuid, label, partlabel, partuuid, comment };
|
||||
|
||||
FstabEntry(const QString& fsSpec, const QString& mountPoint, const QString& type, const QString& options, int dumpFreq = 0, int passNumber = 0, const QString& comment = QString());
|
||||
|
||||
const QString& fsSpec() const {
|
||||
return m_fsSpec; /**< @return the fs_spec field of fstab entry */
|
||||
}
|
||||
const QString& deviceNode() const {
|
||||
return m_deviceNode; /**< @return the device node corresponding to fs_spec entry */
|
||||
}
|
||||
const QString& mountPoint() const {
|
||||
return m_mountPoint; /**< @return the mount point (target) for the file system */
|
||||
}
|
||||
const QString& type() const {
|
||||
return m_type; /**< @return the type of the file system */
|
||||
}
|
||||
const QStringList& options() const {
|
||||
return m_options; /**< @return the mount options associated with the file system */
|
||||
}
|
||||
int dumpFreq() const {
|
||||
return m_dumpFreq; /**< @return the fs_freq field of fstab entry */
|
||||
}
|
||||
int passNumber() const {
|
||||
return m_passNumber; /**< @return the fs_passno field of fstab entry */
|
||||
}
|
||||
const QString& comment() const {
|
||||
return m_comment; /**< @return commented part of the line in fstab file */
|
||||
}
|
||||
FstabEntryType entryType() const {
|
||||
return m_entryType; /**< @return the type of fstab entry, e.g. device node or UUID or comment only */
|
||||
}
|
||||
/**
|
||||
* @return the fs_spec field of fstab entry
|
||||
*/
|
||||
const QString& fsSpec() const;
|
||||
|
||||
/**
|
||||
* @return the device node corresponding to fs_spec entry
|
||||
*/
|
||||
const QString& deviceNode() const;
|
||||
|
||||
/**
|
||||
* @return the mount point (target) for the file system
|
||||
*/
|
||||
const QString& mountPoint() const;
|
||||
|
||||
/**
|
||||
* @return the type of the file system
|
||||
*/
|
||||
const QString& type() const;
|
||||
|
||||
/**
|
||||
* @return the mount options associated with the file system
|
||||
*/
|
||||
const QStringList& options() const;
|
||||
|
||||
/**
|
||||
* @return the fs_freq field of fstab entry
|
||||
*/
|
||||
int dumpFreq() const;
|
||||
|
||||
/**
|
||||
* @return the fs_passno field of fstab entry
|
||||
*/
|
||||
int passNumber() const;
|
||||
|
||||
/**
|
||||
* @return commented part of the line in fstab file
|
||||
*/
|
||||
const QString& comment() const;
|
||||
|
||||
/**
|
||||
* @return the type of fstab entry, e.g. device node or UUID or comment only
|
||||
*/
|
||||
Type entryType() const;
|
||||
|
||||
/**
|
||||
* @param s the new value for the fs_spec field of fstab entry
|
||||
*/
|
||||
void setFsSpec(const QString& s);
|
||||
void setMountPoint(const QString& s) {
|
||||
m_mountPoint = s; /**< @param s the new value for the mount point */
|
||||
}
|
||||
void setOptions(const QStringList& s) {
|
||||
m_options = s; /**< @param s the new list with the mount options */
|
||||
}
|
||||
void setDumpFreq(int s) {
|
||||
m_dumpFreq = s; /**< @param s the new value for the dump frequency */
|
||||
}
|
||||
void setPassNumber(int s) {
|
||||
m_passNumber = s; /**< @param s the new value for the pass number */
|
||||
}
|
||||
|
||||
/**
|
||||
* @param s the new value for the mount point
|
||||
*/
|
||||
void setMountPoint(const QString& s);
|
||||
|
||||
/**
|
||||
* @param s the new list with the mount options
|
||||
*/
|
||||
void setOptions(const QStringList& s);
|
||||
|
||||
/**
|
||||
* @param s the new value for the dump frequency
|
||||
*/
|
||||
void setDumpFreq(int s);
|
||||
|
||||
/**
|
||||
* @param s the new value for the pass number
|
||||
*/
|
||||
void setPassNumber(int s);
|
||||
|
||||
private:
|
||||
QString m_fsSpec;
|
||||
QString m_deviceNode;
|
||||
QString m_mountPoint;
|
||||
QString m_type;
|
||||
QStringList m_options;
|
||||
int m_dumpFreq;
|
||||
int m_passNumber;
|
||||
QString m_comment;
|
||||
FstabEntryType m_entryType;
|
||||
std::shared_ptr<FstabEntryPrivate> d;
|
||||
};
|
||||
|
||||
typedef QList<FstabEntry> FstabEntryList;
|
||||
|
||||
LIBKPMCORE_EXPORT FstabEntryList readFstabEntries(const QString& fstabPath = QStringLiteral("/etc/fstab"));
|
||||
LIBKPMCORE_EXPORT QStringList possibleMountPoints(const QString& deviceNode, const QString& fstabPath = QStringLiteral("/etc/fstab"));
|
||||
LIBKPMCORE_EXPORT bool writeMountpoints(const FstabEntryList fstabEntries, const QString& filename = QStringLiteral("/etc/fstab"));
|
||||
LIBKPMCORE_EXPORT bool writeMountpoints(const FstabEntryList& fstabEntries, const QString& filename = QStringLiteral("/etc/fstab"));
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,14 +18,16 @@
|
|||
|
||||
#include "core/lvmdevice.h"
|
||||
#include "core/partition.h"
|
||||
#include "core/partitiontable.h"
|
||||
#include "core/volumemanagerdevice_p.h"
|
||||
#include "fs/filesystem.h"
|
||||
#include "fs/lvm2_pv.h"
|
||||
#include "fs/luks.h"
|
||||
#include "fs/filesystemfactory.h"
|
||||
|
||||
#include "core/partitiontable.h"
|
||||
#include "util/externalcommand.h"
|
||||
#include "util/helpers.h"
|
||||
#include "util/globallog.h"
|
||||
#include "util/report.h"
|
||||
|
||||
#include <QRegularExpression>
|
||||
|
@ -34,26 +36,43 @@
|
|||
|
||||
#include <KLocalizedString>
|
||||
|
||||
#define d_ptr std::static_pointer_cast<LvmDevicePrivate>(d)
|
||||
|
||||
class LvmDevicePrivate : public VolumeManagerDevicePrivate
|
||||
{
|
||||
public:
|
||||
qint64 m_peSize;
|
||||
qint64 m_totalPE;
|
||||
qint64 m_allocPE;
|
||||
qint64 m_freePE;
|
||||
QString m_UUID;
|
||||
|
||||
mutable QStringList m_LVPathList;
|
||||
QVector <const Partition*> m_PVs;
|
||||
mutable std::unique_ptr<QHash<QString, qint64>> m_LVSizeMap;
|
||||
};
|
||||
|
||||
/** Constructs a representation of LVM device with initialized LV as Partitions
|
||||
*
|
||||
* @param vgName Volume Group name
|
||||
* @param iconName Icon representing LVM Volume group
|
||||
*/
|
||||
LvmDevice::LvmDevice(const QString& vgName, const QString& iconName)
|
||||
: VolumeManagerDevice(vgName,
|
||||
: VolumeManagerDevice(std::make_shared<LvmDevicePrivate>(),
|
||||
vgName,
|
||||
(QStringLiteral("/dev/") + vgName),
|
||||
getPeSize(vgName),
|
||||
getTotalPE(vgName),
|
||||
iconName,
|
||||
Device::LVM_Device)
|
||||
Device::Type::LVM_Device)
|
||||
{
|
||||
m_peSize = logicalSize();
|
||||
m_totalPE = totalLogical();
|
||||
m_freePE = getFreePE(vgName);
|
||||
m_allocPE = m_totalPE - m_freePE;
|
||||
m_UUID = getUUID(vgName);
|
||||
m_LVPathList = new QStringList(getLVs(vgName));
|
||||
m_LVSizeMap = new QHash<QString, qint64>();
|
||||
d_ptr->m_peSize = logicalSize();
|
||||
d_ptr->m_totalPE = totalLogical();
|
||||
d_ptr->m_freePE = getFreePE(vgName);
|
||||
d_ptr->m_allocPE = d_ptr->m_totalPE - d_ptr->m_freePE;
|
||||
d_ptr->m_UUID = getUUID(vgName);
|
||||
d_ptr->m_LVPathList = getLVs(vgName);
|
||||
d_ptr->m_LVSizeMap = std::make_unique<QHash<QString, qint64>>();
|
||||
|
||||
initPartitions();
|
||||
}
|
||||
|
@ -64,36 +83,47 @@ LvmDevice::LvmDevice(const QString& vgName, const QString& iconName)
|
|||
*/
|
||||
QVector<const Partition*> LvmDevice::s_DirtyPVs;
|
||||
|
||||
|
||||
/**
|
||||
* shared list of PVs paths that are member of VGs that will be deleted soon.
|
||||
*/
|
||||
QVector<const Partition*> LvmDevice::s_OrphanPVs;
|
||||
|
||||
LvmDevice::~LvmDevice()
|
||||
{
|
||||
delete m_LVPathList;
|
||||
delete m_LVSizeMap;
|
||||
}
|
||||
|
||||
void LvmDevice::initPartitions()
|
||||
{
|
||||
qint64 firstUsable = 0;
|
||||
qint64 lastusable = totalPE() - 1;
|
||||
PartitionTable* pTable = new PartitionTable(PartitionTable::vmd, firstUsable, lastusable);
|
||||
qint64 lastUsable = totalPE() - 1;
|
||||
PartitionTable* pTable = new PartitionTable(PartitionTable::vmd, firstUsable, lastUsable);
|
||||
|
||||
for (const auto &p : scanPartitions(pTable)) {
|
||||
LVSizeMap()->insert(p->partitionPath(), p->length());
|
||||
pTable->append(p);
|
||||
}
|
||||
|
||||
if (pTable)
|
||||
pTable->updateUnallocated(*this);
|
||||
else
|
||||
pTable = new PartitionTable(PartitionTable::vmd, firstUsable, lastUsable);
|
||||
|
||||
setPartitionTable(pTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan LVM LV Partitions
|
||||
*
|
||||
* @param pTable Virtual PartitionTable of LVM device
|
||||
* @return an initialized Partition(LV) list
|
||||
*/
|
||||
const QList<Partition*> LvmDevice::scanPartitions(PartitionTable* pTable) const
|
||||
{
|
||||
QList<Partition*> pList;
|
||||
for (const auto &lvPath : partitionNodes()) {
|
||||
pList.append(scanPartition(lvPath, pTable));
|
||||
Partition *p = scanPartition(lvPath, pTable);
|
||||
pList.append(p);
|
||||
}
|
||||
return pList;
|
||||
}
|
||||
|
@ -129,7 +159,7 @@ Partition* LvmDevice::scanPartition(const QString& lvPath, PartitionTable* pTabl
|
|||
bool mounted;
|
||||
|
||||
// Handle LUKS partition
|
||||
if (fs->type() == FileSystem::Luks) {
|
||||
if (fs->type() == FileSystem::Type::Luks) {
|
||||
r |= PartitionRole::Luks;
|
||||
FS::luks* luksFs = static_cast<FS::luks*>(fs);
|
||||
luksFs->initLUKS();
|
||||
|
@ -141,9 +171,9 @@ Partition* LvmDevice::scanPartition(const QString& lvPath, PartitionTable* pTabl
|
|||
mountPoint = FileSystem::detectMountPoint(fs, lvPath);
|
||||
mounted = FileSystem::detectMountStatus(fs, lvPath);
|
||||
|
||||
if (mountPoint != QString() && fs->type() != FileSystem::LinuxSwap) {
|
||||
if (mountPoint != QString() && fs->type() != FileSystem::Type::LinuxSwap) {
|
||||
const QStorageInfo storage = QStorageInfo(mountPoint);
|
||||
if (logicalSize() > 0 && fs->type() != FileSystem::Luks && mounted && storage.isValid())
|
||||
if (logicalSize() > 0 && fs->type() != FileSystem::Type::Luks && mounted && storage.isValid())
|
||||
fs->setSectorsUsed( (storage.bytesTotal() - storage.bytesFree()) / logicalSize() );
|
||||
}
|
||||
else if (fs->supportGetUsed() == FileSystem::cmdSupportFileSystem)
|
||||
|
@ -175,23 +205,26 @@ Partition* LvmDevice::scanPartition(const QString& lvPath, PartitionTable* pTabl
|
|||
*/
|
||||
void LvmDevice::scanSystemLVM(QList<Device*>& devices)
|
||||
{
|
||||
LvmDevice::s_OrphanPVs.clear();
|
||||
|
||||
QList<LvmDevice*> lvmList;
|
||||
for (const auto &vgName : getVGs()) {
|
||||
lvmList.append(new LvmDevice(vgName));
|
||||
}
|
||||
|
||||
// Some LVM operations require additional information about LVM physical volumes which we store in LVM::pvList
|
||||
LVM::pvList = FS::lvm2_pv::getPVs(devices);
|
||||
// Some LVM operations require additional information about LVM physical volumes which we store in LVM::pvList::list()
|
||||
LVM::pvList::list().clear();
|
||||
LVM::pvList::list().append(FS::lvm2_pv::getPVs(devices));
|
||||
|
||||
// Look for LVM physical volumes in LVM VGs
|
||||
for (const auto &d : lvmList) {
|
||||
devices.append(d);
|
||||
LVM::pvList.append(FS::lvm2_pv::getPVinNode(d->partitionTable()));
|
||||
LVM::pvList::list().append(FS::lvm2_pv::getPVinNode(d->partitionTable()));
|
||||
}
|
||||
|
||||
// Inform LvmDevice about which physical volumes form that particular LvmDevice
|
||||
for (const auto &d : lvmList)
|
||||
for (const auto &p : qAsConst(LVM::pvList))
|
||||
for (const auto &p : qAsConst(LVM::pvList::list()))
|
||||
if (p.vgName() == d->name())
|
||||
d->physicalVolumes().append(p.partition());
|
||||
|
||||
|
@ -225,9 +258,9 @@ const QStringList LvmDevice::deviceNodes() const
|
|||
return pvList;
|
||||
}
|
||||
|
||||
const QStringList LvmDevice::partitionNodes() const
|
||||
const QStringList& LvmDevice::partitionNodes() const
|
||||
{
|
||||
return *LVPathList();
|
||||
return d_ptr->m_LVPathList;
|
||||
}
|
||||
|
||||
qint64 LvmDevice::partitionSize(QString& partitionPath) const
|
||||
|
@ -240,7 +273,7 @@ const QStringList LvmDevice::getVGs()
|
|||
QStringList vgList;
|
||||
QString output = getField(QStringLiteral("vg_name"));
|
||||
if (!output.isEmpty()) {
|
||||
const QStringList vgNameList = output.split(QStringLiteral("\n"), QString::SkipEmptyParts);
|
||||
const QStringList vgNameList = output.split(QLatin1Char('\n'), QString::SkipEmptyParts);
|
||||
for (const auto &vgName : vgNameList) {
|
||||
vgList.append(vgName.trimmed());
|
||||
}
|
||||
|
@ -254,7 +287,7 @@ const QStringList LvmDevice::getLVs(const QString& vgName)
|
|||
QString cmdOutput = getField(QStringLiteral("lv_path"), vgName);
|
||||
|
||||
if (cmdOutput.size()) {
|
||||
const QStringList tempPathList = cmdOutput.split(QStringLiteral("\n"), QString::SkipEmptyParts);
|
||||
const QStringList tempPathList = cmdOutput.split(QLatin1Char('\n'), QString::SkipEmptyParts);
|
||||
for (const auto &lvPath : tempPathList) {
|
||||
lvPathList.append(lvPath.trimmed());
|
||||
}
|
||||
|
@ -333,6 +366,7 @@ qint64 LvmDevice::getTotalLE(const QString& lvPath)
|
|||
return match.captured(1).toInt();
|
||||
}
|
||||
}
|
||||
Log(Log::Level::error) << xi18nc("@info:status", "An error occurred while running lvdisplay.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -419,8 +453,7 @@ bool LvmDevice::movePV(Report& report, const QString& pvPath, const QStringList&
|
|||
if (FS::lvm2_pv::getAllocatedPE(pvPath) <= 0)
|
||||
return true;
|
||||
|
||||
QStringList args = QStringList();
|
||||
args << QStringLiteral("pvmove");
|
||||
QStringList args = { QStringLiteral("pvmove") };
|
||||
args << pvPath;
|
||||
if (!destinations.isEmpty())
|
||||
for (const auto &destPath : destinations)
|
||||
|
@ -432,8 +465,7 @@ bool LvmDevice::movePV(Report& report, const QString& pvPath, const QStringList&
|
|||
|
||||
bool LvmDevice::createVG(Report& report, const QString vgName, const QVector<const Partition*>& pvList, const qint32 peSize)
|
||||
{
|
||||
QStringList args = QStringList();
|
||||
args << QStringLiteral("vgcreate") << QStringLiteral("--physicalextentsize") << QString::number(peSize);
|
||||
QStringList args = { QStringLiteral("vgcreate"), QStringLiteral("--physicalextentsize"), QString::number(peSize) };
|
||||
args << vgName;
|
||||
for (const auto &p : pvList) {
|
||||
if (p->roles().has(PartitionRole::Luks))
|
||||
|
@ -492,3 +524,43 @@ bool LvmDevice::activateLV(const QString& lvPath)
|
|||
lvPath });
|
||||
return deactivate.run(-1) && deactivate.exitCode() == 0;
|
||||
}
|
||||
|
||||
qint64 LvmDevice::peSize() const
|
||||
{
|
||||
return d_ptr->m_peSize;
|
||||
}
|
||||
|
||||
qint64 LvmDevice::totalPE() const
|
||||
{
|
||||
return d_ptr->m_totalPE;
|
||||
}
|
||||
|
||||
qint64 LvmDevice::allocatedPE() const
|
||||
{
|
||||
return d_ptr->m_allocPE;
|
||||
}
|
||||
|
||||
qint64 LvmDevice::freePE() const
|
||||
{
|
||||
return d_ptr->m_freePE;
|
||||
}
|
||||
|
||||
QString LvmDevice::UUID() const
|
||||
{
|
||||
return d_ptr->m_UUID;
|
||||
}
|
||||
|
||||
QVector <const Partition*>& LvmDevice::physicalVolumes()
|
||||
{
|
||||
return d_ptr->m_PVs;
|
||||
}
|
||||
|
||||
const QVector <const Partition*>& LvmDevice::physicalVolumes() const
|
||||
{
|
||||
return d_ptr->m_PVs;
|
||||
}
|
||||
|
||||
std::unique_ptr<QHash<QString, qint64>>& LvmDevice::LVSizeMap() const
|
||||
{
|
||||
return d_ptr->m_LVSizeMap;
|
||||
}
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(KPMCORE_LVMDEVICE_H)
|
||||
|
||||
#ifndef KPMCORE_LVMDEVICE_H
|
||||
#define KPMCORE_LVMDEVICE_H
|
||||
|
||||
#include "core/device.h"
|
||||
|
@ -52,12 +51,12 @@ public:
|
|||
|
||||
public:
|
||||
const QStringList deviceNodes() const override;
|
||||
const QStringList partitionNodes() const override;
|
||||
const QStringList& partitionNodes() const override;
|
||||
qint64 partitionSize(QString& partitionPath) const override;
|
||||
|
||||
static QVector<const Partition*> s_DirtyPVs;
|
||||
static QVector<const Partition*> s_OrphanPVs;
|
||||
|
||||
public:
|
||||
static void scanSystemLVM(QList<Device*>& devices);
|
||||
|
||||
static const QStringList getVGs();
|
||||
|
@ -89,54 +88,22 @@ public:
|
|||
static bool activateVG(Report& report, const LvmDevice& d);
|
||||
|
||||
protected:
|
||||
|
||||
void initPartitions() override;
|
||||
const QList<Partition*> scanPartitions(PartitionTable* pTable) const;
|
||||
Partition* scanPartition(const QString& lvPath, PartitionTable* pTable) const;
|
||||
qint64 mappedSector(const QString& lvPath, qint64 sector) const override;
|
||||
|
||||
public:
|
||||
qint64 peSize() const {
|
||||
return m_peSize;
|
||||
}
|
||||
qint64 totalPE() const {
|
||||
return m_totalPE;
|
||||
}
|
||||
qint64 allocatedPE() const {
|
||||
return m_allocPE;
|
||||
}
|
||||
qint64 freePE() const {
|
||||
return m_freePE;
|
||||
}
|
||||
QString UUID() const {
|
||||
return m_UUID;
|
||||
}
|
||||
QStringList* LVPathList() const {
|
||||
return m_LVPathList;
|
||||
}
|
||||
QVector <const Partition*>& physicalVolumes() {
|
||||
return m_PVs;
|
||||
}
|
||||
const QVector <const Partition*>& physicalVolumes() const {
|
||||
return m_PVs;
|
||||
}
|
||||
qint64 peSize() const;
|
||||
qint64 totalPE() const;
|
||||
qint64 allocatedPE() const;
|
||||
qint64 freePE() const;
|
||||
QString UUID() const;
|
||||
QVector <const Partition*>& physicalVolumes();
|
||||
const QVector <const Partition*>& physicalVolumes() const;
|
||||
|
||||
protected:
|
||||
QHash<QString, qint64>* LVSizeMap() const {
|
||||
return m_LVSizeMap;
|
||||
}
|
||||
|
||||
private:
|
||||
qint64 m_peSize;
|
||||
qint64 m_totalPE;
|
||||
qint64 m_allocPE;
|
||||
qint64 m_freePE;
|
||||
QString m_UUID;
|
||||
|
||||
mutable QStringList* m_LVPathList;
|
||||
QVector <const Partition*> m_PVs;
|
||||
mutable QHash<QString, qint64>* m_LVSizeMap;
|
||||
|
||||
std::unique_ptr<QHash<QString, qint64>>& LVSizeMap() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,9 +25,6 @@
|
|||
#include <QDBusReply>
|
||||
#include <QMutex>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/** Constructs an OperationRunner.
|
||||
@param ostack the OperationStack to act on
|
||||
*/
|
||||
|
@ -50,15 +47,6 @@ void OperationRunner::run()
|
|||
bool status = true;
|
||||
|
||||
// Disable Plasma removable device automounting
|
||||
unsigned int currentUid = getuid(); // 0 if running as root
|
||||
char *login = getlogin();
|
||||
if (login != nullptr){
|
||||
passwd* pwnam = getpwnam(login);
|
||||
if (pwnam != nullptr) {
|
||||
unsigned int userId = pwnam->pw_uid; // uid of original user before sudo
|
||||
seteuid(userId);
|
||||
}
|
||||
}
|
||||
QStringList modules;
|
||||
QDBusConnection bus = QDBusConnection::connectToBus(QDBusConnection::SessionBus, QStringLiteral("sessionBus"));
|
||||
QDBusInterface kdedInterface( QStringLiteral("org.kde.kded5"), QStringLiteral("/kded"), QStringLiteral("org.kde.kded5"), bus );
|
||||
|
@ -69,7 +57,6 @@ void OperationRunner::run()
|
|||
bool automounter = modules.contains(automounterService);
|
||||
if (automounter)
|
||||
kdedInterface.call( QStringLiteral("unloadModule"), automounterService );
|
||||
seteuid(currentUid);
|
||||
|
||||
for (int i = 0; i < numOperations(); i++) {
|
||||
suspendMutex().lock();
|
||||
|
|
|
@ -555,7 +555,7 @@ void OperationStack::addDevice(Device* d)
|
|||
static bool deviceLessThan(const Device* d1, const Device* d2)
|
||||
{
|
||||
// Display alphabetically sorted disk devices above LVM VGs
|
||||
if (d1->type() == Device::LVM_Device && d2->type() == Device::Disk_Device )
|
||||
if (d1->type() == Device::Type::LVM_Device && d2->type() == Device::Type::Disk_Device )
|
||||
return false;
|
||||
|
||||
return d1->deviceNode() <= d2->deviceNode();
|
||||
|
|
|
@ -80,10 +80,10 @@ public:
|
|||
New, /**< from a NewOperation */
|
||||
Copy, /**< from a CopyOperation */
|
||||
Restore, /**< from a RestoreOperation */
|
||||
StateNone = None,
|
||||
StateNew = New,
|
||||
StateCopy = Copy,
|
||||
StateRestore = Restore
|
||||
StateNone __attribute__((deprecated("Use Partition::State::None"))) = None,
|
||||
StateNew __attribute__((deprecated("Use Partition::State::New"))) = New,
|
||||
StateCopy __attribute__((deprecated("Use Partition::State::Copy"))) = Copy,
|
||||
StateRestore __attribute__((deprecated("Use Partition::State::Restore"))) = Restore
|
||||
};
|
||||
|
||||
Partition(PartitionNode* parent, const Device& device, const PartitionRole& role, FileSystem* fs, qint64 sectorStart, qint64 sectorEnd, QString partitionPath, PartitionTable::Flags availableFlags = PartitionTable::FlagNone, const QString& mountPoint = QString(), bool mounted = false, PartitionTable::Flags activeFlags = PartitionTable::FlagNone, State state = State::None);
|
||||
|
|
|
@ -85,10 +85,10 @@ bool PartitionAlignment::isAligned(const Device& d, const Partition& p, bool qui
|
|||
bool PartitionAlignment::isAligned(const Device& d, const Partition& p, qint64 newFirst, qint64 newLast, bool quiet)
|
||||
{
|
||||
if (firstDelta(d, p, newFirst) && !quiet)
|
||||
Log(Log::warning) << xi18nc("@info:status", "Partition <filename>%1</filename> is not properly aligned (first sector: %2, modulo: %3).", p.deviceNode(), newFirst, firstDelta(d, p, newFirst));
|
||||
Log(Log::Level::warning) << xi18nc("@info:status", "Partition <filename>%1</filename> is not properly aligned (first sector: %2, modulo: %3).", p.deviceNode(), newFirst, firstDelta(d, p, newFirst));
|
||||
|
||||
if (lastDelta(d, p, newLast) && !quiet)
|
||||
Log(Log::warning) << xi18nc("@info:status", "Partition <filename>%1</filename> is not properly aligned (last sector: %2, modulo: %3).", p.deviceNode(), newLast, lastDelta(d, p, newLast));
|
||||
Log(Log::Level::warning) << xi18nc("@info:status", "Partition <filename>%1</filename> is not properly aligned (last sector: %2, modulo: %3).", p.deviceNode(), newLast, lastDelta(d, p, newLast));
|
||||
|
||||
return firstDelta(d, p, newFirst) == 0 && lastDelta(d, p, newLast) == 0;
|
||||
}
|
||||
|
|
|
@ -274,7 +274,7 @@ QStringList PartitionTable::flagNames(Flags flags)
|
|||
|
||||
bool PartitionTable::getUnallocatedRange(const Device& d, PartitionNode& parent, qint64& start, qint64& end)
|
||||
{
|
||||
if (d.type() == Device::Disk_Device) {
|
||||
if (d.type() == Device::Type::Disk_Device) {
|
||||
const DiskDevice& device = dynamic_cast<const DiskDevice&>(d);
|
||||
if (!parent.isRoot()) {
|
||||
Partition* extended = dynamic_cast<Partition*>(&parent);
|
||||
|
@ -295,7 +295,7 @@ bool PartitionTable::getUnallocatedRange(const Device& d, PartitionNode& parent,
|
|||
}
|
||||
|
||||
return end - start + 1 >= PartitionAlignment::sectorAlignment(device);
|
||||
} else if (d.type() == Device::LVM_Device) {
|
||||
} else if (d.type() == Device::Type::LVM_Device || d.type() == Device::Type::SoftwareRAID_Device) {
|
||||
if (end - start + 1 > 0) {
|
||||
return true;
|
||||
}
|
||||
|
@ -319,13 +319,13 @@ Partition* createUnallocated(const Device& device, PartitionNode& parent, qint64
|
|||
r |= PartitionRole::Logical;
|
||||
|
||||
// Mark unallocated space in LVM VG as LVM LV so that pasting can be easily disabled (it does not work yet)
|
||||
if (device.type() == Device::LVM_Device)
|
||||
if (device.type() == Device::Type::LVM_Device)
|
||||
r |= PartitionRole::Lvm_Lv;
|
||||
|
||||
if (!PartitionTable::getUnallocatedRange(device, parent, start, end))
|
||||
return nullptr;
|
||||
|
||||
return new Partition(&parent, device, PartitionRole(r), FileSystemFactory::create(FileSystem::Unknown, start, end, device.logicalSize()), start, end, QString());
|
||||
return new Partition(&parent, device, PartitionRole(r), FileSystemFactory::create(FileSystem::Type::Unknown, start, end, device.logicalSize()), start, end, QString());
|
||||
}
|
||||
|
||||
/** Removes all unallocated children from a PartitionNode
|
||||
|
@ -379,7 +379,7 @@ void PartitionTable::insertUnallocated(const Device& d, PartitionNode* p, qint64
|
|||
|
||||
qint64 lastEnd = start;
|
||||
|
||||
if (d.type() == Device::LVM_Device && !p->children().isEmpty()) {
|
||||
if (d.type() == Device::Type::LVM_Device && !p->children().isEmpty()) {
|
||||
// rearranging the sectors of all partitions to keep unallocated space at the end
|
||||
lastEnd = 0;
|
||||
std::sort(children().begin(), children().end(), [](const Partition* p1, const Partition* p2) { return p1->deviceNode() < p2->deviceNode(); });
|
||||
|
@ -402,6 +402,13 @@ void PartitionTable::insertUnallocated(const Device& d, PartitionNode* p, qint64
|
|||
}
|
||||
}
|
||||
|
||||
if (d.type() == Device::Type::LVM_Device)
|
||||
{
|
||||
const LvmDevice& lvm = static_cast<const LvmDevice&>(d);
|
||||
p->insert(createUnallocated(d, *p, lastEnd, lastEnd + lvm.freePE() - 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Take care of the free space between the end of the last child and the end
|
||||
// of the device or the extended partition.
|
||||
qint64 parentEnd = lastUsable();
|
||||
|
@ -414,6 +421,7 @@ void PartitionTable::insertUnallocated(const Device& d, PartitionNode* p, qint64
|
|||
|
||||
if (parentEnd >= firstUsable() && parentEnd >= lastEnd)
|
||||
p->insert(createUnallocated(d, *p, lastEnd, parentEnd));
|
||||
}
|
||||
}
|
||||
|
||||
/** Updates the unallocated Partitions for this PartitionTable.
|
||||
|
@ -428,7 +436,7 @@ void PartitionTable::updateUnallocated(const Device& d)
|
|||
qint64 PartitionTable::defaultFirstUsable(const Device& d, TableType t)
|
||||
{
|
||||
Q_UNUSED(t)
|
||||
if (d.type() == Device::LVM_Device) {
|
||||
if (d.type() == Device::Type::LVM_Device || d.type() == Device::Type::SoftwareRAID_Device) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -518,7 +526,7 @@ bool PartitionTable::tableTypeIsReadOnly(TableType l)
|
|||
*/
|
||||
bool PartitionTable::isSectorBased(const Device& d) const
|
||||
{
|
||||
if (d.type() == Device::Disk_Device) {
|
||||
if (d.type() == Device::Type::Disk_Device) {
|
||||
const DiskDevice& diskDevice = dynamic_cast<const DiskDevice&>(d);
|
||||
|
||||
if (type() == PartitionTable::msdos) {
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
set(RAID_SRC
|
||||
core/raid/softwareraid.cpp
|
||||
)
|
||||
|
||||
set(RAID_LIB_HDRS
|
||||
core/raid/softwareraid.h
|
||||
)
|
|
@ -0,0 +1,480 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2018 by Caio Carvalho <caiojcarvalho@gmail.com> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 3 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "softwareraid.h"
|
||||
|
||||
#include "backend/corebackend.h"
|
||||
#include "backend/corebackendmanager.h"
|
||||
#include "core/partition.h"
|
||||
#include "core/volumemanagerdevice_p.h"
|
||||
#include "fs/filesystem.h"
|
||||
#include "fs/filesystemfactory.h"
|
||||
#include "util/externalcommand.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
#include <QFile>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#define d_ptr std::static_pointer_cast<SoftwareRAIDPrivate>(d)
|
||||
|
||||
class SoftwareRAIDPrivate : public VolumeManagerDevicePrivate
|
||||
{
|
||||
public:
|
||||
qint32 m_raidLevel;
|
||||
qint64 m_chunkSize;
|
||||
qint64 m_totalChunk;
|
||||
qint64 m_arraySize;
|
||||
QString m_UUID;
|
||||
QStringList m_devicePathList;
|
||||
SoftwareRAID::Status m_status;
|
||||
};
|
||||
|
||||
SoftwareRAID::SoftwareRAID(const QString& name, SoftwareRAID::Status status, const QString& iconName)
|
||||
: VolumeManagerDevice(std::make_shared<SoftwareRAIDPrivate>(),
|
||||
name,
|
||||
(QStringLiteral("/dev/") + name),
|
||||
getChunkSize(QStringLiteral("/dev/") + name),
|
||||
getTotalChunk(QStringLiteral("/dev/") + name),
|
||||
iconName,
|
||||
Device::Type::SoftwareRAID_Device)
|
||||
{
|
||||
d_ptr->m_raidLevel = getRaidLevel(deviceNode());
|
||||
d_ptr->m_chunkSize = logicalSize();
|
||||
d_ptr->m_totalChunk = totalLogical();
|
||||
d_ptr->m_arraySize = getArraySize(deviceNode());
|
||||
d_ptr->m_UUID = getUUID(deviceNode());
|
||||
d_ptr->m_devicePathList = getDevicePathList(deviceNode());
|
||||
d_ptr->m_status = status;
|
||||
|
||||
initPartitions();
|
||||
}
|
||||
|
||||
const QStringList SoftwareRAID::deviceNodes() const
|
||||
{
|
||||
return d_ptr->m_devicePathList;
|
||||
}
|
||||
|
||||
const QStringList& SoftwareRAID::partitionNodes() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
qint64 SoftwareRAID::partitionSize(QString &partitionPath) const
|
||||
{
|
||||
Q_UNUSED(partitionPath)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool SoftwareRAID::growArray(Report &report, const QStringList &devices)
|
||||
{
|
||||
Q_UNUSED(report)
|
||||
Q_UNUSED(devices)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SoftwareRAID::shrinkArray(Report &report, const QStringList &devices)
|
||||
{
|
||||
Q_UNUSED(report)
|
||||
Q_UNUSED(devices)
|
||||
return false;
|
||||
}
|
||||
|
||||
QString SoftwareRAID::prettyName() const
|
||||
{
|
||||
QString raidInfo;
|
||||
|
||||
if (status() == SoftwareRAID::Status::Active)
|
||||
raidInfo = xi18nc("@item:inlistbox [RAID level]", " [RAID %1]", raidLevel());
|
||||
else if (status() == SoftwareRAID::Status::Recovery)
|
||||
raidInfo = xi18nc("@item:inlistbox [RAID level - Recovering]", " [RAID %1 - Recovering]", raidLevel());
|
||||
else if (status() == SoftwareRAID::Status::Resync)
|
||||
raidInfo = xi18nc("@item:inlistbox [RAID level - Resyncing]", " [RAID %1 - Resyncing]", raidLevel());
|
||||
else
|
||||
raidInfo = QStringLiteral(" [RAID]");
|
||||
|
||||
return VolumeManagerDevice::prettyName() + raidInfo;
|
||||
}
|
||||
|
||||
bool SoftwareRAID::operator ==(const Device& other) const
|
||||
{
|
||||
bool equalDeviceNode = Device::operator ==(other);
|
||||
|
||||
if (other.type() == Device::Type::SoftwareRAID_Device) {
|
||||
const SoftwareRAID& raid = static_cast<const SoftwareRAID&>(other);
|
||||
|
||||
if (!equalDeviceNode)
|
||||
return raid.uuid() == uuid();
|
||||
}
|
||||
|
||||
return equalDeviceNode;
|
||||
}
|
||||
|
||||
qint32 SoftwareRAID::raidLevel() const
|
||||
{
|
||||
return d_ptr->m_raidLevel;
|
||||
}
|
||||
|
||||
qint64 SoftwareRAID::chunkSize() const
|
||||
{
|
||||
return d_ptr->m_chunkSize;
|
||||
}
|
||||
|
||||
qint64 SoftwareRAID::totalChunk() const
|
||||
{
|
||||
return d_ptr->m_totalChunk;
|
||||
}
|
||||
|
||||
qint64 SoftwareRAID::arraySize() const
|
||||
{
|
||||
return d_ptr->m_arraySize;
|
||||
}
|
||||
|
||||
QString SoftwareRAID::uuid() const
|
||||
{
|
||||
return d_ptr->m_UUID;
|
||||
}
|
||||
|
||||
QStringList SoftwareRAID::devicePathList() const
|
||||
{
|
||||
return d_ptr->m_devicePathList;
|
||||
}
|
||||
|
||||
SoftwareRAID::Status SoftwareRAID::status() const
|
||||
{
|
||||
return d_ptr->m_status;
|
||||
}
|
||||
|
||||
void SoftwareRAID::setStatus(SoftwareRAID::Status status)
|
||||
{
|
||||
d_ptr->m_status = status;
|
||||
}
|
||||
|
||||
void SoftwareRAID::scanSoftwareRAID(QList<Device*>& devices)
|
||||
{
|
||||
QStringList availableInConf;
|
||||
|
||||
// TODO: Support custom config files.
|
||||
QString config = getRAIDConfiguration(QStringLiteral("/etc/mdadm.conf"));
|
||||
|
||||
if (!config.isEmpty()) {
|
||||
QRegularExpression re(QStringLiteral("([\\t\\r\\n\\f\\s]|INACTIVE-)ARRAY \\/dev\\/([\\/\\w-]+)"));
|
||||
QRegularExpressionMatchIterator i = re.globalMatch(config);
|
||||
|
||||
while (i.hasNext()) {
|
||||
QRegularExpressionMatch reMatch = i.next();
|
||||
QString deviceName = reMatch.captured(2).trimmed();
|
||||
|
||||
availableInConf << deviceName;
|
||||
}
|
||||
}
|
||||
|
||||
QFile mdstat(QStringLiteral("/proc/mdstat"));
|
||||
|
||||
if (mdstat.open(QIODevice::ReadOnly)) {
|
||||
QTextStream stream(&mdstat);
|
||||
|
||||
QString content = stream.readAll();
|
||||
|
||||
mdstat.close();
|
||||
|
||||
QRegularExpression re(QStringLiteral("md([\\/\\w]+)\\s+:\\s+([\\w]+)"));
|
||||
QRegularExpressionMatchIterator i = re.globalMatch(content);
|
||||
while (i.hasNext()) {
|
||||
QRegularExpressionMatch reMatch = i.next();
|
||||
|
||||
QString deviceNode = QStringLiteral("/dev/md") + reMatch.captured(1).trimmed();
|
||||
QString status = reMatch.captured(2).trimmed();
|
||||
|
||||
SoftwareRAID* d = static_cast<SoftwareRAID *>(CoreBackendManager::self()->backend()->scanDevice(deviceNode));
|
||||
|
||||
// Just to prevent segfault in some case
|
||||
if (d == nullptr)
|
||||
continue;
|
||||
|
||||
const QStringList constAvailableInConf = availableInConf;
|
||||
|
||||
for (const QString& path : constAvailableInConf)
|
||||
if (getUUID(QStringLiteral("/dev/") + path) == d->uuid())
|
||||
availableInConf.removeAll(path);
|
||||
|
||||
devices << d;
|
||||
|
||||
if (status == QStringLiteral("inactive"))
|
||||
d->setStatus(SoftwareRAID::Status::Inactive);
|
||||
|
||||
if (d->raidLevel() > 0) {
|
||||
QRegularExpression reMirrorStatus(d->name() + QStringLiteral("\\s+:\\s+(.*\\n\\s+)+\\[[=>.]+\\]\\s+(resync|recovery)"));
|
||||
|
||||
QRegularExpressionMatch reMirrorStatusMatch = reMirrorStatus.match(content);
|
||||
|
||||
if (reMirrorStatusMatch.hasMatch()) {
|
||||
if (reMirrorStatusMatch.captured(2) == QStringLiteral("resync"))
|
||||
d->setStatus(SoftwareRAID::Status::Resync);
|
||||
else if (reMirrorStatusMatch.captured(2) == QStringLiteral("recovery"))
|
||||
d->setStatus(SoftwareRAID::Status::Recovery);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const QString& name : qAsConst(availableInConf)) {
|
||||
SoftwareRAID *raidDevice = new SoftwareRAID(name, SoftwareRAID::Status::Inactive);
|
||||
devices << raidDevice;
|
||||
}
|
||||
}
|
||||
|
||||
qint32 SoftwareRAID::getRaidLevel(const QString &path)
|
||||
{
|
||||
QString output = getDetail(path);
|
||||
|
||||
if (!output.isEmpty()) {
|
||||
QRegularExpression re(QStringLiteral("Raid Level :\\s+\\w+(\\d+)"));
|
||||
QRegularExpressionMatch reMatch = re.match(output);
|
||||
if (reMatch.hasMatch())
|
||||
return reMatch.captured(1).toLongLong();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
qint64 SoftwareRAID::getChunkSize(const QString &path)
|
||||
{
|
||||
if (getRaidLevel(path) == 1) {
|
||||
QStringList devices = getDevicePathList(path);
|
||||
|
||||
if (!devices.isEmpty()) {
|
||||
QString device = devices[0];
|
||||
// Look sector size for the first device/partition on the list, as RAID 1 is composed by mirrored devices
|
||||
ExternalCommand sectorSize(QStringLiteral("blockdev"), { QStringLiteral("--getss"), device });
|
||||
|
||||
if (sectorSize.run(-1) && sectorSize.exitCode() == 0) {
|
||||
int sectors = sectorSize.output().trimmed().toLongLong();
|
||||
return sectors;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
QString output = getDetail(path);
|
||||
if (!output.isEmpty()) {
|
||||
QRegularExpression re(QStringLiteral("Chunk Size :\\s+(\\d+)"));
|
||||
QRegularExpressionMatch reMatch = re.match(output);
|
||||
if (reMatch.hasMatch())
|
||||
return reMatch.captured(1).toLongLong();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
qint64 SoftwareRAID::getTotalChunk(const QString &path)
|
||||
{
|
||||
return getArraySize(path) / getChunkSize(path);
|
||||
}
|
||||
|
||||
qint64 SoftwareRAID::getArraySize(const QString &path)
|
||||
{
|
||||
QString output = getDetail(path);
|
||||
if (!output.isEmpty()) {
|
||||
QRegularExpression re(QStringLiteral("Array Size :\\s+(\\d+)"));
|
||||
QRegularExpressionMatch reMatch = re.match(output);
|
||||
if (reMatch.hasMatch())
|
||||
return reMatch.captured(1).toLongLong() * 1024;
|
||||
}
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
QString SoftwareRAID::getUUID(const QString &path)
|
||||
{
|
||||
QString output = getDetail(path);
|
||||
|
||||
if (!output.isEmpty()) {
|
||||
QRegularExpression re(QStringLiteral("UUID :\\s+([\\w:]+)"));
|
||||
QRegularExpressionMatch reMatch = re.match(output);
|
||||
|
||||
if (reMatch.hasMatch())
|
||||
return reMatch.captured(1);
|
||||
}
|
||||
|
||||
// If UUID was not found in detail output, it should be searched in config file
|
||||
|
||||
// TODO: Support custom config files.
|
||||
QString config = getRAIDConfiguration(QStringLiteral("/etc/mdadm.conf"));
|
||||
|
||||
if (!config.isEmpty()) {
|
||||
QRegularExpression re(QStringLiteral("([\\t\\r\\n\\f\\s]|INACTIVE-)ARRAY \\/dev\\/md([\\/\\w-]+)(.*)"));
|
||||
QRegularExpressionMatchIterator i = re.globalMatch(config);
|
||||
|
||||
while (i.hasNext()) {
|
||||
QRegularExpressionMatch reMatch = i.next();
|
||||
QString deviceNode = QStringLiteral("/dev/md") + reMatch.captured(2).trimmed();
|
||||
QString otherInfo = reMatch.captured(3).trimmed();
|
||||
|
||||
// Consider device node as name=host:deviceNode when the captured device node string has '-' character
|
||||
// It happens when user have included the device to config file using 'mdadm --examine --scan'
|
||||
if (deviceNode.contains(QLatin1Char('-'))) {
|
||||
QRegularExpression reName(QStringLiteral("name=[\\w:]+\\/dev\\/md\\/([\\/\\w]+)"));
|
||||
QRegularExpressionMatch nameMatch = reName.match(otherInfo);
|
||||
|
||||
if (nameMatch.hasMatch())
|
||||
deviceNode = nameMatch.captured(1);
|
||||
}
|
||||
|
||||
if (deviceNode == path) {
|
||||
QRegularExpression reUUID(QStringLiteral("(UUID=|uuid=)([\\w:]+)"));
|
||||
QRegularExpressionMatch uuidMatch = reUUID.match(otherInfo);
|
||||
|
||||
if (uuidMatch.hasMatch())
|
||||
return uuidMatch.captured(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
QStringList SoftwareRAID::getDevicePathList(const QString &path)
|
||||
{
|
||||
QStringList result;
|
||||
|
||||
QString detail = getDetail(path);
|
||||
|
||||
if (!detail.isEmpty()) {
|
||||
QRegularExpression re(QStringLiteral("\\s+\\/dev\\/(\\w+)"));
|
||||
QRegularExpressionMatchIterator i = re.globalMatch(detail);
|
||||
|
||||
while (i.hasNext()) {
|
||||
QRegularExpressionMatch match = i.next();
|
||||
|
||||
QString device = QStringLiteral("/dev/") + match.captured(1);
|
||||
if (device != path)
|
||||
result << device;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool SoftwareRAID::isRaidPath(const QString &path)
|
||||
{
|
||||
return !getDetail(path).isEmpty();
|
||||
}
|
||||
|
||||
bool SoftwareRAID::createSoftwareRAID(Report &report,
|
||||
const QString &name,
|
||||
const QStringList devicePathList,
|
||||
const qint32 raidLevel,
|
||||
const qint32 chunkSize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SoftwareRAID::deleteSoftwareRAID(Report &report,
|
||||
SoftwareRAID &raidDevice)
|
||||
{
|
||||
Q_UNUSED(report)
|
||||
Q_UNUSED(raidDevice)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SoftwareRAID::assembleSoftwareRAID(const QString& deviceNode)
|
||||
{
|
||||
if (!isRaidPath(deviceNode))
|
||||
return false;
|
||||
|
||||
ExternalCommand cmd(QStringLiteral("mdadm"),
|
||||
{ QStringLiteral("--assemble"), QStringLiteral("--scan"), deviceNode });
|
||||
|
||||
return cmd.run(-1) && cmd.exitCode() == 0;
|
||||
}
|
||||
|
||||
bool SoftwareRAID::stopSoftwareRAID(const QString& deviceNode)
|
||||
{
|
||||
if (!isRaidPath(deviceNode))
|
||||
return false;
|
||||
|
||||
ExternalCommand cmd(QStringLiteral("mdadm"),
|
||||
{ QStringLiteral("--manage"), QStringLiteral("--stop"), deviceNode });
|
||||
|
||||
return cmd.run(-1) && cmd.exitCode() == 0;
|
||||
}
|
||||
|
||||
bool SoftwareRAID::reassembleSoftwareRAID(const QString &deviceNode)
|
||||
{
|
||||
return stopSoftwareRAID(deviceNode) && assembleSoftwareRAID(deviceNode);
|
||||
}
|
||||
|
||||
bool SoftwareRAID::isRaidMember(const QString &path)
|
||||
{
|
||||
QFile mdstat(QStringLiteral("/proc/mdstat"));
|
||||
|
||||
if (!mdstat.open(QIODevice::ReadOnly))
|
||||
return false;
|
||||
|
||||
QTextStream stream(&mdstat);
|
||||
|
||||
QString content = stream.readAll();
|
||||
|
||||
mdstat.close();
|
||||
|
||||
QRegularExpression re(QStringLiteral("(\\w+)\\[\\d+\\]"));
|
||||
QRegularExpressionMatchIterator i = re.globalMatch(content);
|
||||
|
||||
while (i.hasNext()) {
|
||||
QRegularExpressionMatch reMatch = i.next();
|
||||
|
||||
QString match = QStringLiteral("/dev/") + reMatch.captured(1);
|
||||
|
||||
if (match == path)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SoftwareRAID::initPartitions()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
qint64 SoftwareRAID::mappedSector(const QString &partitionPath, qint64 sector) const
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
QString SoftwareRAID::getDetail(const QString &path)
|
||||
{
|
||||
ExternalCommand cmd(QStringLiteral("mdadm"),
|
||||
{ QStringLiteral("--misc"), QStringLiteral("--detail"), path });
|
||||
return (cmd.run(-1) && cmd.exitCode() == 0) ? cmd.output() : QString();
|
||||
}
|
||||
|
||||
QString SoftwareRAID::getRAIDConfiguration(const QString &configurationPath)
|
||||
{
|
||||
QFile config(configurationPath);
|
||||
|
||||
if (!config.open(QIODevice::ReadOnly))
|
||||
return QString();
|
||||
|
||||
QTextStream stream(&config);
|
||||
|
||||
QString result = stream.readAll();
|
||||
|
||||
config.close();
|
||||
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2018 by Caio Carvalho <caiojcarvalho@gmail.com> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 3 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(KPMCORE_SOFTWARERAID_H)
|
||||
#define KPMCORE_SOFTWARERAID_H
|
||||
|
||||
#include "core/volumemanagerdevice.h"
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
#include "util/report.h"
|
||||
|
||||
class LIBKPMCORE_EXPORT SoftwareRAID : public VolumeManagerDevice
|
||||
{
|
||||
Q_DISABLE_COPY(SoftwareRAID)
|
||||
|
||||
public:
|
||||
enum class Status {
|
||||
Active,
|
||||
Inactive,
|
||||
Resync,
|
||||
Recovery,
|
||||
};
|
||||
|
||||
SoftwareRAID(const QString& name,
|
||||
SoftwareRAID::Status status = SoftwareRAID::Status::Active,
|
||||
const QString& iconName = QString());
|
||||
|
||||
const QStringList deviceNodes() const override;
|
||||
const QStringList& partitionNodes() const override;
|
||||
qint64 partitionSize(QString &partitionPath) const override;
|
||||
|
||||
virtual bool growArray(Report& report, const QStringList& devices);
|
||||
|
||||
virtual bool shrinkArray(Report& report, const QStringList& devices);
|
||||
|
||||
virtual QString prettyName() const override;
|
||||
|
||||
virtual bool operator==(const Device& other) const override;
|
||||
|
||||
qint32 raidLevel() const;
|
||||
qint64 chunkSize() const;
|
||||
qint64 totalChunk() const;
|
||||
qint64 arraySize() const;
|
||||
QString uuid() const;
|
||||
QStringList devicePathList() const;
|
||||
SoftwareRAID::Status status() const;
|
||||
|
||||
void setStatus(SoftwareRAID::Status status);
|
||||
|
||||
public:
|
||||
static void scanSoftwareRAID(QList<Device*>& devices);
|
||||
|
||||
static qint32 getRaidLevel(const QString& path);
|
||||
static qint64 getChunkSize(const QString& path);
|
||||
static qint64 getTotalChunk(const QString& path);
|
||||
static qint64 getArraySize(const QString& path);
|
||||
static QString getUUID(const QString& path);
|
||||
static QStringList getDevicePathList(const QString& path);
|
||||
|
||||
static bool isRaidPath(const QString& path);
|
||||
|
||||
static bool createSoftwareRAID(Report& report,
|
||||
const QString& name,
|
||||
const QStringList devicePathList,
|
||||
const qint32 raidLevel,
|
||||
const qint32 chunkSize);
|
||||
|
||||
static bool deleteSoftwareRAID(Report& report,
|
||||
SoftwareRAID& raidDevice);
|
||||
|
||||
static bool assembleSoftwareRAID(const QString& deviceNode);
|
||||
|
||||
static bool stopSoftwareRAID(const QString& deviceNode);
|
||||
|
||||
static bool reassembleSoftwareRAID(const QString& deviceNode);
|
||||
|
||||
static bool isRaidMember(const QString& path);
|
||||
|
||||
protected:
|
||||
void initPartitions() override;
|
||||
|
||||
qint64 mappedSector(const QString &partitionPath, qint64 sector) const override;
|
||||
|
||||
private:
|
||||
static QString getDetail(const QString& path);
|
||||
|
||||
static QString getRAIDConfiguration(const QString& configurationPath);
|
||||
};
|
||||
|
||||
#endif // SOFTWARERAID_H
|
|
@ -18,78 +18,78 @@
|
|||
|
||||
#include "core/smartattribute.h"
|
||||
#include "core/smartstatus.h"
|
||||
#include "core/smartattributeparseddata.h"
|
||||
|
||||
#include <QLocale>
|
||||
|
||||
#include <KLocalizedString>
|
||||
#include <KFormat>
|
||||
|
||||
#include <atasmart.h>
|
||||
|
||||
static QString getAttrName(qint32 id);
|
||||
static QString getAttrDescription(qint32 id);
|
||||
static QString getPrettyValue(quint64 value, qint64 unit);
|
||||
static SmartAttribute::Assessment getAssessment(const SkSmartAttributeParsedData* a);
|
||||
static QString getRaw(const uint8_t*);
|
||||
static QString getPrettyValue(quint64 value, SmartAttributeUnit unit);
|
||||
static SmartAttribute::Assessment getAssessment(const SmartAttributeParsedData& a);
|
||||
static QString getRaw(quint64 raw);
|
||||
|
||||
SmartAttribute::SmartAttribute(const SkSmartAttributeParsedData* a) :
|
||||
m_Id(a->id),
|
||||
m_Name(getAttrName(a->id)),
|
||||
m_Desc(getAttrDescription(a->id)),
|
||||
m_FailureType(a->prefailure ? PreFailure : OldAge),
|
||||
m_UpdateType(a->online ? Online : Offline),
|
||||
m_Current(a->current_value_valid ? a->current_value : -1),
|
||||
m_Worst(a->worst_value_valid ? a->worst_value : -1),
|
||||
m_Threshold(a->threshold_valid ? a->threshold : -1),
|
||||
m_Raw(getRaw(a->raw)),
|
||||
SmartAttribute::SmartAttribute(const SmartAttributeParsedData& a) :
|
||||
m_Id(a.id()),
|
||||
m_Name(getAttrName(a.id())),
|
||||
m_Desc(getAttrDescription(a.id())),
|
||||
m_FailureType(a.prefailure() ? FailureType::PreFailure : FailureType::OldAge),
|
||||
m_UpdateType(a.online() ? UpdateType::Online : UpdateType::Offline),
|
||||
m_Current(a.currentValueValid() ? a.currentValue() : -1),
|
||||
m_Worst(a.worstValueValid() ? a.worstValue() : -1),
|
||||
m_Threshold(a.thresholdValid() ? a.threshold() : -1),
|
||||
m_Raw(getRaw(a.raw())),
|
||||
m_Assessment(getAssessment(a)),
|
||||
m_Value(getPrettyValue(a->pretty_value, a->pretty_unit))
|
||||
m_Value(getPrettyValue(a.prettyValue(), a.prettyUnit()))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString SmartAttribute::assessmentToString(Assessment a)
|
||||
{
|
||||
switch (a) {
|
||||
case Failing:
|
||||
case Assessment::Failing:
|
||||
return xi18nc("@item:intable", "failing");
|
||||
|
||||
case HasFailed:
|
||||
case Assessment::HasFailed:
|
||||
return xi18nc("@item:intable", "has failed");
|
||||
|
||||
case Warning:
|
||||
case Assessment::Warning:
|
||||
return xi18nc("@item:intable", "warning");
|
||||
|
||||
case Good:
|
||||
case Assessment::Good:
|
||||
return xi18nc("@item:intable", "good");
|
||||
|
||||
case NotApplicable:
|
||||
case Assessment::NotApplicable:
|
||||
default:
|
||||
return xi18nc("@item:intable not applicable", "N/A");
|
||||
}
|
||||
}
|
||||
|
||||
static QString getPrettyValue(quint64 value, qint64 unit)
|
||||
static QString getPrettyValue(quint64 value, SmartAttributeUnit unit)
|
||||
{
|
||||
QString rval;
|
||||
|
||||
switch (unit) {
|
||||
case SK_SMART_ATTRIBUTE_UNIT_MSECONDS:
|
||||
case SmartAttributeUnit::Miliseconds:
|
||||
rval = KFormat().formatDuration(value);
|
||||
break;
|
||||
|
||||
case SK_SMART_ATTRIBUTE_UNIT_SECTORS:
|
||||
case SmartAttributeUnit::Sectors:
|
||||
rval = xi18ncp("@item:intable", "%1 sector", "%1 sectors", value);
|
||||
break;
|
||||
|
||||
case SK_SMART_ATTRIBUTE_UNIT_MKELVIN:
|
||||
case SmartAttributeUnit::Milikelvin:
|
||||
rval = SmartStatus::tempToString(value);
|
||||
break;
|
||||
|
||||
case SK_SMART_ATTRIBUTE_UNIT_NONE:
|
||||
case SmartAttributeUnit::None:
|
||||
rval = QLocale().toString(value);
|
||||
break;
|
||||
|
||||
case SK_SMART_ATTRIBUTE_UNIT_UNKNOWN:
|
||||
case SmartAttributeUnit::Unknown:
|
||||
default:
|
||||
rval = xi18nc("@item:intable not applicable", "N/A");
|
||||
break;
|
||||
|
@ -214,43 +214,41 @@ static QString getAttrDescription(qint32 id)
|
|||
return QString();
|
||||
}
|
||||
|
||||
static SmartAttribute::Assessment getAssessment(const SkSmartAttributeParsedData* a)
|
||||
static SmartAttribute::Assessment getAssessment(const SmartAttributeParsedData& a)
|
||||
{
|
||||
SmartAttribute::Assessment rval = SmartAttribute::NotApplicable;
|
||||
SmartAttribute::Assessment rval = SmartAttribute::Assessment::NotApplicable;
|
||||
|
||||
bool failed = false;
|
||||
bool hasFailed = false;
|
||||
|
||||
if (a->prefailure) {
|
||||
if (a->good_now_valid && !a->good_now)
|
||||
if (a.prefailure()) {
|
||||
if (a.goodNowValid() && !a.goodNow())
|
||||
failed = true;
|
||||
|
||||
if (a->good_in_the_past_valid && !a->good_in_the_past)
|
||||
if (a.goodInThePastValid() && !a.goodInThePast())
|
||||
hasFailed = true;
|
||||
} else if (a->threshold_valid) {
|
||||
if (a->current_value_valid && a->current_value <= a->threshold)
|
||||
} else if (a.thresholdValid()) {
|
||||
if (a.currentValueValid() && a.currentValue() <= a.threshold())
|
||||
failed = true;
|
||||
else if (a->worst_value_valid && a->worst_value <= a->threshold)
|
||||
else if (a.worstValueValid() && a.worstValue() <= a.threshold())
|
||||
hasFailed = true;
|
||||
}
|
||||
|
||||
if (failed)
|
||||
rval = SmartAttribute::Failing;
|
||||
rval = SmartAttribute::Assessment::Failing;
|
||||
else if (hasFailed)
|
||||
rval = SmartAttribute::HasFailed;
|
||||
else if (a->warn)
|
||||
rval = SmartAttribute::Warning;
|
||||
else if (a->good_now_valid)
|
||||
rval = SmartAttribute::Good;
|
||||
rval = SmartAttribute::Assessment::HasFailed;
|
||||
else if (a.warn())
|
||||
rval = SmartAttribute::Assessment::Warning;
|
||||
else if (a.goodNowValid())
|
||||
rval = SmartAttribute::Assessment::Good;
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
static QString getRaw(const uint8_t* raw)
|
||||
static QString getRaw(quint64 raw)
|
||||
{
|
||||
QString rval = QStringLiteral("0x");
|
||||
for (qint32 i = 5; i >= 0; i--)
|
||||
rval += QStringLiteral("%1").arg(raw[i], 2, 16, QLatin1Char('0'));
|
||||
|
||||
rval += QStringLiteral("%1").arg(raw, 12, 16, QLatin1Char('0'));
|
||||
return rval;
|
||||
}
|
||||
|
|
|
@ -15,30 +15,29 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(KPMCORE_SMARTATTRIBUTE_H)
|
||||
|
||||
#ifndef KPMCORE_SMARTATTRIBUTE_H
|
||||
#define KPMCORE_SMARTATTRIBUTE_H
|
||||
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
struct SkSmartAttributeParsedData;
|
||||
class SmartAttributeParsedData;
|
||||
|
||||
class LIBKPMCORE_EXPORT SmartAttribute
|
||||
{
|
||||
public:
|
||||
enum FailureType {
|
||||
enum class FailureType {
|
||||
PreFailure,
|
||||
OldAge
|
||||
};
|
||||
|
||||
enum UpdateType {
|
||||
enum class UpdateType {
|
||||
Online,
|
||||
Offline
|
||||
};
|
||||
|
||||
enum Assessment {
|
||||
enum class Assessment {
|
||||
NotApplicable,
|
||||
Failing,
|
||||
HasFailed,
|
||||
|
@ -47,7 +46,7 @@ public:
|
|||
};
|
||||
|
||||
public:
|
||||
SmartAttribute(const SkSmartAttributeParsedData* a);
|
||||
SmartAttribute(const SmartAttributeParsedData& a);
|
||||
|
||||
public:
|
||||
qint32 id() const {
|
||||
|
@ -104,4 +103,3 @@ private:
|
|||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,644 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2018 by Caio Carvalho <caiojcarvalho@gmail.com> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 3 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "smartattributeparseddata.h"
|
||||
#include "core/smartdiskinformation.h"
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QMap>
|
||||
#include <QRegularExpression>
|
||||
#include <QVariant>
|
||||
#include <QVector>
|
||||
|
||||
#define MKELVIN_VALID_MIN ((qint64) ((-15LL*1000LL) + 273150LL))
|
||||
#define MKELVIN_VALID_MAX ((qint64) ((100LL*1000LL) + 273150LL))
|
||||
|
||||
#define MSECOND_VALID_MIN 1ULL
|
||||
#define MSECOND_VALID_SHORT_MAX (60ULL * 60ULL * 1000ULL)
|
||||
#define MSECOND_VALID_LONG_MAX (30ULL * 365ULL * 24ULL * 60ULL * 60ULL * 1000ULL)
|
||||
|
||||
static QMap<qint32, SmartAttributeUnit> tableUnit();
|
||||
static SmartQuirk getQuirk(QString model, QString firmware);
|
||||
|
||||
/** Creates a new SmartAttributeParsedData object.
|
||||
@param disk the reference to the disk that this attribute is allocated to
|
||||
@param jsonAttribute JSON attribute data
|
||||
*/
|
||||
SmartAttributeParsedData::SmartAttributeParsedData(SmartDiskInformation *disk,
|
||||
QJsonObject jsonAttribute) :
|
||||
m_Id(0),
|
||||
m_CurrentValue(0),
|
||||
m_WorstValue(0),
|
||||
m_Threshold(0),
|
||||
m_Raw(0),
|
||||
m_PrettyValue(0),
|
||||
m_CurrentValueValid(false),
|
||||
m_WorstValueValid(false),
|
||||
m_ThresholdValid(false),
|
||||
m_Prefailure(false),
|
||||
m_Online(false),
|
||||
m_GoodNow(true),
|
||||
m_GoodNowValid(false),
|
||||
m_GoodInThePast(true),
|
||||
m_GoodInThePastValid(false),
|
||||
m_Warn(false),
|
||||
m_PrettyUnit(SmartAttributeUnit::Unknown),
|
||||
m_Disk(disk),
|
||||
m_Quirk(SmartQuirk::None)
|
||||
{
|
||||
if (disk)
|
||||
m_Quirk = getQuirk(disk->model(), disk->firmware());
|
||||
|
||||
if (!jsonAttribute.isEmpty()) {
|
||||
QString id = QStringLiteral("id");
|
||||
QString value = QStringLiteral("value");
|
||||
QString worst = QStringLiteral("worst");
|
||||
QString thresh = QStringLiteral("thresh");
|
||||
QString raw = QStringLiteral("raw");
|
||||
QString flags = QStringLiteral("flags");
|
||||
QString prefailure = QStringLiteral("prefailure");
|
||||
QString online = QStringLiteral("updated_online");
|
||||
|
||||
m_Id = jsonAttribute[id].toInt();
|
||||
m_CurrentValue = jsonAttribute[value].toInt();
|
||||
m_WorstValue = jsonAttribute[worst].toInt();
|
||||
m_Threshold = jsonAttribute[thresh].toInt();
|
||||
|
||||
QJsonObject rawObj = jsonAttribute[raw].toObject();
|
||||
|
||||
m_Raw = rawObj[value].toVariant().toULongLong();
|
||||
|
||||
QJsonObject flagsObj = jsonAttribute[flags].toObject();
|
||||
|
||||
m_Prefailure = flagsObj[prefailure].toBool();
|
||||
m_Online = flagsObj[online].toBool();
|
||||
|
||||
if (!updateUnit())
|
||||
m_PrettyUnit = SmartAttributeUnit::Unknown;
|
||||
|
||||
makePretty();
|
||||
|
||||
validateValues();
|
||||
|
||||
verifyAttribute();
|
||||
}
|
||||
}
|
||||
|
||||
/** @param other SmartAttributeParsedData to copy
|
||||
*/
|
||||
SmartAttributeParsedData::SmartAttributeParsedData(const SmartAttributeParsedData &other) :
|
||||
m_Id(other.id()),
|
||||
m_CurrentValue(other.currentValue()),
|
||||
m_WorstValue(other.worstValue()),
|
||||
m_Threshold(other.threshold()),
|
||||
m_Raw(other.raw()),
|
||||
m_PrettyValue(other.prettyValue()),
|
||||
m_CurrentValueValid(other.currentValueValid()),
|
||||
m_WorstValueValid(other.worstValueValid()),
|
||||
m_ThresholdValid(other.thresholdValid()),
|
||||
m_Prefailure(other.prefailure()),
|
||||
m_Online(other.online()),
|
||||
m_GoodNow(other.goodNow()),
|
||||
m_GoodNowValid(other.goodNowValid()),
|
||||
m_GoodInThePast(other.goodInThePast()),
|
||||
m_GoodInThePastValid(other.goodInThePastValid()),
|
||||
m_Warn(other.warn()),
|
||||
m_PrettyUnit(other.prettyUnit()),
|
||||
m_Disk(other.disk()),
|
||||
m_Quirk(other.m_Quirk)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/** Validate values from the current attribute */
|
||||
void SmartAttributeParsedData::validateValues()
|
||||
{
|
||||
m_CurrentValueValid = m_CurrentValue >= 1 && m_CurrentValue <= 0xFD;
|
||||
m_WorstValueValid = m_WorstValue >= 1 && m_WorstValue <= 0xFD;
|
||||
m_ThresholdValid = m_Threshold != 0xFE;
|
||||
|
||||
if (m_Threshold >= 1 && m_Threshold <= 0xFD) {
|
||||
if (m_WorstValueValid) {
|
||||
m_GoodInThePast = m_GoodInThePast && (m_WorstValue > m_Threshold);
|
||||
m_GoodInThePastValid = true;
|
||||
}
|
||||
if (m_CurrentValueValid) {
|
||||
m_GoodNow = m_GoodNow && (m_CurrentValue > m_Threshold);
|
||||
m_GoodNowValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
m_Warn = (m_GoodNowValid && !m_GoodNow) || (m_GoodInThePastValid && !m_GoodInThePast);
|
||||
}
|
||||
|
||||
/** Make a pretty value from raw based on attribute's id */
|
||||
void SmartAttributeParsedData::makePretty()
|
||||
{
|
||||
if (m_PrettyUnit == SmartAttributeUnit::Unknown)
|
||||
return;
|
||||
|
||||
switch (id()) {
|
||||
case 3:
|
||||
m_PrettyValue = raw() & 0xFFFF;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
m_PrettyValue = raw() & 0xFFFFFFFFU;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
m_PrettyValue = (raw() & 0xFFFFFFFFU) * 60 * 60 * 1000;
|
||||
break;
|
||||
|
||||
case 170:
|
||||
m_PrettyValue = currentValue();
|
||||
break;
|
||||
|
||||
case 190:
|
||||
m_PrettyValue = (raw() & 0xFFFF) * 1000 + 273150;
|
||||
break;
|
||||
|
||||
case 194:
|
||||
m_PrettyValue = (raw() & 0xFFFF) * 1000 + 273150;
|
||||
break;
|
||||
|
||||
case 197:
|
||||
m_PrettyValue = (raw() & 0xFFFFFFFFU);
|
||||
break;
|
||||
|
||||
case 222:
|
||||
m_PrettyValue = (raw() & 0xFFFFFFFFU) * 60 * 60 * 1000;
|
||||
break;
|
||||
|
||||
case 228:
|
||||
m_PrettyValue = raw() * 60 * 1000;
|
||||
break;
|
||||
|
||||
case 231:
|
||||
m_PrettyValue = (raw() & 0xFFFF) * 1000 + 273150;
|
||||
break;
|
||||
|
||||
case 232:
|
||||
m_PrettyValue = currentValue();
|
||||
break;
|
||||
|
||||
case 240:
|
||||
m_PrettyValue = (raw() & 0xFFFFFFFFU) * 60 * 60 * 1000;
|
||||
break;
|
||||
|
||||
case 241:
|
||||
m_PrettyValue = raw() * 65536ULL * 512ULL / 1000000ULL;
|
||||
break;
|
||||
|
||||
case 242:
|
||||
m_PrettyValue = raw() * 65536ULL * 512ULL / 1000000ULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
m_PrettyValue = raw();
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/** Verify attribute's unit */
|
||||
void SmartAttributeParsedData::verifyAttribute()
|
||||
{
|
||||
if (id() == 3 || id() == 226)
|
||||
verifyShortTime();
|
||||
else if (id() == 5 || id() == 187 || id() == 197 || id() == 198)
|
||||
verifySectors();
|
||||
else if (id() == 9 || id() == 222 || id() == 240)
|
||||
verifyLongTime();
|
||||
else if (id() == 190 || id() == 194 || id() == 231)
|
||||
verifyTemperature();
|
||||
}
|
||||
|
||||
void SmartAttributeParsedData::verifyTemperature()
|
||||
{
|
||||
if (prettyUnit() != SmartAttributeUnit::Milikelvin)
|
||||
return;
|
||||
|
||||
if (prettyValue() < MKELVIN_VALID_MIN || prettyValue() > MKELVIN_VALID_MAX)
|
||||
m_PrettyUnit = SmartAttributeUnit::Unknown;
|
||||
}
|
||||
|
||||
void SmartAttributeParsedData::verifyShortTime()
|
||||
{
|
||||
if (prettyUnit() != SmartAttributeUnit::Miliseconds)
|
||||
return;
|
||||
|
||||
if (prettyValue() < MSECOND_VALID_MIN || prettyValue() > MSECOND_VALID_SHORT_MAX)
|
||||
m_PrettyUnit = SmartAttributeUnit::Unknown;
|
||||
}
|
||||
|
||||
void SmartAttributeParsedData::verifyLongTime()
|
||||
{
|
||||
if (prettyUnit() != SmartAttributeUnit::Miliseconds)
|
||||
return;
|
||||
|
||||
if (prettyValue() < MSECOND_VALID_MIN || prettyValue() > MSECOND_VALID_LONG_MAX)
|
||||
m_PrettyUnit = SmartAttributeUnit::Unknown;
|
||||
}
|
||||
|
||||
void SmartAttributeParsedData::verifySectors()
|
||||
{
|
||||
if (prettyUnit() != SmartAttributeUnit::Sectors)
|
||||
return;
|
||||
|
||||
quint64 maxSectors = disk()->size() / 512ULL;
|
||||
|
||||
if (prettyValue() == 0xFFFFFFFFULL || prettyValue() == 0xFFFFFFFFFFFFULL || (maxSectors > 0
|
||||
&& prettyValue() > maxSectors))
|
||||
m_PrettyUnit = SmartAttributeUnit::Unknown;
|
||||
else if ((id() == 5 || id() == 197) && prettyValue() > 0)
|
||||
m_Warn = true;
|
||||
}
|
||||
|
||||
bool SmartAttributeParsedData::updateUnit()
|
||||
{
|
||||
if (m_Quirk) {
|
||||
switch (id()) {
|
||||
case 3:
|
||||
if (m_Quirk & SmartQuirk::SMART_QUIRK_3_UNUSED) {
|
||||
m_PrettyUnit = SmartAttributeUnit::Unknown;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (m_Quirk & SmartQuirk::SMART_QUIRK_4_UNUSED) {
|
||||
m_PrettyUnit = SmartAttributeUnit::Unknown;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 5:
|
||||
if (m_Quirk & SmartQuirk::SMART_QUIRK_5_UNKNOWN)
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
if (m_Quirk & SmartQuirk::SMART_QUIRK_9_POWERONMINUTES) {
|
||||
m_PrettyUnit = SmartAttributeUnit::Miliseconds;
|
||||
return true;
|
||||
} else if (m_Quirk & SmartQuirk::SMART_QUIRK_9_POWERONSECONDS) {
|
||||
m_PrettyUnit = SmartAttributeUnit::Miliseconds;
|
||||
return true;
|
||||
} else if (m_Quirk & SmartQuirk::SMART_QUIRK_9_POWERONHALFMINUTES) {
|
||||
m_PrettyUnit = SmartAttributeUnit::Miliseconds;
|
||||
return true;
|
||||
} else if (m_Quirk & SmartQuirk::SMART_QUIRK_9_UNKNOWN)
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 190:
|
||||
if (m_Quirk & SmartQuirk::SMART_QUIRK_190_UNKNOWN)
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 192:
|
||||
if (m_Quirk & SmartQuirk::SMART_QUIRK_192_EMERGENCYRETRACTCYCLECT) {
|
||||
m_PrettyUnit = SmartAttributeUnit::None;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 194:
|
||||
if (m_Quirk & SmartQuirk::SMART_QUIRK_194_10XCELSIUS) {
|
||||
m_PrettyUnit = SmartAttributeUnit::Milikelvin;
|
||||
return true;
|
||||
} else if (m_Quirk & SmartQuirk::SMART_QUIRK_194_UNKNOWN)
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 197:
|
||||
if (m_Quirk & SmartQuirk::SMART_QUIRK_197_UNKNOWN)
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 198:
|
||||
if (m_Quirk & SmartQuirk::SMART_QUIRK_198_UNKNOWN)
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 200:
|
||||
if (m_Quirk & SmartQuirk::SMART_QUIRK_200_WRITEERRORCOUNT) {
|
||||
m_PrettyUnit = SmartAttributeUnit::None;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 201:
|
||||
if (m_Quirk & SmartQuirk::SMART_QUIRK_201_DETECTEDTACOUNT) {
|
||||
m_PrettyUnit = SmartAttributeUnit::None;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 225:
|
||||
if (m_Quirk & SmartQuirk::SMART_QUIRK_225_TOTALLBASWRITTEN) {
|
||||
m_PrettyUnit = SmartAttributeUnit::MB;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 226:
|
||||
if (m_Quirk & SmartQuirk::SMART_QUIRK_226_TIMEWORKLOADMEDIAWEAR) {
|
||||
m_PrettyUnit = SmartAttributeUnit::SmallPercent;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 227:
|
||||
if (m_Quirk & SmartQuirk::SMART_QUIRK_227_TIMEWORKLOADHOSTREADS) {
|
||||
m_PrettyUnit = SmartAttributeUnit::SmallPercent;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 228:
|
||||
if (m_Quirk & SmartQuirk::SMART_QUIRK_228_WORKLOADTIMER) {
|
||||
m_PrettyUnit = SmartAttributeUnit::Miliseconds;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 232:
|
||||
if (m_Quirk & SmartQuirk::SMART_QUIRK_232_AVAILABLERESERVEDSPACE) {
|
||||
m_PrettyUnit = SmartAttributeUnit::Percent;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case 233:
|
||||
if (m_Quirk & SmartQuirk::SMART_QUIRK_233_MEDIAWEAROUTINDICATOR) {
|
||||
m_PrettyUnit = SmartAttributeUnit::Percent;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (tableUnit().contains(id())) {
|
||||
m_PrettyUnit = tableUnit()[id()];
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static QMap<qint32, SmartAttributeUnit> tableUnit()
|
||||
{
|
||||
QMap<qint32, SmartAttributeUnit> table;
|
||||
table.insert(1, SmartAttributeUnit::None);
|
||||
table.insert(2, SmartAttributeUnit::Unknown);
|
||||
table.insert(3, SmartAttributeUnit::Miliseconds);
|
||||
table.insert(4, SmartAttributeUnit::None);
|
||||
table.insert(5, SmartAttributeUnit::Sectors);
|
||||
table.insert(6, SmartAttributeUnit::Unknown);
|
||||
table.insert(7, SmartAttributeUnit::None);
|
||||
table.insert(8, SmartAttributeUnit::Unknown);
|
||||
table.insert(9, SmartAttributeUnit::Miliseconds);
|
||||
table.insert(10, SmartAttributeUnit::None);
|
||||
table.insert(11, SmartAttributeUnit::None);
|
||||
table.insert(12, SmartAttributeUnit::None);
|
||||
table.insert(13, SmartAttributeUnit::None);
|
||||
table.insert(170, SmartAttributeUnit::Percent);
|
||||
table.insert(171, SmartAttributeUnit::None);
|
||||
table.insert(172, SmartAttributeUnit::None);
|
||||
table.insert(175, SmartAttributeUnit::None);
|
||||
table.insert(176, SmartAttributeUnit::None);
|
||||
table.insert(177, SmartAttributeUnit::None);
|
||||
table.insert(178, SmartAttributeUnit::None);
|
||||
table.insert(179, SmartAttributeUnit::None);
|
||||
table.insert(180, SmartAttributeUnit::None);
|
||||
table.insert(181, SmartAttributeUnit::None);
|
||||
table.insert(182, SmartAttributeUnit::None);
|
||||
table.insert(183, SmartAttributeUnit::None);
|
||||
table.insert(184, SmartAttributeUnit::None);
|
||||
table.insert(187, SmartAttributeUnit::Sectors);
|
||||
table.insert(188, SmartAttributeUnit::None);
|
||||
table.insert(189, SmartAttributeUnit::None);
|
||||
table.insert(190, SmartAttributeUnit::Milikelvin);
|
||||
table.insert(191, SmartAttributeUnit::None);
|
||||
table.insert(192, SmartAttributeUnit::None);
|
||||
table.insert(193, SmartAttributeUnit::None);
|
||||
table.insert(194, SmartAttributeUnit::Milikelvin);
|
||||
table.insert(195, SmartAttributeUnit::None);
|
||||
table.insert(196, SmartAttributeUnit::None);
|
||||
table.insert(197, SmartAttributeUnit::Sectors);
|
||||
table.insert(198, SmartAttributeUnit::Sectors);
|
||||
table.insert(199, SmartAttributeUnit::None);
|
||||
table.insert(200, SmartAttributeUnit::None);
|
||||
table.insert(201, SmartAttributeUnit::None);
|
||||
table.insert(202, SmartAttributeUnit::None);
|
||||
table.insert(203, SmartAttributeUnit::Unknown);
|
||||
table.insert(204, SmartAttributeUnit::None);
|
||||
table.insert(205, SmartAttributeUnit::None);
|
||||
table.insert(206, SmartAttributeUnit::Unknown);
|
||||
table.insert(207, SmartAttributeUnit::Unknown);
|
||||
table.insert(208, SmartAttributeUnit::Unknown);
|
||||
table.insert(209, SmartAttributeUnit::Unknown);
|
||||
table.insert(220, SmartAttributeUnit::Unknown);
|
||||
table.insert(221, SmartAttributeUnit::None);
|
||||
table.insert(222, SmartAttributeUnit::Miliseconds);
|
||||
table.insert(223, SmartAttributeUnit::None);
|
||||
table.insert(224, SmartAttributeUnit::Unknown);
|
||||
table.insert(225, SmartAttributeUnit::None);
|
||||
table.insert(226, SmartAttributeUnit::Miliseconds);
|
||||
table.insert(227, SmartAttributeUnit::None);
|
||||
table.insert(228, SmartAttributeUnit::None);
|
||||
table.insert(230, SmartAttributeUnit::Unknown);
|
||||
table.insert(231, SmartAttributeUnit::Milikelvin);
|
||||
table.insert(232, SmartAttributeUnit::Percent);
|
||||
table.insert(233, SmartAttributeUnit::Unknown);
|
||||
table.insert(234, SmartAttributeUnit::Sectors);
|
||||
table.insert(235, SmartAttributeUnit::Unknown);
|
||||
table.insert(240, SmartAttributeUnit::Miliseconds);
|
||||
table.insert(241, SmartAttributeUnit::MB);
|
||||
table.insert(242, SmartAttributeUnit::MB);
|
||||
table.insert(250, SmartAttributeUnit::None);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
static const QVector<SmartAttributeParsedData::SmartQuirkDataBase> quirkDatabase()
|
||||
{
|
||||
typedef SmartAttributeParsedData::SmartQuirkDataBase QuirkDatabase;
|
||||
|
||||
QVector<QuirkDatabase> quirkDb;
|
||||
|
||||
quirkDb << QuirkDatabase(QStringLiteral("^(FUJITSU MHY2120BH|FUJITSU MHY2250BH)$"), QStringLiteral("^0085000B$"),
|
||||
static_cast<SmartQuirk>(SmartQuirk::SMART_QUIRK_9_POWERONMINUTES |
|
||||
SmartQuirk::SMART_QUIRK_197_UNKNOWN |
|
||||
SmartQuirk::SMART_QUIRK_198_UNKNOWN));
|
||||
|
||||
quirkDb << QuirkDatabase(QStringLiteral("^FUJITSU MHR2040AT$"), QStringLiteral(),
|
||||
static_cast<SmartQuirk>(SmartQuirk::SMART_QUIRK_9_POWERONSECONDS |
|
||||
SmartQuirk::SMART_QUIRK_192_EMERGENCYRETRACTCYCLECT |
|
||||
SmartQuirk::SMART_QUIRK_200_WRITEERRORCOUNT));
|
||||
|
||||
quirkDb << QuirkDatabase(QStringLiteral("^FUJITSU MHS20[6432]0AT( .)?$"), QStringLiteral(),
|
||||
static_cast<SmartQuirk>(SmartQuirk::SMART_QUIRK_9_POWERONSECONDS |
|
||||
SmartQuirk::SMART_QUIRK_192_EMERGENCYRETRACTCYCLECT |
|
||||
SmartQuirk::SMART_QUIRK_200_WRITEERRORCOUNT |
|
||||
SmartQuirk::SMART_QUIRK_201_DETECTEDTACOUNT));
|
||||
|
||||
quirkDb << QuirkDatabase(QStringLiteral("^("
|
||||
"FUJITSU M1623TAU|"
|
||||
"FUJITSU MHG2...ATU?.*|"
|
||||
"FUJITSU MHH2...ATU?.*|"
|
||||
"FUJITSU MHJ2...ATU?.*|"
|
||||
"FUJITSU MHK2...ATU?.*|"
|
||||
"FUJITSU MHL2300AT|"
|
||||
"FUJITSU MHM2(20|15|10|06)0AT|"
|
||||
"FUJITSU MHN2...AT|"
|
||||
"FUJITSU MHR2020AT|"
|
||||
"FUJITSU MHT2...(AH|AS|AT|BH)U?.*|"
|
||||
"FUJITSU MHU2...ATU?.*|"
|
||||
"FUJITSU MHV2...(AH|AS|AT|BH|BS|BT).*|"
|
||||
"FUJITSU MP[A-G]3...A[HTEV]U?.*"
|
||||
")$"),
|
||||
QStringLiteral(),
|
||||
SmartQuirk::SMART_QUIRK_9_POWERONSECONDS);
|
||||
|
||||
quirkDb << QuirkDatabase(QStringLiteral("^("
|
||||
"SAMSUNG SV4012H|"
|
||||
"SAMSUNG SP(0451|08[0124]2|12[0145]3|16[0145]4)[CN]"
|
||||
")$"),
|
||||
QStringLiteral(),
|
||||
SmartQuirk::SMART_QUIRK_9_POWERONHALFMINUTES);
|
||||
|
||||
quirkDb << QuirkDatabase(QStringLiteral("^("
|
||||
"SAMSUNG SV0412H|"
|
||||
"SAMSUNG SV1204H"
|
||||
")$"),
|
||||
QStringLiteral(),
|
||||
static_cast<SmartQuirk>(SmartQuirk::SMART_QUIRK_9_POWERONHALFMINUTES | SmartQuirk::SMART_QUIRK_194_10XCELSIUS));
|
||||
|
||||
quirkDb << QuirkDatabase(QStringLiteral("^SAMSUNG SP40A2H$"),
|
||||
QStringLiteral("^RR100-07$"),
|
||||
SmartQuirk::SMART_QUIRK_9_POWERONHALFMINUTES);
|
||||
|
||||
quirkDb << QuirkDatabase(QStringLiteral("^SAMSUNG SP80A4H$"),
|
||||
QStringLiteral("^RT100-06$"),
|
||||
SmartQuirk::SMART_QUIRK_9_POWERONHALFMINUTES);
|
||||
|
||||
quirkDb << QuirkDatabase(QStringLiteral("^SAMSUNG SP8004H$"),
|
||||
QStringLiteral("^QW100-61$"),
|
||||
SmartQuirk::SMART_QUIRK_9_POWERONHALFMINUTES);
|
||||
|
||||
quirkDb << QuirkDatabase(QStringLiteral("^("
|
||||
"Maxtor 2B0(0[468]|1[05]|20)H1|"
|
||||
"Maxtor 4G(120J6|160J[68])|"
|
||||
"Maxtor 4D0(20H1|40H2|60H3|80H4)"
|
||||
")$"),
|
||||
QStringLiteral(),
|
||||
static_cast<SmartQuirk>(SmartQuirk::SMART_QUIRK_9_POWERONMINUTES | SmartQuirk::SMART_QUIRK_194_UNKNOWN));
|
||||
|
||||
quirkDb << QuirkDatabase(QStringLiteral("^("
|
||||
"Maxtor 2F0[234]0[JL]0|"
|
||||
"Maxtor 8(1280A2|2160A4|2560A4|3840A6|4000A6|5120A8)|"
|
||||
"Maxtor 8(2160D2|3228D3|3240D3|4320D4|6480D6|8400D8|8455D8)|"
|
||||
"Maxtor 9(0510D4|0576D4|0648D5|0720D5|0840D6|0845D6|0864D6|1008D7|1080D8|1152D8)|"
|
||||
"Maxtor 9(1(360|350|202)D8|1190D7|10[12]0D6|0840D5|06[48]0D4|0510D3|1(350|202)E8|1010E6|0840E5|0640E4)|"
|
||||
"Maxtor 9(0512D2|0680D3|0750D3|0913D4|1024D4|1360D6|1536D6|1792D7|2048D8)|"
|
||||
"Maxtor 9(2732U8|2390U7|204[09]U6|1707U5|1366U4|1024U3|0845U3|0683U2)|"
|
||||
"Maxtor 4(R0[68]0[JL]0|R1[26]0L0|A160J0|R120L4)|"
|
||||
"Maxtor (91728D8|91512D7|91303D6|91080D5|90845D4|90645D3|90648D[34]|90432D2)|"
|
||||
"Maxtor 9(0431U1|0641U2|0871U2|1301U3|1741U4)|"
|
||||
"Maxtor (94091U8|93071U6|92561U5|92041U4|91731U4|91531U3|91361U3|91021U2|90841U2|90651U2)|"
|
||||
"Maxtor (33073U4|32049U3|31536U2|30768U1|33073H4|32305H3|31536H2|30768H1)|"
|
||||
"Maxtor (93652U8|92739U6|91826U4|91369U3|90913U2|90845U2|90435U1)|"
|
||||
"Maxtor 9(0684U2|1024U2|1362U3|1536U3|2049U4|2562U5|3073U6|4098U8)|"
|
||||
"Maxtor (54098[UH]8|53073[UH]6|52732[UH]6|52049[UH]4|51536[UH]3|51369[UH]3|51024[UH]2)|"
|
||||
"Maxtor 3(1024H1|1535H2|2049H2|3073H3|4098H4)( B)?|"
|
||||
"Maxtor 5(4610H6|4098H6|3073H4|2049H3|1536H2|1369H2|1023H2)|"
|
||||
"Maxtor 9(1023U2|1536U2|2049U3|2305U3|3073U4|4610U6|6147U8)|"
|
||||
"Maxtor 9(1023H2|1536H2|2049H3|2305H3|3073H4|4098H6|4610H6|6147H8)|"
|
||||
"Maxtor 5T0(60H6|40H4|30H3|20H2|10H1)|"
|
||||
"Maxtor (98196H8|96147H6)|"
|
||||
"Maxtor 4W(100H6|080H6|060H4|040H3|030H2)|"
|
||||
"Maxtor 6(E0[234]|K04)0L0|"
|
||||
"Maxtor 6(B(30|25|20|16|12|10|08)0[MPRS]|L(080[MLP]|(100|120)[MP]|160[MP]|200[MPRS]|250[RS]|300[RS]))0|"
|
||||
"Maxtor 6Y((060|080|120|160)L0|(060|080|120|160|200|250)P0|(060|080|120|160|200|250)M0)|"
|
||||
"Maxtor 7Y250[PM]0|"
|
||||
"Maxtor [45]A(25|30|32)0[JN]0|"
|
||||
"Maxtor 7L(25|30)0[SR]0"
|
||||
")$"),
|
||||
QStringLiteral(),
|
||||
SmartQuirk::SMART_QUIRK_9_POWERONMINUTES);
|
||||
|
||||
quirkDb << QuirkDatabase(QStringLiteral("^("
|
||||
"HITACHI_DK14FA-20B|"
|
||||
"HITACHI_DK23..-..B?|"
|
||||
"HITACHI_DK23FA-20J|HTA422020F9AT[JN]0|"
|
||||
"HE[JN]4230[23]0F9AT00|"
|
||||
"HTC4260[23]0G5CE00|HTC4260[56]0G8CE00"
|
||||
")$"),
|
||||
QStringLiteral(),
|
||||
static_cast<SmartQuirk>(SmartQuirk::SMART_QUIRK_9_POWERONMINUTES | SmartQuirk::SMART_QUIRK_193_LOADUNLOAD));
|
||||
|
||||
quirkDb << QuirkDatabase(QStringLiteral("^HTS541010G9SA00$"),
|
||||
QStringLiteral("^MBZOC60P$"),
|
||||
SmartQuirk::SMART_QUIRK_5_UNKNOWN);
|
||||
|
||||
quirkDb << QuirkDatabase(QStringLiteral("^MCCOE64GEMPP$"),
|
||||
QStringLiteral("^2.9.0[3-9]$"),
|
||||
static_cast<SmartQuirk>(SmartQuirk::SMART_QUIRK_5_UNKNOWN | SmartQuirk::SMART_QUIRK_190_UNKNOWN));
|
||||
|
||||
quirkDb << QuirkDatabase(QStringLiteral("^INTEL SSDSA2(CT|BT|CW|BW)[0-9]{3}G3.*$"),
|
||||
QStringLiteral(),
|
||||
static_cast<SmartQuirk>(SmartQuirk::SMART_QUIRK_3_UNUSED |
|
||||
SmartQuirk::SMART_QUIRK_4_UNUSED |
|
||||
SmartQuirk::SMART_QUIRK_225_TOTALLBASWRITTEN |
|
||||
SmartQuirk::SMART_QUIRK_226_TIMEWORKLOADMEDIAWEAR |
|
||||
SmartQuirk::SMART_QUIRK_227_TIMEWORKLOADHOSTREADS |
|
||||
SmartQuirk::SMART_QUIRK_228_WORKLOADTIMER |
|
||||
SmartQuirk::SMART_QUIRK_232_AVAILABLERESERVEDSPACE |
|
||||
SmartQuirk::SMART_QUIRK_233_MEDIAWEAROUTINDICATOR));
|
||||
|
||||
return quirkDb;
|
||||
}
|
||||
|
||||
static SmartQuirk getQuirk(QString model, QString firmware)
|
||||
{
|
||||
const QVector<SmartAttributeParsedData::SmartQuirkDataBase> db = quirkDatabase();
|
||||
|
||||
QRegularExpression modelRegex;
|
||||
QRegularExpression firmwareRegex;
|
||||
|
||||
for (const SmartAttributeParsedData::SmartQuirkDataBase &item : qAsConst(db)) {
|
||||
if (!item.model.isEmpty()) {
|
||||
modelRegex.setPattern(item.model);
|
||||
QRegularExpressionMatch match = modelRegex.match(model);
|
||||
if (!match.hasMatch())
|
||||
continue;
|
||||
}
|
||||
if (!item.firmware.isEmpty()) {
|
||||
firmwareRegex.setPattern(item.firmware);
|
||||
QRegularExpressionMatch match = firmwareRegex.match(firmware);
|
||||
if (!match.hasMatch())
|
||||
continue;
|
||||
}
|
||||
return item.quirk;
|
||||
}
|
||||
|
||||
return SmartQuirk::None;
|
||||
}
|
|
@ -0,0 +1,225 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2018 by Caio Carvalho <caiojcarvalho@gmail.com> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 3 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#ifndef KPMCORE_SMARTATTRIBUTEPARSEDDATA_H
|
||||
#define KPMCORE_SMARTATTRIBUTEPARSEDDATA_H
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QString>
|
||||
|
||||
class SmartDiskInformation;
|
||||
|
||||
/** SMART Quirk */
|
||||
enum SmartQuirk {
|
||||
None = 0x000000,
|
||||
SMART_QUIRK_9_POWERONMINUTES = 0x000001,
|
||||
SMART_QUIRK_9_POWERONSECONDS = 0x000002,
|
||||
SMART_QUIRK_9_POWERONHALFMINUTES = 0x000004,
|
||||
SMART_QUIRK_192_EMERGENCYRETRACTCYCLECT = 0x000008,
|
||||
SMART_QUIRK_193_LOADUNLOAD = 0x000010,
|
||||
SMART_QUIRK_194_10XCELSIUS = 0x000020,
|
||||
SMART_QUIRK_194_UNKNOWN = 0x000040,
|
||||
SMART_QUIRK_200_WRITEERRORCOUNT = 0x000080,
|
||||
SMART_QUIRK_201_DETECTEDTACOUNT = 0x000100,
|
||||
SMART_QUIRK_5_UNKNOWN = 0x000200,
|
||||
SMART_QUIRK_9_UNKNOWN = 0x000400,
|
||||
SMART_QUIRK_197_UNKNOWN = 0x000800,
|
||||
SMART_QUIRK_198_UNKNOWN = 0x001000,
|
||||
SMART_QUIRK_190_UNKNOWN = 0x002000,
|
||||
SMART_QUIRK_232_AVAILABLERESERVEDSPACE = 0x004000,
|
||||
SMART_QUIRK_233_MEDIAWEAROUTINDICATOR = 0x008000,
|
||||
SMART_QUIRK_225_TOTALLBASWRITTEN = 0x010000,
|
||||
SMART_QUIRK_4_UNUSED = 0x020000,
|
||||
SMART_QUIRK_226_TIMEWORKLOADMEDIAWEAR = 0x040000,
|
||||
SMART_QUIRK_227_TIMEWORKLOADHOSTREADS = 0x080000,
|
||||
SMART_QUIRK_228_WORKLOADTIMER = 0x100000,
|
||||
SMART_QUIRK_3_UNUSED = 0x200000,
|
||||
};
|
||||
|
||||
/** A unit for SMART attributes */
|
||||
enum class SmartAttributeUnit {
|
||||
Unknown,
|
||||
None,
|
||||
Miliseconds,
|
||||
Sectors,
|
||||
Milikelvin,
|
||||
SmallPercent, /* percentage with 3 decimal points */
|
||||
Percent,
|
||||
MB,
|
||||
};
|
||||
|
||||
/** A SMART parsed attribute.
|
||||
|
||||
It receives the attribute data from JSON, retrieve its data and validates its values.
|
||||
|
||||
@author Caio Carvalho <caiojcarvalho@gmail.com>
|
||||
*/
|
||||
class SmartAttributeParsedData
|
||||
{
|
||||
public:
|
||||
/** SMART Quirk to some particular model and firmware */
|
||||
struct SmartQuirkDataBase {
|
||||
QString model;
|
||||
QString firmware;
|
||||
SmartQuirk quirk;
|
||||
|
||||
SmartQuirkDataBase(const QString &m = QString(),
|
||||
const QString &f = QString(),
|
||||
SmartQuirk q = SmartQuirk::None) :
|
||||
model(m),
|
||||
firmware(f),
|
||||
quirk(q)
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
public:
|
||||
SmartAttributeParsedData(SmartDiskInformation *disk, QJsonObject jsonAttribute);
|
||||
|
||||
SmartAttributeParsedData(const SmartAttributeParsedData &other);
|
||||
|
||||
public:
|
||||
quint32 id() const
|
||||
{
|
||||
return m_Id; /**< @return attribute id */
|
||||
}
|
||||
|
||||
qint32 currentValue() const
|
||||
{
|
||||
return m_CurrentValue; /**< @return attribute current value */
|
||||
}
|
||||
|
||||
qint32 worstValue() const
|
||||
{
|
||||
return m_WorstValue; /**< @return attribute worst value */
|
||||
}
|
||||
|
||||
qint32 threshold() const
|
||||
{
|
||||
return m_Threshold; /**< @return attribute threshold value */
|
||||
}
|
||||
|
||||
bool prefailure() const
|
||||
{
|
||||
return m_Prefailure; /**< @return attribute prefailure status */
|
||||
}
|
||||
|
||||
bool online() const
|
||||
{
|
||||
return m_Online; /**< @return attribute online status */
|
||||
}
|
||||
|
||||
quint64 raw() const
|
||||
{
|
||||
return m_Raw; /**< @return attribute raw value */
|
||||
}
|
||||
|
||||
quint64 prettyValue() const
|
||||
{
|
||||
return m_PrettyValue; /**< @return attribute pretty value */
|
||||
}
|
||||
|
||||
SmartAttributeUnit prettyUnit() const
|
||||
{
|
||||
return m_PrettyUnit; /**< @return pretty unit value */
|
||||
}
|
||||
|
||||
bool goodNowValid() const
|
||||
{
|
||||
return m_GoodNowValid; /**< @return good now attribute status validation */
|
||||
}
|
||||
|
||||
bool goodNow() const
|
||||
{
|
||||
return m_GoodNow; /**< @return good now attribute status */
|
||||
}
|
||||
|
||||
bool goodInThePastValid() const
|
||||
{
|
||||
return m_GoodInThePastValid; /**< @return good in the past attribute status validation */
|
||||
}
|
||||
|
||||
bool goodInThePast() const
|
||||
{
|
||||
return m_GoodInThePast; /**< @return good in the past attribute status */
|
||||
}
|
||||
|
||||
bool thresholdValid() const
|
||||
{
|
||||
return m_ThresholdValid; /**< @return threshold value validation */
|
||||
}
|
||||
|
||||
bool currentValueValid() const
|
||||
{
|
||||
return m_CurrentValueValid; /**< @return current value validation */
|
||||
}
|
||||
|
||||
bool worstValueValid() const
|
||||
{
|
||||
return m_WorstValueValid; /**< @return worst value validation */
|
||||
}
|
||||
|
||||
bool warn() const
|
||||
{
|
||||
return m_Warn; /**< @return warn status */
|
||||
}
|
||||
|
||||
SmartDiskInformation *disk() const
|
||||
{
|
||||
return m_Disk; /**< @return attribute's disk reference */
|
||||
}
|
||||
|
||||
protected:
|
||||
void validateValues();
|
||||
|
||||
bool updateUnit();
|
||||
|
||||
void makePretty();
|
||||
|
||||
void verifyAttribute();
|
||||
|
||||
void verifyTemperature();
|
||||
|
||||
void verifyShortTime();
|
||||
|
||||
void verifyLongTime();
|
||||
|
||||
void verifySectors();
|
||||
|
||||
private:
|
||||
quint32 m_Id;
|
||||
qint32 m_CurrentValue;
|
||||
qint32 m_WorstValue;
|
||||
qint32 m_Threshold;
|
||||
quint64 m_Raw;
|
||||
quint64 m_PrettyValue;
|
||||
bool m_CurrentValueValid;
|
||||
bool m_WorstValueValid;
|
||||
bool m_ThresholdValid;
|
||||
bool m_Prefailure;
|
||||
bool m_Online;
|
||||
bool m_GoodNow;
|
||||
bool m_GoodNowValid;
|
||||
bool m_GoodInThePast;
|
||||
bool m_GoodInThePastValid;
|
||||
bool m_Warn;
|
||||
SmartAttributeUnit m_PrettyUnit;
|
||||
SmartDiskInformation *m_Disk;
|
||||
SmartQuirk m_Quirk;
|
||||
};
|
||||
|
||||
#endif // SMARTATTRIBUTEPARSEDDATA_H
|
|
@ -0,0 +1,198 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2018 by Caio Carvalho <caiojcarvalho@gmail.com> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 3 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "core/smartdiskinformation.h"
|
||||
#include "core/smartattributeparseddata.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
static quint64 u64log2(quint64 n);
|
||||
|
||||
/** Creates a new SmartDiskInformationObject */
|
||||
SmartDiskInformation::SmartDiskInformation() :
|
||||
m_ModelName(QString()),
|
||||
m_FirmwareVersion(QString()),
|
||||
m_SerialNumber(QString()),
|
||||
m_Size(0),
|
||||
m_Temperature(0),
|
||||
m_BadSectors(0),
|
||||
m_PoweredOn(0),
|
||||
m_PowerCycles(0),
|
||||
m_SmartStatus(false),
|
||||
m_BadAttributeNow(false),
|
||||
m_BadAttributeInThePast(false),
|
||||
m_SelfTestExecutionStatus(SmartStatus::SelfTestStatus::Success),
|
||||
m_Overall(SmartStatus::Overall::Bad)
|
||||
{
|
||||
}
|
||||
|
||||
/** Update the number of bad sectors based on reallocated sector count and current pending sector attributes data */
|
||||
void SmartDiskInformation::updateBadSectors()
|
||||
{
|
||||
std::unique_ptr<SmartAttributeParsedData> reallocatedSectorCt(findAttribute(5));
|
||||
std::unique_ptr<SmartAttributeParsedData> currentPendingSector(findAttribute(197));
|
||||
|
||||
if (!reallocatedSectorCt && !currentPendingSector)
|
||||
m_BadSectors = 0;
|
||||
else if (reallocatedSectorCt && currentPendingSector)
|
||||
m_BadSectors = reallocatedSectorCt->prettyValue() + currentPendingSector->prettyValue();
|
||||
else if (reallocatedSectorCt)
|
||||
m_BadSectors = reallocatedSectorCt->prettyValue();
|
||||
else
|
||||
m_BadSectors = currentPendingSector->prettyValue();
|
||||
}
|
||||
|
||||
/** Update SMART overall data based on the quantity of bad sectors and the status of SMART attributes */
|
||||
void SmartDiskInformation::updateOverall()
|
||||
{
|
||||
if (!smartStatus()) {
|
||||
m_Overall = SmartStatus::Overall::Bad;
|
||||
return;
|
||||
}
|
||||
|
||||
quint64 sector_threshold = u64log2(size() / 512) * 1024;
|
||||
|
||||
if (badSectors() >= sector_threshold) {
|
||||
m_Overall = SmartStatus::Overall::BadSectorsMany;
|
||||
return;
|
||||
}
|
||||
|
||||
validateBadAttributes();
|
||||
|
||||
if (m_BadAttributeNow) {
|
||||
m_Overall = SmartStatus::Overall::BadNow;
|
||||
return;
|
||||
}
|
||||
|
||||
if (badSectors() > 0) {
|
||||
m_Overall = SmartStatus::Overall::BadSectors;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_BadAttributeInThePast) {
|
||||
m_Overall = SmartStatus::Overall::BadPast;
|
||||
return;
|
||||
}
|
||||
|
||||
m_Overall = SmartStatus::Overall::Good;
|
||||
}
|
||||
|
||||
/** Update the temperature value based on SMART attributes
|
||||
@return a boolean representing the status of the operation
|
||||
*/
|
||||
bool SmartDiskInformation::updateTemperature()
|
||||
{
|
||||
std::unique_ptr<SmartAttributeParsedData> temperatureCelsius(findAttribute(231));
|
||||
std::unique_ptr<SmartAttributeParsedData> temperatureCelsius2(findAttribute(194));
|
||||
std::unique_ptr<SmartAttributeParsedData> airflowTemperatureCelsius(findAttribute(190));
|
||||
|
||||
if (temperatureCelsius != nullptr
|
||||
&& temperatureCelsius->prettyUnit() == SmartAttributeUnit::Milikelvin) {
|
||||
m_Temperature = temperatureCelsius->prettyValue();
|
||||
return true;
|
||||
} else if (temperatureCelsius2 != nullptr
|
||||
&& temperatureCelsius2->prettyUnit() == SmartAttributeUnit::Milikelvin) {
|
||||
m_Temperature = temperatureCelsius2->prettyValue();
|
||||
return true;
|
||||
} else if (airflowTemperatureCelsius != nullptr
|
||||
&& airflowTemperatureCelsius->prettyUnit() ==
|
||||
SmartAttributeUnit::Milikelvin) {
|
||||
m_Temperature = airflowTemperatureCelsius->prettyValue();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Update the powered on value based on SMART attributes
|
||||
@return a boolean representing the status of the operation
|
||||
*/
|
||||
bool SmartDiskInformation::updatePowerOn()
|
||||
{
|
||||
std::unique_ptr<SmartAttributeParsedData> powerOnHours(findAttribute(9));
|
||||
std::unique_ptr<SmartAttributeParsedData> powerOnSeconds(findAttribute(233));
|
||||
|
||||
if (powerOnHours != nullptr
|
||||
&& powerOnHours->prettyUnit() == SmartAttributeUnit::Miliseconds) {
|
||||
m_PoweredOn = powerOnHours->prettyValue();
|
||||
return true;
|
||||
} else if (powerOnSeconds != nullptr
|
||||
&& powerOnSeconds->prettyUnit() == SmartAttributeUnit::Miliseconds) {
|
||||
m_PoweredOn = powerOnSeconds->prettyValue();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Update the power cycles value based on SMART attributes
|
||||
@return a boolean representing the status of the operation
|
||||
*/
|
||||
bool SmartDiskInformation::updatePowerCycle()
|
||||
{
|
||||
std::unique_ptr<SmartAttributeParsedData> powerCycleCount(findAttribute(12));
|
||||
|
||||
if (powerCycleCount != nullptr
|
||||
&& powerCycleCount->prettyUnit() == SmartAttributeUnit::None) {
|
||||
m_PowerCycles = powerCycleCount->prettyValue();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Validate disk attributes status */
|
||||
void SmartDiskInformation::validateBadAttributes()
|
||||
{
|
||||
for (const SmartAttributeParsedData &attribute : qAsConst(m_Attributes)) {
|
||||
if (attribute.prefailure()) {
|
||||
if (attribute.goodNowValid() && !attribute.goodNow())
|
||||
m_BadAttributeNow = true;
|
||||
if (attribute.goodInThePastValid() && !attribute.goodInThePast())
|
||||
m_BadAttributeInThePast = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Search for a attribute based on its id number
|
||||
@return a reference to the attribute
|
||||
*/
|
||||
SmartAttributeParsedData *SmartDiskInformation::findAttribute(quint32 id)
|
||||
{
|
||||
SmartAttributeParsedData *attr = nullptr;
|
||||
for (const SmartAttributeParsedData &attribute : qAsConst(m_Attributes)) {
|
||||
if (id == attribute.id()) {
|
||||
attr = new SmartAttributeParsedData(attribute);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return attr;
|
||||
}
|
||||
|
||||
static quint64 u64log2(quint64 n)
|
||||
{
|
||||
quint64 r;
|
||||
|
||||
if (n <= 1)
|
||||
return 0;
|
||||
|
||||
r = 0;
|
||||
for (;;) {
|
||||
n = n >> 1;
|
||||
if (!n)
|
||||
return r;
|
||||
r++;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2018 by Caio Carvalho <caiojcarvalho@gmail.com> *
|
||||
* Copyright (C) 2018 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/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#ifndef KPMCORE_SMARTDISKINFORMATION_H
|
||||
#define KPMCORE_SMARTDISKINFORMATION_H
|
||||
|
||||
#include "core/smartstatus.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
|
||||
class SmartAttributeParsedData;
|
||||
|
||||
/** Disk information retrieved by SMART.
|
||||
|
||||
It includes a list with your SMART attributes.
|
||||
|
||||
@author Caio Carvalho <caiojcarvalho@gmail.com>
|
||||
*/
|
||||
class SmartDiskInformation
|
||||
{
|
||||
public:
|
||||
SmartDiskInformation();
|
||||
|
||||
public:
|
||||
void updateBadSectors();
|
||||
|
||||
void updateOverall();
|
||||
|
||||
bool updateTemperature();
|
||||
|
||||
bool updatePowerOn();
|
||||
|
||||
bool updatePowerCycle();
|
||||
|
||||
SmartAttributeParsedData *findAttribute(quint32 id);
|
||||
|
||||
public:
|
||||
const QString model() const
|
||||
{
|
||||
return m_ModelName; /**< @return the disk model name */
|
||||
}
|
||||
|
||||
const QString firmware() const
|
||||
{
|
||||
return m_FirmwareVersion; /**< @return the disk firmware version */
|
||||
}
|
||||
|
||||
const QString serial() const
|
||||
{
|
||||
return m_SerialNumber; /**< @return the disk serial number */
|
||||
}
|
||||
|
||||
quint64 size() const
|
||||
{
|
||||
return m_Size; /**< @return disk size */
|
||||
}
|
||||
|
||||
bool smartStatus() const
|
||||
{
|
||||
return m_SmartStatus; /**< @return a boolean representing SMART status */
|
||||
}
|
||||
|
||||
SmartStatus::SelfTestStatus selfTestExecutionStatus() const
|
||||
{
|
||||
return m_SelfTestExecutionStatus; /**< @return SMART self execution status */
|
||||
}
|
||||
|
||||
SmartStatus::Overall overall() const
|
||||
{
|
||||
return m_Overall; /**< @return SMART overall status */
|
||||
}
|
||||
|
||||
quint64 temperature() const
|
||||
{
|
||||
return m_Temperature; /**< @return disk temperature in kelvin */
|
||||
}
|
||||
|
||||
quint64 badSectors() const
|
||||
{
|
||||
return m_BadSectors; /**< @return the number of bad sectors */
|
||||
}
|
||||
|
||||
quint64 poweredOn() const
|
||||
{
|
||||
return m_PoweredOn; /**< @return quantity of time that device is powered on */
|
||||
}
|
||||
|
||||
quint64 powerCycles() const
|
||||
{
|
||||
return m_PowerCycles; /**< @return quantity of power cycles */
|
||||
}
|
||||
|
||||
QList<SmartAttributeParsedData> attributes() const
|
||||
{
|
||||
return m_Attributes; /**< @return a list that contains the disk SMART attributes */
|
||||
}
|
||||
|
||||
public:
|
||||
void setModel(QString modelName)
|
||||
{
|
||||
m_ModelName = modelName;
|
||||
}
|
||||
|
||||
void setFirmware(QString firmware)
|
||||
{
|
||||
m_FirmwareVersion = firmware;
|
||||
}
|
||||
|
||||
void setSerial(QString serial)
|
||||
{
|
||||
m_SerialNumber = serial;
|
||||
}
|
||||
|
||||
void setSize(quint64 size)
|
||||
{
|
||||
m_Size = size;
|
||||
}
|
||||
|
||||
void setPowerCycles(quint64 powerCycleCt)
|
||||
{
|
||||
m_PowerCycles = powerCycleCt;
|
||||
}
|
||||
|
||||
void setSmartStatus(bool smartStatus)
|
||||
{
|
||||
m_SmartStatus = smartStatus;
|
||||
}
|
||||
|
||||
void setSelfTestExecutionStatus(SmartStatus::SelfTestStatus status)
|
||||
{
|
||||
m_SelfTestExecutionStatus = status;
|
||||
}
|
||||
|
||||
void addAttribute(SmartAttributeParsedData &attribute)
|
||||
{
|
||||
m_Attributes << attribute;
|
||||
}
|
||||
|
||||
protected:
|
||||
void validateBadAttributes();
|
||||
|
||||
private:
|
||||
QString m_ModelName;
|
||||
QString m_FirmwareVersion;
|
||||
QString m_SerialNumber;
|
||||
quint64 m_Size;
|
||||
quint64 m_Temperature;
|
||||
quint64 m_BadSectors;
|
||||
quint64 m_PoweredOn;
|
||||
quint64 m_PowerCycles;
|
||||
bool m_SmartStatus;
|
||||
bool m_BadAttributeNow;
|
||||
bool m_BadAttributeInThePast;
|
||||
SmartStatus::SelfTestStatus m_SelfTestExecutionStatus;
|
||||
SmartStatus::Overall m_Overall;
|
||||
QList<SmartAttributeParsedData> m_Attributes;
|
||||
};
|
||||
|
||||
#endif // SMARTDISKINFORMATION_H
|
|
@ -0,0 +1,161 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2018 by Caio Carvalho <caiojcarvalho@gmail.com> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 3 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "core/smartparser.h"
|
||||
|
||||
#include "core/smartattributeparseddata.h"
|
||||
#include "core/smartdiskinformation.h"
|
||||
|
||||
#include "util/externalcommand.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QString>
|
||||
|
||||
/** Creates a new SmartParser object
|
||||
@param device_path device path that indicates the device that SMART must analyse
|
||||
*/
|
||||
SmartParser::SmartParser(const QString &device_path) :
|
||||
m_DevicePath(device_path),
|
||||
m_DiskInformation(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
SmartParser::~SmartParser()
|
||||
{
|
||||
delete m_DiskInformation;
|
||||
}
|
||||
|
||||
/** Initialize SmartParser data, retrieve the information from SMART JSON and initialize the disk information data */
|
||||
bool SmartParser::init()
|
||||
{
|
||||
loadSmartOutput();
|
||||
|
||||
if (m_SmartOutput.isEmpty())
|
||||
return false;
|
||||
|
||||
QJsonObject smartJson = m_SmartOutput.object();
|
||||
|
||||
QString model_name = QStringLiteral("model_name");
|
||||
QString firmware = QStringLiteral("firmware_version");
|
||||
QString serial_number = QStringLiteral("serial_number");
|
||||
QString device = QStringLiteral("device");
|
||||
QString smart_status = QStringLiteral("smart_status");
|
||||
QString passed = QStringLiteral("passed");
|
||||
QString self_test = QStringLiteral("self_test");
|
||||
QString status = QStringLiteral("status");
|
||||
QString value = QStringLiteral("value");
|
||||
QString user_capacity = QStringLiteral("user_capacity");
|
||||
|
||||
if (!smartJson.contains(device)) {
|
||||
qDebug() << "smart disk open failed for " << devicePath() << ": " << strerror(errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!smartJson.contains(smart_status)) {
|
||||
qDebug() << "getting smart status failed for " << devicePath() << ": " << strerror(errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!smartJson.contains(model_name) || !smartJson.contains(firmware)
|
||||
|| !smartJson.contains(serial_number)) {
|
||||
qDebug() << "getting disk identification data failed for " << devicePath() << ": " << strerror(
|
||||
errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_DiskInformation = new SmartDiskInformation();
|
||||
|
||||
QJsonObject smartStatus = smartJson[smart_status].toObject();
|
||||
|
||||
m_DiskInformation->setSmartStatus(smartStatus[passed].toBool());
|
||||
|
||||
m_DiskInformation->setModel(smartJson[model_name].toString());
|
||||
m_DiskInformation->setFirmware(smartJson[firmware].toString());
|
||||
m_DiskInformation->setSerial(smartJson[serial_number].toString());
|
||||
m_DiskInformation->setSize(smartJson[user_capacity].toVariant().toULongLong());
|
||||
|
||||
QJsonObject selfTest = smartJson[self_test].toObject();
|
||||
QJsonObject selfTestStatus = selfTest[status].toObject();
|
||||
|
||||
m_DiskInformation->setSelfTestExecutionStatus(static_cast<SmartStatus::SelfTestStatus>(selfTestStatus[value].toInt()));
|
||||
|
||||
loadAttributes();
|
||||
|
||||
m_DiskInformation->updateBadSectors();
|
||||
|
||||
m_DiskInformation->updateOverall();
|
||||
|
||||
if (!m_DiskInformation->updateTemperature())
|
||||
qDebug() << "getting temp failed for " << devicePath() << ": " << strerror(errno);
|
||||
|
||||
if (!m_DiskInformation->updatePowerOn())
|
||||
qDebug() << "getting powered on time failed for " << devicePath() << ": " << strerror(errno);
|
||||
|
||||
if (!m_DiskInformation->updatePowerCycle())
|
||||
qDebug() << "getting power cycles failed for " << devicePath() << ": " << strerror(errno);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Run smartctl command and recover its output */
|
||||
void SmartParser::loadSmartOutput()
|
||||
{
|
||||
if (m_SmartOutput.isEmpty()) {
|
||||
ExternalCommand smartctl(QStringLiteral("smartctl"), { QStringLiteral("--all"), QStringLiteral("--json"), devicePath() });
|
||||
|
||||
if (smartctl.run() && smartctl.exitCode() == 0) {
|
||||
QByteArray output = smartctl.rawOutput();
|
||||
|
||||
m_SmartOutput = QJsonDocument::fromJson(output);
|
||||
}
|
||||
else
|
||||
qDebug() << "smartctl initialization failed for " << devicePath() << ": " << strerror(errno);
|
||||
}
|
||||
}
|
||||
|
||||
/** Load SMART disk attributes from JSON data */
|
||||
void SmartParser::loadAttributes()
|
||||
{
|
||||
loadSmartOutput();
|
||||
|
||||
if (m_SmartOutput.isEmpty())
|
||||
return;
|
||||
|
||||
QJsonObject smartJson = m_SmartOutput.object();
|
||||
|
||||
QString ata_smart_attributes = QStringLiteral("ata_smart_attributes");
|
||||
QString table = QStringLiteral("table");
|
||||
|
||||
QJsonObject ataSmartAttributes = smartJson[ata_smart_attributes].toObject();
|
||||
|
||||
QJsonArray attributeArray = ataSmartAttributes[table].toArray();
|
||||
|
||||
if (!m_DiskInformation) {
|
||||
qDebug() << "error loading smart attributes for " << devicePath() << ": " << strerror(errno);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const QJsonValue &value : qAsConst(attributeArray)) {
|
||||
SmartAttributeParsedData parsedObject(m_DiskInformation, value.toObject());
|
||||
m_DiskInformation->addAttribute(parsedObject);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de> *
|
||||
* Copyright (C) 2018 by Caio Carvalho <caiojcarvalho@gmail.com> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
|
@ -15,48 +15,50 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(KPMCORE_LIBPARTEDDEVICE_H)
|
||||
#ifndef KPMCORE_SMARTPARSER_H
|
||||
#define KPMCORE_SMARTPARSER_H
|
||||
|
||||
#define KPMCORE_LIBPARTEDDEVICE_H
|
||||
#include <QJsonDocument>
|
||||
#include <QString>
|
||||
|
||||
#include "backend/corebackenddevice.h"
|
||||
class SmartDiskInformation;
|
||||
|
||||
#include <QtGlobal>
|
||||
/** A parser to SMART JSON output.
|
||||
|
||||
#include <parted/parted.h>
|
||||
Responsible to execute smartctl and parse its output.
|
||||
|
||||
class Partition;
|
||||
class PartitionTable;
|
||||
class Report;
|
||||
class CoreBackendPartitionTable;
|
||||
|
||||
class LibPartedDevice : public CoreBackendDevice
|
||||
@author Caio Carvalho <caiojcarvalho@gmail.com>
|
||||
*/
|
||||
class SmartParser
|
||||
{
|
||||
Q_DISABLE_COPY(LibPartedDevice)
|
||||
public:
|
||||
SmartParser(const QString &device_path);
|
||||
~SmartParser();
|
||||
|
||||
public:
|
||||
LibPartedDevice(const QString& deviceNode);
|
||||
~LibPartedDevice();
|
||||
bool init();
|
||||
|
||||
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;
|
||||
|
||||
protected:
|
||||
PedDevice* pedDevice() {
|
||||
return m_PedDevice;
|
||||
const QString &devicePath() const
|
||||
{
|
||||
return m_DevicePath; /**< @return the device path that SMART must analyse */
|
||||
}
|
||||
|
||||
SmartDiskInformation *diskInformation() const
|
||||
{
|
||||
return m_DiskInformation; /**< @return a reference to parsed disk information */
|
||||
}
|
||||
|
||||
protected:
|
||||
void loadSmartOutput();
|
||||
|
||||
void loadAttributes();
|
||||
|
||||
private:
|
||||
PedDevice* m_PedDevice;
|
||||
const QString m_DevicePath;
|
||||
QJsonDocument m_SmartOutput;
|
||||
SmartDiskInformation *m_DiskInformation;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // SMARTPARSER_H
|
|
@ -18,24 +18,27 @@
|
|||
|
||||
#include "core/smartstatus.h"
|
||||
|
||||
#include "core/smartparser.h"
|
||||
#include "core/smartdiskinformation.h"
|
||||
#include "core/smartattributeparseddata.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include <atasmart.h>
|
||||
#include <errno.h>
|
||||
|
||||
SmartStatus::SmartStatus(const QString& device_path) :
|
||||
SmartStatus::SmartStatus(const QString &device_path) :
|
||||
m_DevicePath(device_path),
|
||||
m_InitSuccess(false),
|
||||
m_Status(false),
|
||||
m_ModelName(),
|
||||
m_Serial(),
|
||||
m_Firmware(),
|
||||
m_Overall(Bad),
|
||||
m_SelfTestStatus(Success),
|
||||
m_Overall(Overall::Bad),
|
||||
m_SelfTestStatus(SelfTestStatus::Success),
|
||||
m_Temp(0),
|
||||
m_BadSectors(0),
|
||||
m_PowerCycles(0),
|
||||
|
@ -46,148 +49,31 @@ SmartStatus::SmartStatus(const QString& device_path) :
|
|||
|
||||
void SmartStatus::update()
|
||||
{
|
||||
SkDisk* skDisk = nullptr;
|
||||
SkBool skSmartStatus = false;
|
||||
uint64_t mkelvin = 0;
|
||||
uint64_t skBadSectors = 0;
|
||||
uint64_t skPoweredOn = 0;
|
||||
uint64_t skPowerCycles = 0;
|
||||
SmartParser parser(devicePath());
|
||||
|
||||
if (sk_disk_open(devicePath().toLocal8Bit().constData(), &skDisk) < 0) {
|
||||
qDebug() << "smart disk open failed for " << devicePath() << ": " << strerror(errno);
|
||||
if (!parser.init()) {
|
||||
qDebug() << "error during smart output parsing for " << devicePath() << ": " << strerror(errno);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sk_disk_smart_status(skDisk, &skSmartStatus) < 0) {
|
||||
qDebug() << "getting smart status failed for " << devicePath() << ": " << strerror(errno);
|
||||
sk_disk_free(skDisk);
|
||||
SmartDiskInformation *disk;
|
||||
|
||||
disk = parser.diskInformation();
|
||||
|
||||
if (!disk)
|
||||
return;
|
||||
}
|
||||
|
||||
setStatus(skSmartStatus);
|
||||
|
||||
if (sk_disk_smart_read_data(skDisk) < 0) {
|
||||
qDebug() << "reading smart data failed for " << devicePath() << ": " << strerror(errno);
|
||||
sk_disk_free(skDisk);
|
||||
return;
|
||||
}
|
||||
|
||||
const SkIdentifyParsedData* skIdentify;
|
||||
|
||||
if (sk_disk_identify_parse(skDisk, &skIdentify) < 0)
|
||||
qDebug() << "getting identify data failed for " << devicePath() << ": " << strerror(errno);
|
||||
else {
|
||||
setModelName(QString::fromLocal8Bit(skIdentify->model));
|
||||
setFirmware(QString::fromLocal8Bit(skIdentify->firmware));
|
||||
setSerial(QString::fromLocal8Bit(skIdentify->serial));
|
||||
}
|
||||
|
||||
const SkSmartParsedData* skParsed;
|
||||
if (sk_disk_smart_parse(skDisk, &skParsed) < 0)
|
||||
qDebug() << "parsing disk smart data failed for " << devicePath() << ": " << strerror(errno);
|
||||
else {
|
||||
switch (skParsed->self_test_execution_status) {
|
||||
case SK_SMART_SELF_TEST_EXECUTION_STATUS_ABORTED:
|
||||
setSelfTestStatus(Aborted);
|
||||
break;
|
||||
|
||||
case SK_SMART_SELF_TEST_EXECUTION_STATUS_INTERRUPTED:
|
||||
setSelfTestStatus(Interrupted);
|
||||
break;
|
||||
|
||||
case SK_SMART_SELF_TEST_EXECUTION_STATUS_FATAL:
|
||||
setSelfTestStatus(Fatal);
|
||||
break;
|
||||
|
||||
case SK_SMART_SELF_TEST_EXECUTION_STATUS_ERROR_UNKNOWN:
|
||||
setSelfTestStatus(ErrorUnknown);
|
||||
break;
|
||||
|
||||
case SK_SMART_SELF_TEST_EXECUTION_STATUS_ERROR_ELECTRICAL:
|
||||
setSelfTestStatus(ErrorEletrical);
|
||||
break;
|
||||
|
||||
case SK_SMART_SELF_TEST_EXECUTION_STATUS_ERROR_SERVO:
|
||||
setSelfTestStatus(ErrorServo);
|
||||
break;
|
||||
|
||||
case SK_SMART_SELF_TEST_EXECUTION_STATUS_ERROR_READ:
|
||||
setSelfTestStatus(ErrorRead);
|
||||
break;
|
||||
|
||||
case SK_SMART_SELF_TEST_EXECUTION_STATUS_ERROR_HANDLING:
|
||||
setSelfTestStatus(ErrorHandling);
|
||||
break;
|
||||
|
||||
case SK_SMART_SELF_TEST_EXECUTION_STATUS_INPROGRESS:
|
||||
setSelfTestStatus(InProgress);
|
||||
break;
|
||||
|
||||
default:
|
||||
case SK_SMART_SELF_TEST_EXECUTION_STATUS_SUCCESS_OR_NEVER:
|
||||
setSelfTestStatus(Success);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SkSmartOverall overall;
|
||||
|
||||
if (sk_disk_smart_get_overall(skDisk, &overall) < 0)
|
||||
qDebug() << "getting status failed for " << devicePath() << ": " << strerror(errno);
|
||||
else {
|
||||
switch (overall) {
|
||||
case SK_SMART_OVERALL_GOOD:
|
||||
setOverall(Good);
|
||||
break;
|
||||
|
||||
case SK_SMART_OVERALL_BAD_ATTRIBUTE_IN_THE_PAST:
|
||||
setOverall(BadPast);
|
||||
break;
|
||||
|
||||
case SK_SMART_OVERALL_BAD_SECTOR:
|
||||
setOverall(BadSectors);
|
||||
break;
|
||||
|
||||
case SK_SMART_OVERALL_BAD_ATTRIBUTE_NOW:
|
||||
setOverall(BadNow);
|
||||
break;
|
||||
|
||||
case SK_SMART_OVERALL_BAD_SECTOR_MANY:
|
||||
setOverall(BadSectorsMany);
|
||||
break;
|
||||
|
||||
default:
|
||||
case SK_SMART_OVERALL_BAD_STATUS:
|
||||
setOverall(Bad);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sk_disk_smart_get_temperature(skDisk, &mkelvin) < 0)
|
||||
qDebug() << "getting temp failed for " << devicePath() << ": " << strerror(errno);
|
||||
else
|
||||
setTemp(mkelvin);
|
||||
|
||||
if (sk_disk_smart_get_bad(skDisk, &skBadSectors) < 0)
|
||||
qDebug() << "getting bad sectors failed for " << devicePath() << ": " << strerror(errno);
|
||||
else
|
||||
setBadSectors(skBadSectors);
|
||||
|
||||
if (sk_disk_smart_get_power_on(skDisk, &skPoweredOn) < 0)
|
||||
qDebug() << "getting powered on time failed for " << devicePath() << ": " << strerror(errno);
|
||||
else
|
||||
setPoweredOn(skPoweredOn);
|
||||
|
||||
if (sk_disk_smart_get_power_cycle(skDisk, &skPowerCycles) < 0)
|
||||
qDebug() << "getting power cycles failed for " << devicePath() << ": " << strerror(errno);
|
||||
else
|
||||
setPowerCycles(skPowerCycles);
|
||||
|
||||
m_Attributes.clear();
|
||||
|
||||
sk_disk_smart_parse_attributes(skDisk, callback, this);
|
||||
|
||||
sk_disk_free(skDisk);
|
||||
setStatus(disk->smartStatus());
|
||||
setModelName(disk->model());
|
||||
setFirmware(disk->firmware());
|
||||
setSerial(disk->serial());
|
||||
setSelfTestStatus(disk->selfTestExecutionStatus());
|
||||
setOverall(disk->overall());
|
||||
setTemp(disk->temperature());
|
||||
setBadSectors(disk->badSectors());
|
||||
setPoweredOn(disk->poweredOn());
|
||||
setPowerCycles(disk->powerCycles());
|
||||
addAttributes(disk->attributes());
|
||||
setInitSuccess(true);
|
||||
}
|
||||
|
||||
|
@ -195,40 +81,41 @@ QString SmartStatus::tempToString(quint64 mkelvin)
|
|||
{
|
||||
const double celsius = (mkelvin - 273150.0) / 1000.0;
|
||||
const double fahrenheit = 9.0 * celsius / 5.0 + 32;
|
||||
return xi18nc("@item:intable degrees in Celsius and Fahrenheit", "%1° C / %2° F", QLocale().toString(celsius, 1), QLocale().toString(fahrenheit, 1));
|
||||
return xi18nc("@item:intable degrees in Celsius and Fahrenheit", "%1° C / %2° F",
|
||||
QLocale().toString(celsius, 1), QLocale().toString(fahrenheit, 1));
|
||||
}
|
||||
|
||||
QString SmartStatus::selfTestStatusToString(SmartStatus::SelfTestStatus s)
|
||||
{
|
||||
switch (s) {
|
||||
case Aborted:
|
||||
case SelfTestStatus::Aborted:
|
||||
return xi18nc("@item", "Aborted");
|
||||
|
||||
case Interrupted:
|
||||
case SelfTestStatus::Interrupted:
|
||||
return xi18nc("@item", "Interrupted");
|
||||
|
||||
case Fatal:
|
||||
case SelfTestStatus::Fatal:
|
||||
return xi18nc("@item", "Fatal error");
|
||||
|
||||
case ErrorUnknown:
|
||||
case SelfTestStatus::ErrorUnknown:
|
||||
return xi18nc("@item", "Unknown error");
|
||||
|
||||
case ErrorEletrical:
|
||||
case SelfTestStatus::ErrorEletrical:
|
||||
return xi18nc("@item", "Electrical error");
|
||||
|
||||
case ErrorServo:
|
||||
case SelfTestStatus::ErrorServo:
|
||||
return xi18nc("@item", "Servo error");
|
||||
|
||||
case ErrorRead:
|
||||
case SelfTestStatus::ErrorRead:
|
||||
return xi18nc("@item", "Read error");
|
||||
|
||||
case ErrorHandling:
|
||||
case SelfTestStatus::ErrorHandling:
|
||||
return xi18nc("@item", "Handling error");
|
||||
|
||||
case InProgress:
|
||||
case SelfTestStatus::InProgress:
|
||||
return xi18nc("@item", "Self test in progress");
|
||||
|
||||
case Success:
|
||||
case SelfTestStatus::Success:
|
||||
default:
|
||||
return xi18nc("@item", "Success");
|
||||
}
|
||||
|
@ -238,33 +125,35 @@ QString SmartStatus::selfTestStatusToString(SmartStatus::SelfTestStatus s)
|
|||
QString SmartStatus::overallAssessmentToString(Overall o)
|
||||
{
|
||||
switch (o) {
|
||||
case Good:
|
||||
case Overall::Good:
|
||||
return xi18nc("@item", "Healthy");
|
||||
|
||||
case BadPast:
|
||||
case Overall::BadPast:
|
||||
return xi18nc("@item", "Has been used outside of its design parameters in the past.");
|
||||
|
||||
case BadSectors:
|
||||
case Overall::BadSectors:
|
||||
return xi18nc("@item", "Has some bad sectors.");
|
||||
|
||||
case BadNow:
|
||||
case Overall::BadNow:
|
||||
return xi18nc("@item", "Is being used outside of its design parameters right now.");
|
||||
|
||||
case BadSectorsMany:
|
||||
case Overall::BadSectorsMany:
|
||||
return xi18nc("@item", "Has many bad sectors.");
|
||||
|
||||
case Bad:
|
||||
case Overall::Bad:
|
||||
default:
|
||||
return xi18nc("@item", "Disk failure is imminent. Backup all data!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SmartStatus::callback(SkDisk*, const SkSmartAttributeParsedData* a, void* user_data)
|
||||
void SmartStatus::addAttributes(QList<SmartAttributeParsedData> attr)
|
||||
{
|
||||
SmartStatus* self = reinterpret_cast<SmartStatus*>(user_data);
|
||||
m_Attributes.clear();
|
||||
|
||||
SmartAttribute sm(a);
|
||||
self->m_Attributes.append(sm);
|
||||
for (const SmartAttributeParsedData &at : qAsConst(attr)) {
|
||||
SmartAttribute sm(at);
|
||||
m_Attributes.append(sm);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(KPMCORE_SMARTSTATUS_H)
|
||||
|
||||
#ifndef KPMCORE_SMARTSTATUS_H
|
||||
#define KPMCORE_SMARTSTATUS_H
|
||||
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
|
@ -32,7 +31,7 @@ struct SkDisk;
|
|||
class LIBKPMCORE_EXPORT SmartStatus
|
||||
{
|
||||
public:
|
||||
enum Overall {
|
||||
enum class Overall {
|
||||
Good,
|
||||
BadPast,
|
||||
BadSectors,
|
||||
|
@ -41,7 +40,7 @@ public:
|
|||
Bad
|
||||
};
|
||||
|
||||
enum SelfTestStatus {
|
||||
enum class SelfTestStatus {
|
||||
Success,
|
||||
Aborted,
|
||||
Interrupted,
|
||||
|
@ -51,99 +50,123 @@ public:
|
|||
ErrorServo,
|
||||
ErrorRead,
|
||||
ErrorHandling,
|
||||
InProgress
|
||||
InProgress = 15,
|
||||
};
|
||||
|
||||
public:
|
||||
typedef QList<SmartAttribute> Attributes;
|
||||
|
||||
public:
|
||||
SmartStatus(const QString& device_path);
|
||||
SmartStatus(const QString &device_path);
|
||||
|
||||
public:
|
||||
void update();
|
||||
|
||||
const QString& devicePath() const {
|
||||
const QString &devicePath() const
|
||||
{
|
||||
return m_DevicePath;
|
||||
}
|
||||
bool isValid() const {
|
||||
bool isValid() const
|
||||
{
|
||||
return m_InitSuccess;
|
||||
}
|
||||
bool status() const {
|
||||
bool status() const
|
||||
{
|
||||
return m_Status;
|
||||
}
|
||||
const QString& modelName() const {
|
||||
const QString &modelName() const
|
||||
{
|
||||
return m_ModelName;
|
||||
}
|
||||
const QString& serial() const {
|
||||
const QString &serial() const
|
||||
{
|
||||
return m_Serial;
|
||||
}
|
||||
const QString& firmware() const {
|
||||
const QString &firmware() const
|
||||
{
|
||||
return m_Firmware;
|
||||
}
|
||||
quint64 temp() const {
|
||||
quint64 temp() const
|
||||
{
|
||||
return m_Temp;
|
||||
}
|
||||
quint64 badSectors() const {
|
||||
quint64 badSectors() const
|
||||
{
|
||||
return m_BadSectors;
|
||||
}
|
||||
quint64 powerCycles() const {
|
||||
quint64 powerCycles() const
|
||||
{
|
||||
return m_PowerCycles;
|
||||
}
|
||||
quint64 poweredOn() const {
|
||||
quint64 poweredOn() const
|
||||
{
|
||||
return m_PoweredOn;
|
||||
}
|
||||
const Attributes& attributes() const {
|
||||
const Attributes &attributes() const
|
||||
{
|
||||
return m_Attributes;
|
||||
}
|
||||
Overall overall() const {
|
||||
Overall overall() const
|
||||
{
|
||||
return m_Overall;
|
||||
}
|
||||
SelfTestStatus selfTestStatus() const {
|
||||
SelfTestStatus selfTestStatus() const
|
||||
{
|
||||
return m_SelfTestStatus;
|
||||
}
|
||||
|
||||
void addAttributes(QList<SmartAttributeParsedData> attr);
|
||||
|
||||
static QString tempToString(quint64 mkelvin);
|
||||
static QString overallAssessmentToString(Overall o);
|
||||
static QString selfTestStatusToString(SmartStatus::SelfTestStatus s);
|
||||
|
||||
protected:
|
||||
void setStatus(bool s) {
|
||||
private:
|
||||
void setStatus(bool s)
|
||||
{
|
||||
m_Status = s;
|
||||
}
|
||||
void setModelName(const QString& name) {
|
||||
void setModelName(const QString &name)
|
||||
{
|
||||
m_ModelName = name;
|
||||
}
|
||||
void setSerial(const QString& s) {
|
||||
void setSerial(const QString &s)
|
||||
{
|
||||
m_Serial = s;
|
||||
}
|
||||
void setFirmware(const QString& f) {
|
||||
void setFirmware(const QString &f)
|
||||
{
|
||||
m_Firmware = f;
|
||||
}
|
||||
void setTemp(quint64 t) {
|
||||
void setTemp(quint64 t)
|
||||
{
|
||||
m_Temp = t;
|
||||
}
|
||||
void setInitSuccess(bool b) {
|
||||
void setInitSuccess(bool b)
|
||||
{
|
||||
m_InitSuccess = b;
|
||||
}
|
||||
void setBadSectors(quint64 s) {
|
||||
void setBadSectors(quint64 s)
|
||||
{
|
||||
m_BadSectors = s;
|
||||
}
|
||||
void setPowerCycles(quint64 p) {
|
||||
void setPowerCycles(quint64 p)
|
||||
{
|
||||
m_PowerCycles = p;
|
||||
}
|
||||
void setPoweredOn(quint64 t) {
|
||||
void setPoweredOn(quint64 t)
|
||||
{
|
||||
m_PoweredOn = t;
|
||||
}
|
||||
void setOverall(Overall o) {
|
||||
void setOverall(Overall o)
|
||||
{
|
||||
m_Overall = o;
|
||||
}
|
||||
void setSelfTestStatus(SelfTestStatus s) {
|
||||
void setSelfTestStatus(SelfTestStatus s)
|
||||
{
|
||||
m_SelfTestStatus = s;
|
||||
}
|
||||
|
||||
static void callback(SkDisk* skDisk, const SkSmartAttributeParsedData* a, void* user_data);
|
||||
|
||||
private:
|
||||
const QString m_DevicePath;
|
||||
bool m_InitSuccess;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
||||
* Copyright (C) 2018 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 *
|
||||
|
@ -15,18 +16,24 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "core/device_p.h"
|
||||
#include "core/volumemanagerdevice.h"
|
||||
#include "core/volumemanagerdevice_p.h"
|
||||
|
||||
/** Constructs an abstract Volume Manager Device with an empty PartitionTable.
|
||||
*
|
||||
* @param name the Device's name
|
||||
* @param deviceNode the Device's node
|
||||
* @param logicalExtentSize the logical extent size that device uses
|
||||
*/
|
||||
VolumeManagerDevice::VolumeManagerDevice(const QString& name,
|
||||
VolumeManagerDevice::VolumeManagerDevice(std::shared_ptr<VolumeManagerDevicePrivate> d,
|
||||
const QString& name,
|
||||
const QString& deviceNode,
|
||||
const qint64 logicalSize,
|
||||
const qint64 logicalExtentSize,
|
||||
const qint64 totalLogical,
|
||||
const QString& iconName,
|
||||
Device::Type type)
|
||||
: Device(name, deviceNode, logicalSize, totalLogical, iconName, type)
|
||||
: Device(std::static_pointer_cast<DevicePrivate>(d), name, deviceNode, logicalExtentSize, totalLogical, iconName, type)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -34,3 +41,9 @@ QString VolumeManagerDevice::prettyDeviceNodeList() const
|
|||
{
|
||||
return deviceNodes().join(QStringLiteral(", "));
|
||||
}
|
||||
|
||||
void VolumeManagerDevice::setTotalLogical(qint64 n)
|
||||
{
|
||||
Q_ASSERT(n > 0);
|
||||
d->m_TotalLogical = n;
|
||||
}
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(KPMCORE_VOLUMEMANAGERDEVICE_H)
|
||||
|
||||
#ifndef KPMCORE_VOLUMEMANAGERDEVICE_H
|
||||
#define KPMCORE_VOLUMEMANAGERDEVICE_H
|
||||
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
|
@ -27,6 +26,8 @@
|
|||
#include <QObject>
|
||||
#include <QtGlobal>
|
||||
|
||||
class VolumeManagerDevicePrivate;
|
||||
|
||||
/** A Volume Manager of physical devices represented as an abstract device.
|
||||
*
|
||||
* VolumeManagerDevice is an abstract device class for volume manager. e.g: LVM, SoftRAID.
|
||||
|
@ -41,8 +42,7 @@ class LIBKPMCORE_EXPORT VolumeManagerDevice : public Device
|
|||
Q_DISABLE_COPY(VolumeManagerDevice)
|
||||
|
||||
public:
|
||||
|
||||
VolumeManagerDevice(const QString& name, const QString& deviceNode, const qint64 logicalSize, const qint64 totalLogical, const QString& iconName = QString(), Device::Type type = Device::Unknown_Device);
|
||||
VolumeManagerDevice(std::shared_ptr<VolumeManagerDevicePrivate> d, const QString& name, const QString& deviceNode, const qint64 logicalSectorSize, const qint64 totalLogical, const QString& iconName = QString(), Device::Type type = Device::Type::Unknown_Device);
|
||||
|
||||
/**
|
||||
* @return list of physical device's path that makes up volumeManagerDevice.(e.g: /dev/sda, /dev/sdb1)
|
||||
|
@ -52,7 +52,7 @@ public:
|
|||
/**
|
||||
* @return list of logical partition's path.
|
||||
*/
|
||||
virtual const QStringList partitionNodes() const = 0;
|
||||
virtual const QStringList& partitionNodes() const = 0;
|
||||
|
||||
/**
|
||||
* @return size of logical partition at the given path in bytes.
|
||||
|
@ -80,9 +80,9 @@ protected:
|
|||
|
||||
public:
|
||||
|
||||
/** string deviceNodes together into comma-sperated list
|
||||
/** join deviceNodes together into comma-separated list
|
||||
*
|
||||
* @return comma-seperated list of deviceNodes
|
||||
* @return comma-separated list of deviceNodes
|
||||
*/
|
||||
virtual QString prettyDeviceNodeList() const;
|
||||
|
||||
|
@ -90,10 +90,7 @@ public:
|
|||
*
|
||||
* @param n Number of sectors.
|
||||
*/
|
||||
void setTotalLogical(qint64 n) {
|
||||
Q_ASSERT(n > 0);
|
||||
m_TotalLogical = n;
|
||||
}
|
||||
void setTotalLogical(qint64 n);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2018 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/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#ifndef KPMCORE_VOLUMEMANAGERDEVICE_P_H
|
||||
#define KPMCORE_VOLUMEMANAGERDEVICE_P_H
|
||||
|
||||
#include "core/device_p.h"
|
||||
|
||||
class VolumeManagerDevicePrivate : public DevicePrivate
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
|
@ -16,6 +16,7 @@ set(FS_SRC
|
|||
fs/hpfs.cpp
|
||||
fs/iso9660.cpp
|
||||
fs/jfs.cpp
|
||||
fs/linuxraidmember.cpp
|
||||
fs/linuxswap.cpp
|
||||
fs/luks.cpp
|
||||
fs/luks2.cpp
|
||||
|
@ -51,6 +52,7 @@ set(FS_LIB_HDRS
|
|||
fs/hpfs.h
|
||||
fs/iso9660.h
|
||||
fs/jfs.h
|
||||
fs/linuxraidmember.h
|
||||
fs/linuxswap.h
|
||||
fs/luks.h
|
||||
fs/luks2.h
|
||||
|
|
|
@ -44,7 +44,7 @@ FileSystem::CommandSupportType btrfs::m_UpdateUUID = FileSystem::cmdSupportNone;
|
|||
FileSystem::CommandSupportType btrfs::m_GetUUID = FileSystem::cmdSupportNone;
|
||||
|
||||
btrfs::btrfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Btrfs)
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Btrfs)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -91,12 +91,12 @@ FileSystem::SupportTool btrfs::supportToolName() const
|
|||
|
||||
qint64 btrfs::minCapacity() const
|
||||
{
|
||||
return 256 * Capacity::unitFactor(Capacity::Byte, Capacity::MiB);
|
||||
return 256 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
|
||||
}
|
||||
|
||||
qint64 btrfs::maxCapacity() const
|
||||
{
|
||||
return Capacity::unitFactor(Capacity::Byte, Capacity::EiB);
|
||||
return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB);
|
||||
}
|
||||
|
||||
int btrfs::maxLabelLength() const
|
||||
|
|
|
@ -39,7 +39,7 @@ FileSystem::CommandSupportType exfat::m_UpdateUUID = FileSystem::cmdSupportNone;
|
|||
FileSystem::CommandSupportType exfat::m_GetUUID = FileSystem::cmdSupportNone;
|
||||
|
||||
exfat::exfat(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Exfat)
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Exfat)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ FileSystem::SupportTool exfat::supportToolName() const
|
|||
|
||||
qint64 exfat::maxCapacity() const
|
||||
{
|
||||
return Capacity::unitFactor(Capacity::Byte, Capacity::EiB);
|
||||
return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB);
|
||||
}
|
||||
|
||||
int exfat::maxLabelLength() const
|
||||
|
@ -112,8 +112,8 @@ bool exfat::writeLabel(Report& report, const QString& deviceNode, const QString&
|
|||
|
||||
bool exfat::updateUUID(Report& report, const QString& deviceNode) const
|
||||
{
|
||||
Q_UNUSED(report);
|
||||
Q_UNUSED(deviceNode);
|
||||
Q_UNUSED(report)
|
||||
Q_UNUSED(deviceNode)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ FileSystem::SupportTool ext2::supportToolName() const
|
|||
|
||||
qint64 ext2::maxCapacity() const
|
||||
{
|
||||
return 16 * Capacity::unitFactor(Capacity::Byte, Capacity::TiB) - Capacity::unitFactor(Capacity::Byte, Capacity::MiB);
|
||||
return 16 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::TiB) - Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
|
||||
}
|
||||
|
||||
int ext2::maxLabelLength() const
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace FS
|
|||
class LIBKPMCORE_EXPORT ext2 : public FileSystem
|
||||
{
|
||||
public:
|
||||
ext2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type t = FileSystem::Ext2);
|
||||
ext2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type t = FileSystem::Type::Ext2);
|
||||
|
||||
public:
|
||||
void init() override;
|
||||
|
|
|
@ -25,13 +25,13 @@
|
|||
namespace FS
|
||||
{
|
||||
ext3::ext3(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
ext2(firstsector, lastsector, sectorsused, label, FileSystem::Ext3)
|
||||
ext2(firstsector, lastsector, sectorsused, label, FileSystem::Type::Ext3)
|
||||
{
|
||||
}
|
||||
|
||||
qint64 ext3::maxCapacity() const
|
||||
{
|
||||
return 16 * Capacity::unitFactor(Capacity::Byte, Capacity::TiB) - Capacity::unitFactor(Capacity::Byte, Capacity::MiB);
|
||||
return 16 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::TiB) - Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
|
||||
}
|
||||
|
||||
bool ext3::create(Report& report, const QString& deviceNode)
|
||||
|
|
|
@ -25,13 +25,13 @@
|
|||
namespace FS
|
||||
{
|
||||
ext4::ext4(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
ext2(firstsector, lastsector, sectorsused, label, FileSystem::Ext4)
|
||||
ext2(firstsector, lastsector, sectorsused, label, FileSystem::Type::Ext4)
|
||||
{
|
||||
}
|
||||
|
||||
qint64 ext4::maxCapacity() const
|
||||
{
|
||||
return Capacity::unitFactor(Capacity::Byte, Capacity::EiB);
|
||||
return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB);
|
||||
}
|
||||
|
||||
bool ext4::create(Report& report, const QString& deviceNode)
|
||||
|
|
|
@ -25,7 +25,7 @@ FileSystem::CommandSupportType extended::m_Shrink = FileSystem::cmdSupportCore;
|
|||
FileSystem::CommandSupportType extended::m_Move = FileSystem::cmdSupportCore;
|
||||
|
||||
extended::extended(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Extended)
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Extended)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ FileSystem::CommandSupportType f2fs::m_GetUUID = FileSystem::cmdSupportNone;
|
|||
bool f2fs::oldVersion = false; // 1.8.x or older
|
||||
|
||||
f2fs::f2fs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::F2fs)
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::F2fs)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -100,12 +100,12 @@ FileSystem::SupportTool f2fs::supportToolName() const
|
|||
|
||||
qint64 f2fs::minCapacity() const
|
||||
{
|
||||
return 30 * Capacity::unitFactor(Capacity::Byte, Capacity::MiB);
|
||||
return 30 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
|
||||
}
|
||||
|
||||
qint64 f2fs::maxCapacity() const
|
||||
{
|
||||
return 16 * Capacity::unitFactor(Capacity::Byte, Capacity::TiB);
|
||||
return 16 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::TiB);
|
||||
}
|
||||
|
||||
int f2fs::maxLabelLength() const
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(KPMCORE_F2FS_H)
|
||||
|
||||
#ifndef KPMCORE_F2FS_H
|
||||
#define KPMCORE_F2FS_H
|
||||
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
|
|
|
@ -87,12 +87,12 @@ FileSystem::SupportTool fat12::supportToolName() const
|
|||
|
||||
qint64 fat12::minCapacity() const
|
||||
{
|
||||
return 1 * Capacity::unitFactor(Capacity::Byte, Capacity::MiB);
|
||||
return 1 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
|
||||
}
|
||||
|
||||
qint64 fat12::maxCapacity() const
|
||||
{
|
||||
return 255 * Capacity::unitFactor(Capacity::Byte, Capacity::MiB);
|
||||
return 255 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
|
||||
}
|
||||
|
||||
int fat12::maxLabelLength() const
|
||||
|
@ -167,12 +167,7 @@ bool fat12::updateUUID(Report& report, const QString& deviceNode) const
|
|||
|
||||
ExternalCommand cmd(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode , QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=39") });
|
||||
|
||||
if (!cmd.start())
|
||||
return false;
|
||||
|
||||
if (cmd.write(uuid, sizeof(uuid)) != sizeof(uuid))
|
||||
return false;
|
||||
|
||||
return cmd.waitFor(-1);
|
||||
cmd.write(QByteArray(uuid, sizeof(uuid)));
|
||||
return cmd.start();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(KPMCORE_FAT12_H)
|
||||
|
||||
#ifndef KPMCORE_FAT12_H
|
||||
#define KPMCORE_FAT12_H
|
||||
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
|
@ -38,7 +37,7 @@ namespace FS
|
|||
class LIBKPMCORE_EXPORT fat12 : public FileSystem
|
||||
{
|
||||
public:
|
||||
fat12(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type t = FileSystem::Fat12);
|
||||
fat12(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type t = FileSystem::Type::Fat12);
|
||||
|
||||
public:
|
||||
void init() override;
|
||||
|
@ -62,10 +61,10 @@ public:
|
|||
return m_Create;
|
||||
}
|
||||
CommandSupportType supportGrow() const override {
|
||||
return m_Grow;
|
||||
return cmdSupportNone;
|
||||
}
|
||||
CommandSupportType supportShrink() const override {
|
||||
return m_Shrink;
|
||||
return cmdSupportNone;
|
||||
}
|
||||
CommandSupportType supportMove() const override {
|
||||
return m_Move;
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
namespace FS
|
||||
{
|
||||
fat16::fat16(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
fat12(firstsector, lastsector, sectorsused, label, FileSystem::Fat16)
|
||||
fat12(firstsector, lastsector, sectorsused, label, FileSystem::Type::Fat16)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -75,12 +75,12 @@ bool fat16::supportToolFound() const
|
|||
|
||||
qint64 fat16::minCapacity() const
|
||||
{
|
||||
return 16 * Capacity::unitFactor(Capacity::Byte, Capacity::MiB);
|
||||
return 16 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
|
||||
}
|
||||
|
||||
qint64 fat16::maxCapacity() const
|
||||
{
|
||||
return 4 * Capacity::unitFactor(Capacity::Byte, Capacity::GiB) - Capacity::unitFactor(Capacity::Byte, Capacity::MiB);
|
||||
return 4 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::GiB) - Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
|
||||
}
|
||||
|
||||
bool fat16::create(Report& report, const QString& deviceNode)
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(KPMCORE_FAT16_H)
|
||||
|
||||
#ifndef KPMCORE_FAT16_H
|
||||
#define KPMCORE_FAT16_H
|
||||
|
||||
#include "fs/fat12.h"
|
||||
|
@ -43,6 +42,13 @@ public:
|
|||
bool create(Report& report, const QString& deviceNode) override;
|
||||
bool resize(Report& report, const QString& deviceNode, qint64 length) const override;
|
||||
|
||||
CommandSupportType supportGrow() const override {
|
||||
return m_Grow;
|
||||
}
|
||||
CommandSupportType supportShrink() const override {
|
||||
return m_Shrink;
|
||||
}
|
||||
|
||||
qint64 minCapacity() const override;
|
||||
qint64 maxCapacity() const override;
|
||||
bool supportToolFound() const override;
|
||||
|
|
|
@ -26,18 +26,18 @@
|
|||
namespace FS
|
||||
{
|
||||
fat32::fat32(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
fat16(firstsector, lastsector, sectorsused, label, FileSystem::Fat32)
|
||||
fat16(firstsector, lastsector, sectorsused, label, FileSystem::Type::Fat32)
|
||||
{
|
||||
}
|
||||
|
||||
qint64 fat32::minCapacity() const
|
||||
{
|
||||
return 32 * Capacity::unitFactor(Capacity::Byte, Capacity::MiB);
|
||||
return 32 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
|
||||
}
|
||||
|
||||
qint64 fat32::maxCapacity() const
|
||||
{
|
||||
return 16 * Capacity::unitFactor(Capacity::Byte, Capacity::TiB) - Capacity::unitFactor(Capacity::Byte, Capacity::MiB);
|
||||
return 16 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::TiB) - Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
|
||||
}
|
||||
|
||||
bool fat32::create(Report& report, const QString& deviceNode)
|
||||
|
@ -59,12 +59,7 @@ bool fat32::updateUUID(Report& report, const QString& deviceNode) const
|
|||
// HACK: replace this hack with fatlabel "-i" (dosfstools 4.2)
|
||||
ExternalCommand cmd(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode, QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=67") });
|
||||
|
||||
if (!cmd.start())
|
||||
return false;
|
||||
|
||||
if (cmd.write(uuid, sizeof(uuid)) != sizeof(uuid))
|
||||
return false;
|
||||
|
||||
return cmd.waitFor(-1);
|
||||
cmd.write(QByteArray(uuid, sizeof(uuid)));
|
||||
return cmd.start();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2012 by Volker Lanz <vl@fidra.de> *
|
||||
* Copyright (C) 2015 by Teo Mrnjavac <teo@kde.org> *
|
||||
* Copyright (C) 2016 by Andrius Štikonas <andrius@stikonas.eu> *
|
||||
* Copyright (C) 2016-2018 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 *
|
||||
|
@ -31,10 +31,12 @@
|
|||
|
||||
#include <KLocalizedString>
|
||||
|
||||
#include <QColor>
|
||||
#include <QFileInfo>
|
||||
#include <QStandardPaths>
|
||||
#include <QStorageInfo>
|
||||
|
||||
const std::array< QColor, FileSystem::__lastType > FileSystem::defaultColorCode =
|
||||
const std::vector<QColor> FileSystem::defaultColorCode =
|
||||
{
|
||||
{
|
||||
QColor( 220,205,175 ), // unknown
|
||||
|
@ -66,25 +68,40 @@ const std::array< QColor, FileSystem::__lastType > FileSystem::defaultColorCode
|
|||
QColor( 170,120,255 ), // udf
|
||||
QColor( 177,82,69 ), // iso9660
|
||||
QColor( 223,39,104 ), // luks2
|
||||
QColor( 204,179,255 ) // fat12
|
||||
QColor( 204,179,255 ), // fat12
|
||||
QColor( 255,100,100 ) // linux_raid_member
|
||||
}
|
||||
};
|
||||
|
||||
struct FileSystemPrivate {
|
||||
FileSystem::Type m_Type;
|
||||
qint64 m_FirstSector;
|
||||
qint64 m_LastSector;
|
||||
qint64 m_SectorSize;
|
||||
qint64 m_SectorsUsed;
|
||||
QString m_Label;
|
||||
QString m_UUID;
|
||||
};
|
||||
|
||||
/** Creates a new FileSystem object
|
||||
@param firstsector the first sector used by this FileSystem on the Device
|
||||
@param lastsector the last sector used by this FileSystem on the Device
|
||||
@param sectorsused the number of sectors in use on the FileSystem
|
||||
@param l the FileSystem label
|
||||
@param t the FileSystem type
|
||||
@param label the FileSystem label
|
||||
@param type the FileSystem type
|
||||
*/
|
||||
FileSystem::FileSystem(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& l, FileSystem::Type t) :
|
||||
m_Type(t),
|
||||
m_FirstSector(firstsector),
|
||||
m_LastSector(lastsector),
|
||||
m_SectorsUsed(sectorsused),
|
||||
m_Label(l),
|
||||
m_UUID()
|
||||
FileSystem::FileSystem(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type type) :
|
||||
d(std::make_unique<FileSystemPrivate>())
|
||||
{
|
||||
d->m_Type = type;
|
||||
d->m_FirstSector = firstsector;
|
||||
d->m_LastSector = lastsector;
|
||||
d->m_SectorsUsed = sectorsused;
|
||||
d->m_Label = label;
|
||||
d->m_UUID = QString();
|
||||
}
|
||||
|
||||
FileSystem::~FileSystem()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -106,7 +123,7 @@ FileSystem::Type FileSystem::detectFileSystem(const QString& partitionPath)
|
|||
|
||||
QString FileSystem::detectMountPoint(FileSystem* fs, const QString& partitionPath)
|
||||
{
|
||||
if (fs->type() == FileSystem::Lvm2_PV)
|
||||
if (fs->type() == FileSystem::Type::Lvm2_PV)
|
||||
return FS::lvm2_pv::getVGName(partitionPath);
|
||||
|
||||
if (partitionPath.isEmpty()) // Happens when during initial scan LUKS is closed
|
||||
|
@ -131,7 +148,7 @@ bool FileSystem::detectMountStatus(FileSystem* fs, const QString& partitionPath)
|
|||
{
|
||||
bool mounted = false;
|
||||
|
||||
if (fs->type() == FileSystem::Lvm2_PV) {
|
||||
if (fs->type() == FileSystem::Type::Lvm2_PV) {
|
||||
mounted = FS::lvm2_pv::getVGName(partitionPath) != QString();
|
||||
} else {
|
||||
mounted = isMounted(partitionPath);
|
||||
|
@ -360,13 +377,13 @@ bool FileSystem::updateBootSector(Report& report, const QString& deviceNode) con
|
|||
/** @return the minimum capacity valid for this FileSystem in bytes */
|
||||
qint64 FileSystem::minCapacity() const
|
||||
{
|
||||
return 8 * Capacity::unitFactor(Capacity::Byte, Capacity::MiB);
|
||||
return 8 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
|
||||
}
|
||||
|
||||
/** @return the maximum capacity valid for this FileSystem in bytes */
|
||||
qint64 FileSystem::maxCapacity() const
|
||||
{
|
||||
return Capacity::unitFactor(Capacity::Byte, Capacity::EiB);
|
||||
return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB);
|
||||
}
|
||||
|
||||
/** @return the maximum label length valid for this FileSystem */
|
||||
|
@ -390,6 +407,11 @@ QString FileSystem::name(const QStringList& languages) const
|
|||
return nameForType(type(), languages);
|
||||
}
|
||||
|
||||
FileSystem::Type FileSystem::type() const
|
||||
{
|
||||
return d->m_Type;
|
||||
}
|
||||
|
||||
/** @return a pointer to a QString C array with all FileSystem names */
|
||||
static const KLocalizedString* typeNames()
|
||||
{
|
||||
|
@ -424,7 +446,8 @@ static const KLocalizedString* typeNames()
|
|||
kxi18nc("@item filesystem name", "udf"),
|
||||
kxi18nc("@item filesystem name", "iso9660"),
|
||||
kxi18nc("@item filesystem name", "luks2"),
|
||||
kxi18nc("@item filesystem name", "fat12")
|
||||
kxi18nc("@item filesystem name", "fat12"),
|
||||
kxi18nc("@item filesystem name", "linux_raid_member"),
|
||||
};
|
||||
|
||||
return s;
|
||||
|
@ -435,10 +458,9 @@ static const KLocalizedString* typeNames()
|
|||
*/
|
||||
QString FileSystem::nameForType(FileSystem::Type t, const QStringList& languages)
|
||||
{
|
||||
Q_ASSERT(t >= 0);
|
||||
Q_ASSERT(t < __lastType);
|
||||
Q_ASSERT(t < Type::__lastType);
|
||||
|
||||
return typeNames()[t].toString(languages);
|
||||
return typeNames()[static_cast<int>(t)].toString(languages);
|
||||
}
|
||||
|
||||
/** @param s the name to get the type for
|
||||
|
@ -446,11 +468,11 @@ QString FileSystem::nameForType(FileSystem::Type t, const QStringList& languages
|
|||
*/
|
||||
FileSystem::Type FileSystem::typeForName(const QString& s, const QStringList& languages )
|
||||
{
|
||||
for (quint32 i = 0; i < __lastType; i++)
|
||||
for (quint32 i = 0; i < static_cast<int>(Type::__lastType); i++)
|
||||
if (typeNames()[i].toString(languages) == s)
|
||||
return static_cast<FileSystem::Type>(i);
|
||||
|
||||
return Unknown;
|
||||
return Type::Unknown;
|
||||
}
|
||||
|
||||
/** @return a QList of all known types */
|
||||
|
@ -458,8 +480,8 @@ QList<FileSystem::Type> FileSystem::types()
|
|||
{
|
||||
QList<FileSystem::Type> result;
|
||||
|
||||
int i = Ext2; // first "real" filesystem
|
||||
while (i != __lastType)
|
||||
int i = static_cast<int>(Type::Ext2); // first "real" filesystem
|
||||
while (i != static_cast<int>(Type::__lastType))
|
||||
result.append(static_cast<FileSystem::Type>(i++));
|
||||
|
||||
return result;
|
||||
|
@ -529,9 +551,25 @@ bool FileSystem::unmount(Report& report, const QString& deviceNode)
|
|||
return false;
|
||||
}
|
||||
|
||||
qint64 FileSystem::firstSector() const
|
||||
{
|
||||
return d->m_FirstSector;
|
||||
}
|
||||
|
||||
qint64 FileSystem::lastSector() const
|
||||
{
|
||||
return d->m_LastSector;
|
||||
}
|
||||
|
||||
bool FileSystem::findExternal(const QString& cmdName, const QStringList& args, int expectedCode)
|
||||
{
|
||||
ExternalCommand cmd(cmdName, args);
|
||||
QString cmdFullPath = QStandardPaths::findExecutable(cmdName);
|
||||
if (cmdFullPath.isEmpty())
|
||||
cmdFullPath = QStandardPaths::findExecutable(cmdName, { QStringLiteral("/sbin/"), QStringLiteral("/usr/sbin/"), QStringLiteral("/usr/local/sbin/") });
|
||||
if (cmdFullPath.isEmpty())
|
||||
return false;
|
||||
|
||||
ExternalCommand cmd(cmdFullPath, args);
|
||||
if (!cmd.run())
|
||||
return false;
|
||||
|
||||
|
@ -547,3 +585,53 @@ FileSystem::SupportTool FileSystem::supportToolName() const
|
|||
{
|
||||
return SupportTool();
|
||||
}
|
||||
|
||||
void FileSystem::setFirstSector(qint64 s)
|
||||
{
|
||||
d->m_FirstSector = s;
|
||||
}
|
||||
|
||||
void FileSystem::setLastSector(qint64 s)
|
||||
{
|
||||
d->m_LastSector = s;
|
||||
}
|
||||
|
||||
const QString& FileSystem::label() const
|
||||
{
|
||||
return d->m_Label;
|
||||
}
|
||||
|
||||
qint64 FileSystem::sectorSize() const
|
||||
{
|
||||
return d->m_SectorSize;
|
||||
}
|
||||
|
||||
qint64 FileSystem::sectorsUsed() const
|
||||
{
|
||||
return d->m_SectorsUsed;
|
||||
}
|
||||
|
||||
const QString& FileSystem::uuid() const
|
||||
{
|
||||
return d->m_UUID;
|
||||
}
|
||||
|
||||
void FileSystem::setSectorSize(qint64 s)
|
||||
{
|
||||
d->m_SectorSize = s;
|
||||
}
|
||||
|
||||
void FileSystem::setSectorsUsed(qint64 s)
|
||||
{
|
||||
d->m_SectorsUsed = s;
|
||||
}
|
||||
|
||||
void FileSystem::setLabel(const QString& s)
|
||||
{
|
||||
d->m_Label = s;
|
||||
}
|
||||
|
||||
void FileSystem::setUUID(const QString& s)
|
||||
{
|
||||
d->m_UUID = s;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2012 by Volker Lanz <vl@fidra.de> *
|
||||
* Copyright (C) 2015 by Teo Mrnjavac <teo@kde.org> *
|
||||
* Copyright (C) 2016 by Andrius Štikonas <andrius@stikonas.eu> *
|
||||
* Copyright (C) 2016-2018 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 *
|
||||
|
@ -17,23 +17,25 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(KPMCORE_FILESYSTEM_H)
|
||||
#ifndef KPMCORE_FILESYSTEM_H
|
||||
#define KPMCORE_FILESYSTEM_H
|
||||
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
|
||||
#include <QColor>
|
||||
#include <QList>
|
||||
#include <QStringList>
|
||||
#include <QString>
|
||||
#include <QtGlobal>
|
||||
#include <QUrl>
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
class QColor;
|
||||
class QValidator;
|
||||
class Device;
|
||||
class Report;
|
||||
struct FileSystemPrivate;
|
||||
|
||||
/** Base class for all FileSystems.
|
||||
|
||||
|
@ -57,40 +59,41 @@ public:
|
|||
};
|
||||
|
||||
/** Supported FileSystem types */
|
||||
enum Type {
|
||||
Unknown = 0,
|
||||
Extended = 1,
|
||||
enum Type : int {
|
||||
Unknown,
|
||||
Extended,
|
||||
|
||||
Ext2 = 2,
|
||||
Ext3 = 3,
|
||||
Ext4 = 4,
|
||||
LinuxSwap = 5,
|
||||
Fat16 = 6,
|
||||
Fat32 = 7,
|
||||
Ntfs = 8,
|
||||
ReiserFS = 9,
|
||||
Reiser4 = 10,
|
||||
Xfs = 11,
|
||||
Jfs = 12,
|
||||
Hfs = 13,
|
||||
HfsPlus = 14,
|
||||
Ufs = 15,
|
||||
Unformatted = 16,
|
||||
Btrfs = 17,
|
||||
Hpfs = 18,
|
||||
Luks = 19,
|
||||
Ocfs2 = 20,
|
||||
Zfs = 21,
|
||||
Exfat = 22,
|
||||
Nilfs2 = 23,
|
||||
Lvm2_PV = 24,
|
||||
F2fs = 25,
|
||||
Udf = 26,
|
||||
Iso9660 = 27,
|
||||
Luks2 = 28,
|
||||
Fat12 = 29,
|
||||
Ext2,
|
||||
Ext3,
|
||||
Ext4,
|
||||
LinuxSwap,
|
||||
Fat16,
|
||||
Fat32,
|
||||
Ntfs,
|
||||
ReiserFS,
|
||||
Reiser4,
|
||||
Xfs,
|
||||
Jfs,
|
||||
Hfs,
|
||||
HfsPlus,
|
||||
Ufs,
|
||||
Unformatted,
|
||||
Btrfs,
|
||||
Hpfs,
|
||||
Luks,
|
||||
Ocfs2,
|
||||
Zfs,
|
||||
Exfat,
|
||||
Nilfs2,
|
||||
Lvm2_PV,
|
||||
F2fs,
|
||||
Udf,
|
||||
Iso9660,
|
||||
Luks2,
|
||||
Fat12,
|
||||
LinuxRaidMember,
|
||||
|
||||
__lastType = 30
|
||||
__lastType
|
||||
};
|
||||
|
||||
/** The type of support for a given FileSystem action */
|
||||
|
@ -101,15 +104,15 @@ public:
|
|||
cmdSupportBackend = 4 /**< supported by the backend */
|
||||
};
|
||||
|
||||
static const std::array< QColor, __lastType > defaultColorCode;
|
||||
static const std::vector<QColor> defaultColorCode;
|
||||
|
||||
Q_DECLARE_FLAGS(CommandSupportTypes, CommandSupportType)
|
||||
|
||||
protected:
|
||||
FileSystem(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type t);
|
||||
FileSystem(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type type);
|
||||
|
||||
public:
|
||||
virtual ~FileSystem() {}
|
||||
virtual ~FileSystem();
|
||||
|
||||
public:
|
||||
virtual void init() {}
|
||||
|
@ -196,9 +199,11 @@ public:
|
|||
* @see nameForType()
|
||||
*/
|
||||
virtual QString name(const QStringList& languages = {}) const;
|
||||
virtual FileSystem::Type type() const {
|
||||
return m_Type; /**< @return the FileSystem's type */
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the FileSystem's type
|
||||
*/
|
||||
virtual FileSystem::Type type() const;
|
||||
|
||||
/**
|
||||
* Returns the name of the given filesystem type. If @p languages
|
||||
|
@ -228,12 +233,12 @@ public:
|
|||
virtual bool mount(Report& report, const QString& deviceNode, const QString& mountPoint);
|
||||
virtual bool unmount(Report& report, const QString& deviceNode);
|
||||
|
||||
qint64 firstSector() const {
|
||||
return m_FirstSector; /**< @return the FileSystem's first sector */
|
||||
}
|
||||
qint64 lastSector() const {
|
||||
return m_LastSector; /**< @return the FileSystem's last sector */
|
||||
}
|
||||
/**< @return the FileSystem's first sector */
|
||||
qint64 firstSector() const;
|
||||
|
||||
/**< @return the FileSystem's last sector */
|
||||
qint64 lastSector() const;
|
||||
|
||||
qint64 length() const {
|
||||
return lastSector() - firstSector() + 1; /**< @return the FileSystem's length */
|
||||
}
|
||||
|
@ -244,52 +249,42 @@ public:
|
|||
return firstByte() + length() * sectorSize() - 1; /**< @return the FileSystem's last byte */
|
||||
}
|
||||
|
||||
void setFirstSector(qint64 s) {
|
||||
m_FirstSector = s; /**< @param s the new first sector */
|
||||
}
|
||||
void setLastSector(qint64 s) {
|
||||
m_LastSector = s; /**< @param s the new last sector */
|
||||
}
|
||||
/**< @param s the new first sector */
|
||||
void setFirstSector(qint64 s);
|
||||
|
||||
/**< @param s the new last sector */
|
||||
void setLastSector(qint64 s);
|
||||
|
||||
void move(qint64 newStartSector);
|
||||
|
||||
const QString& label() const {
|
||||
return m_Label; /**< @return the FileSystem's label */
|
||||
}
|
||||
qint64 sectorSize() const {
|
||||
return m_SectorSize; /**< @return the sector size in the underlying Device */
|
||||
}
|
||||
qint64 sectorsUsed() const {
|
||||
return m_SectorsUsed; /**< @return the sectors in use on the FileSystem */
|
||||
}
|
||||
const QString& uuid() const {
|
||||
return m_UUID; /**< @return the FileSystem's UUID */
|
||||
}
|
||||
/**< @return the FileSystem's label */
|
||||
const QString& label() const;
|
||||
|
||||
void setSectorSize(qint64 s) {
|
||||
m_SectorSize = s; /**< @param s the new value for sector size */
|
||||
}
|
||||
void setSectorsUsed(qint64 s) {
|
||||
m_SectorsUsed = s; /**< @param s the new value for sectors in use */
|
||||
}
|
||||
void setLabel(const QString& s) {
|
||||
m_Label = s; /**< @param s the new label */
|
||||
}
|
||||
void setUUID(const QString& s) {
|
||||
m_UUID = s; /**< @param s the new UUID */
|
||||
}
|
||||
/**< @return the sector size in the underlying Device */
|
||||
qint64 sectorSize() const;
|
||||
|
||||
/**< @return the sectors in use on the FileSystem */
|
||||
qint64 sectorsUsed() const;
|
||||
|
||||
/**< @return the FileSystem's UUID */
|
||||
const QString& uuid() const;
|
||||
|
||||
/**< @param s the new value for sector size */
|
||||
void setSectorSize(qint64 s);
|
||||
|
||||
/**< @param s the new value for sectors in use */
|
||||
void setSectorsUsed(qint64 s);
|
||||
|
||||
/**< @param s the new label */
|
||||
void setLabel(const QString& s);
|
||||
|
||||
/**< @param s the new UUID */
|
||||
void setUUID(const QString& s);
|
||||
|
||||
protected:
|
||||
static bool findExternal(const QString& cmdName, const QStringList& args = QStringList(), int exptectedCode = 1);
|
||||
|
||||
protected:
|
||||
FileSystem::Type m_Type;
|
||||
qint64 m_FirstSector;
|
||||
qint64 m_LastSector;
|
||||
qint64 m_SectorSize;
|
||||
qint64 m_SectorsUsed;
|
||||
QString m_Label;
|
||||
QString m_UUID;
|
||||
std::unique_ptr<FileSystemPrivate> d;
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(FileSystem::CommandSupportTypes)
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2018 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/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#ifndef KPMCORE_FILESYSTEM_P_H
|
||||
#define KPMCORE_FILESYSTEM_P_H
|
||||
|
||||
#include "fs/filesystem.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
class FileSystemPrivate {
|
||||
public:
|
||||
FileSystem::Type m_Type;
|
||||
qint64 m_FirstSector;
|
||||
qint64 m_LastSector;
|
||||
qint64 m_SectorSize;
|
||||
qint64 m_SectorsUsed;
|
||||
QString m_Label;
|
||||
QString m_UUID;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -34,6 +34,7 @@
|
|||
#include "fs/hpfs.h"
|
||||
#include "fs/iso9660.h"
|
||||
#include "fs/jfs.h"
|
||||
#include "fs/linuxraidmember.h"
|
||||
#include "fs/linuxswap.h"
|
||||
#include "fs/luks.h"
|
||||
#include "fs/luks2.h"
|
||||
|
@ -61,36 +62,37 @@ void FileSystemFactory::init()
|
|||
qDeleteAll(m_FileSystems);
|
||||
m_FileSystems.clear();
|
||||
|
||||
m_FileSystems.insert(FileSystem::Btrfs, new FS::btrfs(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Exfat, new FS::exfat(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Ext2, new FS::ext2(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Ext3, new FS::ext3(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Ext4, new FS::ext4(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Extended, new FS::extended(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::F2fs, new FS::f2fs(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Fat12, new FS::fat12(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Fat16, new FS::fat16(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Fat32, new FS::fat32(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Hfs, new FS::hfs(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::HfsPlus, new FS::hfsplus(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Hpfs, new FS::hpfs(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Iso9660, new FS::iso9660(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Jfs, new FS::jfs(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::LinuxSwap, new FS::linuxswap(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Luks, new FS::luks(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Luks2, new FS::luks2(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Lvm2_PV, new FS::lvm2_pv(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Nilfs2, new FS::nilfs2(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Ntfs, new FS::ntfs(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Ocfs2, new FS::ocfs2(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::ReiserFS, new FS::reiserfs(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Reiser4, new FS::reiser4(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Udf, new FS::udf(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Ufs, new FS::ufs(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Unformatted, new FS::unformatted(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Unknown, new FS::unknown(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Xfs, new FS::xfs(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Zfs, new FS::zfs(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Btrfs, new FS::btrfs(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Exfat, new FS::exfat(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Ext2, new FS::ext2(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Ext3, new FS::ext3(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Ext4, new FS::ext4(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Extended, new FS::extended(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::F2fs, new FS::f2fs(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Fat12, new FS::fat12(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Fat16, new FS::fat16(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Fat32, new FS::fat32(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Hfs, new FS::hfs(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::HfsPlus, new FS::hfsplus(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Hpfs, new FS::hpfs(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Iso9660, new FS::iso9660(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Jfs, new FS::jfs(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::LinuxRaidMember, new FS::linuxraidmember(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::LinuxSwap, new FS::linuxswap(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Luks, new FS::luks(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Luks2, new FS::luks2(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Lvm2_PV, new FS::lvm2_pv(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Nilfs2, new FS::nilfs2(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Ntfs, new FS::ntfs(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Ocfs2, new FS::ocfs2(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::ReiserFS, new FS::reiserfs(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Reiser4, new FS::reiser4(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Udf, new FS::udf(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Ufs, new FS::ufs(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Unformatted, new FS::unformatted(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Unknown, new FS::unknown(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Xfs, new FS::xfs(-1, -1, -1, QString()));
|
||||
m_FileSystems.insert(FileSystem::Type::Zfs, new FS::zfs(-1, -1, -1, QString()));
|
||||
|
||||
for (const auto &fs : FileSystemFactory::map())
|
||||
fs->init();
|
||||
|
@ -111,36 +113,37 @@ FileSystem* FileSystemFactory::create(FileSystem::Type t, qint64 firstsector, qi
|
|||
FileSystem* fs = nullptr;
|
||||
|
||||
switch (t) {
|
||||
case FileSystem::Btrfs: fs = new FS::btrfs(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Exfat: fs = new FS::exfat(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Ext2: fs = new FS::ext2(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Ext3: fs = new FS::ext3(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Ext4: fs = new FS::ext4(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Extended: fs = new FS::extended(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::F2fs: fs = new FS::f2fs(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Fat12: fs = new FS::fat12(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Fat16: fs = new FS::fat16(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Fat32: fs = new FS::fat32(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Hfs: fs = new FS::hfs(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::HfsPlus: fs = new FS::hfsplus(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Hpfs: fs = new FS::hpfs(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Iso9660: fs = new FS::iso9660(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Jfs: fs = new FS::jfs(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::LinuxSwap: fs = new FS::linuxswap(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Luks: fs = new FS::luks(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Luks2: fs = new FS::luks2(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Lvm2_PV: fs = new FS::lvm2_pv(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Nilfs2: fs = new FS::nilfs2(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Ntfs: fs = new FS::ntfs(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Ocfs2: fs = new FS::ocfs2(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::ReiserFS: fs = new FS::reiserfs(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Reiser4: fs = new FS::reiser4(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Udf: fs = new FS::udf(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Ufs: fs = new FS::ufs(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Unformatted: fs = new FS::unformatted(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Unknown: fs = new FS::unknown(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Xfs: fs = new FS::xfs(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Zfs: fs = new FS::zfs(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Btrfs: fs = new FS::btrfs(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Exfat: fs = new FS::exfat(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Ext2: fs = new FS::ext2(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Ext3: fs = new FS::ext3(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Ext4: fs = new FS::ext4(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Extended: fs = new FS::extended(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::F2fs: fs = new FS::f2fs(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Fat12: fs = new FS::fat12(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Fat16: fs = new FS::fat16(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Fat32: fs = new FS::fat32(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Hfs: fs = new FS::hfs(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::HfsPlus: fs = new FS::hfsplus(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Hpfs: fs = new FS::hpfs(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Iso9660: fs = new FS::iso9660(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Jfs: fs = new FS::jfs(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::LinuxRaidMember: fs = new FS::linuxraidmember(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::LinuxSwap: fs = new FS::linuxswap(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Luks: fs = new FS::luks(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Luks2: fs = new FS::luks2(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Lvm2_PV: fs = new FS::lvm2_pv(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Nilfs2: fs = new FS::nilfs2(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Ntfs: fs = new FS::ntfs(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Ocfs2: fs = new FS::ocfs2(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::ReiserFS: fs = new FS::reiserfs(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Reiser4: fs = new FS::reiser4(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Udf: fs = new FS::udf(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Ufs: fs = new FS::ufs(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Unformatted: fs = new FS::unformatted(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Unknown: fs = new FS::unknown(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Xfs: fs = new FS::xfs(firstsector, lastsector, sectorsused, label); break;
|
||||
case FileSystem::Type::Zfs: fs = new FS::zfs(firstsector, lastsector, sectorsused, label); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(KPMCORE_FILESYSTEMFACTORY_H)
|
||||
|
||||
#ifndef KPMCORE_FILESYSTEMFACTORY_H
|
||||
#define KPMCORE_FILESYSTEMFACTORY_H
|
||||
|
||||
#include "fs/filesystem.h"
|
||||
|
|
|
@ -35,7 +35,7 @@ FileSystem::CommandSupportType hfs::m_Copy = FileSystem::cmdSupportNone;
|
|||
FileSystem::CommandSupportType hfs::m_Backup = FileSystem::cmdSupportNone;
|
||||
|
||||
hfs::hfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Hfs)
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Hfs)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ FileSystem::SupportTool hfs::supportToolName() const
|
|||
|
||||
qint64 hfs::maxCapacity() const
|
||||
{
|
||||
return 2 * Capacity::unitFactor(Capacity::Byte, Capacity::TiB);
|
||||
return 2 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::TiB);
|
||||
}
|
||||
|
||||
int hfs::maxLabelLength() const
|
||||
|
|
|
@ -35,7 +35,7 @@ FileSystem::CommandSupportType hfsplus::m_Copy = FileSystem::cmdSupportNone;
|
|||
FileSystem::CommandSupportType hfsplus::m_Backup = FileSystem::cmdSupportNone;
|
||||
|
||||
hfsplus::hfsplus(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::HfsPlus)
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::HfsPlus)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ FileSystem::SupportTool hfsplus::supportToolName() const
|
|||
|
||||
qint64 hfsplus::maxCapacity() const
|
||||
{
|
||||
return Capacity::unitFactor(Capacity::Byte, Capacity::EiB);
|
||||
return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB);
|
||||
}
|
||||
|
||||
int hfsplus::maxLabelLength() const
|
||||
|
|
|
@ -37,12 +37,12 @@ FileSystem::CommandSupportType hpfs::m_UpdateUUID = FileSystem::cmdSupportNone;
|
|||
FileSystem::CommandSupportType hpfs::m_GetUUID = FileSystem::cmdSupportNone;
|
||||
|
||||
hpfs::hpfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Hpfs)
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Hpfs)
|
||||
{
|
||||
}
|
||||
|
||||
qint64 hpfs::maxCapacity() const
|
||||
{
|
||||
return 2 * Capacity::unitFactor(Capacity::Byte, Capacity::TiB);
|
||||
return 2 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::TiB);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace FS
|
|||
{
|
||||
|
||||
iso9660::iso9660(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Iso9660)
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Iso9660)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ FileSystem::CommandSupportType jfs::m_Backup = FileSystem::cmdSupportNone;
|
|||
FileSystem::CommandSupportType jfs::m_SetLabel = FileSystem::cmdSupportNone;
|
||||
|
||||
jfs::jfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Jfs)
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Jfs)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -79,12 +79,12 @@ FileSystem::SupportTool jfs::supportToolName() const
|
|||
|
||||
qint64 jfs::minCapacity() const
|
||||
{
|
||||
return 16 * Capacity::unitFactor(Capacity::Byte, Capacity::MiB);
|
||||
return 16 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
|
||||
}
|
||||
|
||||
qint64 jfs::maxCapacity() const
|
||||
{
|
||||
return 16 * Capacity::unitFactor(Capacity::Byte, Capacity::TiB);
|
||||
return 16 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::TiB);
|
||||
}
|
||||
|
||||
int jfs::maxLabelLength() const
|
||||
|
@ -96,7 +96,7 @@ qint64 jfs::readUsedCapacity(const QString& deviceNode) const
|
|||
{
|
||||
ExternalCommand cmd(QStringLiteral("jfs_debugfs"), QStringList() << deviceNode);
|
||||
|
||||
if (cmd.start() && cmd.write("dm") == 2 && cmd.waitFor()) {
|
||||
if (cmd.write(QByteArrayLiteral("dm")) && cmd.start()) {
|
||||
qint64 blockSize = -1;
|
||||
QRegularExpression re(QStringLiteral("Block Size: (\\d+)"));
|
||||
QRegularExpressionMatch reBlockSize = re.match(cmd.output());
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2018 by Caio Carvalho <caiojcarvalho@gmail.com> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 3 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "fs/linuxraidmember.h"
|
||||
|
||||
namespace FS
|
||||
{
|
||||
|
||||
linuxraidmember::linuxraidmember(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::LinuxRaidMember)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*************************************************************************
|
||||
* Copyright (C) 2018 by Caio Carvalho <caiojcarvalho@gmail.com> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 3 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#ifndef LINUXRAIDMEMBER_H
|
||||
#define LINUXRAIDMEMBER_H
|
||||
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
|
||||
#include "fs/filesystem.h"
|
||||
|
||||
class Report;
|
||||
|
||||
class QString;
|
||||
|
||||
namespace FS
|
||||
{
|
||||
/** A linux_raid_member file system.
|
||||
@author Caio Carvalho <caiojcarvalho@gmail.com>
|
||||
*/
|
||||
class LIBKPMCORE_EXPORT linuxraidmember : public FileSystem
|
||||
{
|
||||
public:
|
||||
linuxraidmember(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // LINUXRAIDMEMBER_H
|
|
@ -40,7 +40,7 @@ FileSystem::CommandSupportType linuxswap::m_GetUUID = FileSystem::cmdSupportNone
|
|||
FileSystem::CommandSupportType linuxswap::m_UpdateUUID = FileSystem::cmdSupportNone;
|
||||
|
||||
linuxswap::linuxswap(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::LinuxSwap)
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::LinuxSwap)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ bool linuxswap::create(Report& report, const QString& deviceNode)
|
|||
|
||||
bool linuxswap::resize(Report& report, const QString& deviceNode, qint64 length) const
|
||||
{
|
||||
Q_UNUSED(length);
|
||||
Q_UNUSED(length)
|
||||
const QString label = readLabel(deviceNode);
|
||||
const QString uuid = readUUID(deviceNode);
|
||||
|
||||
|
@ -145,14 +145,14 @@ QString linuxswap::unmountTitle() const
|
|||
}
|
||||
|
||||
bool linuxswap::canMount(const QString& deviceNode, const QString& mountPoint) const {
|
||||
Q_UNUSED(deviceNode);
|
||||
Q_UNUSED(deviceNode)
|
||||
// linux swap doesn't require mount point to activate
|
||||
return mountPoint != QStringLiteral("/");
|
||||
}
|
||||
|
||||
bool linuxswap::mount(Report& report, const QString& deviceNode, const QString& mountPoint)
|
||||
{
|
||||
Q_UNUSED(mountPoint);
|
||||
Q_UNUSED(mountPoint)
|
||||
ExternalCommand cmd(report, QStringLiteral("swapon"), { deviceNode });
|
||||
return cmd.run(-1) && cmd.exitCode() == 0;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <QStorageInfo>
|
||||
#include <QString>
|
||||
#include <QUuid>
|
||||
#include <QWidget>
|
||||
|
||||
#include <KLocalizedString>
|
||||
#include <KPasswordDialog>
|
||||
|
@ -129,9 +130,8 @@ bool luks::create(Report& report, const QString& deviceNode)
|
|||
QStringLiteral("--type"), QStringLiteral("luks1"),
|
||||
QStringLiteral("luksFormat"),
|
||||
deviceNode });
|
||||
if (!( createCmd.start(-1) &&
|
||||
createCmd.write(m_passphrase.toLocal8Bit() + '\n') == m_passphrase.toLocal8Bit().length() + 1 &&
|
||||
createCmd.waitFor() && createCmd.exitCode() == 0))
|
||||
if (!( createCmd.write(m_passphrase.toLocal8Bit() + '\n') &&
|
||||
createCmd.start(-1) && createCmd.exitCode() == 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ bool luks::create(Report& report, const QString& deviceNode)
|
|||
deviceNode,
|
||||
suggestedMapperName(deviceNode) });
|
||||
|
||||
if (!( openCmd.start(-1) && openCmd.write(m_passphrase.toLocal8Bit() + '\n') == m_passphrase.toLocal8Bit().length() + 1 && openCmd.waitFor()))
|
||||
if (!( openCmd.write(m_passphrase.toLocal8Bit() + '\n') && openCmd.start(-1)))
|
||||
return false;
|
||||
|
||||
setPayloadSize();
|
||||
|
@ -168,12 +168,12 @@ QString luks::unmountTitle() const
|
|||
|
||||
QString luks::cryptOpenTitle() const
|
||||
{
|
||||
return xi18nc("@title:menu", "Decrypt");
|
||||
return xi18nc("@title:menu", "Unlock");
|
||||
}
|
||||
|
||||
QString luks::cryptCloseTitle() const
|
||||
{
|
||||
return xi18nc("@title:menu", "Deactivate");
|
||||
return xi18nc("@title:menu", "Lock");
|
||||
}
|
||||
|
||||
void luks::setPassphrase(const QString& passphrase)
|
||||
|
@ -265,9 +265,8 @@ bool luks::cryptOpen(QWidget* parent, const QString& deviceNode)
|
|||
deviceNode,
|
||||
suggestedMapperName(deviceNode) });
|
||||
|
||||
if (!( openCmd.start(-1) &&
|
||||
openCmd.write(passphrase.toLocal8Bit() + '\n') == passphrase.toLocal8Bit().length() + 1 &&
|
||||
openCmd.waitFor() && openCmd.exitCode() == 0) )
|
||||
if (!( openCmd.write(passphrase.toLocal8Bit() + '\n') &&
|
||||
openCmd.start(-1) && openCmd.exitCode() == 0) )
|
||||
return false;
|
||||
|
||||
if (m_innerFs) {
|
||||
|
@ -286,8 +285,8 @@ bool luks::cryptOpen(QWidget* parent, const QString& deviceNode)
|
|||
if (!m_isCryptOpen)
|
||||
return false;
|
||||
|
||||
for (auto &p : LVM::pvList)
|
||||
if (p.isLuks() && p.partition()->deviceNode() == deviceNode && p.partition()->fileSystem().type() == FileSystem::Lvm2_PV)
|
||||
for (auto &p : LVM::pvList::list())
|
||||
if (p.isLuks() && p.partition()->deviceNode() == deviceNode && p.partition()->fileSystem().type() == FileSystem::Type::Lvm2_PV)
|
||||
p.setLuks(false);
|
||||
|
||||
m_passphrase = passphrase;
|
||||
|
@ -325,7 +324,7 @@ bool luks::cryptClose(const QString& deviceNode)
|
|||
|
||||
m_isCryptOpen = (m_innerFs != nullptr);
|
||||
|
||||
for (auto &p : LVM::pvList)
|
||||
for (auto &p : LVM::pvList::list())
|
||||
if (!p.isLuks() && p.partition()->deviceNode() == deviceNode)
|
||||
p.setLuks(true);
|
||||
|
||||
|
@ -464,7 +463,7 @@ FileSystem::Type luks::type() const
|
|||
{
|
||||
if (m_isCryptOpen && m_innerFs)
|
||||
return m_innerFs->type();
|
||||
return FileSystem::Luks;
|
||||
return FileSystem::Type::Luks;
|
||||
}
|
||||
|
||||
QString luks::suggestedMapperName(const QString& deviceNode) const
|
||||
|
@ -647,19 +646,19 @@ bool luks::canEncryptType(FileSystem::Type type)
|
|||
{
|
||||
switch (type)
|
||||
{
|
||||
case Btrfs:
|
||||
case F2fs:
|
||||
case Ext2:
|
||||
case Ext3:
|
||||
case Ext4:
|
||||
case Jfs:
|
||||
case LinuxSwap:
|
||||
case Lvm2_PV:
|
||||
case Nilfs2:
|
||||
case ReiserFS:
|
||||
case Reiser4:
|
||||
case Xfs:
|
||||
case Zfs:
|
||||
case Type::Btrfs:
|
||||
case Type::F2fs:
|
||||
case Type::Ext2:
|
||||
case Type::Ext3:
|
||||
case Type::Ext4:
|
||||
case Type::Jfs:
|
||||
case Type::LinuxSwap:
|
||||
case Type::Lvm2_PV:
|
||||
case Type::Nilfs2:
|
||||
case Type::ReiserFS:
|
||||
case Type::Reiser4:
|
||||
case Type::Xfs:
|
||||
case Type::Zfs:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -690,7 +689,7 @@ void luks::setPayloadSize()
|
|||
|
||||
bool luks::testPassphrase(const QString& deviceNode, const QString& passphrase) const {
|
||||
ExternalCommand cmd(QStringLiteral("cryptsetup"), { QStringLiteral("open"), QStringLiteral("--tries"), QStringLiteral("1"), QStringLiteral("--test-passphrase"), deviceNode });
|
||||
if (cmd.start(-1) && cmd.write(passphrase.toLocal8Bit() + '\n') == passphrase.toLocal8Bit().length() + 1 && cmd.waitFor() && cmd.exitCode() == 0)
|
||||
if (cmd.write(passphrase.toLocal8Bit() + '\n') && cmd.start(-1) && cmd.exitCode() == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
|
@ -17,8 +17,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#if !defined(KPMCORE_LUKS_H)
|
||||
|
||||
#ifndef KPMCORE_LUKS_H
|
||||
#define KPMCORE_LUKS_H
|
||||
|
||||
#include "util/libpartitionmanagerexport.h"
|
||||
|
@ -26,11 +25,11 @@
|
|||
#include "fs/filesystem.h"
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QWidget>
|
||||
|
||||
class Report;
|
||||
|
||||
class QString;
|
||||
class QWidget;
|
||||
|
||||
namespace FS
|
||||
{
|
||||
|
@ -40,10 +39,10 @@ namespace FS
|
|||
class LIBKPMCORE_EXPORT luks : public FileSystem
|
||||
{
|
||||
public:
|
||||
luks(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type t = FileSystem::Luks);
|
||||
luks(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type t = FileSystem::Type::Luks);
|
||||
~luks() override;
|
||||
|
||||
enum KeyLocation {
|
||||
enum class KeyLocation {
|
||||
unknown,
|
||||
dmcrypt,
|
||||
keyring
|
||||
|
@ -225,7 +224,7 @@ protected:
|
|||
qint64 m_PayloadSize;
|
||||
QString m_outerUuid;
|
||||
|
||||
luks::KeyLocation m_KeyLocation = unknown;
|
||||
luks::KeyLocation m_KeyLocation = KeyLocation::unknown;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace FS
|
|||
{
|
||||
|
||||
luks2::luks2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label)
|
||||
: luks(firstsector, lastsector, sectorsused, label, FileSystem::Luks2)
|
||||
: luks(firstsector, lastsector, sectorsused, label, FileSystem::Type::Luks2)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ FileSystem::Type luks2::type() const
|
|||
{
|
||||
if (m_isCryptOpen && m_innerFs)
|
||||
return m_innerFs->type();
|
||||
return FileSystem::Luks2;
|
||||
return FileSystem::Type::Luks2;
|
||||
}
|
||||
|
||||
bool luks2::create(Report& report, const QString& deviceNode)
|
||||
|
@ -56,9 +56,8 @@ bool luks2::create(Report& report, const QString& deviceNode)
|
|||
QStringLiteral("--type"), QStringLiteral("luks2"),
|
||||
QStringLiteral("luksFormat"),
|
||||
deviceNode });
|
||||
if (!( createCmd.start(-1) &&
|
||||
createCmd.write(m_passphrase.toLocal8Bit() + '\n') == m_passphrase.toLocal8Bit().length() + 1 &&
|
||||
createCmd.waitFor() && createCmd.exitCode() == 0))
|
||||
if (!( createCmd.write(m_passphrase.toLocal8Bit() + '\n') &&
|
||||
createCmd.start(-1) && createCmd.exitCode() == 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -68,7 +67,7 @@ bool luks2::create(Report& report, const QString& deviceNode)
|
|||
deviceNode,
|
||||
suggestedMapperName(deviceNode) });
|
||||
|
||||
if (!( openCmd.start(-1) && openCmd.write(m_passphrase.toLocal8Bit() + '\n') == m_passphrase.toLocal8Bit().length() + 1 && openCmd.waitFor()))
|
||||
if (!( openCmd.write(m_passphrase.toLocal8Bit() + '\n') && openCmd.start(-1)))
|
||||
return false;
|
||||
|
||||
setPayloadSize();
|
||||
|
@ -95,13 +94,13 @@ bool luks2::resize(Report& report, const QString& deviceNode, qint64 newLength)
|
|||
ExternalCommand cryptResizeCmd(report, QStringLiteral("cryptsetup"), { QStringLiteral("resize"), mapperName() });
|
||||
report.line() << xi18nc("@info:progress", "Resizing LUKS crypt on partition <filename>%1</filename>.", deviceNode);
|
||||
|
||||
cryptResizeCmd.start(-1);
|
||||
if (m_KeyLocation == keyring) {
|
||||
if (m_KeyLocation == KeyLocation::keyring) {
|
||||
if (m_passphrase.isEmpty())
|
||||
return false;
|
||||
cryptResizeCmd.write(m_passphrase.toLocal8Bit() + '\n');
|
||||
}
|
||||
cryptResizeCmd.waitFor();
|
||||
if (!cryptResizeCmd.start(-1))
|
||||
return false;
|
||||
if ( cryptResizeCmd.exitCode() == 0 )
|
||||
return m_innerFs->resize(report, mapperName(), m_PayloadSize);
|
||||
}
|
||||
|
@ -111,13 +110,13 @@ bool luks2::resize(Report& report, const QString& deviceNode, qint64 newLength)
|
|||
{ QStringLiteral("--size"), QString::number(m_PayloadSize / 512), // FIXME, LUKS2 can have different sector sizes
|
||||
QStringLiteral("resize"), mapperName() });
|
||||
report.line() << xi18nc("@info:progress", "Resizing LUKS crypt on partition <filename>%1</filename>.", deviceNode);
|
||||
cryptResizeCmd.start(-1);
|
||||
if (m_KeyLocation == keyring) {
|
||||
if (m_KeyLocation == KeyLocation::keyring) {
|
||||
if (m_passphrase.isEmpty())
|
||||
return false;
|
||||
cryptResizeCmd.write(m_passphrase.toLocal8Bit() + '\n');
|
||||
}
|
||||
cryptResizeCmd.waitFor();
|
||||
if (!cryptResizeCmd.start(-1))
|
||||
return false;
|
||||
if ( cryptResizeCmd.exitCode() == 0 )
|
||||
return true;
|
||||
}
|
||||
|
@ -127,16 +126,16 @@ bool luks2::resize(Report& report, const QString& deviceNode, qint64 newLength)
|
|||
|
||||
luks::KeyLocation luks2::keyLocation()
|
||||
{
|
||||
m_KeyLocation = unknown;
|
||||
m_KeyLocation = KeyLocation::unknown;
|
||||
ExternalCommand statusCmd(QStringLiteral("cryptsetup"), { QStringLiteral("status"), mapperName() });
|
||||
if (statusCmd.run(-1) && statusCmd.exitCode() == 0) {
|
||||
QRegularExpression re(QStringLiteral("key location:\\s+(\\w+)"));
|
||||
QRegularExpressionMatch rem = re.match(statusCmd.output());
|
||||
if (rem.hasMatch()) {
|
||||
if (rem.captured(1) == QStringLiteral("keyring"))
|
||||
m_KeyLocation = keyring;
|
||||
m_KeyLocation = KeyLocation::keyring;
|
||||
else if (rem.captured(1) == QStringLiteral("dm-crypt"))
|
||||
m_KeyLocation = dmcrypt;
|
||||
m_KeyLocation = KeyLocation::dmcrypt;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ FileSystem::CommandSupportType lvm2_pv::m_GetUUID = FileSystem::cmdSupportNone;
|
|||
|
||||
lvm2_pv::lvm2_pv(qint64 firstsector, qint64 lastsector,
|
||||
qint64 sectorsused, const QString& label)
|
||||
: FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Lvm2_PV)
|
||||
: FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Lvm2_PV)
|
||||
, m_PESize(0)
|
||||
, m_TotalPE(0)
|
||||
, m_AllocatedPE(0)
|
||||
|
@ -99,7 +99,7 @@ FileSystem::SupportTool lvm2_pv::supportToolName() const
|
|||
|
||||
qint64 lvm2_pv::maxCapacity() const
|
||||
{
|
||||
return Capacity::unitFactor(Capacity::Byte, Capacity::EiB);
|
||||
return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB);
|
||||
}
|
||||
|
||||
qint64 lvm2_pv::readUsedCapacity(const QString& deviceNode) const
|
||||
|
@ -270,10 +270,10 @@ QList<LvmPV> lvm2_pv::getPVinNode(const PartitionNode* parent)
|
|||
partitions.append(getPVinNode(node));
|
||||
|
||||
// FIXME: reenable newly created PVs (before applying) once everything works
|
||||
if(p->fileSystem().type() == FileSystem::Lvm2_PV && p->deviceNode() == p->partitionPath())
|
||||
if(p->fileSystem().type() == FileSystem::Type::Lvm2_PV && p->deviceNode() == p->partitionPath())
|
||||
partitions.append(LvmPV(p->mountPoint(), p));
|
||||
|
||||
if(p->fileSystem().type() == FileSystem::Luks && p->deviceNode() == p->partitionPath())
|
||||
if(p->fileSystem().type() == FileSystem::Type::Luks && p->deviceNode() == p->partitionPath())
|
||||
partitions.append(LvmPV(p->mountPoint(), p, true));
|
||||
}
|
||||
|
||||
|
@ -296,7 +296,11 @@ QList<LvmPV> lvm2_pv::getPVs(const QList<Device*>& devices)
|
|||
|
||||
}
|
||||
|
||||
QList<LvmPV> LVM::pvList;
|
||||
namespace LVM {
|
||||
|
||||
QList<LvmPV> pvList::m_list;
|
||||
|
||||
}
|
||||
|
||||
LvmPV::LvmPV(const QString vgName, const Partition* p, bool isLuks)
|
||||
: m_vgName(vgName)
|
||||
|
|
|
@ -62,7 +62,22 @@ private:
|
|||
};
|
||||
|
||||
namespace LVM {
|
||||
extern LIBKPMCORE_EXPORT QList<LvmPV> pvList;
|
||||
/** Class to access a global LVM PV list.
|
||||
@author Caio Carvalho <caiojcarvalho@gmail.com>
|
||||
*/
|
||||
class LIBKPMCORE_EXPORT pvList
|
||||
{
|
||||
public:
|
||||
static QList<LvmPV> &list() {
|
||||
return m_list;
|
||||
}
|
||||
|
||||
private:
|
||||
pvList() { }
|
||||
|
||||
private:
|
||||
static QList<LvmPV> m_list;
|
||||
};
|
||||
}
|
||||
|
||||
namespace FS
|
||||
|
|
|
@ -47,7 +47,7 @@ FileSystem::CommandSupportType nilfs2::m_UpdateUUID = FileSystem::cmdSupportNone
|
|||
FileSystem::CommandSupportType nilfs2::m_GetUUID = FileSystem::cmdSupportNone;
|
||||
|
||||
nilfs2::nilfs2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Nilfs2)
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Nilfs2)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -96,12 +96,12 @@ FileSystem::SupportTool nilfs2::supportToolName() const
|
|||
|
||||
qint64 nilfs2::minCapacity() const
|
||||
{
|
||||
return 128 * Capacity::unitFactor(Capacity::Byte, Capacity::MiB);
|
||||
return 128 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
|
||||
}
|
||||
|
||||
qint64 nilfs2::maxCapacity() const
|
||||
{
|
||||
return Capacity::unitFactor(Capacity::Byte, Capacity::EiB);
|
||||
return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB);
|
||||
}
|
||||
|
||||
int nilfs2::maxLabelLength() const
|
||||
|
|
|
@ -50,7 +50,7 @@ FileSystem::CommandSupportType ntfs::m_UpdateUUID = FileSystem::cmdSupportNone;
|
|||
FileSystem::CommandSupportType ntfs::m_GetUUID = FileSystem::cmdSupportNone;
|
||||
|
||||
ntfs::ntfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Ntfs)
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Ntfs)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -91,12 +91,12 @@ FileSystem::SupportTool ntfs::supportToolName() const
|
|||
|
||||
qint64 ntfs::minCapacity() const
|
||||
{
|
||||
return 2 * Capacity::unitFactor(Capacity::Byte, Capacity::MiB);
|
||||
return 2 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
|
||||
}
|
||||
|
||||
qint64 ntfs::maxCapacity() const
|
||||
{
|
||||
return 256 * Capacity::unitFactor(Capacity::Byte, Capacity::TiB);
|
||||
return 256 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::TiB);
|
||||
}
|
||||
|
||||
int ntfs::maxLabelLength() const
|
||||
|
@ -125,8 +125,7 @@ qint64 ntfs::readUsedCapacity(const QString& deviceNode) const
|
|||
|
||||
bool ntfs::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel)
|
||||
{
|
||||
ExternalCommand writeCmd(report, QStringLiteral("ntfslabel"), { QStringLiteral("--force"), deviceNode, newLabel });
|
||||
writeCmd.setProcessChannelMode(QProcess::SeparateChannels);
|
||||
ExternalCommand writeCmd(report, QStringLiteral("ntfslabel"), { QStringLiteral("--force"), deviceNode, newLabel }, QProcess::SeparateChannels);
|
||||
|
||||
if (!writeCmd.run(-1))
|
||||
return false;
|
||||
|
@ -171,7 +170,7 @@ bool ntfs::resize(Report& report, const QString& deviceNode, qint64 length) cons
|
|||
|
||||
bool ntfs::updateUUID(Report& report, const QString& deviceNode) const
|
||||
{
|
||||
Q_UNUSED(report);
|
||||
Q_UNUSED(report)
|
||||
ExternalCommand cmd(QStringLiteral("ntfslabel"), { QStringLiteral("--new-serial"), deviceNode });
|
||||
|
||||
return cmd.run(-1) && cmd.exitCode() == 0;
|
||||
|
@ -191,24 +190,22 @@ bool ntfs::updateBootSector(Report& report, const QString& deviceNode) const
|
|||
|
||||
ExternalCommand cmd(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode , QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=28") });
|
||||
|
||||
cmd.write(QByteArray(s, sizeof(s)));
|
||||
if (!cmd.start()) {
|
||||
Log() << xi18nc("@info:progress", "Could not write new start sector to partition <filename>%1</filename> when trying to update the NTFS boot sector.", deviceNode);
|
||||
return false;
|
||||
}
|
||||
cmd.write(QByteArray(s, sizeof(s)));
|
||||
cmd.waitFor(-1);
|
||||
|
||||
// Also update backup NTFS boot sector located at the end of the partition
|
||||
// NOTE: this should fail if filesystem does not span the whole partition
|
||||
qint64 pos = (lastSector() - firstSector()) * sectorSize() + 28;
|
||||
ExternalCommand cmd2(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode , QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=") + QString::number(pos) });
|
||||
|
||||
cmd2.write(QByteArray(s, sizeof(s)));
|
||||
if (!cmd2.start()) {
|
||||
Log() << xi18nc("@info:progress", "Could not write new start sector to partition <filename>%1</filename> when trying to update the NTFS boot sector.", deviceNode);
|
||||
return false;
|
||||
}
|
||||
cmd2.write(QByteArray(s, sizeof(s)));
|
||||
cmd2.waitFor(-1);
|
||||
|
||||
Log() << xi18nc("@info:progress", "Updated NTFS boot sector for partition <filename>%1</filename> successfully.", deviceNode);
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ FileSystem::CommandSupportType ocfs2::m_UpdateUUID = FileSystem::cmdSupportNone;
|
|||
FileSystem::CommandSupportType ocfs2::m_GetUUID = FileSystem::cmdSupportNone;
|
||||
|
||||
ocfs2::ocfs2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Ocfs2)
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Ocfs2)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -89,17 +89,17 @@ FileSystem::SupportTool ocfs2::supportToolName() const
|
|||
|
||||
qint64 ocfs2::minCapacity() const
|
||||
{
|
||||
return 14000 * Capacity::unitFactor(Capacity::Byte, Capacity::KiB);
|
||||
return 14000 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::KiB);
|
||||
}
|
||||
|
||||
qint64 ocfs2::maxCapacity() const
|
||||
{
|
||||
return 4 * Capacity::unitFactor(Capacity::Byte, Capacity::PiB);
|
||||
return 4 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::PiB);
|
||||
}
|
||||
|
||||
qint64 ocfs2::readUsedCapacity(const QString& deviceNode) const
|
||||
{
|
||||
Q_UNUSED(deviceNode);
|
||||
Q_UNUSED(deviceNode)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -113,15 +113,12 @@ bool ocfs2::create(Report& report, const QString& deviceNode)
|
|||
{
|
||||
ExternalCommand cmd(report, QStringLiteral("mkfs.ocfs2"), { deviceNode });
|
||||
|
||||
if (cmd.start())
|
||||
{
|
||||
cmd.write("y\n");
|
||||
cmd.waitFor(-1);
|
||||
if (!cmd.start())
|
||||
return false;
|
||||
|
||||
return cmd.exitCode() == 0;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool ocfs2::resize(Report& report, const QString& deviceNode, qint64 length) const
|
||||
|
|
|
@ -35,7 +35,7 @@ FileSystem::CommandSupportType reiser4::m_Copy = FileSystem::cmdSupportNone;
|
|||
FileSystem::CommandSupportType reiser4::m_Backup = FileSystem::cmdSupportNone;
|
||||
|
||||
reiser4::reiser4(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Reiser4)
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Reiser4)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ qint64 reiser4::maxCapacity() const
|
|||
{
|
||||
// looks like it's actually unknown. see
|
||||
// http://en.wikipedia.org/wiki/Comparison_of_file_systems
|
||||
return Capacity::unitFactor(Capacity::Byte, Capacity::EiB);
|
||||
return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB);
|
||||
}
|
||||
|
||||
int reiser4::maxLabelLength() const
|
||||
|
|
|
@ -42,7 +42,7 @@ FileSystem::CommandSupportType reiserfs::m_UpdateUUID = FileSystem::cmdSupportNo
|
|||
FileSystem::CommandSupportType reiserfs::m_GetUUID = FileSystem::cmdSupportNone;
|
||||
|
||||
reiserfs::reiserfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::ReiserFS)
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::ReiserFS)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -85,12 +85,12 @@ FileSystem::SupportTool reiserfs::supportToolName() const
|
|||
|
||||
qint64 reiserfs::minCapacity() const
|
||||
{
|
||||
return 32 * Capacity::unitFactor(Capacity::Byte, Capacity::MiB);
|
||||
return 32 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
|
||||
}
|
||||
|
||||
qint64 reiserfs::maxCapacity() const
|
||||
{
|
||||
return 16 * Capacity::unitFactor(Capacity::Byte, Capacity::TiB) - Capacity::unitFactor(Capacity::Byte, Capacity::MiB);
|
||||
return 16 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::TiB) - Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
|
||||
}
|
||||
|
||||
int reiserfs::maxLabelLength() const
|
||||
|
@ -154,15 +154,15 @@ bool reiserfs::resize(Report& report, const QString& deviceNode, qint64 length)
|
|||
ExternalCommand cmd(report, QStringLiteral("resize_reiserfs"),
|
||||
{ deviceNode, QStringLiteral("-q"), QStringLiteral("-s"), QString::number(length) });
|
||||
|
||||
bool rval = cmd.start(-1);
|
||||
bool rval = cmd.write(QByteArrayLiteral("y\n"));
|
||||
|
||||
if (!rval)
|
||||
return false;
|
||||
|
||||
if (cmd.write("y\n", 2) != 2)
|
||||
if (!cmd.start(-1))
|
||||
return false;
|
||||
|
||||
return cmd.waitFor(-1) && (cmd.exitCode() == 0 || cmd.exitCode() == 256);
|
||||
return cmd.exitCode() == 0 || cmd.exitCode() == 256;
|
||||
}
|
||||
|
||||
bool reiserfs::resizeOnline(Report& report, const QString& deviceNode, const QString&, qint64 length) const
|
||||
|
|
|
@ -40,7 +40,7 @@ FileSystem::CommandSupportType udf::m_Create = FileSystem::cmdSupportNone;
|
|||
bool udf::oldMkudffsVersion = false;
|
||||
|
||||
udf::udf(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Udf)
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Udf)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ FileSystem::CommandSupportType ufs::m_Copy = FileSystem::cmdSupportCore;
|
|||
FileSystem::CommandSupportType ufs::m_Backup = FileSystem::cmdSupportCore;
|
||||
|
||||
ufs::ufs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Ufs)
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Ufs)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace FS
|
|||
FileSystem::CommandSupportType unformatted::m_Create = FileSystem::cmdSupportFileSystem;
|
||||
|
||||
unformatted::unformatted(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Unformatted)
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Unformatted)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
namespace FS
|
||||
{
|
||||
unknown::unknown(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Unknown)
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Unknown)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ FileSystem::CommandSupportType xfs::m_Backup = FileSystem::cmdSupportNone;
|
|||
FileSystem::CommandSupportType xfs::m_SetLabel = FileSystem::cmdSupportNone;
|
||||
|
||||
xfs::xfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Xfs)
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Xfs)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -83,12 +83,12 @@ FileSystem::SupportTool xfs::supportToolName() const
|
|||
|
||||
qint64 xfs::minCapacity() const
|
||||
{
|
||||
return 32 * Capacity::unitFactor(Capacity::Byte, Capacity::MiB);
|
||||
return 32 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
|
||||
}
|
||||
|
||||
qint64 xfs::maxCapacity() const
|
||||
{
|
||||
return Capacity::unitFactor(Capacity::Byte, Capacity::EiB);
|
||||
return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB);
|
||||
}
|
||||
|
||||
int xfs::maxLabelLength() const
|
||||
|
|
|
@ -40,7 +40,7 @@ FileSystem::CommandSupportType zfs::m_UpdateUUID = FileSystem::cmdSupportNone;
|
|||
FileSystem::CommandSupportType zfs::m_GetUUID = FileSystem::cmdSupportNone;
|
||||
|
||||
zfs::zfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Zfs)
|
||||
FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Zfs)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -77,12 +77,12 @@ FileSystem::SupportTool zfs::supportToolName() const
|
|||
|
||||
qint64 zfs::minCapacity() const
|
||||
{
|
||||
return 64 * Capacity::unitFactor(Capacity::Byte, Capacity::MiB);
|
||||
return 64 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB);
|
||||
}
|
||||
|
||||
qint64 zfs::maxCapacity() const
|
||||
{
|
||||
return Capacity::unitFactor(Capacity::Byte, Capacity::EiB);
|
||||
return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB);
|
||||
}
|
||||
|
||||
bool zfs::remove(Report& report, const QString& deviceNode) const
|
||||
|
|
|
@ -21,10 +21,10 @@
|
|||
#include "fs/filesystem.h"
|
||||
#include "util/capacity.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QStyleOptionButton>
|
||||
#include <QApplication>
|
||||
#include <QFontDatabase>
|
||||
#include <QPainter>
|
||||
#include <QStyleOptionButton>
|
||||
|
||||
/** Creates a new PartWidget
|
||||
@param parent pointer to the parent widget
|
||||
|
@ -71,7 +71,7 @@ void PartWidget::updateChildren()
|
|||
}
|
||||
}
|
||||
|
||||
void PartWidget::setFileSystemColorCode(const std::array< QColor, FileSystem::__lastType >& colorCode)
|
||||
void PartWidget::setFileSystemColorCode(const std::vector<QColor>& colorCode)
|
||||
{
|
||||
m_fileSystemColorCode = colorCode;
|
||||
repaint();
|
||||
|
@ -101,12 +101,12 @@ void PartWidget::paintEvent(QPaintEvent*)
|
|||
|
||||
if (partition()->roles().has(PartitionRole::Extended)) {
|
||||
drawGradient(&painter, activeColor(
|
||||
m_fileSystemColorCode[ partition()->fileSystem().type() ]),
|
||||
m_fileSystemColorCode[ static_cast<int>(partition()->fileSystem().type()) ]),
|
||||
QRect(0, 0, width(), height()));
|
||||
return;
|
||||
}
|
||||
|
||||
const QColor base = activeColor(m_fileSystemColorCode[ partition()->fileSystem().type() ]);
|
||||
const QColor base = activeColor(m_fileSystemColorCode[ static_cast<int>(partition()->fileSystem().type()) ]);
|
||||
|
||||
if (!partition()->roles().has(PartitionRole::Unallocated)) {
|
||||
const QColor dark = base.darker(105);
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
|
||||
#include <QColor>
|
||||
|
||||
#include <array>
|
||||
|
||||
class Partition;
|
||||
|
||||
class QPaintEvent;
|
||||
|
@ -63,7 +61,7 @@ public:
|
|||
return m_Partition; /**< @return the widget's Partition */
|
||||
}
|
||||
|
||||
void setFileSystemColorCode( const std::array< QColor, FileSystem::__lastType >& colorCode );
|
||||
void setFileSystemColorCode( const std::vector<QColor>& colorCode );
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event);
|
||||
|
@ -76,7 +74,7 @@ protected:
|
|||
private:
|
||||
Partition* m_Partition;
|
||||
bool m_Active;
|
||||
std::array< QColor, FileSystem::__lastType > m_fileSystemColorCode;
|
||||
std::vector<QColor> m_fileSystemColorCode;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "core/copytargetfile.h"
|
||||
|
||||
#include "fs/filesystem.h"
|
||||
|
||||
#include "util/externalcommand.h"
|
||||
#include "util/report.h"
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue