Merge branch 'kauth'
This commit is contained in:
commit
24d9d1bd73
|
@ -16,14 +16,22 @@
|
||||||
|
|
||||||
project(kpmcore)
|
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_USE_RELATIVE_PATHS OFF)
|
||||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
|
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_MAJOR "3")
|
||||||
set(VERSION_MINOR "3")
|
set(VERSION_MINOR "50")
|
||||||
set(VERSION_RELEASE "0")
|
set(VERSION_RELEASE "0")
|
||||||
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_RELEASE})
|
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_RELEASE})
|
||||||
set(SOVERSION "8")
|
set(SOVERSION "8")
|
||||||
|
@ -32,7 +40,7 @@ add_definitions(-D'VERSION="${VERSION}"') #"
|
||||||
set(CMAKE_CXX_STANDARD 14)
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
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/")
|
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/")
|
||||||
|
|
||||||
include(KDEInstallDirs)
|
include(KDEInstallDirs)
|
||||||
|
@ -41,7 +49,6 @@ include(KDECompilerSettings NO_POLICY_SCOPE)
|
||||||
include(FeatureSummary)
|
include(FeatureSummary)
|
||||||
include(GenerateExportHeader)
|
include(GenerateExportHeader)
|
||||||
include(ECMSetupVersion)
|
include(ECMSetupVersion)
|
||||||
include(ECMPackageConfigHelpers)
|
|
||||||
|
|
||||||
ecm_setup_version(${VERSION} VARIABLE_PREFIX KPMCORE
|
ecm_setup_version(${VERSION} VARIABLE_PREFIX KPMCORE
|
||||||
VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/kpmcore_version.h"
|
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
|
# Load the frameworks we need
|
||||||
find_package(KF5 REQUIRED
|
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED
|
||||||
|
Auth
|
||||||
I18n
|
I18n
|
||||||
CoreAddons
|
CoreAddons
|
||||||
WidgetsAddons
|
WidgetsAddons
|
||||||
)
|
)
|
||||||
|
|
||||||
|
find_package(Qca-qt5 REQUIRED)
|
||||||
|
|
||||||
# use sane compile flags
|
# use sane compile flags
|
||||||
add_definitions(
|
add_definitions(
|
||||||
-DQT_USE_QSTRINGBUILDER
|
-DQT_USE_QSTRINGBUILDER
|
||||||
|
@ -76,10 +86,10 @@ add_definitions(
|
||||||
)
|
)
|
||||||
kde_enable_exceptions()
|
kde_enable_exceptions()
|
||||||
|
|
||||||
|
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
pkg_check_modules(BLKID REQUIRED blkid>=2.30)
|
pkg_check_modules(BLKID REQUIRED blkid>=${BLKID_MIN_VERSION})
|
||||||
pkg_check_modules(LIBATASMART REQUIRED libatasmart)
|
endif()
|
||||||
|
|
||||||
include_directories(${Qt5Core_INCLUDE_DIRS} ${UUID_INCLUDE_DIRS} ${BLKID_INCLUDE_DIRS} lib/ src/)
|
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(INCLUDE_INSTALL_DIR "include/kpmcore/")
|
||||||
set(CMAKECONFIG_INSTALL_DIR "${CMAKECONFIG_INSTALL_PREFIX}/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"
|
"${CMAKE_CURRENT_BINARY_DIR}/KPMcoreConfig.cmake"
|
||||||
INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR}
|
INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR}
|
||||||
PATH_VARS INCLUDE_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
|
1. Dependencies
|
||||||
|
|
||||||
libparted: Either get it from http://www.gnu.org/software/parted/download.shtml
|
util-linux 2.32: available at https://github.com/karelzak/util-linux
|
||||||
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
|
|
||||||
|
|
||||||
KDE Frameworks: The minimum required version is 5.0.
|
KDE Frameworks: The minimum required version is 5.0.
|
||||||
|
|
||||||
|
|
||||||
2. Configure
|
2. Configure
|
||||||
|
|
||||||
KPMcore is built with cmake. It is recommended to build out of tree:
|
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:
|
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
|
$ cd kpmcore-x.y.z
|
||||||
$ mkdir build
|
$ mkdir build
|
||||||
$ cd build
|
$ cd build
|
||||||
|
|
|
@ -14,7 +14,7 @@ of storage devices on a system:
|
||||||
There are multiple backends so that KPMcore can support different
|
There are multiple backends so that KPMcore can support different
|
||||||
operating systems, although the only functional backend is the
|
operating systems, although the only functional backend is the
|
||||||
one for Linux systems:
|
one for Linux systems:
|
||||||
* libparted backend (Linux)
|
* sfdisk backend (Linux)
|
||||||
* null backend
|
* null backend
|
||||||
|
|
||||||
## Using KPMcore
|
## 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})
|
ki18n_wrap_ui(kpmcore_SRCS ${gui_UIFILES})
|
||||||
|
|
||||||
add_library(kpmcore SHARED ${kpmcore_SRCS})
|
add_library(kpmcore SHARED ${kpmcore_SRCS})
|
||||||
target_link_libraries( kpmcore
|
target_link_libraries( kpmcore PUBLIC
|
||||||
${UUID_LIBRARIES}
|
Qt5::Core
|
||||||
|
PRIVATE
|
||||||
${BLKID_LIBRARIES}
|
${BLKID_LIBRARIES}
|
||||||
${LIBATASMART_LIBRARIES}
|
|
||||||
Qt5::DBus
|
Qt5::DBus
|
||||||
|
Qt5::Gui
|
||||||
|
qca-qt5
|
||||||
KF5::I18n
|
KF5::I18n
|
||||||
KF5::CoreAddons
|
KF5::CoreAddons
|
||||||
KF5::WidgetsAddons
|
KF5::WidgetsAddons
|
||||||
|
KF5::Auth
|
||||||
)
|
)
|
||||||
|
|
||||||
install(TARGETS kpmcore EXPORT KPMcoreTargets ${INSTALL_TARGETS_DEFAULT_ARGS})
|
install(TARGETS kpmcore EXPORT KPMcoreTargets ${INSTALL_TARGETS_DEFAULT_ARGS})
|
||||||
|
|
|
@ -24,20 +24,18 @@
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
class CoreBackend::CoreBackendPrivate
|
struct CoreBackendPrivate
|
||||||
{
|
{
|
||||||
public:
|
QString m_id, m_version;
|
||||||
CoreBackendPrivate() {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
CoreBackend::CoreBackend() :
|
CoreBackend::CoreBackend() :
|
||||||
d(new CoreBackendPrivate())
|
d(std::make_unique<CoreBackendPrivate>())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CoreBackend::~CoreBackend()
|
CoreBackend::~CoreBackend()
|
||||||
{
|
{
|
||||||
delete d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoreBackend::emitProgress(int i)
|
void CoreBackend::emitProgress(int i)
|
||||||
|
@ -59,3 +57,23 @@ void CoreBackend::setPartitionTableMaxPrimaries(PartitionTable& p, qint32 max_pr
|
||||||
{
|
{
|
||||||
p.setMaxPrimaries(max_primaries);
|
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 "util/libpartitionmanagerexport.h"
|
||||||
#include "fs/filesystem.h"
|
#include "fs/filesystem.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
|
||||||
class CoreBackendManager;
|
class CoreBackendManager;
|
||||||
class CoreBackendDevice;
|
class CoreBackendDevice;
|
||||||
|
struct CoreBackendPrivate;
|
||||||
class Device;
|
class Device;
|
||||||
class PartitionTable;
|
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
|
||||||
* @return the plugin's unique Id from JSON metadata
|
* @return the plugin's unique Id from JSON metadata
|
||||||
*/
|
*/
|
||||||
QString id() {
|
QString id();
|
||||||
return m_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the plugin's version from JSON metadata
|
* Return the plugin's version from JSON metadata
|
||||||
* @return the plugin's version from JSON metadata
|
* @return the plugin's version from JSON metadata
|
||||||
*/
|
*/
|
||||||
QString version() {
|
QString version();
|
||||||
return m_version;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the plugin's FileSystem support
|
* Initialize the plugin's FileSystem support
|
||||||
|
@ -130,29 +129,23 @@ public:
|
||||||
/**
|
/**
|
||||||
* Open a device for reading.
|
* Open a device for reading.
|
||||||
* @param deviceNode The path of the device that is to be opened (e.g. /dev/sda)
|
* @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
|
* @return a pointer to a CoreBackendDevice or nullptr if the open failed.
|
||||||
* an instance is returned, it's the caller's responsibility to delete the
|
|
||||||
* object.
|
|
||||||
*/
|
*/
|
||||||
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.
|
* Open a device in exclusive mode for writing.
|
||||||
* @param deviceNode The path of the device that is to be opened (e.g. /dev/sda)
|
* @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
|
* @return a pointer to a CoreBackendDevice or nullptr if the open failed.
|
||||||
* an instance is returned, it's the caller's responsibility to delete the
|
|
||||||
* object.
|
|
||||||
*/
|
*/
|
||||||
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.
|
* Close a CoreBackendDevice that has previously been opened.
|
||||||
* @param core_device Pointer to the CoreBackendDevice to be closed. Must not be nullptr.
|
* @param core_device Pointer to the CoreBackendDevice to be closed. Must not be nullptr.
|
||||||
* @return true if closing the CoreBackendDevice succeeded, otherwise false.
|
* @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.
|
* Emit progress.
|
||||||
|
@ -176,18 +169,11 @@ protected:
|
||||||
static void setPartitionTableMaxPrimaries(PartitionTable& p, qint32 max_primaries);
|
static void setPartitionTableMaxPrimaries(PartitionTable& p, qint32 max_primaries);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setId(const QString& id) {
|
void setId(const QString& id);
|
||||||
m_id = id;
|
void setVersion(const QString& version);
|
||||||
}
|
|
||||||
void setVersion(const QString& version) {
|
|
||||||
m_version = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_id, m_version;
|
std::unique_ptr<CoreBackendPrivate> d;
|
||||||
|
|
||||||
class CoreBackendPrivate;
|
|
||||||
CoreBackendPrivate* d;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#define KPMCORE_COREBACKENDDEVICE_H
|
#define KPMCORE_COREBACKENDDEVICE_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
class CoreBackendPartition;
|
class CoreBackendPartition;
|
||||||
|
@ -81,7 +82,7 @@ public:
|
||||||
* @return a pointer to the CoreBackendPartitionTable for this device or nullptr in case
|
* @return a pointer to the CoreBackendPartitionTable for this device or nullptr in case
|
||||||
* of errors
|
* of errors
|
||||||
*/
|
*/
|
||||||
virtual CoreBackendPartitionTable* openPartitionTable() = 0;
|
virtual std::unique_ptr<CoreBackendPartitionTable> openPartitionTable() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new partition table on this device.
|
* Create a new partition table on this device.
|
||||||
|
@ -91,23 +92,6 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual bool createPartitionTable(Report& report, const PartitionTable& ptable) = 0;
|
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:
|
protected:
|
||||||
void setExclusive(bool b) {
|
void setExclusive(bool b) {
|
||||||
m_Exclusive = b;
|
m_Exclusive = b;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de> *
|
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de> *
|
||||||
* Copyright (C) 2015 by Teo Mrnjavac <teo@kde.org> *
|
* 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 *
|
* This program is free software; you can redistribute it and/or *
|
||||||
* modify it under the terms of the GNU General Public License as *
|
* modify it under the terms of the GNU General Public License as *
|
||||||
|
@ -20,8 +20,8 @@
|
||||||
#include "backend/corebackendmanager.h"
|
#include "backend/corebackendmanager.h"
|
||||||
#include "backend/corebackend.h"
|
#include "backend/corebackend.h"
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QStringList>
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
|
@ -30,8 +30,17 @@
|
||||||
#include <KPluginLoader>
|
#include <KPluginLoader>
|
||||||
#include <KPluginMetaData>
|
#include <KPluginMetaData>
|
||||||
|
|
||||||
|
struct CoreBackendManagerPrivate
|
||||||
|
{
|
||||||
|
CoreBackend *m_Backend;
|
||||||
|
};
|
||||||
|
|
||||||
CoreBackendManager::CoreBackendManager() :
|
CoreBackendManager::CoreBackendManager() :
|
||||||
m_Backend(nullptr)
|
d(std::make_unique<CoreBackendManagerPrivate>())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CoreBackendManager::~CoreBackendManager()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +54,11 @@ CoreBackendManager* CoreBackendManager::self()
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CoreBackend* CoreBackendManager::backend()
|
||||||
|
{
|
||||||
|
return d->m_Backend;
|
||||||
|
}
|
||||||
|
|
||||||
QVector<KPluginMetaData> CoreBackendManager::list() const
|
QVector<KPluginMetaData> CoreBackendManager::list() const
|
||||||
{
|
{
|
||||||
auto filter = [&](const KPluginMetaData &metaData) {
|
auto filter = [&](const KPluginMetaData &metaData) {
|
||||||
|
@ -66,7 +80,7 @@ bool CoreBackendManager::load(const QString& name)
|
||||||
KPluginFactory* factory = loader.factory();
|
KPluginFactory* factory = loader.factory();
|
||||||
|
|
||||||
if (factory != nullptr) {
|
if (factory != nullptr) {
|
||||||
m_Backend = factory->create<CoreBackend>(nullptr);
|
d->m_Backend = factory->create<CoreBackend>(nullptr);
|
||||||
|
|
||||||
QString id = loader.metaData().toVariantMap().value(QStringLiteral("MetaData"))
|
QString id = loader.metaData().toVariantMap().value(QStringLiteral("MetaData"))
|
||||||
.toMap().value(QStringLiteral("KPlugin")).toMap().value(QStringLiteral("Id")).toString();
|
.toMap().value(QStringLiteral("KPlugin")).toMap().value(QStringLiteral("Id")).toString();
|
||||||
|
@ -78,6 +92,7 @@ bool CoreBackendManager::load(const QString& name)
|
||||||
backend()->setId(id);
|
backend()->setId(id);
|
||||||
backend()->setVersion(version);
|
backend()->setVersion(version);
|
||||||
qDebug() << "Loaded backend plugin: " << backend()->id();
|
qDebug() << "Loaded backend plugin: " << backend()->id();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +102,4 @@ bool CoreBackendManager::load(const QString& name)
|
||||||
|
|
||||||
void CoreBackendManager::unload()
|
void CoreBackendManager::unload()
|
||||||
{
|
{
|
||||||
delete m_Backend;
|
|
||||||
m_Backend = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de> *
|
* 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 *
|
* This program is free software; you can redistribute it and/or *
|
||||||
* modify it under the terms of the GNU General Public License as *
|
* 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/>.*
|
* 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
|
#define KPMCORE_COREBACKENDMANAGER_H
|
||||||
|
|
||||||
#include "util/libpartitionmanagerexport.h"
|
#include "util/libpartitionmanagerexport.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
class QString;
|
class QString;
|
||||||
class QStringList;
|
class QStringList;
|
||||||
class KPluginMetaData;
|
class KPluginMetaData;
|
||||||
class CoreBackend;
|
class CoreBackend;
|
||||||
|
struct CoreBackendManagerPrivate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The backend manager class.
|
* The backend manager class.
|
||||||
|
@ -37,8 +40,8 @@ class CoreBackend;
|
||||||
*/
|
*/
|
||||||
class LIBKPMCORE_EXPORT CoreBackendManager
|
class LIBKPMCORE_EXPORT CoreBackendManager
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
CoreBackendManager();
|
CoreBackendManager();
|
||||||
|
~CoreBackendManager();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -50,7 +53,7 @@ public:
|
||||||
* @return the name of the default backend plugin
|
* @return the name of the default backend plugin
|
||||||
*/
|
*/
|
||||||
static QString defaultBackendName() {
|
static QString defaultBackendName() {
|
||||||
return QStringLiteral("pmlibpartedbackendplugin");
|
return QStringLiteral("pmsfdiskbackendplugin");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,12 +76,10 @@ public:
|
||||||
/**
|
/**
|
||||||
* @return a pointer to the currently loaded backend
|
* @return a pointer to the currently loaded backend
|
||||||
*/
|
*/
|
||||||
CoreBackend* backend() {
|
CoreBackend* backend();
|
||||||
return m_Backend;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CoreBackend* m_Backend;
|
std::unique_ptr<CoreBackendManagerPrivate> d;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
include(core/raid/CMakeLists.txt)
|
||||||
|
|
||||||
set(CORE_SRC
|
set(CORE_SRC
|
||||||
core/copysource.cpp
|
core/copysource.cpp
|
||||||
core/copysourcedevice.cpp
|
core/copysourcedevice.cpp
|
||||||
|
@ -20,7 +22,11 @@ set(CORE_SRC
|
||||||
core/partitiontable.cpp
|
core/partitiontable.cpp
|
||||||
core/smartstatus.cpp
|
core/smartstatus.cpp
|
||||||
core/smartattribute.cpp
|
core/smartattribute.cpp
|
||||||
|
core/smartparser.cpp
|
||||||
|
core/smartattributeparseddata.cpp
|
||||||
|
core/smartdiskinformation.cpp
|
||||||
core/volumemanagerdevice.cpp
|
core/volumemanagerdevice.cpp
|
||||||
|
${RAID_SRC}
|
||||||
)
|
)
|
||||||
|
|
||||||
set(CORE_LIB_HDRS
|
set(CORE_LIB_HDRS
|
||||||
|
@ -39,5 +45,5 @@ set(CORE_LIB_HDRS
|
||||||
core/smartattribute.h
|
core/smartattribute.h
|
||||||
core/smartstatus.h
|
core/smartstatus.h
|
||||||
core/volumemanagerdevice.h
|
core/volumemanagerdevice.h
|
||||||
|
${RAID_LIB_HDRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
|
||||||
class CopyTarget;
|
class CopyTarget;
|
||||||
|
class QString;
|
||||||
|
|
||||||
/** Base class for something to copy from.
|
/** Base class for something to copy from.
|
||||||
|
|
||||||
|
@ -41,14 +42,12 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual bool open() = 0;
|
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 qint64 length() const = 0;
|
||||||
virtual bool overlaps(const CopyTarget& target) const = 0;
|
virtual bool overlaps(const CopyTarget& target) const = 0;
|
||||||
|
|
||||||
virtual qint64 firstByte() const = 0;
|
virtual qint64 firstByte() const = 0;
|
||||||
virtual qint64 lastByte() const = 0;
|
virtual qint64 lastByte() const = 0;
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
|
|
||||||
#include "backend/corebackend.h"
|
#include "backend/corebackend.h"
|
||||||
#include "backend/corebackendmanager.h"
|
#include "backend/corebackendmanager.h"
|
||||||
#include "backend/corebackenddevice.h"
|
|
||||||
|
|
||||||
#include "core/copytarget.h"
|
#include "core/copytarget.h"
|
||||||
#include "core/copytargetdevice.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
|
/** Opens the Device
|
||||||
@return true if the Device could be successfully opened
|
@return true if the Device could be successfully opened
|
||||||
*/
|
*/
|
||||||
|
@ -63,22 +56,6 @@ qint64 CopySourceDevice::length() const
|
||||||
return lastByte() - firstByte() + 1;
|
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
|
/** Checks if this CopySourceDevice overlaps with the given CopyTarget
|
||||||
@param target the CopyTarget to check overlapping with
|
@param target the CopyTarget to check overlapping with
|
||||||
@return true if overlaps
|
@return true if overlaps
|
||||||
|
@ -103,3 +80,8 @@ bool CopySourceDevice::overlaps(const CopyTarget& target) const
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString CopySourceDevice::path() const
|
||||||
|
{
|
||||||
|
return m_Device.deviceNode();
|
||||||
|
}
|
||||||
|
|
|
@ -19,14 +19,18 @@
|
||||||
|
|
||||||
#define KPMCORE_COPYSOURCEDEVICE_H
|
#define KPMCORE_COPYSOURCEDEVICE_H
|
||||||
|
|
||||||
|
#include "backend/corebackenddevice.h"
|
||||||
#include "core/copysource.h"
|
#include "core/copysource.h"
|
||||||
#include "util/libpartitionmanagerexport.h"
|
#include "util/libpartitionmanagerexport.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
|
||||||
class Device;
|
class Device;
|
||||||
class CopyTarget;
|
class CopyTarget;
|
||||||
class CoreBackendDevice;
|
class CoreBackendDevice;
|
||||||
|
class QString;
|
||||||
|
|
||||||
/** A Device to copy from.
|
/** A Device to copy from.
|
||||||
|
|
||||||
|
@ -40,11 +44,9 @@ class CopySourceDevice : public CopySource
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CopySourceDevice(Device& d, qint64 firstbyte, qint64 lastbyte);
|
CopySourceDevice(Device& d, qint64 firstbyte, qint64 lastbyte);
|
||||||
~CopySourceDevice();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool open() override;
|
bool open() override;
|
||||||
bool readData(QByteArray& buffer, qint64 readOffset, qint64 size) override;
|
|
||||||
qint64 length() const override;
|
qint64 length() const override;
|
||||||
bool overlaps(const CopyTarget& target) const override;
|
bool overlaps(const CopyTarget& target) const override;
|
||||||
|
|
||||||
|
@ -62,12 +64,13 @@ public:
|
||||||
return m_Device; /**< @return Device to copy from */
|
return m_Device; /**< @return Device to copy from */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString path() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Device& m_Device;
|
Device& m_Device;
|
||||||
const qint64 m_FirstByte;
|
const qint64 m_FirstByte;
|
||||||
const qint64 m_LastByte;
|
const qint64 m_LastByte;
|
||||||
CoreBackendDevice* m_BackendDevice
|
std::unique_ptr<CoreBackendDevice> m_BackendDevice;
|
||||||
;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -45,18 +45,3 @@ qint64 CopySourceFile::length() const
|
||||||
{
|
{
|
||||||
return QFileInfo(file()).size();
|
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:
|
public:
|
||||||
bool open() override;
|
bool open() override;
|
||||||
bool readData(QByteArray& buffer, qint64 readOffset, qint64 size) override;
|
|
||||||
qint64 length() const override;
|
qint64 length() const override;
|
||||||
|
|
||||||
bool overlaps(const CopyTarget&) const override {
|
bool overlaps(const CopyTarget&) const override {
|
||||||
|
@ -52,6 +51,9 @@ public:
|
||||||
qint64 lastByte() const override {
|
qint64 lastByte() const override {
|
||||||
return length(); /**< @return equal to length for file. @see length() */
|
return length(); /**< @return equal to length for file. @see length() */
|
||||||
}
|
}
|
||||||
|
QString path() const override {
|
||||||
|
return m_File.fileName();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QFile& file() {
|
QFile& file() {
|
||||||
|
|
|
@ -43,17 +43,3 @@ qint64 CopySourceShred::length() const
|
||||||
{
|
{
|
||||||
return size();
|
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>
|
#include <QFile>
|
||||||
|
|
||||||
class CopyTarget;
|
class CopyTarget;
|
||||||
|
class QString;
|
||||||
|
|
||||||
/** A source for securely overwriting a partition (shredding).
|
/** A source for securely overwriting a partition (shredding).
|
||||||
|
|
||||||
|
@ -38,7 +39,6 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool open() override;
|
bool open() override;
|
||||||
bool readData(QByteArray& buffer, qint64 readOffset, qint64 size) override;
|
|
||||||
qint64 length() const override;
|
qint64 length() const override;
|
||||||
|
|
||||||
bool overlaps(const CopyTarget&) const override {
|
bool overlaps(const CopyTarget&) const override {
|
||||||
|
@ -50,6 +50,9 @@ public:
|
||||||
qint64 lastByte() const override {
|
qint64 lastByte() const override {
|
||||||
return length(); /**< @return equal to length for shred source. @see length() */
|
return length(); /**< @return equal to length for shred source. @see length() */
|
||||||
}
|
}
|
||||||
|
QString path() const override {
|
||||||
|
return m_SourceFile.fileName();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QFile& sourceFile() {
|
QFile& sourceFile() {
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
class QString;
|
||||||
|
|
||||||
/** Base class for something to copy to.
|
/** Base class for something to copy to.
|
||||||
|
|
||||||
|
@ -40,10 +41,9 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual bool open() = 0;
|
virtual bool open() = 0;
|
||||||
virtual bool writeData(QByteArray& buffer, qint64 writeOffset) = 0;
|
|
||||||
virtual qint64 firstByte() const = 0;
|
virtual qint64 firstByte() const = 0;
|
||||||
virtual qint64 lastByte() const = 0;
|
virtual qint64 lastByte() const = 0;
|
||||||
|
virtual QString path() const = 0;
|
||||||
qint64 bytesWritten() const {
|
qint64 bytesWritten() const {
|
||||||
return m_BytesWritten;
|
return m_BytesWritten;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,9 @@
|
||||||
|
|
||||||
#include "backend/corebackend.h"
|
#include "backend/corebackend.h"
|
||||||
#include "backend/corebackendmanager.h"
|
#include "backend/corebackendmanager.h"
|
||||||
#include "backend/corebackenddevice.h"
|
|
||||||
|
|
||||||
#include "core/device.h"
|
#include "core/device.h"
|
||||||
|
|
||||||
|
|
||||||
/** Constructs a device to copy to.
|
/** Constructs a device to copy to.
|
||||||
@param d the Device to copy to
|
@param d the Device to copy to
|
||||||
@param firstbyte the first byte on the Device to write 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.
|
/** Opens a CopyTargetDevice for writing to.
|
||||||
@return true on success
|
@return true on success
|
||||||
*/
|
*/
|
||||||
|
@ -53,21 +45,7 @@ bool CopyTargetDevice::open()
|
||||||
return m_BackendDevice != nullptr;
|
return m_BackendDevice != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Writes the given number of bytes to the Device.
|
QString CopyTargetDevice::path() const
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
Q_ASSERT(writeOffset >= 0);
|
return m_Device.deviceNode();
|
||||||
bool rval = m_BackendDevice->writeData(buffer, writeOffset);
|
|
||||||
|
|
||||||
if (rval)
|
|
||||||
setBytesWritten(bytesWritten() + buffer.size());
|
|
||||||
|
|
||||||
return rval;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,12 @@
|
||||||
|
|
||||||
#define KPMCORE_COPYTARGETDEVICE_H
|
#define KPMCORE_COPYTARGETDEVICE_H
|
||||||
|
|
||||||
|
#include "backend/corebackenddevice.h"
|
||||||
#include "core/copytarget.h"
|
#include "core/copytarget.h"
|
||||||
#include "util/libpartitionmanagerexport.h"
|
#include "util/libpartitionmanagerexport.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
|
||||||
class Device;
|
class Device;
|
||||||
|
@ -42,11 +45,9 @@ class CopyTargetDevice : public CopyTarget
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CopyTargetDevice(Device& d, qint64 firstbyte, qint64 lastbyte);
|
CopyTargetDevice(Device& d, qint64 firstbyte, qint64 lastbyte);
|
||||||
~CopyTargetDevice();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool open() override;
|
bool open() override;
|
||||||
bool writeData(QByteArray& buffer, qint64 writeOffset) override;
|
|
||||||
qint64 firstByte() const override {
|
qint64 firstByte() const override {
|
||||||
return m_FirstByte; /**< @return the first byte to write to */
|
return m_FirstByte; /**< @return the first byte to write to */
|
||||||
}
|
}
|
||||||
|
@ -60,10 +61,11 @@ public:
|
||||||
const Device& device() const {
|
const Device& device() const {
|
||||||
return m_Device; /**< @return the Device to write to */
|
return m_Device; /**< @return the Device to write to */
|
||||||
}
|
}
|
||||||
|
QString path() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Device& m_Device;
|
Device& m_Device;
|
||||||
CoreBackendDevice* m_BackendDevice;
|
std::unique_ptr<CoreBackendDevice> m_BackendDevice;
|
||||||
const qint64 m_FirstByte;
|
const qint64 m_FirstByte;
|
||||||
const qint64 m_LastByte;
|
const qint64 m_LastByte;
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,21 +33,3 @@ bool CopyTargetFile::open()
|
||||||
{
|
{
|
||||||
return file().open(QIODevice::WriteOnly | QIODevice::Truncate);
|
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:
|
public:
|
||||||
bool open() override;
|
bool open() override;
|
||||||
bool writeData(QByteArray& buffer, qint64 writeOffset) override;
|
|
||||||
|
|
||||||
qint64 firstByte() const override {
|
qint64 firstByte() const override {
|
||||||
return 0; /**< @return always 0 for a file */
|
return 0; /**< @return always 0 for a file */
|
||||||
|
@ -49,6 +48,10 @@ public:
|
||||||
return bytesWritten(); /**< @return the number of bytes written so far */
|
return bytesWritten(); /**< @return the number of bytes written so far */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString path() const override {
|
||||||
|
return m_File.fileName();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QFile& file() {
|
QFile& file() {
|
||||||
return m_File;
|
return m_File;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Copyright (C) 2008 by Volker Lanz <vl@fidra.de> *
|
* 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 *
|
* This program is free software; you can redistribute it and/or *
|
||||||
* modify it under the terms of the GNU General Public License as *
|
* modify it under the terms of the GNU General Public License as *
|
||||||
|
@ -17,6 +17,7 @@
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
#include "core/device.h"
|
#include "core/device.h"
|
||||||
|
#include "core/device_p.h"
|
||||||
#include "core/partitiontable.h"
|
#include "core/partitiontable.h"
|
||||||
#include "core/smartstatus.h"
|
#include "core/smartstatus.h"
|
||||||
|
|
||||||
|
@ -28,22 +29,24 @@
|
||||||
@param name the Device's name, usually some string defined by the manufacturer
|
@param name the Device's name, usually some string defined by the manufacturer
|
||||||
@param deviceNode the Device's node, for example "/dev/sda"
|
@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 QString& deviceNode,
|
||||||
const qint64 logicalSize,
|
const qint64 logicalSectorSize,
|
||||||
const qint64 totalLogical,
|
const qint64 totalLogicalSectors,
|
||||||
const QString& iconName,
|
const QString& iconName,
|
||||||
Device::Type type)
|
Device::Type type)
|
||||||
: QObject()
|
: QObject()
|
||||||
, m_Name(name.length() > 0 ? name : i18n("Unknown Device"))
|
, d(d_ptr)
|
||||||
, 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->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.
|
/** Copy constructor for Device.
|
||||||
|
@ -51,30 +54,31 @@ Device::Device(const QString& name,
|
||||||
*/
|
*/
|
||||||
Device::Device(const Device& other)
|
Device::Device(const Device& other)
|
||||||
: QObject()
|
: QObject()
|
||||||
, m_Name(other.m_Name)
|
, d(std::make_shared<DevicePrivate>())
|
||||||
, 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)
|
|
||||||
{
|
{
|
||||||
if (other.m_PartitionTable)
|
d->m_Name = other.d->m_Name;
|
||||||
m_PartitionTable = new PartitionTable(*other.m_PartitionTable);
|
d->m_DeviceNode = other.d->m_DeviceNode;
|
||||||
if (other.m_SmartStatus)
|
d->m_LogicalSectorSize = other.d->m_LogicalSectorSize;
|
||||||
m_SmartStatus = new SmartStatus(*other.m_SmartStatus);
|
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. */
|
/** Destructs a Device. */
|
||||||
Device::~Device()
|
Device::~Device()
|
||||||
{
|
{
|
||||||
delete m_PartitionTable;
|
delete d->m_PartitionTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device::operator==(const Device& other) const
|
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
|
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());
|
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/>.*
|
* 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
|
#define KPMCORE_DEVICE_H
|
||||||
|
|
||||||
#include "util/libpartitionmanagerexport.h"
|
#include "util/libpartitionmanagerexport.h"
|
||||||
|
@ -24,10 +23,13 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
class PartitionTable;
|
class PartitionTable;
|
||||||
class CreatePartitionTableOperation;
|
class CreatePartitionTableOperation;
|
||||||
class CoreBackend;
|
class CoreBackend;
|
||||||
class SmartStatus;
|
class SmartStatus;
|
||||||
|
class DevicePrivate;
|
||||||
|
|
||||||
/** A device description.
|
/** A device description.
|
||||||
|
|
||||||
|
@ -48,96 +50,66 @@ class LIBKPMCORE_EXPORT Device : public QObject
|
||||||
friend class CoreBackend;
|
friend class CoreBackend;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum Type {
|
enum class Type {
|
||||||
Disk_Device = 0,
|
Unknown_Device,
|
||||||
LVM_Device = 1, /* VG */
|
Disk_Device,
|
||||||
RAID_Device = 2, /* software RAID device */
|
LVM_Device, /* VG */
|
||||||
Unknown_Device = 4
|
SoftwareRAID_Device, /* software RAID device, i.e. mdraid */
|
||||||
|
FakeRAID_Device, /* fake RAID device, i.e. dmraid */
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
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);
|
||||||
explicit Device(const QString& name, const QString& deviceNode, const qint64 logicalSize, const qint64 totalLogical, const QString& iconName = QString(), Device::Type type = Device::Disk_Device);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Device(const Device& other);
|
explicit Device(const Device& other);
|
||||||
virtual ~Device();
|
virtual ~Device();
|
||||||
|
|
||||||
public:
|
|
||||||
virtual bool operator==(const Device& other) const;
|
virtual bool operator==(const Device& other) const;
|
||||||
virtual bool operator!=(const Device& other) const;
|
virtual bool operator!=(const Device& other) const;
|
||||||
|
|
||||||
virtual QString& name() {
|
/**< @return the Device's name, usually some manufacturer string */
|
||||||
return m_Name; /**< @return the Device's name, usually some manufacturer string */
|
virtual QString& name();
|
||||||
}
|
virtual const QString& name() const;
|
||||||
|
|
||||||
virtual const QString& name() const {
|
/**< @return the Device's node, for example "/dev/sda" */
|
||||||
return m_Name; /**< @return the Device's name, usually some manufacturer string */
|
virtual const QString& deviceNode() const;
|
||||||
}
|
|
||||||
|
|
||||||
virtual const QString& deviceNode() const {
|
/**< @return the logical sector size the Device uses (would be extent size for e.g. LVM devices) */
|
||||||
return m_DeviceNode; /**< @return the Device's node, for example "/dev/sda" */
|
virtual qint64 logicalSize() const;
|
||||||
}
|
|
||||||
|
|
||||||
virtual PartitionTable* partitionTable() {
|
/**< @return the total number of logical sectors on the device */
|
||||||
return m_PartitionTable; /**< @return the Device's PartitionTable */
|
virtual qint64 totalLogical() const;
|
||||||
}
|
|
||||||
|
|
||||||
virtual const PartitionTable* partitionTable() const {
|
/**< @return the Device's PartitionTable */
|
||||||
return m_PartitionTable; /**< @return the Device's PartitionTable */
|
virtual PartitionTable* partitionTable();
|
||||||
}
|
virtual const PartitionTable* partitionTable() const;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change the description of the partition table for different one.
|
* Change the description of the partition table for different one.
|
||||||
* The device itself is not changed; use CreatePartitionTableOperation
|
* The device itself is not changed; use CreatePartitionTableOperation
|
||||||
* for that. The Device instance becomes the owner of @p ptable .
|
* for that. The Device instance becomes the owner of @p ptable .
|
||||||
*/
|
*/
|
||||||
virtual void setPartitionTable(PartitionTable* ptable) {
|
virtual void setPartitionTable(PartitionTable* ptable);
|
||||||
m_PartitionTable = ptable;
|
|
||||||
|
virtual qint64 capacity() const { /**< @return the Device's capacity in bytes */
|
||||||
|
return logicalSize() * totalLogical();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual qint64 logicalSize() const {
|
/**< @return suggested icon name for this Device */
|
||||||
return m_LogicalSize;
|
virtual const QString& iconName() const;
|
||||||
}
|
|
||||||
|
|
||||||
virtual qint64 totalLogical() const {
|
/**< @param name set the new Icon for this Device */
|
||||||
return m_TotalLogical;
|
virtual void setIconName(const QString& name);
|
||||||
}
|
|
||||||
|
|
||||||
virtual Device::Type type() const {
|
virtual SmartStatus& smartStatus();
|
||||||
return m_Type;
|
virtual const SmartStatus& smartStatus() const;
|
||||||
}
|
|
||||||
|
virtual Device::Type type() const;
|
||||||
|
|
||||||
virtual QString prettyName() const;
|
virtual QString prettyName() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QString m_Name;
|
std::shared_ptr<DevicePrivate> d;
|
||||||
QString m_DeviceNode;
|
|
||||||
qint64 m_LogicalSize;
|
|
||||||
qint64 m_TotalLogical;
|
|
||||||
PartitionTable* m_PartitionTable;
|
|
||||||
QString m_IconName;
|
|
||||||
SmartStatus* m_SmartStatus;
|
|
||||||
Device::Type m_Type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#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) 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 *
|
* This program is free software; you can redistribute it and/or *
|
||||||
* modify it under the terms of the GNU General Public License as *
|
* modify it under the terms of the GNU General Public License as *
|
||||||
|
@ -17,6 +17,7 @@
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
#include "core/diskdevice.h"
|
#include "core/diskdevice.h"
|
||||||
|
#include "core/device_p.h"
|
||||||
|
|
||||||
#include "core/partitiontable.h"
|
#include "core/partitiontable.h"
|
||||||
#include "core/smartstatus.h"
|
#include "core/smartstatus.h"
|
||||||
|
@ -39,14 +40,25 @@
|
||||||
#define BLKPBSZGET _IO(0x12,123)/* get block physical sector size */
|
#define BLKPBSZGET _IO(0x12,123)/* get block physical sector size */
|
||||||
#endif
|
#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)
|
static qint64 getPhysicalSectorSize(const QString& device_node)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* possible ways of getting the physical sector size for a drive:
|
* possible ways of getting the physical sector size for a drive:
|
||||||
* - ioctl(BLKPBSZGET) -- supported with Linux 2.6.32 and later
|
* - ioctl(BLKPBSZGET) -- supported with Linux 2.6.32 and later
|
||||||
* - /sys/block/sda/queue/physical_block_size
|
* - /sys/block/sda/queue/physical_block_size
|
||||||
* - libblkid from util-linux-ng 2.17 or later
|
* - libblkid from util-linux 2.17 or later (not implemented)
|
||||||
* TODO: implement the blkid method
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(BLKPBSZGET)
|
#if defined(BLKPBSZGET)
|
||||||
|
@ -87,11 +99,46 @@ DiskDevice::DiskDevice(const QString& name,
|
||||||
qint32 cylinders,
|
qint32 cylinders,
|
||||||
qint64 sectorSize,
|
qint64 sectorSize,
|
||||||
const QString& iconName)
|
const QString& iconName)
|
||||||
: Device(name, deviceNode, sectorSize, (static_cast<qint64>(heads) * cylinders * numSectors), iconName, Device::Disk_Device)
|
: Device(std::make_shared<DiskDevicePrivate>(), name, deviceNode, sectorSize, (static_cast<qint64>(heads) * cylinders * numSectors), iconName, Device::Type::Disk_Device)
|
||||||
, m_Heads(heads)
|
|
||||||
, m_SectorsPerTrack(numSectors)
|
|
||||||
, m_Cylinders(cylinders)
|
|
||||||
, m_LogicalSectorSize(sectorSize)
|
|
||||||
, m_PhysicalSectorSize(getPhysicalSectorSize(deviceNode))
|
|
||||||
{
|
{
|
||||||
|
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) 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 *
|
* This program is free software; you can redistribute it and/or *
|
||||||
* modify it under the terms of the GNU General Public License as *
|
* 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/>.*
|
* 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
|
#define KPMCORE_DISKDEVICE_H
|
||||||
|
|
||||||
#include "util/libpartitionmanagerexport.h"
|
#include "util/libpartitionmanagerexport.h"
|
||||||
#include "core/device.h"
|
#include "core/device.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
@ -30,6 +32,7 @@ class PartitionTable;
|
||||||
class CreatePartitionTableOperation;
|
class CreatePartitionTableOperation;
|
||||||
class CoreBackend;
|
class CoreBackend;
|
||||||
class SmartStatus;
|
class SmartStatus;
|
||||||
|
class DiskDevicePrivate;
|
||||||
|
|
||||||
/** A disk device.
|
/** A disk device.
|
||||||
|
|
||||||
|
@ -40,6 +43,7 @@ class SmartStatus;
|
||||||
@see PartitionTable, Partition
|
@see PartitionTable, Partition
|
||||||
@author Volker Lanz <vl@fidra.de>
|
@author Volker Lanz <vl@fidra.de>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class LIBKPMCORE_EXPORT DiskDevice : public Device
|
class LIBKPMCORE_EXPORT DiskDevice : public Device
|
||||||
{
|
{
|
||||||
Q_DISABLE_COPY(DiskDevice)
|
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());
|
DiskDevice(const QString& name, const QString& deviceNode, qint32 heads, qint32 numSectors, qint32 cylinders, qint64 sectorSize, const QString& iconName = QString());
|
||||||
|
|
||||||
public:
|
public:
|
||||||
qint32 heads() const {
|
/**
|
||||||
return m_Heads; /**< @return the number of heads on the Device in CHS notation */
|
* @return the number of heads on the Device in CHS notation
|
||||||
}
|
*/
|
||||||
qint32 cylinders() const {
|
[[deprecated]]
|
||||||
return m_Cylinders; /**< @return the number of cylinders on the Device in CHS notation */
|
qint32 heads() const;
|
||||||
}
|
|
||||||
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 */
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
/**
|
||||||
qint32 m_Heads;
|
* @return the number of cylinders on the Device in CHS notation
|
||||||
qint32 m_SectorsPerTrack;
|
*/
|
||||||
qint32 m_Cylinders;
|
[[deprecated]]
|
||||||
qint64 m_LogicalSectorSize;
|
qint32 cylinders() const;
|
||||||
qint64 m_PhysicalSectorSize;
|
|
||||||
|
/**
|
||||||
|
* @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
|
#endif
|
||||||
|
|
|
@ -18,38 +18,47 @@
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
#include "core/fstab.h"
|
#include "core/fstab.h"
|
||||||
|
#include "util/externalcommand.h"
|
||||||
|
|
||||||
|
#if defined(Q_OS_LINUX)
|
||||||
#include <blkid/blkid.h>
|
#include <blkid/blkid.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <QChar>
|
#include <QChar>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QFile>
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
#include <QTemporaryFile>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
|
|
||||||
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);
|
||||||
static QString findBlkIdDevice(const QString& token, const QString& value);
|
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)
|
struct FstabEntryPrivate
|
||||||
: m_fsSpec(fsSpec)
|
|
||||||
, m_mountPoint(mountPoint)
|
|
||||||
, m_type(type)
|
|
||||||
, m_dumpFreq(dumpFreq)
|
|
||||||
, m_passNumber(passNumber)
|
|
||||||
, m_comment(comment)
|
|
||||||
{
|
{
|
||||||
m_options = options.split(QLatin1Char(','));
|
QString m_fsSpec;
|
||||||
parseFsSpec(m_fsSpec, m_entryType, m_deviceNode);
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
FstabEntry::FstabEntry(const QString& fsSpec, const QString& mountPoint, const QString& type, const QString& options, int dumpFreq, int passNumber, const QString& comment) :
|
||||||
@param s the new value for the fs_spec field of fstab entry
|
d(std::make_unique<FstabEntryPrivate>())
|
||||||
*/
|
|
||||||
void FstabEntry::setFsSpec(const QString& s)
|
|
||||||
{
|
{
|
||||||
m_fsSpec = s;
|
d->m_fsSpec = fsSpec;
|
||||||
parseFsSpec(m_fsSpec, m_entryType, m_deviceNode);
|
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 )
|
FstabEntryList readFstabEntries( const QString& fstabPath )
|
||||||
|
@ -63,7 +72,7 @@ FstabEntryList readFstabEntries( const QString& fstabPath )
|
||||||
{
|
{
|
||||||
QString line = rawLine.trimmed();
|
QString line = rawLine.trimmed();
|
||||||
if ( line.startsWith( QLatin1Char('#') ) || line.isEmpty()) {
|
if ( line.startsWith( QLatin1Char('#') ) || line.isEmpty()) {
|
||||||
fstabEntries.append( { {}, {}, {}, {}, {}, {}, line } );
|
fstabEntries.push_back( { {}, {}, {}, {}, {}, {}, line } );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,27 +89,98 @@ FstabEntryList readFstabEntries( const QString& fstabPath )
|
||||||
// (#) comment (optional).
|
// (#) comment (optional).
|
||||||
switch (splitLine.length()) {
|
switch (splitLine.length()) {
|
||||||
case 4:
|
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;
|
break;
|
||||||
case 5:
|
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;
|
break;
|
||||||
case 6:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
fstabEntries.append( { {}, {}, {}, {}, {}, {}, QLatin1Char('#') + line } );
|
fstabEntries.push_back( { {}, {}, {}, {}, {}, {}, QLatin1Char('#') + line } );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fstabFile.close();
|
fstabFile.close();
|
||||||
if (fstabEntries.last().entryType() == comment && fstabEntries.last().comment().isEmpty())
|
if (fstabEntries.back().entryType() == FstabEntry::Type::comment && fstabEntries.back().comment().isEmpty())
|
||||||
fstabEntries.removeLast();
|
fstabEntries.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
return fstabEntries;
|
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 possibleMountPoints(const QString& deviceNode, const QString& fstabPath)
|
||||||
{
|
{
|
||||||
QStringList mountPoints;
|
QStringList mountPoints;
|
||||||
|
@ -113,40 +193,37 @@ QStringList possibleMountPoints(const QString& deviceNode, const QString& fstabP
|
||||||
return mountPoints;
|
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;
|
QString rval;
|
||||||
|
|
||||||
if (blkid_get_cache(&cache, nullptr) == 0) {
|
#if defined(Q_OS_LINUX)
|
||||||
if (char* c = blkid_evaluate_tag(token.toLocal8Bit().constData(), value.toLocal8Bit().constData(), &cache)) {
|
if (char* c = blkid_evaluate_tag(token, value.toLocal8Bit().constData(), nullptr)) {
|
||||||
rval = QString::fromLocal8Bit(c);
|
rval = QString::fromLocal8Bit(c);
|
||||||
free(c);
|
free(c);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
blkid_put_cache(cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rval;
|
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="))) {
|
if (m_fsSpec.startsWith(QStringLiteral("UUID="))) {
|
||||||
m_entryType = FstabEntryType::uuid;
|
m_entryType = FstabEntry::Type::uuid;
|
||||||
m_deviceNode = findBlkIdDevice(QStringLiteral("UUID"), QString(m_fsSpec).remove(QStringLiteral("UUID=")));
|
m_deviceNode = findBlkIdDevice("UUID", QString(m_fsSpec).remove(QStringLiteral("UUID=")));
|
||||||
} else if (m_fsSpec.startsWith(QStringLiteral("LABEL="))) {
|
} else if (m_fsSpec.startsWith(QStringLiteral("LABEL="))) {
|
||||||
m_entryType = FstabEntryType::label;
|
m_entryType = FstabEntry::Type::label;
|
||||||
m_deviceNode = findBlkIdDevice(QStringLiteral("LABEL"), QString(m_fsSpec).remove(QStringLiteral("LABEL=")));
|
m_deviceNode = findBlkIdDevice("LABEL", QString(m_fsSpec).remove(QStringLiteral("LABEL=")));
|
||||||
} else if (m_fsSpec.startsWith(QStringLiteral("PARTUUID="))) {
|
} else if (m_fsSpec.startsWith(QStringLiteral("PARTUUID="))) {
|
||||||
m_entryType = FstabEntryType::uuid;
|
m_entryType = FstabEntry::Type::uuid;
|
||||||
m_deviceNode = findBlkIdDevice(QStringLiteral("PARTUUID"), QString(m_fsSpec).remove(QStringLiteral("PARTUUID=")));
|
m_deviceNode = findBlkIdDevice("PARTUUID", QString(m_fsSpec).remove(QStringLiteral("PARTUUID=")));
|
||||||
} else if (m_fsSpec.startsWith(QStringLiteral("PARTLABEL="))) {
|
} else if (m_fsSpec.startsWith(QStringLiteral("PARTLABEL="))) {
|
||||||
m_entryType = FstabEntryType::label;
|
m_entryType = FstabEntry::Type::label;
|
||||||
m_deviceNode = findBlkIdDevice(QStringLiteral("PARTLABEL"), QString(m_fsSpec).remove(QStringLiteral("PARTLABEL=")));
|
m_deviceNode = findBlkIdDevice("PARTLABEL", QString(m_fsSpec).remove(QStringLiteral("PARTLABEL=")));
|
||||||
} else if (m_fsSpec.startsWith(QStringLiteral("/"))) {
|
} else if (m_fsSpec.startsWith(QStringLiteral("/"))) {
|
||||||
m_entryType = FstabEntryType::deviceNode;
|
m_entryType = FstabEntry::Type::deviceNode;
|
||||||
m_deviceNode = m_fsSpec;
|
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)
|
static void writeEntry(QFile& output, const FstabEntry& entry)
|
||||||
{
|
{
|
||||||
QTextStream s(&output);
|
QTextStream s(&output);
|
||||||
if (entry.entryType() == FstabEntryType::comment) {
|
if (entry.entryType() == FstabEntry::Type::comment) {
|
||||||
s << entry.comment() << "\n";
|
s << entry.comment() << "\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -177,34 +254,34 @@ static void writeEntry(QFile& output, const FstabEntry& entry)
|
||||||
<< entry.comment() << "\n";
|
<< entry.comment() << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool writeMountpoints(const FstabEntryList fstabEntries, const QString& filename)
|
bool writeMountpoints(const FstabEntryList& fstabEntries, const QString& filename)
|
||||||
{
|
{
|
||||||
bool rval = true;
|
QTemporaryFile out;
|
||||||
const QString newFilename = QStringLiteral("%1.new").arg(filename);
|
out.setAutoRemove(false);
|
||||||
QFile out(newFilename);
|
|
||||||
|
|
||||||
if (!out.open(QFile::ReadWrite | QFile::Truncate)) {
|
if (!out.open()) {
|
||||||
qWarning() << "could not open output file " << newFilename;
|
qWarning() << "could not open output file " << out.fileName();
|
||||||
rval = false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
for (const auto &e : fstabEntries)
|
for (const auto &e : fstabEntries)
|
||||||
writeEntry(out, e);
|
writeEntry(out, e);
|
||||||
|
|
||||||
out.close();
|
out.close();
|
||||||
|
|
||||||
const QString bakFilename = QStringLiteral("%1.bak").arg(filename);
|
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)) {
|
if ( !(mvCmd.run(-1) && mvCmd.exitCode() == 0) ) {
|
||||||
qWarning() << "could not rename " << filename << " to " << bakFilename;
|
qWarning() << "could not backup " << filename << " to " << bakFilename;
|
||||||
rval = false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rval && !QFile::rename(newFilename, filename)) {
|
ExternalCommand mvCmd2(QStringLiteral("mv"), { out.fileName(), filename } );
|
||||||
qWarning() << "could not rename " << newFilename << " to " << filename;
|
|
||||||
rval = false;
|
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 *
|
* This program is free software; you can redistribute it and/or *
|
||||||
* modify it under the terms of the GNU General Public License as *
|
* modify it under the terms of the GNU General Public License as *
|
||||||
|
@ -20,10 +20,12 @@
|
||||||
|
|
||||||
#include "util/libpartitionmanagerexport.h"
|
#include "util/libpartitionmanagerexport.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
enum FstabEntryType { deviceNode, uuid, label, partlabel, partuuid, comment };
|
struct FstabEntryPrivate;
|
||||||
|
|
||||||
/** Base class for fstab handling.
|
/** Base class for fstab handling.
|
||||||
|
|
||||||
|
@ -35,65 +37,88 @@ enum FstabEntryType { deviceNode, uuid, label, partlabel, partuuid, comment };
|
||||||
class LIBKPMCORE_EXPORT FstabEntry
|
class LIBKPMCORE_EXPORT FstabEntry
|
||||||
{
|
{
|
||||||
public:
|
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());
|
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 */
|
* @return the fs_spec field of fstab entry
|
||||||
}
|
*/
|
||||||
const QString& deviceNode() const {
|
const QString& fsSpec() 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 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 setFsSpec(const QString& s);
|
||||||
void setMountPoint(const QString& s) {
|
|
||||||
m_mountPoint = s; /**< @param s the new value for the mount point */
|
/**
|
||||||
}
|
* @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 setMountPoint(const QString& s);
|
||||||
}
|
|
||||||
void setDumpFreq(int s) {
|
/**
|
||||||
m_dumpFreq = s; /**< @param s the new value for the dump frequency */
|
* @param s the new list with the mount options
|
||||||
}
|
*/
|
||||||
void setPassNumber(int s) {
|
void setOptions(const QStringList& s);
|
||||||
m_passNumber = s; /**< @param s the new value for the pass number */
|
|
||||||
}
|
/**
|
||||||
|
* @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:
|
private:
|
||||||
QString m_fsSpec;
|
std::shared_ptr<FstabEntryPrivate> d;
|
||||||
QString m_deviceNode;
|
|
||||||
QString m_mountPoint;
|
|
||||||
QString m_type;
|
|
||||||
QStringList m_options;
|
|
||||||
int m_dumpFreq;
|
|
||||||
int m_passNumber;
|
|
||||||
QString m_comment;
|
|
||||||
FstabEntryType m_entryType;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef QList<FstabEntry> FstabEntryList;
|
typedef QList<FstabEntry> FstabEntryList;
|
||||||
|
|
||||||
LIBKPMCORE_EXPORT FstabEntryList readFstabEntries(const QString& fstabPath = QStringLiteral("/etc/fstab"));
|
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 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
|
#endif
|
||||||
|
|
|
@ -18,14 +18,16 @@
|
||||||
|
|
||||||
#include "core/lvmdevice.h"
|
#include "core/lvmdevice.h"
|
||||||
#include "core/partition.h"
|
#include "core/partition.h"
|
||||||
|
#include "core/partitiontable.h"
|
||||||
|
#include "core/volumemanagerdevice_p.h"
|
||||||
#include "fs/filesystem.h"
|
#include "fs/filesystem.h"
|
||||||
#include "fs/lvm2_pv.h"
|
#include "fs/lvm2_pv.h"
|
||||||
#include "fs/luks.h"
|
#include "fs/luks.h"
|
||||||
#include "fs/filesystemfactory.h"
|
#include "fs/filesystemfactory.h"
|
||||||
|
|
||||||
#include "core/partitiontable.h"
|
|
||||||
#include "util/externalcommand.h"
|
#include "util/externalcommand.h"
|
||||||
#include "util/helpers.h"
|
#include "util/helpers.h"
|
||||||
|
#include "util/globallog.h"
|
||||||
#include "util/report.h"
|
#include "util/report.h"
|
||||||
|
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
@ -34,26 +36,43 @@
|
||||||
|
|
||||||
#include <KLocalizedString>
|
#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
|
/** Constructs a representation of LVM device with initialized LV as Partitions
|
||||||
*
|
*
|
||||||
* @param vgName Volume Group name
|
* @param vgName Volume Group name
|
||||||
* @param iconName Icon representing LVM Volume group
|
* @param iconName Icon representing LVM Volume group
|
||||||
*/
|
*/
|
||||||
LvmDevice::LvmDevice(const QString& vgName, const QString& iconName)
|
LvmDevice::LvmDevice(const QString& vgName, const QString& iconName)
|
||||||
: VolumeManagerDevice(vgName,
|
: VolumeManagerDevice(std::make_shared<LvmDevicePrivate>(),
|
||||||
|
vgName,
|
||||||
(QStringLiteral("/dev/") + vgName),
|
(QStringLiteral("/dev/") + vgName),
|
||||||
getPeSize(vgName),
|
getPeSize(vgName),
|
||||||
getTotalPE(vgName),
|
getTotalPE(vgName),
|
||||||
iconName,
|
iconName,
|
||||||
Device::LVM_Device)
|
Device::Type::LVM_Device)
|
||||||
{
|
{
|
||||||
m_peSize = logicalSize();
|
d_ptr->m_peSize = logicalSize();
|
||||||
m_totalPE = totalLogical();
|
d_ptr->m_totalPE = totalLogical();
|
||||||
m_freePE = getFreePE(vgName);
|
d_ptr->m_freePE = getFreePE(vgName);
|
||||||
m_allocPE = m_totalPE - m_freePE;
|
d_ptr->m_allocPE = d_ptr->m_totalPE - d_ptr->m_freePE;
|
||||||
m_UUID = getUUID(vgName);
|
d_ptr->m_UUID = getUUID(vgName);
|
||||||
m_LVPathList = new QStringList(getLVs(vgName));
|
d_ptr->m_LVPathList = getLVs(vgName);
|
||||||
m_LVSizeMap = new QHash<QString, qint64>();
|
d_ptr->m_LVSizeMap = std::make_unique<QHash<QString, qint64>>();
|
||||||
|
|
||||||
initPartitions();
|
initPartitions();
|
||||||
}
|
}
|
||||||
|
@ -64,36 +83,47 @@ LvmDevice::LvmDevice(const QString& vgName, const QString& iconName)
|
||||||
*/
|
*/
|
||||||
QVector<const Partition*> LvmDevice::s_DirtyPVs;
|
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()
|
LvmDevice::~LvmDevice()
|
||||||
{
|
{
|
||||||
delete m_LVPathList;
|
|
||||||
delete m_LVSizeMap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LvmDevice::initPartitions()
|
void LvmDevice::initPartitions()
|
||||||
{
|
{
|
||||||
qint64 firstUsable = 0;
|
qint64 firstUsable = 0;
|
||||||
qint64 lastusable = totalPE() - 1;
|
qint64 lastUsable = totalPE() - 1;
|
||||||
PartitionTable* pTable = new PartitionTable(PartitionTable::vmd, firstUsable, lastusable);
|
PartitionTable* pTable = new PartitionTable(PartitionTable::vmd, firstUsable, lastUsable);
|
||||||
|
|
||||||
for (const auto &p : scanPartitions(pTable)) {
|
for (const auto &p : scanPartitions(pTable)) {
|
||||||
LVSizeMap()->insert(p->partitionPath(), p->length());
|
LVSizeMap()->insert(p->partitionPath(), p->length());
|
||||||
pTable->append(p);
|
pTable->append(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pTable)
|
||||||
pTable->updateUnallocated(*this);
|
pTable->updateUnallocated(*this);
|
||||||
|
else
|
||||||
|
pTable = new PartitionTable(PartitionTable::vmd, firstUsable, lastUsable);
|
||||||
|
|
||||||
setPartitionTable(pTable);
|
setPartitionTable(pTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Scan LVM LV Partitions
|
||||||
|
*
|
||||||
|
* @param pTable Virtual PartitionTable of LVM device
|
||||||
* @return an initialized Partition(LV) list
|
* @return an initialized Partition(LV) list
|
||||||
*/
|
*/
|
||||||
const QList<Partition*> LvmDevice::scanPartitions(PartitionTable* pTable) const
|
const QList<Partition*> LvmDevice::scanPartitions(PartitionTable* pTable) const
|
||||||
{
|
{
|
||||||
QList<Partition*> pList;
|
QList<Partition*> pList;
|
||||||
for (const auto &lvPath : partitionNodes()) {
|
for (const auto &lvPath : partitionNodes()) {
|
||||||
pList.append(scanPartition(lvPath, pTable));
|
Partition *p = scanPartition(lvPath, pTable);
|
||||||
|
pList.append(p);
|
||||||
}
|
}
|
||||||
return pList;
|
return pList;
|
||||||
}
|
}
|
||||||
|
@ -129,7 +159,7 @@ Partition* LvmDevice::scanPartition(const QString& lvPath, PartitionTable* pTabl
|
||||||
bool mounted;
|
bool mounted;
|
||||||
|
|
||||||
// Handle LUKS partition
|
// Handle LUKS partition
|
||||||
if (fs->type() == FileSystem::Luks) {
|
if (fs->type() == FileSystem::Type::Luks) {
|
||||||
r |= PartitionRole::Luks;
|
r |= PartitionRole::Luks;
|
||||||
FS::luks* luksFs = static_cast<FS::luks*>(fs);
|
FS::luks* luksFs = static_cast<FS::luks*>(fs);
|
||||||
luksFs->initLUKS();
|
luksFs->initLUKS();
|
||||||
|
@ -141,9 +171,9 @@ Partition* LvmDevice::scanPartition(const QString& lvPath, PartitionTable* pTabl
|
||||||
mountPoint = FileSystem::detectMountPoint(fs, lvPath);
|
mountPoint = FileSystem::detectMountPoint(fs, lvPath);
|
||||||
mounted = FileSystem::detectMountStatus(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);
|
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() );
|
fs->setSectorsUsed( (storage.bytesTotal() - storage.bytesFree()) / logicalSize() );
|
||||||
}
|
}
|
||||||
else if (fs->supportGetUsed() == FileSystem::cmdSupportFileSystem)
|
else if (fs->supportGetUsed() == FileSystem::cmdSupportFileSystem)
|
||||||
|
@ -175,23 +205,26 @@ Partition* LvmDevice::scanPartition(const QString& lvPath, PartitionTable* pTabl
|
||||||
*/
|
*/
|
||||||
void LvmDevice::scanSystemLVM(QList<Device*>& devices)
|
void LvmDevice::scanSystemLVM(QList<Device*>& devices)
|
||||||
{
|
{
|
||||||
|
LvmDevice::s_OrphanPVs.clear();
|
||||||
|
|
||||||
QList<LvmDevice*> lvmList;
|
QList<LvmDevice*> lvmList;
|
||||||
for (const auto &vgName : getVGs()) {
|
for (const auto &vgName : getVGs()) {
|
||||||
lvmList.append(new LvmDevice(vgName));
|
lvmList.append(new LvmDevice(vgName));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some LVM operations require additional information about LVM physical volumes which we store in LVM::pvList
|
// Some LVM operations require additional information about LVM physical volumes which we store in LVM::pvList::list()
|
||||||
LVM::pvList = FS::lvm2_pv::getPVs(devices);
|
LVM::pvList::list().clear();
|
||||||
|
LVM::pvList::list().append(FS::lvm2_pv::getPVs(devices));
|
||||||
|
|
||||||
// Look for LVM physical volumes in LVM VGs
|
// Look for LVM physical volumes in LVM VGs
|
||||||
for (const auto &d : lvmList) {
|
for (const auto &d : lvmList) {
|
||||||
devices.append(d);
|
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
|
// Inform LvmDevice about which physical volumes form that particular LvmDevice
|
||||||
for (const auto &d : lvmList)
|
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())
|
if (p.vgName() == d->name())
|
||||||
d->physicalVolumes().append(p.partition());
|
d->physicalVolumes().append(p.partition());
|
||||||
|
|
||||||
|
@ -225,9 +258,9 @@ const QStringList LvmDevice::deviceNodes() const
|
||||||
return pvList;
|
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
|
qint64 LvmDevice::partitionSize(QString& partitionPath) const
|
||||||
|
@ -240,7 +273,7 @@ const QStringList LvmDevice::getVGs()
|
||||||
QStringList vgList;
|
QStringList vgList;
|
||||||
QString output = getField(QStringLiteral("vg_name"));
|
QString output = getField(QStringLiteral("vg_name"));
|
||||||
if (!output.isEmpty()) {
|
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) {
|
for (const auto &vgName : vgNameList) {
|
||||||
vgList.append(vgName.trimmed());
|
vgList.append(vgName.trimmed());
|
||||||
}
|
}
|
||||||
|
@ -254,7 +287,7 @@ const QStringList LvmDevice::getLVs(const QString& vgName)
|
||||||
QString cmdOutput = getField(QStringLiteral("lv_path"), vgName);
|
QString cmdOutput = getField(QStringLiteral("lv_path"), vgName);
|
||||||
|
|
||||||
if (cmdOutput.size()) {
|
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) {
|
for (const auto &lvPath : tempPathList) {
|
||||||
lvPathList.append(lvPath.trimmed());
|
lvPathList.append(lvPath.trimmed());
|
||||||
}
|
}
|
||||||
|
@ -333,6 +366,7 @@ qint64 LvmDevice::getTotalLE(const QString& lvPath)
|
||||||
return match.captured(1).toInt();
|
return match.captured(1).toInt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Log(Log::Level::error) << xi18nc("@info:status", "An error occurred while running lvdisplay.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,8 +453,7 @@ bool LvmDevice::movePV(Report& report, const QString& pvPath, const QStringList&
|
||||||
if (FS::lvm2_pv::getAllocatedPE(pvPath) <= 0)
|
if (FS::lvm2_pv::getAllocatedPE(pvPath) <= 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
QStringList args = QStringList();
|
QStringList args = { QStringLiteral("pvmove") };
|
||||||
args << QStringLiteral("pvmove");
|
|
||||||
args << pvPath;
|
args << pvPath;
|
||||||
if (!destinations.isEmpty())
|
if (!destinations.isEmpty())
|
||||||
for (const auto &destPath : destinations)
|
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)
|
bool LvmDevice::createVG(Report& report, const QString vgName, const QVector<const Partition*>& pvList, const qint32 peSize)
|
||||||
{
|
{
|
||||||
QStringList args = QStringList();
|
QStringList args = { QStringLiteral("vgcreate"), QStringLiteral("--physicalextentsize"), QString::number(peSize) };
|
||||||
args << QStringLiteral("vgcreate") << QStringLiteral("--physicalextentsize") << QString::number(peSize);
|
|
||||||
args << vgName;
|
args << vgName;
|
||||||
for (const auto &p : pvList) {
|
for (const auto &p : pvList) {
|
||||||
if (p->roles().has(PartitionRole::Luks))
|
if (p->roles().has(PartitionRole::Luks))
|
||||||
|
@ -492,3 +524,43 @@ bool LvmDevice::activateLV(const QString& lvPath)
|
||||||
lvPath });
|
lvPath });
|
||||||
return deactivate.run(-1) && deactivate.exitCode() == 0;
|
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/>.*
|
* 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
|
#define KPMCORE_LVMDEVICE_H
|
||||||
|
|
||||||
#include "core/device.h"
|
#include "core/device.h"
|
||||||
|
@ -52,12 +51,12 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const QStringList deviceNodes() const override;
|
const QStringList deviceNodes() const override;
|
||||||
const QStringList partitionNodes() const override;
|
const QStringList& partitionNodes() const override;
|
||||||
qint64 partitionSize(QString& partitionPath) const override;
|
qint64 partitionSize(QString& partitionPath) const override;
|
||||||
|
|
||||||
static QVector<const Partition*> s_DirtyPVs;
|
static QVector<const Partition*> s_DirtyPVs;
|
||||||
|
static QVector<const Partition*> s_OrphanPVs;
|
||||||
|
|
||||||
public:
|
|
||||||
static void scanSystemLVM(QList<Device*>& devices);
|
static void scanSystemLVM(QList<Device*>& devices);
|
||||||
|
|
||||||
static const QStringList getVGs();
|
static const QStringList getVGs();
|
||||||
|
@ -89,54 +88,22 @@ public:
|
||||||
static bool activateVG(Report& report, const LvmDevice& d);
|
static bool activateVG(Report& report, const LvmDevice& d);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void initPartitions() override;
|
void initPartitions() override;
|
||||||
const QList<Partition*> scanPartitions(PartitionTable* pTable) const;
|
const QList<Partition*> scanPartitions(PartitionTable* pTable) const;
|
||||||
Partition* scanPartition(const QString& lvPath, PartitionTable* pTable) const;
|
Partition* scanPartition(const QString& lvPath, PartitionTable* pTable) const;
|
||||||
qint64 mappedSector(const QString& lvPath, qint64 sector) const override;
|
qint64 mappedSector(const QString& lvPath, qint64 sector) const override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
qint64 peSize() const {
|
qint64 peSize() const;
|
||||||
return m_peSize;
|
qint64 totalPE() const;
|
||||||
}
|
qint64 allocatedPE() const;
|
||||||
qint64 totalPE() const {
|
qint64 freePE() const;
|
||||||
return m_totalPE;
|
QString UUID() const;
|
||||||
}
|
QVector <const Partition*>& physicalVolumes();
|
||||||
qint64 allocatedPE() const {
|
const QVector <const Partition*>& physicalVolumes() 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QHash<QString, qint64>* LVSizeMap() const {
|
std::unique_ptr<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;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -25,9 +25,6 @@
|
||||||
#include <QDBusReply>
|
#include <QDBusReply>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
|
|
||||||
#include <pwd.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
/** Constructs an OperationRunner.
|
/** Constructs an OperationRunner.
|
||||||
@param ostack the OperationStack to act on
|
@param ostack the OperationStack to act on
|
||||||
*/
|
*/
|
||||||
|
@ -50,15 +47,6 @@ void OperationRunner::run()
|
||||||
bool status = true;
|
bool status = true;
|
||||||
|
|
||||||
// Disable Plasma removable device automounting
|
// 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;
|
QStringList modules;
|
||||||
QDBusConnection bus = QDBusConnection::connectToBus(QDBusConnection::SessionBus, QStringLiteral("sessionBus"));
|
QDBusConnection bus = QDBusConnection::connectToBus(QDBusConnection::SessionBus, QStringLiteral("sessionBus"));
|
||||||
QDBusInterface kdedInterface( QStringLiteral("org.kde.kded5"), QStringLiteral("/kded"), QStringLiteral("org.kde.kded5"), bus );
|
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);
|
bool automounter = modules.contains(automounterService);
|
||||||
if (automounter)
|
if (automounter)
|
||||||
kdedInterface.call( QStringLiteral("unloadModule"), automounterService );
|
kdedInterface.call( QStringLiteral("unloadModule"), automounterService );
|
||||||
seteuid(currentUid);
|
|
||||||
|
|
||||||
for (int i = 0; i < numOperations(); i++) {
|
for (int i = 0; i < numOperations(); i++) {
|
||||||
suspendMutex().lock();
|
suspendMutex().lock();
|
||||||
|
|
|
@ -555,7 +555,7 @@ void OperationStack::addDevice(Device* d)
|
||||||
static bool deviceLessThan(const Device* d1, const Device* d2)
|
static bool deviceLessThan(const Device* d1, const Device* d2)
|
||||||
{
|
{
|
||||||
// Display alphabetically sorted disk devices above LVM VGs
|
// 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 false;
|
||||||
|
|
||||||
return d1->deviceNode() <= d2->deviceNode();
|
return d1->deviceNode() <= d2->deviceNode();
|
||||||
|
|
|
@ -80,10 +80,10 @@ public:
|
||||||
New, /**< from a NewOperation */
|
New, /**< from a NewOperation */
|
||||||
Copy, /**< from a CopyOperation */
|
Copy, /**< from a CopyOperation */
|
||||||
Restore, /**< from a RestoreOperation */
|
Restore, /**< from a RestoreOperation */
|
||||||
StateNone = None,
|
StateNone __attribute__((deprecated("Use Partition::State::None"))) = None,
|
||||||
StateNew = New,
|
StateNew __attribute__((deprecated("Use Partition::State::New"))) = New,
|
||||||
StateCopy = Copy,
|
StateCopy __attribute__((deprecated("Use Partition::State::Copy"))) = Copy,
|
||||||
StateRestore = Restore
|
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);
|
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)
|
bool PartitionAlignment::isAligned(const Device& d, const Partition& p, qint64 newFirst, qint64 newLast, bool quiet)
|
||||||
{
|
{
|
||||||
if (firstDelta(d, p, newFirst) && !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)
|
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;
|
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)
|
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);
|
const DiskDevice& device = dynamic_cast<const DiskDevice&>(d);
|
||||||
if (!parent.isRoot()) {
|
if (!parent.isRoot()) {
|
||||||
Partition* extended = dynamic_cast<Partition*>(&parent);
|
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);
|
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) {
|
if (end - start + 1 > 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -319,13 +319,13 @@ Partition* createUnallocated(const Device& device, PartitionNode& parent, qint64
|
||||||
r |= PartitionRole::Logical;
|
r |= PartitionRole::Logical;
|
||||||
|
|
||||||
// Mark unallocated space in LVM VG as LVM LV so that pasting can be easily disabled (it does not work yet)
|
// 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;
|
r |= PartitionRole::Lvm_Lv;
|
||||||
|
|
||||||
if (!PartitionTable::getUnallocatedRange(device, parent, start, end))
|
if (!PartitionTable::getUnallocatedRange(device, parent, start, end))
|
||||||
return nullptr;
|
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
|
/** Removes all unallocated children from a PartitionNode
|
||||||
|
@ -379,7 +379,7 @@ void PartitionTable::insertUnallocated(const Device& d, PartitionNode* p, qint64
|
||||||
|
|
||||||
qint64 lastEnd = start;
|
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
|
// rearranging the sectors of all partitions to keep unallocated space at the end
|
||||||
lastEnd = 0;
|
lastEnd = 0;
|
||||||
std::sort(children().begin(), children().end(), [](const Partition* p1, const Partition* p2) { return p1->deviceNode() < p2->deviceNode(); });
|
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
|
// Take care of the free space between the end of the last child and the end
|
||||||
// of the device or the extended partition.
|
// of the device or the extended partition.
|
||||||
qint64 parentEnd = lastUsable();
|
qint64 parentEnd = lastUsable();
|
||||||
|
@ -415,6 +422,7 @@ void PartitionTable::insertUnallocated(const Device& d, PartitionNode* p, qint64
|
||||||
if (parentEnd >= firstUsable() && parentEnd >= lastEnd)
|
if (parentEnd >= firstUsable() && parentEnd >= lastEnd)
|
||||||
p->insert(createUnallocated(d, *p, lastEnd, parentEnd));
|
p->insert(createUnallocated(d, *p, lastEnd, parentEnd));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Updates the unallocated Partitions for this PartitionTable.
|
/** Updates the unallocated Partitions for this PartitionTable.
|
||||||
@param d the Device this PartitionTable is on
|
@param d the Device this PartitionTable is on
|
||||||
|
@ -428,7 +436,7 @@ void PartitionTable::updateUnallocated(const Device& d)
|
||||||
qint64 PartitionTable::defaultFirstUsable(const Device& d, TableType t)
|
qint64 PartitionTable::defaultFirstUsable(const Device& d, TableType t)
|
||||||
{
|
{
|
||||||
Q_UNUSED(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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,7 +526,7 @@ bool PartitionTable::tableTypeIsReadOnly(TableType l)
|
||||||
*/
|
*/
|
||||||
bool PartitionTable::isSectorBased(const Device& d) const
|
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);
|
const DiskDevice& diskDevice = dynamic_cast<const DiskDevice&>(d);
|
||||||
|
|
||||||
if (type() == PartitionTable::msdos) {
|
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/smartattribute.h"
|
||||||
#include "core/smartstatus.h"
|
#include "core/smartstatus.h"
|
||||||
|
#include "core/smartattributeparseddata.h"
|
||||||
|
|
||||||
#include <QLocale>
|
#include <QLocale>
|
||||||
|
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
#include <KFormat>
|
#include <KFormat>
|
||||||
|
|
||||||
#include <atasmart.h>
|
|
||||||
|
|
||||||
static QString getAttrName(qint32 id);
|
static QString getAttrName(qint32 id);
|
||||||
static QString getAttrDescription(qint32 id);
|
static QString getAttrDescription(qint32 id);
|
||||||
static QString getPrettyValue(quint64 value, qint64 unit);
|
static QString getPrettyValue(quint64 value, SmartAttributeUnit unit);
|
||||||
static SmartAttribute::Assessment getAssessment(const SkSmartAttributeParsedData* a);
|
static SmartAttribute::Assessment getAssessment(const SmartAttributeParsedData& a);
|
||||||
static QString getRaw(const uint8_t*);
|
static QString getRaw(quint64 raw);
|
||||||
|
|
||||||
SmartAttribute::SmartAttribute(const SkSmartAttributeParsedData* a) :
|
SmartAttribute::SmartAttribute(const SmartAttributeParsedData& a) :
|
||||||
m_Id(a->id),
|
m_Id(a.id()),
|
||||||
m_Name(getAttrName(a->id)),
|
m_Name(getAttrName(a.id())),
|
||||||
m_Desc(getAttrDescription(a->id)),
|
m_Desc(getAttrDescription(a.id())),
|
||||||
m_FailureType(a->prefailure ? PreFailure : OldAge),
|
m_FailureType(a.prefailure() ? FailureType::PreFailure : FailureType::OldAge),
|
||||||
m_UpdateType(a->online ? Online : Offline),
|
m_UpdateType(a.online() ? UpdateType::Online : UpdateType::Offline),
|
||||||
m_Current(a->current_value_valid ? a->current_value : -1),
|
m_Current(a.currentValueValid() ? a.currentValue() : -1),
|
||||||
m_Worst(a->worst_value_valid ? a->worst_value : -1),
|
m_Worst(a.worstValueValid() ? a.worstValue() : -1),
|
||||||
m_Threshold(a->threshold_valid ? a->threshold : -1),
|
m_Threshold(a.thresholdValid() ? a.threshold() : -1),
|
||||||
m_Raw(getRaw(a->raw)),
|
m_Raw(getRaw(a.raw())),
|
||||||
m_Assessment(getAssessment(a)),
|
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)
|
QString SmartAttribute::assessmentToString(Assessment a)
|
||||||
{
|
{
|
||||||
switch (a) {
|
switch (a) {
|
||||||
case Failing:
|
case Assessment::Failing:
|
||||||
return xi18nc("@item:intable", "failing");
|
return xi18nc("@item:intable", "failing");
|
||||||
|
|
||||||
case HasFailed:
|
case Assessment::HasFailed:
|
||||||
return xi18nc("@item:intable", "has failed");
|
return xi18nc("@item:intable", "has failed");
|
||||||
|
|
||||||
case Warning:
|
case Assessment::Warning:
|
||||||
return xi18nc("@item:intable", "warning");
|
return xi18nc("@item:intable", "warning");
|
||||||
|
|
||||||
case Good:
|
case Assessment::Good:
|
||||||
return xi18nc("@item:intable", "good");
|
return xi18nc("@item:intable", "good");
|
||||||
|
|
||||||
case NotApplicable:
|
case Assessment::NotApplicable:
|
||||||
default:
|
default:
|
||||||
return xi18nc("@item:intable not applicable", "N/A");
|
return xi18nc("@item:intable not applicable", "N/A");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString getPrettyValue(quint64 value, qint64 unit)
|
static QString getPrettyValue(quint64 value, SmartAttributeUnit unit)
|
||||||
{
|
{
|
||||||
QString rval;
|
QString rval;
|
||||||
|
|
||||||
switch (unit) {
|
switch (unit) {
|
||||||
case SK_SMART_ATTRIBUTE_UNIT_MSECONDS:
|
case SmartAttributeUnit::Miliseconds:
|
||||||
rval = KFormat().formatDuration(value);
|
rval = KFormat().formatDuration(value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SK_SMART_ATTRIBUTE_UNIT_SECTORS:
|
case SmartAttributeUnit::Sectors:
|
||||||
rval = xi18ncp("@item:intable", "%1 sector", "%1 sectors", value);
|
rval = xi18ncp("@item:intable", "%1 sector", "%1 sectors", value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SK_SMART_ATTRIBUTE_UNIT_MKELVIN:
|
case SmartAttributeUnit::Milikelvin:
|
||||||
rval = SmartStatus::tempToString(value);
|
rval = SmartStatus::tempToString(value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SK_SMART_ATTRIBUTE_UNIT_NONE:
|
case SmartAttributeUnit::None:
|
||||||
rval = QLocale().toString(value);
|
rval = QLocale().toString(value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SK_SMART_ATTRIBUTE_UNIT_UNKNOWN:
|
case SmartAttributeUnit::Unknown:
|
||||||
default:
|
default:
|
||||||
rval = xi18nc("@item:intable not applicable", "N/A");
|
rval = xi18nc("@item:intable not applicable", "N/A");
|
||||||
break;
|
break;
|
||||||
|
@ -214,43 +214,41 @@ static QString getAttrDescription(qint32 id)
|
||||||
return QString();
|
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 failed = false;
|
||||||
bool hasFailed = false;
|
bool hasFailed = false;
|
||||||
|
|
||||||
if (a->prefailure) {
|
if (a.prefailure()) {
|
||||||
if (a->good_now_valid && !a->good_now)
|
if (a.goodNowValid() && !a.goodNow())
|
||||||
failed = true;
|
failed = true;
|
||||||
|
|
||||||
if (a->good_in_the_past_valid && !a->good_in_the_past)
|
if (a.goodInThePastValid() && !a.goodInThePast())
|
||||||
hasFailed = true;
|
hasFailed = true;
|
||||||
} else if (a->threshold_valid) {
|
} else if (a.thresholdValid()) {
|
||||||
if (a->current_value_valid && a->current_value <= a->threshold)
|
if (a.currentValueValid() && a.currentValue() <= a.threshold())
|
||||||
failed = true;
|
failed = true;
|
||||||
else if (a->worst_value_valid && a->worst_value <= a->threshold)
|
else if (a.worstValueValid() && a.worstValue() <= a.threshold())
|
||||||
hasFailed = true;
|
hasFailed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (failed)
|
if (failed)
|
||||||
rval = SmartAttribute::Failing;
|
rval = SmartAttribute::Assessment::Failing;
|
||||||
else if (hasFailed)
|
else if (hasFailed)
|
||||||
rval = SmartAttribute::HasFailed;
|
rval = SmartAttribute::Assessment::HasFailed;
|
||||||
else if (a->warn)
|
else if (a.warn())
|
||||||
rval = SmartAttribute::Warning;
|
rval = SmartAttribute::Assessment::Warning;
|
||||||
else if (a->good_now_valid)
|
else if (a.goodNowValid())
|
||||||
rval = SmartAttribute::Good;
|
rval = SmartAttribute::Assessment::Good;
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString getRaw(const uint8_t* raw)
|
static QString getRaw(quint64 raw)
|
||||||
{
|
{
|
||||||
QString rval = QStringLiteral("0x");
|
QString rval = QStringLiteral("0x");
|
||||||
for (qint32 i = 5; i >= 0; i--)
|
rval += QStringLiteral("%1").arg(raw, 12, 16, QLatin1Char('0'));
|
||||||
rval += QStringLiteral("%1").arg(raw[i], 2, 16, QLatin1Char('0'));
|
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,30 +15,29 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
* 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
|
#define KPMCORE_SMARTATTRIBUTE_H
|
||||||
|
|
||||||
#include "util/libpartitionmanagerexport.h"
|
#include "util/libpartitionmanagerexport.h"
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
struct SkSmartAttributeParsedData;
|
class SmartAttributeParsedData;
|
||||||
|
|
||||||
class LIBKPMCORE_EXPORT SmartAttribute
|
class LIBKPMCORE_EXPORT SmartAttribute
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum FailureType {
|
enum class FailureType {
|
||||||
PreFailure,
|
PreFailure,
|
||||||
OldAge
|
OldAge
|
||||||
};
|
};
|
||||||
|
|
||||||
enum UpdateType {
|
enum class UpdateType {
|
||||||
Online,
|
Online,
|
||||||
Offline
|
Offline
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Assessment {
|
enum class Assessment {
|
||||||
NotApplicable,
|
NotApplicable,
|
||||||
Failing,
|
Failing,
|
||||||
HasFailed,
|
HasFailed,
|
||||||
|
@ -47,7 +46,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SmartAttribute(const SkSmartAttributeParsedData* a);
|
SmartAttribute(const SmartAttributeParsedData& a);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
qint32 id() const {
|
qint32 id() const {
|
||||||
|
@ -104,4 +103,3 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#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 *
|
* This program is free software; you can redistribute it and/or *
|
||||||
* modify it under the terms of the GNU General Public License as *
|
* 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/>.*
|
* 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;
|
@author Caio Carvalho <caiojcarvalho@gmail.com>
|
||||||
class PartitionTable;
|
*/
|
||||||
class Report;
|
class SmartParser
|
||||||
class CoreBackendPartitionTable;
|
|
||||||
|
|
||||||
class LibPartedDevice : public CoreBackendDevice
|
|
||||||
{
|
{
|
||||||
Q_DISABLE_COPY(LibPartedDevice)
|
public:
|
||||||
|
SmartParser(const QString &device_path);
|
||||||
|
~SmartParser();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LibPartedDevice(const QString& deviceNode);
|
bool init();
|
||||||
~LibPartedDevice();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool open() override;
|
const QString &devicePath() const
|
||||||
bool openExclusive() override;
|
{
|
||||||
bool close() override;
|
return m_DevicePath; /**< @return the device path that SMART must analyse */
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SmartDiskInformation *diskInformation() const
|
||||||
|
{
|
||||||
|
return m_DiskInformation; /**< @return a reference to parsed disk information */
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void loadSmartOutput();
|
||||||
|
|
||||||
|
void loadAttributes();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PedDevice* m_PedDevice;
|
const QString m_DevicePath;
|
||||||
|
QJsonDocument m_SmartOutput;
|
||||||
|
SmartDiskInformation *m_DiskInformation;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif // SMARTPARSER_H
|
|
@ -18,13 +18,16 @@
|
||||||
|
|
||||||
#include "core/smartstatus.h"
|
#include "core/smartstatus.h"
|
||||||
|
|
||||||
|
#include "core/smartparser.h"
|
||||||
|
#include "core/smartdiskinformation.h"
|
||||||
|
#include "core/smartattributeparseddata.h"
|
||||||
|
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
#include <atasmart.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
SmartStatus::SmartStatus(const QString &device_path) :
|
SmartStatus::SmartStatus(const QString &device_path) :
|
||||||
|
@ -34,8 +37,8 @@ SmartStatus::SmartStatus(const QString& device_path) :
|
||||||
m_ModelName(),
|
m_ModelName(),
|
||||||
m_Serial(),
|
m_Serial(),
|
||||||
m_Firmware(),
|
m_Firmware(),
|
||||||
m_Overall(Bad),
|
m_Overall(Overall::Bad),
|
||||||
m_SelfTestStatus(Success),
|
m_SelfTestStatus(SelfTestStatus::Success),
|
||||||
m_Temp(0),
|
m_Temp(0),
|
||||||
m_BadSectors(0),
|
m_BadSectors(0),
|
||||||
m_PowerCycles(0),
|
m_PowerCycles(0),
|
||||||
|
@ -46,148 +49,31 @@ SmartStatus::SmartStatus(const QString& device_path) :
|
||||||
|
|
||||||
void SmartStatus::update()
|
void SmartStatus::update()
|
||||||
{
|
{
|
||||||
SkDisk* skDisk = nullptr;
|
SmartParser parser(devicePath());
|
||||||
SkBool skSmartStatus = false;
|
|
||||||
uint64_t mkelvin = 0;
|
|
||||||
uint64_t skBadSectors = 0;
|
|
||||||
uint64_t skPoweredOn = 0;
|
|
||||||
uint64_t skPowerCycles = 0;
|
|
||||||
|
|
||||||
if (sk_disk_open(devicePath().toLocal8Bit().constData(), &skDisk) < 0) {
|
if (!parser.init()) {
|
||||||
qDebug() << "smart disk open failed for " << devicePath() << ": " << strerror(errno);
|
qDebug() << "error during smart output parsing for " << devicePath() << ": " << strerror(errno);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sk_disk_smart_status(skDisk, &skSmartStatus) < 0) {
|
SmartDiskInformation *disk;
|
||||||
qDebug() << "getting smart status failed for " << devicePath() << ": " << strerror(errno);
|
|
||||||
sk_disk_free(skDisk);
|
disk = parser.diskInformation();
|
||||||
|
|
||||||
|
if (!disk)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
setStatus(skSmartStatus);
|
setStatus(disk->smartStatus());
|
||||||
|
setModelName(disk->model());
|
||||||
if (sk_disk_smart_read_data(skDisk) < 0) {
|
setFirmware(disk->firmware());
|
||||||
qDebug() << "reading smart data failed for " << devicePath() << ": " << strerror(errno);
|
setSerial(disk->serial());
|
||||||
sk_disk_free(skDisk);
|
setSelfTestStatus(disk->selfTestExecutionStatus());
|
||||||
return;
|
setOverall(disk->overall());
|
||||||
}
|
setTemp(disk->temperature());
|
||||||
|
setBadSectors(disk->badSectors());
|
||||||
const SkIdentifyParsedData* skIdentify;
|
setPoweredOn(disk->poweredOn());
|
||||||
|
setPowerCycles(disk->powerCycles());
|
||||||
if (sk_disk_identify_parse(skDisk, &skIdentify) < 0)
|
addAttributes(disk->attributes());
|
||||||
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);
|
|
||||||
setInitSuccess(true);
|
setInitSuccess(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,40 +81,41 @@ QString SmartStatus::tempToString(quint64 mkelvin)
|
||||||
{
|
{
|
||||||
const double celsius = (mkelvin - 273150.0) / 1000.0;
|
const double celsius = (mkelvin - 273150.0) / 1000.0;
|
||||||
const double fahrenheit = 9.0 * celsius / 5.0 + 32;
|
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)
|
QString SmartStatus::selfTestStatusToString(SmartStatus::SelfTestStatus s)
|
||||||
{
|
{
|
||||||
switch (s) {
|
switch (s) {
|
||||||
case Aborted:
|
case SelfTestStatus::Aborted:
|
||||||
return xi18nc("@item", "Aborted");
|
return xi18nc("@item", "Aborted");
|
||||||
|
|
||||||
case Interrupted:
|
case SelfTestStatus::Interrupted:
|
||||||
return xi18nc("@item", "Interrupted");
|
return xi18nc("@item", "Interrupted");
|
||||||
|
|
||||||
case Fatal:
|
case SelfTestStatus::Fatal:
|
||||||
return xi18nc("@item", "Fatal error");
|
return xi18nc("@item", "Fatal error");
|
||||||
|
|
||||||
case ErrorUnknown:
|
case SelfTestStatus::ErrorUnknown:
|
||||||
return xi18nc("@item", "Unknown error");
|
return xi18nc("@item", "Unknown error");
|
||||||
|
|
||||||
case ErrorEletrical:
|
case SelfTestStatus::ErrorEletrical:
|
||||||
return xi18nc("@item", "Electrical error");
|
return xi18nc("@item", "Electrical error");
|
||||||
|
|
||||||
case ErrorServo:
|
case SelfTestStatus::ErrorServo:
|
||||||
return xi18nc("@item", "Servo error");
|
return xi18nc("@item", "Servo error");
|
||||||
|
|
||||||
case ErrorRead:
|
case SelfTestStatus::ErrorRead:
|
||||||
return xi18nc("@item", "Read error");
|
return xi18nc("@item", "Read error");
|
||||||
|
|
||||||
case ErrorHandling:
|
case SelfTestStatus::ErrorHandling:
|
||||||
return xi18nc("@item", "Handling error");
|
return xi18nc("@item", "Handling error");
|
||||||
|
|
||||||
case InProgress:
|
case SelfTestStatus::InProgress:
|
||||||
return xi18nc("@item", "Self test in progress");
|
return xi18nc("@item", "Self test in progress");
|
||||||
|
|
||||||
case Success:
|
case SelfTestStatus::Success:
|
||||||
default:
|
default:
|
||||||
return xi18nc("@item", "Success");
|
return xi18nc("@item", "Success");
|
||||||
}
|
}
|
||||||
|
@ -238,33 +125,35 @@ QString SmartStatus::selfTestStatusToString(SmartStatus::SelfTestStatus s)
|
||||||
QString SmartStatus::overallAssessmentToString(Overall o)
|
QString SmartStatus::overallAssessmentToString(Overall o)
|
||||||
{
|
{
|
||||||
switch (o) {
|
switch (o) {
|
||||||
case Good:
|
case Overall::Good:
|
||||||
return xi18nc("@item", "Healthy");
|
return xi18nc("@item", "Healthy");
|
||||||
|
|
||||||
case BadPast:
|
case Overall::BadPast:
|
||||||
return xi18nc("@item", "Has been used outside of its design parameters in the past.");
|
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.");
|
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.");
|
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.");
|
return xi18nc("@item", "Has many bad sectors.");
|
||||||
|
|
||||||
case Bad:
|
case Overall::Bad:
|
||||||
default:
|
default:
|
||||||
return xi18nc("@item", "Disk failure is imminent. Backup all data!");
|
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);
|
for (const SmartAttributeParsedData &at : qAsConst(attr)) {
|
||||||
self->m_Attributes.append(sm);
|
SmartAttribute sm(at);
|
||||||
|
m_Attributes.append(sm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
* 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
|
#define KPMCORE_SMARTSTATUS_H
|
||||||
|
|
||||||
#include "util/libpartitionmanagerexport.h"
|
#include "util/libpartitionmanagerexport.h"
|
||||||
|
@ -32,7 +31,7 @@ struct SkDisk;
|
||||||
class LIBKPMCORE_EXPORT SmartStatus
|
class LIBKPMCORE_EXPORT SmartStatus
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Overall {
|
enum class Overall {
|
||||||
Good,
|
Good,
|
||||||
BadPast,
|
BadPast,
|
||||||
BadSectors,
|
BadSectors,
|
||||||
|
@ -41,7 +40,7 @@ public:
|
||||||
Bad
|
Bad
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SelfTestStatus {
|
enum class SelfTestStatus {
|
||||||
Success,
|
Success,
|
||||||
Aborted,
|
Aborted,
|
||||||
Interrupted,
|
Interrupted,
|
||||||
|
@ -51,7 +50,7 @@ public:
|
||||||
ErrorServo,
|
ErrorServo,
|
||||||
ErrorRead,
|
ErrorRead,
|
||||||
ErrorHandling,
|
ErrorHandling,
|
||||||
InProgress
|
InProgress = 15,
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -63,87 +62,111 @@ public:
|
||||||
public:
|
public:
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
const QString& devicePath() const {
|
const QString &devicePath() const
|
||||||
|
{
|
||||||
return m_DevicePath;
|
return m_DevicePath;
|
||||||
}
|
}
|
||||||
bool isValid() const {
|
bool isValid() const
|
||||||
|
{
|
||||||
return m_InitSuccess;
|
return m_InitSuccess;
|
||||||
}
|
}
|
||||||
bool status() const {
|
bool status() const
|
||||||
|
{
|
||||||
return m_Status;
|
return m_Status;
|
||||||
}
|
}
|
||||||
const QString& modelName() const {
|
const QString &modelName() const
|
||||||
|
{
|
||||||
return m_ModelName;
|
return m_ModelName;
|
||||||
}
|
}
|
||||||
const QString& serial() const {
|
const QString &serial() const
|
||||||
|
{
|
||||||
return m_Serial;
|
return m_Serial;
|
||||||
}
|
}
|
||||||
const QString& firmware() const {
|
const QString &firmware() const
|
||||||
|
{
|
||||||
return m_Firmware;
|
return m_Firmware;
|
||||||
}
|
}
|
||||||
quint64 temp() const {
|
quint64 temp() const
|
||||||
|
{
|
||||||
return m_Temp;
|
return m_Temp;
|
||||||
}
|
}
|
||||||
quint64 badSectors() const {
|
quint64 badSectors() const
|
||||||
|
{
|
||||||
return m_BadSectors;
|
return m_BadSectors;
|
||||||
}
|
}
|
||||||
quint64 powerCycles() const {
|
quint64 powerCycles() const
|
||||||
|
{
|
||||||
return m_PowerCycles;
|
return m_PowerCycles;
|
||||||
}
|
}
|
||||||
quint64 poweredOn() const {
|
quint64 poweredOn() const
|
||||||
|
{
|
||||||
return m_PoweredOn;
|
return m_PoweredOn;
|
||||||
}
|
}
|
||||||
const Attributes& attributes() const {
|
const Attributes &attributes() const
|
||||||
|
{
|
||||||
return m_Attributes;
|
return m_Attributes;
|
||||||
}
|
}
|
||||||
Overall overall() const {
|
Overall overall() const
|
||||||
|
{
|
||||||
return m_Overall;
|
return m_Overall;
|
||||||
}
|
}
|
||||||
SelfTestStatus selfTestStatus() const {
|
SelfTestStatus selfTestStatus() const
|
||||||
|
{
|
||||||
return m_SelfTestStatus;
|
return m_SelfTestStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addAttributes(QList<SmartAttributeParsedData> attr);
|
||||||
|
|
||||||
static QString tempToString(quint64 mkelvin);
|
static QString tempToString(quint64 mkelvin);
|
||||||
static QString overallAssessmentToString(Overall o);
|
static QString overallAssessmentToString(Overall o);
|
||||||
static QString selfTestStatusToString(SmartStatus::SelfTestStatus s);
|
static QString selfTestStatusToString(SmartStatus::SelfTestStatus s);
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
void setStatus(bool s) {
|
void setStatus(bool s)
|
||||||
|
{
|
||||||
m_Status = s;
|
m_Status = s;
|
||||||
}
|
}
|
||||||
void setModelName(const QString& name) {
|
void setModelName(const QString &name)
|
||||||
|
{
|
||||||
m_ModelName = name;
|
m_ModelName = name;
|
||||||
}
|
}
|
||||||
void setSerial(const QString& s) {
|
void setSerial(const QString &s)
|
||||||
|
{
|
||||||
m_Serial = s;
|
m_Serial = s;
|
||||||
}
|
}
|
||||||
void setFirmware(const QString& f) {
|
void setFirmware(const QString &f)
|
||||||
|
{
|
||||||
m_Firmware = f;
|
m_Firmware = f;
|
||||||
}
|
}
|
||||||
void setTemp(quint64 t) {
|
void setTemp(quint64 t)
|
||||||
|
{
|
||||||
m_Temp = t;
|
m_Temp = t;
|
||||||
}
|
}
|
||||||
void setInitSuccess(bool b) {
|
void setInitSuccess(bool b)
|
||||||
|
{
|
||||||
m_InitSuccess = b;
|
m_InitSuccess = b;
|
||||||
}
|
}
|
||||||
void setBadSectors(quint64 s) {
|
void setBadSectors(quint64 s)
|
||||||
|
{
|
||||||
m_BadSectors = s;
|
m_BadSectors = s;
|
||||||
}
|
}
|
||||||
void setPowerCycles(quint64 p) {
|
void setPowerCycles(quint64 p)
|
||||||
|
{
|
||||||
m_PowerCycles = p;
|
m_PowerCycles = p;
|
||||||
}
|
}
|
||||||
void setPoweredOn(quint64 t) {
|
void setPoweredOn(quint64 t)
|
||||||
|
{
|
||||||
m_PoweredOn = t;
|
m_PoweredOn = t;
|
||||||
}
|
}
|
||||||
void setOverall(Overall o) {
|
void setOverall(Overall o)
|
||||||
|
{
|
||||||
m_Overall = o;
|
m_Overall = o;
|
||||||
}
|
}
|
||||||
void setSelfTestStatus(SelfTestStatus s) {
|
void setSelfTestStatus(SelfTestStatus s)
|
||||||
|
{
|
||||||
m_SelfTestStatus = s;
|
m_SelfTestStatus = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void callback(SkDisk* skDisk, const SkSmartAttributeParsedData* a, void* user_data);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QString m_DevicePath;
|
const QString m_DevicePath;
|
||||||
bool m_InitSuccess;
|
bool m_InitSuccess;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Copyright (C) 2016 by Chantara Tith <tith.chantara@gmail.com> *
|
* 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 *
|
* This program is free software; you can redistribute it and/or *
|
||||||
* modify it under the terms of the GNU General Public License as *
|
* 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/>.*
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
|
#include "core/device_p.h"
|
||||||
#include "core/volumemanagerdevice.h"
|
#include "core/volumemanagerdevice.h"
|
||||||
|
#include "core/volumemanagerdevice_p.h"
|
||||||
|
|
||||||
/** Constructs an abstract Volume Manager Device with an empty PartitionTable.
|
/** 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 QString& deviceNode,
|
||||||
const qint64 logicalSize,
|
const qint64 logicalExtentSize,
|
||||||
const qint64 totalLogical,
|
const qint64 totalLogical,
|
||||||
const QString& iconName,
|
const QString& iconName,
|
||||||
Device::Type type)
|
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(", "));
|
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/>.*
|
* 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
|
#define KPMCORE_VOLUMEMANAGERDEVICE_H
|
||||||
|
|
||||||
#include "util/libpartitionmanagerexport.h"
|
#include "util/libpartitionmanagerexport.h"
|
||||||
|
@ -27,6 +26,8 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
class VolumeManagerDevicePrivate;
|
||||||
|
|
||||||
/** A Volume Manager of physical devices represented as an abstract device.
|
/** A Volume Manager of physical devices represented as an abstract device.
|
||||||
*
|
*
|
||||||
* VolumeManagerDevice is an abstract device class for volume manager. e.g: LVM, SoftRAID.
|
* 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)
|
Q_DISABLE_COPY(VolumeManagerDevice)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
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);
|
||||||
VolumeManagerDevice(const QString& name, const QString& deviceNode, const qint64 logicalSize, const qint64 totalLogical, const QString& iconName = QString(), Device::Type type = Device::Unknown_Device);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return list of physical device's path that makes up volumeManagerDevice.(e.g: /dev/sda, /dev/sdb1)
|
* @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.
|
* @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.
|
* @return size of logical partition at the given path in bytes.
|
||||||
|
@ -80,9 +80,9 @@ protected:
|
||||||
|
|
||||||
public:
|
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;
|
virtual QString prettyDeviceNodeList() const;
|
||||||
|
|
||||||
|
@ -90,10 +90,7 @@ public:
|
||||||
*
|
*
|
||||||
* @param n Number of sectors.
|
* @param n Number of sectors.
|
||||||
*/
|
*/
|
||||||
void setTotalLogical(qint64 n) {
|
void setTotalLogical(qint64 n);
|
||||||
Q_ASSERT(n > 0);
|
|
||||||
m_TotalLogical = n;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#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/hpfs.cpp
|
||||||
fs/iso9660.cpp
|
fs/iso9660.cpp
|
||||||
fs/jfs.cpp
|
fs/jfs.cpp
|
||||||
|
fs/linuxraidmember.cpp
|
||||||
fs/linuxswap.cpp
|
fs/linuxswap.cpp
|
||||||
fs/luks.cpp
|
fs/luks.cpp
|
||||||
fs/luks2.cpp
|
fs/luks2.cpp
|
||||||
|
@ -51,6 +52,7 @@ set(FS_LIB_HDRS
|
||||||
fs/hpfs.h
|
fs/hpfs.h
|
||||||
fs/iso9660.h
|
fs/iso9660.h
|
||||||
fs/jfs.h
|
fs/jfs.h
|
||||||
|
fs/linuxraidmember.h
|
||||||
fs/linuxswap.h
|
fs/linuxswap.h
|
||||||
fs/luks.h
|
fs/luks.h
|
||||||
fs/luks2.h
|
fs/luks2.h
|
||||||
|
|
|
@ -44,7 +44,7 @@ FileSystem::CommandSupportType btrfs::m_UpdateUUID = FileSystem::cmdSupportNone;
|
||||||
FileSystem::CommandSupportType btrfs::m_GetUUID = FileSystem::cmdSupportNone;
|
FileSystem::CommandSupportType btrfs::m_GetUUID = FileSystem::cmdSupportNone;
|
||||||
|
|
||||||
btrfs::btrfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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
|
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
|
qint64 btrfs::maxCapacity() const
|
||||||
{
|
{
|
||||||
return Capacity::unitFactor(Capacity::Byte, Capacity::EiB);
|
return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB);
|
||||||
}
|
}
|
||||||
|
|
||||||
int btrfs::maxLabelLength() const
|
int btrfs::maxLabelLength() const
|
||||||
|
|
|
@ -39,7 +39,7 @@ FileSystem::CommandSupportType exfat::m_UpdateUUID = FileSystem::cmdSupportNone;
|
||||||
FileSystem::CommandSupportType exfat::m_GetUUID = FileSystem::cmdSupportNone;
|
FileSystem::CommandSupportType exfat::m_GetUUID = FileSystem::cmdSupportNone;
|
||||||
|
|
||||||
exfat::exfat(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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
|
qint64 exfat::maxCapacity() const
|
||||||
{
|
{
|
||||||
return Capacity::unitFactor(Capacity::Byte, Capacity::EiB);
|
return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB);
|
||||||
}
|
}
|
||||||
|
|
||||||
int exfat::maxLabelLength() const
|
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
|
bool exfat::updateUUID(Report& report, const QString& deviceNode) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(report);
|
Q_UNUSED(report)
|
||||||
Q_UNUSED(deviceNode);
|
Q_UNUSED(deviceNode)
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ FileSystem::SupportTool ext2::supportToolName() const
|
||||||
|
|
||||||
qint64 ext2::maxCapacity() 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
|
int ext2::maxLabelLength() const
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace FS
|
||||||
class LIBKPMCORE_EXPORT ext2 : public FileSystem
|
class LIBKPMCORE_EXPORT ext2 : public FileSystem
|
||||||
{
|
{
|
||||||
public:
|
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:
|
public:
|
||||||
void init() override;
|
void init() override;
|
||||||
|
|
|
@ -25,13 +25,13 @@
|
||||||
namespace FS
|
namespace FS
|
||||||
{
|
{
|
||||||
ext3::ext3(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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
|
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)
|
bool ext3::create(Report& report, const QString& deviceNode)
|
||||||
|
|
|
@ -25,13 +25,13 @@
|
||||||
namespace FS
|
namespace FS
|
||||||
{
|
{
|
||||||
ext4::ext4(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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
|
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)
|
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;
|
FileSystem::CommandSupportType extended::m_Move = FileSystem::cmdSupportCore;
|
||||||
|
|
||||||
extended::extended(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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
|
bool f2fs::oldVersion = false; // 1.8.x or older
|
||||||
|
|
||||||
f2fs::f2fs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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
|
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
|
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
|
int f2fs::maxLabelLength() const
|
||||||
|
|
|
@ -15,8 +15,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
* 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
|
#define KPMCORE_F2FS_H
|
||||||
|
|
||||||
#include "util/libpartitionmanagerexport.h"
|
#include "util/libpartitionmanagerexport.h"
|
||||||
|
|
|
@ -87,12 +87,12 @@ FileSystem::SupportTool fat12::supportToolName() const
|
||||||
|
|
||||||
qint64 fat12::minCapacity() 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
|
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
|
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") });
|
ExternalCommand cmd(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode , QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=39") });
|
||||||
|
|
||||||
if (!cmd.start())
|
cmd.write(QByteArray(uuid, sizeof(uuid)));
|
||||||
return false;
|
return cmd.start();
|
||||||
|
|
||||||
if (cmd.write(uuid, sizeof(uuid)) != sizeof(uuid))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return cmd.waitFor(-1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
* 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
|
#define KPMCORE_FAT12_H
|
||||||
|
|
||||||
#include "util/libpartitionmanagerexport.h"
|
#include "util/libpartitionmanagerexport.h"
|
||||||
|
@ -38,7 +37,7 @@ namespace FS
|
||||||
class LIBKPMCORE_EXPORT fat12 : public FileSystem
|
class LIBKPMCORE_EXPORT fat12 : public FileSystem
|
||||||
{
|
{
|
||||||
public:
|
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:
|
public:
|
||||||
void init() override;
|
void init() override;
|
||||||
|
@ -62,10 +61,10 @@ public:
|
||||||
return m_Create;
|
return m_Create;
|
||||||
}
|
}
|
||||||
CommandSupportType supportGrow() const override {
|
CommandSupportType supportGrow() const override {
|
||||||
return m_Grow;
|
return cmdSupportNone;
|
||||||
}
|
}
|
||||||
CommandSupportType supportShrink() const override {
|
CommandSupportType supportShrink() const override {
|
||||||
return m_Shrink;
|
return cmdSupportNone;
|
||||||
}
|
}
|
||||||
CommandSupportType supportMove() const override {
|
CommandSupportType supportMove() const override {
|
||||||
return m_Move;
|
return m_Move;
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
namespace FS
|
namespace FS
|
||||||
{
|
{
|
||||||
fat16::fat16(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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
|
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
|
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)
|
bool fat16::create(Report& report, const QString& deviceNode)
|
||||||
|
|
|
@ -16,8 +16,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
* 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
|
#define KPMCORE_FAT16_H
|
||||||
|
|
||||||
#include "fs/fat12.h"
|
#include "fs/fat12.h"
|
||||||
|
@ -43,6 +42,13 @@ public:
|
||||||
bool create(Report& report, const QString& deviceNode) override;
|
bool create(Report& report, const QString& deviceNode) override;
|
||||||
bool resize(Report& report, const QString& deviceNode, qint64 length) const 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 minCapacity() const override;
|
||||||
qint64 maxCapacity() const override;
|
qint64 maxCapacity() const override;
|
||||||
bool supportToolFound() const override;
|
bool supportToolFound() const override;
|
||||||
|
|
|
@ -26,18 +26,18 @@
|
||||||
namespace FS
|
namespace FS
|
||||||
{
|
{
|
||||||
fat32::fat32(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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
|
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
|
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)
|
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)
|
// 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") });
|
ExternalCommand cmd(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode, QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=67") });
|
||||||
|
|
||||||
if (!cmd.start())
|
cmd.write(QByteArray(uuid, sizeof(uuid)));
|
||||||
return false;
|
return cmd.start();
|
||||||
|
|
||||||
if (cmd.write(uuid, sizeof(uuid)) != sizeof(uuid))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return cmd.waitFor(-1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Copyright (C) 2012 by Volker Lanz <vl@fidra.de> *
|
* Copyright (C) 2012 by Volker Lanz <vl@fidra.de> *
|
||||||
* Copyright (C) 2015 by Teo Mrnjavac <teo@kde.org> *
|
* 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 *
|
* This program is free software; you can redistribute it and/or *
|
||||||
* modify it under the terms of the GNU General Public License as *
|
* modify it under the terms of the GNU General Public License as *
|
||||||
|
@ -31,10 +31,12 @@
|
||||||
|
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
|
|
||||||
|
#include <QColor>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
#include <QStandardPaths>
|
||||||
#include <QStorageInfo>
|
#include <QStorageInfo>
|
||||||
|
|
||||||
const std::array< QColor, FileSystem::__lastType > FileSystem::defaultColorCode =
|
const std::vector<QColor> FileSystem::defaultColorCode =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
QColor( 220,205,175 ), // unknown
|
QColor( 220,205,175 ), // unknown
|
||||||
|
@ -66,25 +68,40 @@ const std::array< QColor, FileSystem::__lastType > FileSystem::defaultColorCode
|
||||||
QColor( 170,120,255 ), // udf
|
QColor( 170,120,255 ), // udf
|
||||||
QColor( 177,82,69 ), // iso9660
|
QColor( 177,82,69 ), // iso9660
|
||||||
QColor( 223,39,104 ), // luks2
|
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
|
/** Creates a new FileSystem object
|
||||||
@param firstsector the first sector used by this FileSystem on the Device
|
@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 lastsector the last sector used by this FileSystem on the Device
|
||||||
@param sectorsused the number of sectors in use on the FileSystem
|
@param sectorsused the number of sectors in use on the FileSystem
|
||||||
@param l the FileSystem label
|
@param label the FileSystem label
|
||||||
@param t the FileSystem type
|
@param type the FileSystem type
|
||||||
*/
|
*/
|
||||||
FileSystem::FileSystem(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& l, FileSystem::Type t) :
|
FileSystem::FileSystem(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type type) :
|
||||||
m_Type(t),
|
d(std::make_unique<FileSystemPrivate>())
|
||||||
m_FirstSector(firstsector),
|
{
|
||||||
m_LastSector(lastsector),
|
d->m_Type = type;
|
||||||
m_SectorsUsed(sectorsused),
|
d->m_FirstSector = firstsector;
|
||||||
m_Label(l),
|
d->m_LastSector = lastsector;
|
||||||
m_UUID()
|
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)
|
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);
|
return FS::lvm2_pv::getVGName(partitionPath);
|
||||||
|
|
||||||
if (partitionPath.isEmpty()) // Happens when during initial scan LUKS is closed
|
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;
|
bool mounted = false;
|
||||||
|
|
||||||
if (fs->type() == FileSystem::Lvm2_PV) {
|
if (fs->type() == FileSystem::Type::Lvm2_PV) {
|
||||||
mounted = FS::lvm2_pv::getVGName(partitionPath) != QString();
|
mounted = FS::lvm2_pv::getVGName(partitionPath) != QString();
|
||||||
} else {
|
} else {
|
||||||
mounted = isMounted(partitionPath);
|
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 */
|
/** @return the minimum capacity valid for this FileSystem in bytes */
|
||||||
qint64 FileSystem::minCapacity() const
|
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 */
|
/** @return the maximum capacity valid for this FileSystem in bytes */
|
||||||
qint64 FileSystem::maxCapacity() const
|
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 */
|
/** @return the maximum label length valid for this FileSystem */
|
||||||
|
@ -390,6 +407,11 @@ QString FileSystem::name(const QStringList& languages) const
|
||||||
return nameForType(type(), languages);
|
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 */
|
/** @return a pointer to a QString C array with all FileSystem names */
|
||||||
static const KLocalizedString* typeNames()
|
static const KLocalizedString* typeNames()
|
||||||
{
|
{
|
||||||
|
@ -424,7 +446,8 @@ static const KLocalizedString* typeNames()
|
||||||
kxi18nc("@item filesystem name", "udf"),
|
kxi18nc("@item filesystem name", "udf"),
|
||||||
kxi18nc("@item filesystem name", "iso9660"),
|
kxi18nc("@item filesystem name", "iso9660"),
|
||||||
kxi18nc("@item filesystem name", "luks2"),
|
kxi18nc("@item filesystem name", "luks2"),
|
||||||
kxi18nc("@item filesystem name", "fat12")
|
kxi18nc("@item filesystem name", "fat12"),
|
||||||
|
kxi18nc("@item filesystem name", "linux_raid_member"),
|
||||||
};
|
};
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
@ -435,10 +458,9 @@ static const KLocalizedString* typeNames()
|
||||||
*/
|
*/
|
||||||
QString FileSystem::nameForType(FileSystem::Type t, const QStringList& languages)
|
QString FileSystem::nameForType(FileSystem::Type t, const QStringList& languages)
|
||||||
{
|
{
|
||||||
Q_ASSERT(t >= 0);
|
Q_ASSERT(t < Type::__lastType);
|
||||||
Q_ASSERT(t < __lastType);
|
|
||||||
|
|
||||||
return typeNames()[t].toString(languages);
|
return typeNames()[static_cast<int>(t)].toString(languages);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param s the name to get the type for
|
/** @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 )
|
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)
|
if (typeNames()[i].toString(languages) == s)
|
||||||
return static_cast<FileSystem::Type>(i);
|
return static_cast<FileSystem::Type>(i);
|
||||||
|
|
||||||
return Unknown;
|
return Type::Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return a QList of all known types */
|
/** @return a QList of all known types */
|
||||||
|
@ -458,8 +480,8 @@ QList<FileSystem::Type> FileSystem::types()
|
||||||
{
|
{
|
||||||
QList<FileSystem::Type> result;
|
QList<FileSystem::Type> result;
|
||||||
|
|
||||||
int i = Ext2; // first "real" filesystem
|
int i = static_cast<int>(Type::Ext2); // first "real" filesystem
|
||||||
while (i != __lastType)
|
while (i != static_cast<int>(Type::__lastType))
|
||||||
result.append(static_cast<FileSystem::Type>(i++));
|
result.append(static_cast<FileSystem::Type>(i++));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -529,9 +551,25 @@ bool FileSystem::unmount(Report& report, const QString& deviceNode)
|
||||||
return false;
|
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)
|
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())
|
if (!cmd.run())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -547,3 +585,53 @@ FileSystem::SupportTool FileSystem::supportToolName() const
|
||||||
{
|
{
|
||||||
return SupportTool();
|
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) 2012 by Volker Lanz <vl@fidra.de> *
|
||||||
* Copyright (C) 2015 by Teo Mrnjavac <teo@kde.org> *
|
* 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 *
|
* This program is free software; you can redistribute it and/or *
|
||||||
* modify it under the terms of the GNU General Public License as *
|
* 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/>.*
|
* 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
|
#define KPMCORE_FILESYSTEM_H
|
||||||
|
|
||||||
#include "util/libpartitionmanagerexport.h"
|
#include "util/libpartitionmanagerexport.h"
|
||||||
|
|
||||||
#include <QColor>
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
#include <array>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class QColor;
|
||||||
class QValidator;
|
class QValidator;
|
||||||
class Device;
|
class Device;
|
||||||
class Report;
|
class Report;
|
||||||
|
struct FileSystemPrivate;
|
||||||
|
|
||||||
/** Base class for all FileSystems.
|
/** Base class for all FileSystems.
|
||||||
|
|
||||||
|
@ -57,40 +59,41 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Supported FileSystem types */
|
/** Supported FileSystem types */
|
||||||
enum Type {
|
enum Type : int {
|
||||||
Unknown = 0,
|
Unknown,
|
||||||
Extended = 1,
|
Extended,
|
||||||
|
|
||||||
Ext2 = 2,
|
Ext2,
|
||||||
Ext3 = 3,
|
Ext3,
|
||||||
Ext4 = 4,
|
Ext4,
|
||||||
LinuxSwap = 5,
|
LinuxSwap,
|
||||||
Fat16 = 6,
|
Fat16,
|
||||||
Fat32 = 7,
|
Fat32,
|
||||||
Ntfs = 8,
|
Ntfs,
|
||||||
ReiserFS = 9,
|
ReiserFS,
|
||||||
Reiser4 = 10,
|
Reiser4,
|
||||||
Xfs = 11,
|
Xfs,
|
||||||
Jfs = 12,
|
Jfs,
|
||||||
Hfs = 13,
|
Hfs,
|
||||||
HfsPlus = 14,
|
HfsPlus,
|
||||||
Ufs = 15,
|
Ufs,
|
||||||
Unformatted = 16,
|
Unformatted,
|
||||||
Btrfs = 17,
|
Btrfs,
|
||||||
Hpfs = 18,
|
Hpfs,
|
||||||
Luks = 19,
|
Luks,
|
||||||
Ocfs2 = 20,
|
Ocfs2,
|
||||||
Zfs = 21,
|
Zfs,
|
||||||
Exfat = 22,
|
Exfat,
|
||||||
Nilfs2 = 23,
|
Nilfs2,
|
||||||
Lvm2_PV = 24,
|
Lvm2_PV,
|
||||||
F2fs = 25,
|
F2fs,
|
||||||
Udf = 26,
|
Udf,
|
||||||
Iso9660 = 27,
|
Iso9660,
|
||||||
Luks2 = 28,
|
Luks2,
|
||||||
Fat12 = 29,
|
Fat12,
|
||||||
|
LinuxRaidMember,
|
||||||
|
|
||||||
__lastType = 30
|
__lastType
|
||||||
};
|
};
|
||||||
|
|
||||||
/** The type of support for a given FileSystem action */
|
/** The type of support for a given FileSystem action */
|
||||||
|
@ -101,15 +104,15 @@ public:
|
||||||
cmdSupportBackend = 4 /**< supported by the backend */
|
cmdSupportBackend = 4 /**< supported by the backend */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::array< QColor, __lastType > defaultColorCode;
|
static const std::vector<QColor> defaultColorCode;
|
||||||
|
|
||||||
Q_DECLARE_FLAGS(CommandSupportTypes, CommandSupportType)
|
Q_DECLARE_FLAGS(CommandSupportTypes, CommandSupportType)
|
||||||
|
|
||||||
protected:
|
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:
|
public:
|
||||||
virtual ~FileSystem() {}
|
virtual ~FileSystem();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void init() {}
|
virtual void init() {}
|
||||||
|
@ -196,9 +199,11 @@ public:
|
||||||
* @see nameForType()
|
* @see nameForType()
|
||||||
*/
|
*/
|
||||||
virtual QString name(const QStringList& languages = {}) const;
|
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
|
* 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 mount(Report& report, const QString& deviceNode, const QString& mountPoint);
|
||||||
virtual bool unmount(Report& report, const QString& deviceNode);
|
virtual bool unmount(Report& report, const QString& deviceNode);
|
||||||
|
|
||||||
qint64 firstSector() const {
|
/**< @return the FileSystem's first sector */
|
||||||
return m_FirstSector; /**< @return the FileSystem's first sector */
|
qint64 firstSector() const;
|
||||||
}
|
|
||||||
qint64 lastSector() const {
|
/**< @return the FileSystem's last sector */
|
||||||
return m_LastSector; /**< @return the FileSystem's last sector */
|
qint64 lastSector() const;
|
||||||
}
|
|
||||||
qint64 length() const {
|
qint64 length() const {
|
||||||
return lastSector() - firstSector() + 1; /**< @return the FileSystem's length */
|
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 */
|
return firstByte() + length() * sectorSize() - 1; /**< @return the FileSystem's last byte */
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFirstSector(qint64 s) {
|
/**< @param s the new first sector */
|
||||||
m_FirstSector = s; /**< @param s the new first sector */
|
void setFirstSector(qint64 s);
|
||||||
}
|
|
||||||
void setLastSector(qint64 s) {
|
/**< @param s the new last sector */
|
||||||
m_LastSector = s; /**< @param s the new last sector */
|
void setLastSector(qint64 s);
|
||||||
}
|
|
||||||
|
|
||||||
void move(qint64 newStartSector);
|
void move(qint64 newStartSector);
|
||||||
|
|
||||||
const QString& label() const {
|
/**< @return the FileSystem's label */
|
||||||
return m_Label; /**< @return the FileSystem's label */
|
const QString& label() const;
|
||||||
}
|
|
||||||
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 */
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSectorSize(qint64 s) {
|
/**< @return the sector size in the underlying Device */
|
||||||
m_SectorSize = s; /**< @param s the new value for sector size */
|
qint64 sectorSize() const;
|
||||||
}
|
|
||||||
void setSectorsUsed(qint64 s) {
|
/**< @return the sectors in use on the FileSystem */
|
||||||
m_SectorsUsed = s; /**< @param s the new value for sectors in use */
|
qint64 sectorsUsed() const;
|
||||||
}
|
|
||||||
void setLabel(const QString& s) {
|
/**< @return the FileSystem's UUID */
|
||||||
m_Label = s; /**< @param s the new label */
|
const QString& uuid() const;
|
||||||
}
|
|
||||||
void setUUID(const QString& s) {
|
/**< @param s the new value for sector size */
|
||||||
m_UUID = s; /**< @param s the new UUID */
|
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:
|
protected:
|
||||||
static bool findExternal(const QString& cmdName, const QStringList& args = QStringList(), int exptectedCode = 1);
|
static bool findExternal(const QString& cmdName, const QStringList& args = QStringList(), int exptectedCode = 1);
|
||||||
|
|
||||||
protected:
|
std::unique_ptr<FileSystemPrivate> d;
|
||||||
FileSystem::Type m_Type;
|
|
||||||
qint64 m_FirstSector;
|
|
||||||
qint64 m_LastSector;
|
|
||||||
qint64 m_SectorSize;
|
|
||||||
qint64 m_SectorsUsed;
|
|
||||||
QString m_Label;
|
|
||||||
QString m_UUID;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(FileSystem::CommandSupportTypes)
|
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/hpfs.h"
|
||||||
#include "fs/iso9660.h"
|
#include "fs/iso9660.h"
|
||||||
#include "fs/jfs.h"
|
#include "fs/jfs.h"
|
||||||
|
#include "fs/linuxraidmember.h"
|
||||||
#include "fs/linuxswap.h"
|
#include "fs/linuxswap.h"
|
||||||
#include "fs/luks.h"
|
#include "fs/luks.h"
|
||||||
#include "fs/luks2.h"
|
#include "fs/luks2.h"
|
||||||
|
@ -61,36 +62,37 @@ void FileSystemFactory::init()
|
||||||
qDeleteAll(m_FileSystems);
|
qDeleteAll(m_FileSystems);
|
||||||
m_FileSystems.clear();
|
m_FileSystems.clear();
|
||||||
|
|
||||||
m_FileSystems.insert(FileSystem::Btrfs, new FS::btrfs(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Btrfs, new FS::btrfs(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Exfat, new FS::exfat(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Exfat, new FS::exfat(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Ext2, new FS::ext2(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Ext2, new FS::ext2(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Ext3, new FS::ext3(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Ext3, new FS::ext3(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Ext4, new FS::ext4(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Ext4, new FS::ext4(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Extended, new FS::extended(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Extended, new FS::extended(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::F2fs, new FS::f2fs(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::F2fs, new FS::f2fs(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Fat12, new FS::fat12(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Fat12, new FS::fat12(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Fat16, new FS::fat16(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Fat16, new FS::fat16(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Fat32, new FS::fat32(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Fat32, new FS::fat32(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Hfs, new FS::hfs(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Hfs, new FS::hfs(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::HfsPlus, new FS::hfsplus(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::HfsPlus, new FS::hfsplus(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Hpfs, new FS::hpfs(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Hpfs, new FS::hpfs(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Iso9660, new FS::iso9660(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Iso9660, new FS::iso9660(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Jfs, new FS::jfs(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Jfs, new FS::jfs(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::LinuxSwap, new FS::linuxswap(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::LinuxRaidMember, new FS::linuxraidmember(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Luks, new FS::luks(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::LinuxSwap, new FS::linuxswap(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Luks2, new FS::luks2(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Luks, new FS::luks(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Lvm2_PV, new FS::lvm2_pv(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Luks2, new FS::luks2(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Nilfs2, new FS::nilfs2(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Lvm2_PV, new FS::lvm2_pv(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Ntfs, new FS::ntfs(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Nilfs2, new FS::nilfs2(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Ocfs2, new FS::ocfs2(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Ntfs, new FS::ntfs(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::ReiserFS, new FS::reiserfs(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Ocfs2, new FS::ocfs2(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Reiser4, new FS::reiser4(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::ReiserFS, new FS::reiserfs(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Udf, new FS::udf(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Reiser4, new FS::reiser4(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Ufs, new FS::ufs(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Udf, new FS::udf(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Unformatted, new FS::unformatted(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Ufs, new FS::ufs(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Unknown, new FS::unknown(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Unformatted, new FS::unformatted(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Xfs, new FS::xfs(-1, -1, -1, QString()));
|
m_FileSystems.insert(FileSystem::Type::Unknown, new FS::unknown(-1, -1, -1, QString()));
|
||||||
m_FileSystems.insert(FileSystem::Zfs, new FS::zfs(-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())
|
for (const auto &fs : FileSystemFactory::map())
|
||||||
fs->init();
|
fs->init();
|
||||||
|
@ -111,36 +113,37 @@ FileSystem* FileSystemFactory::create(FileSystem::Type t, qint64 firstsector, qi
|
||||||
FileSystem* fs = nullptr;
|
FileSystem* fs = nullptr;
|
||||||
|
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case FileSystem::Btrfs: fs = new FS::btrfs(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Btrfs: fs = new FS::btrfs(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Exfat: fs = new FS::exfat(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Exfat: fs = new FS::exfat(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Ext2: fs = new FS::ext2(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Ext2: fs = new FS::ext2(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Ext3: fs = new FS::ext3(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Ext3: fs = new FS::ext3(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Ext4: fs = new FS::ext4(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Ext4: fs = new FS::ext4(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Extended: fs = new FS::extended(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Extended: fs = new FS::extended(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::F2fs: fs = new FS::f2fs(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::F2fs: fs = new FS::f2fs(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Fat12: fs = new FS::fat12(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Fat12: fs = new FS::fat12(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Fat16: fs = new FS::fat16(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Fat16: fs = new FS::fat16(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Fat32: fs = new FS::fat32(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Fat32: fs = new FS::fat32(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Hfs: fs = new FS::hfs(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Hfs: fs = new FS::hfs(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::HfsPlus: fs = new FS::hfsplus(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::HfsPlus: fs = new FS::hfsplus(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Hpfs: fs = new FS::hpfs(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Hpfs: fs = new FS::hpfs(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Iso9660: fs = new FS::iso9660(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Iso9660: fs = new FS::iso9660(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Jfs: fs = new FS::jfs(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Jfs: fs = new FS::jfs(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::LinuxSwap: fs = new FS::linuxswap(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::LinuxRaidMember: fs = new FS::linuxraidmember(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Luks: fs = new FS::luks(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::LinuxSwap: fs = new FS::linuxswap(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Luks2: fs = new FS::luks2(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Luks: fs = new FS::luks(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Lvm2_PV: fs = new FS::lvm2_pv(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Luks2: fs = new FS::luks2(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Nilfs2: fs = new FS::nilfs2(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Lvm2_PV: fs = new FS::lvm2_pv(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Ntfs: fs = new FS::ntfs(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Nilfs2: fs = new FS::nilfs2(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Ocfs2: fs = new FS::ocfs2(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Ntfs: fs = new FS::ntfs(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::ReiserFS: fs = new FS::reiserfs(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Ocfs2: fs = new FS::ocfs2(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Reiser4: fs = new FS::reiser4(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::ReiserFS: fs = new FS::reiserfs(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Udf: fs = new FS::udf(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Reiser4: fs = new FS::reiser4(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Ufs: fs = new FS::ufs(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Udf: fs = new FS::udf(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Unformatted: fs = new FS::unformatted(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Ufs: fs = new FS::ufs(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Unknown: fs = new FS::unknown(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Unformatted: fs = new FS::unformatted(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Xfs: fs = new FS::xfs(firstsector, lastsector, sectorsused, label); break;
|
case FileSystem::Type::Unknown: fs = new FS::unknown(firstsector, lastsector, sectorsused, label); break;
|
||||||
case FileSystem::Zfs: fs = new FS::zfs(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;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
* 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
|
#define KPMCORE_FILESYSTEMFACTORY_H
|
||||||
|
|
||||||
#include "fs/filesystem.h"
|
#include "fs/filesystem.h"
|
||||||
|
|
|
@ -35,7 +35,7 @@ FileSystem::CommandSupportType hfs::m_Copy = FileSystem::cmdSupportNone;
|
||||||
FileSystem::CommandSupportType hfs::m_Backup = FileSystem::cmdSupportNone;
|
FileSystem::CommandSupportType hfs::m_Backup = FileSystem::cmdSupportNone;
|
||||||
|
|
||||||
hfs::hfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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
|
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
|
int hfs::maxLabelLength() const
|
||||||
|
|
|
@ -35,7 +35,7 @@ FileSystem::CommandSupportType hfsplus::m_Copy = FileSystem::cmdSupportNone;
|
||||||
FileSystem::CommandSupportType hfsplus::m_Backup = FileSystem::cmdSupportNone;
|
FileSystem::CommandSupportType hfsplus::m_Backup = FileSystem::cmdSupportNone;
|
||||||
|
|
||||||
hfsplus::hfsplus(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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
|
qint64 hfsplus::maxCapacity() const
|
||||||
{
|
{
|
||||||
return Capacity::unitFactor(Capacity::Byte, Capacity::EiB);
|
return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB);
|
||||||
}
|
}
|
||||||
|
|
||||||
int hfsplus::maxLabelLength() const
|
int hfsplus::maxLabelLength() const
|
||||||
|
|
|
@ -37,12 +37,12 @@ FileSystem::CommandSupportType hpfs::m_UpdateUUID = FileSystem::cmdSupportNone;
|
||||||
FileSystem::CommandSupportType hpfs::m_GetUUID = FileSystem::cmdSupportNone;
|
FileSystem::CommandSupportType hpfs::m_GetUUID = FileSystem::cmdSupportNone;
|
||||||
|
|
||||||
hpfs::hpfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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
|
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) :
|
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;
|
FileSystem::CommandSupportType jfs::m_SetLabel = FileSystem::cmdSupportNone;
|
||||||
|
|
||||||
jfs::jfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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
|
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
|
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
|
int jfs::maxLabelLength() const
|
||||||
|
@ -96,7 +96,7 @@ qint64 jfs::readUsedCapacity(const QString& deviceNode) const
|
||||||
{
|
{
|
||||||
ExternalCommand cmd(QStringLiteral("jfs_debugfs"), QStringList() << deviceNode);
|
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;
|
qint64 blockSize = -1;
|
||||||
QRegularExpression re(QStringLiteral("Block Size: (\\d+)"));
|
QRegularExpression re(QStringLiteral("Block Size: (\\d+)"));
|
||||||
QRegularExpressionMatch reBlockSize = re.match(cmd.output());
|
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;
|
FileSystem::CommandSupportType linuxswap::m_UpdateUUID = FileSystem::cmdSupportNone;
|
||||||
|
|
||||||
linuxswap::linuxswap(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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
|
bool linuxswap::resize(Report& report, const QString& deviceNode, qint64 length) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(length);
|
Q_UNUSED(length)
|
||||||
const QString label = readLabel(deviceNode);
|
const QString label = readLabel(deviceNode);
|
||||||
const QString uuid = readUUID(deviceNode);
|
const QString uuid = readUUID(deviceNode);
|
||||||
|
|
||||||
|
@ -145,14 +145,14 @@ QString linuxswap::unmountTitle() const
|
||||||
}
|
}
|
||||||
|
|
||||||
bool linuxswap::canMount(const QString& deviceNode, const QString& mountPoint) 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
|
// linux swap doesn't require mount point to activate
|
||||||
return mountPoint != QStringLiteral("/");
|
return mountPoint != QStringLiteral("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool linuxswap::mount(Report& report, const QString& deviceNode, const QString& mountPoint)
|
bool linuxswap::mount(Report& report, const QString& deviceNode, const QString& mountPoint)
|
||||||
{
|
{
|
||||||
Q_UNUSED(mountPoint);
|
Q_UNUSED(mountPoint)
|
||||||
ExternalCommand cmd(report, QStringLiteral("swapon"), { deviceNode });
|
ExternalCommand cmd(report, QStringLiteral("swapon"), { deviceNode });
|
||||||
return cmd.run(-1) && cmd.exitCode() == 0;
|
return cmd.run(-1) && cmd.exitCode() == 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include <QStorageInfo>
|
#include <QStorageInfo>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
#include <KPasswordDialog>
|
#include <KPasswordDialog>
|
||||||
|
@ -129,9 +130,8 @@ bool luks::create(Report& report, const QString& deviceNode)
|
||||||
QStringLiteral("--type"), QStringLiteral("luks1"),
|
QStringLiteral("--type"), QStringLiteral("luks1"),
|
||||||
QStringLiteral("luksFormat"),
|
QStringLiteral("luksFormat"),
|
||||||
deviceNode });
|
deviceNode });
|
||||||
if (!( createCmd.start(-1) &&
|
if (!( createCmd.write(m_passphrase.toLocal8Bit() + '\n') &&
|
||||||
createCmd.write(m_passphrase.toLocal8Bit() + '\n') == m_passphrase.toLocal8Bit().length() + 1 &&
|
createCmd.start(-1) && createCmd.exitCode() == 0))
|
||||||
createCmd.waitFor() && createCmd.exitCode() == 0))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -141,7 +141,7 @@ bool luks::create(Report& report, const QString& deviceNode)
|
||||||
deviceNode,
|
deviceNode,
|
||||||
suggestedMapperName(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;
|
return false;
|
||||||
|
|
||||||
setPayloadSize();
|
setPayloadSize();
|
||||||
|
@ -168,12 +168,12 @@ QString luks::unmountTitle() const
|
||||||
|
|
||||||
QString luks::cryptOpenTitle() const
|
QString luks::cryptOpenTitle() const
|
||||||
{
|
{
|
||||||
return xi18nc("@title:menu", "Decrypt");
|
return xi18nc("@title:menu", "Unlock");
|
||||||
}
|
}
|
||||||
|
|
||||||
QString luks::cryptCloseTitle() const
|
QString luks::cryptCloseTitle() const
|
||||||
{
|
{
|
||||||
return xi18nc("@title:menu", "Deactivate");
|
return xi18nc("@title:menu", "Lock");
|
||||||
}
|
}
|
||||||
|
|
||||||
void luks::setPassphrase(const QString& passphrase)
|
void luks::setPassphrase(const QString& passphrase)
|
||||||
|
@ -265,9 +265,8 @@ bool luks::cryptOpen(QWidget* parent, const QString& deviceNode)
|
||||||
deviceNode,
|
deviceNode,
|
||||||
suggestedMapperName(deviceNode) });
|
suggestedMapperName(deviceNode) });
|
||||||
|
|
||||||
if (!( openCmd.start(-1) &&
|
if (!( openCmd.write(passphrase.toLocal8Bit() + '\n') &&
|
||||||
openCmd.write(passphrase.toLocal8Bit() + '\n') == passphrase.toLocal8Bit().length() + 1 &&
|
openCmd.start(-1) && openCmd.exitCode() == 0) )
|
||||||
openCmd.waitFor() && openCmd.exitCode() == 0) )
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (m_innerFs) {
|
if (m_innerFs) {
|
||||||
|
@ -286,8 +285,8 @@ bool luks::cryptOpen(QWidget* parent, const QString& deviceNode)
|
||||||
if (!m_isCryptOpen)
|
if (!m_isCryptOpen)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (auto &p : LVM::pvList)
|
for (auto &p : LVM::pvList::list())
|
||||||
if (p.isLuks() && p.partition()->deviceNode() == deviceNode && p.partition()->fileSystem().type() == FileSystem::Lvm2_PV)
|
if (p.isLuks() && p.partition()->deviceNode() == deviceNode && p.partition()->fileSystem().type() == FileSystem::Type::Lvm2_PV)
|
||||||
p.setLuks(false);
|
p.setLuks(false);
|
||||||
|
|
||||||
m_passphrase = passphrase;
|
m_passphrase = passphrase;
|
||||||
|
@ -325,7 +324,7 @@ bool luks::cryptClose(const QString& deviceNode)
|
||||||
|
|
||||||
m_isCryptOpen = (m_innerFs != nullptr);
|
m_isCryptOpen = (m_innerFs != nullptr);
|
||||||
|
|
||||||
for (auto &p : LVM::pvList)
|
for (auto &p : LVM::pvList::list())
|
||||||
if (!p.isLuks() && p.partition()->deviceNode() == deviceNode)
|
if (!p.isLuks() && p.partition()->deviceNode() == deviceNode)
|
||||||
p.setLuks(true);
|
p.setLuks(true);
|
||||||
|
|
||||||
|
@ -464,7 +463,7 @@ FileSystem::Type luks::type() const
|
||||||
{
|
{
|
||||||
if (m_isCryptOpen && m_innerFs)
|
if (m_isCryptOpen && m_innerFs)
|
||||||
return m_innerFs->type();
|
return m_innerFs->type();
|
||||||
return FileSystem::Luks;
|
return FileSystem::Type::Luks;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString luks::suggestedMapperName(const QString& deviceNode) const
|
QString luks::suggestedMapperName(const QString& deviceNode) const
|
||||||
|
@ -647,19 +646,19 @@ bool luks::canEncryptType(FileSystem::Type type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case Btrfs:
|
case Type::Btrfs:
|
||||||
case F2fs:
|
case Type::F2fs:
|
||||||
case Ext2:
|
case Type::Ext2:
|
||||||
case Ext3:
|
case Type::Ext3:
|
||||||
case Ext4:
|
case Type::Ext4:
|
||||||
case Jfs:
|
case Type::Jfs:
|
||||||
case LinuxSwap:
|
case Type::LinuxSwap:
|
||||||
case Lvm2_PV:
|
case Type::Lvm2_PV:
|
||||||
case Nilfs2:
|
case Type::Nilfs2:
|
||||||
case ReiserFS:
|
case Type::ReiserFS:
|
||||||
case Reiser4:
|
case Type::Reiser4:
|
||||||
case Xfs:
|
case Type::Xfs:
|
||||||
case Zfs:
|
case Type::Zfs:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -690,7 +689,7 @@ void luks::setPayloadSize()
|
||||||
|
|
||||||
bool luks::testPassphrase(const QString& deviceNode, const QString& passphrase) const {
|
bool luks::testPassphrase(const QString& deviceNode, const QString& passphrase) const {
|
||||||
ExternalCommand cmd(QStringLiteral("cryptsetup"), { QStringLiteral("open"), QStringLiteral("--tries"), QStringLiteral("1"), QStringLiteral("--test-passphrase"), deviceNode });
|
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 true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -17,8 +17,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
* 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
|
#define KPMCORE_LUKS_H
|
||||||
|
|
||||||
#include "util/libpartitionmanagerexport.h"
|
#include "util/libpartitionmanagerexport.h"
|
||||||
|
@ -26,11 +25,11 @@
|
||||||
#include "fs/filesystem.h"
|
#include "fs/filesystem.h"
|
||||||
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
#include <QWidget>
|
|
||||||
|
|
||||||
class Report;
|
class Report;
|
||||||
|
|
||||||
class QString;
|
class QString;
|
||||||
|
class QWidget;
|
||||||
|
|
||||||
namespace FS
|
namespace FS
|
||||||
{
|
{
|
||||||
|
@ -40,10 +39,10 @@ namespace FS
|
||||||
class LIBKPMCORE_EXPORT luks : public FileSystem
|
class LIBKPMCORE_EXPORT luks : public FileSystem
|
||||||
{
|
{
|
||||||
public:
|
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;
|
~luks() override;
|
||||||
|
|
||||||
enum KeyLocation {
|
enum class KeyLocation {
|
||||||
unknown,
|
unknown,
|
||||||
dmcrypt,
|
dmcrypt,
|
||||||
keyring
|
keyring
|
||||||
|
@ -225,7 +224,7 @@ protected:
|
||||||
qint64 m_PayloadSize;
|
qint64 m_PayloadSize;
|
||||||
QString m_outerUuid;
|
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)
|
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)
|
if (m_isCryptOpen && m_innerFs)
|
||||||
return m_innerFs->type();
|
return m_innerFs->type();
|
||||||
return FileSystem::Luks2;
|
return FileSystem::Type::Luks2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool luks2::create(Report& report, const QString& deviceNode)
|
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("--type"), QStringLiteral("luks2"),
|
||||||
QStringLiteral("luksFormat"),
|
QStringLiteral("luksFormat"),
|
||||||
deviceNode });
|
deviceNode });
|
||||||
if (!( createCmd.start(-1) &&
|
if (!( createCmd.write(m_passphrase.toLocal8Bit() + '\n') &&
|
||||||
createCmd.write(m_passphrase.toLocal8Bit() + '\n') == m_passphrase.toLocal8Bit().length() + 1 &&
|
createCmd.start(-1) && createCmd.exitCode() == 0))
|
||||||
createCmd.waitFor() && createCmd.exitCode() == 0))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -68,7 +67,7 @@ bool luks2::create(Report& report, const QString& deviceNode)
|
||||||
deviceNode,
|
deviceNode,
|
||||||
suggestedMapperName(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;
|
return false;
|
||||||
|
|
||||||
setPayloadSize();
|
setPayloadSize();
|
||||||
|
@ -95,13 +94,13 @@ bool luks2::resize(Report& report, const QString& deviceNode, qint64 newLength)
|
||||||
ExternalCommand cryptResizeCmd(report, QStringLiteral("cryptsetup"), { QStringLiteral("resize"), mapperName() });
|
ExternalCommand cryptResizeCmd(report, QStringLiteral("cryptsetup"), { QStringLiteral("resize"), mapperName() });
|
||||||
report.line() << xi18nc("@info:progress", "Resizing LUKS crypt on partition <filename>%1</filename>.", deviceNode);
|
report.line() << xi18nc("@info:progress", "Resizing LUKS crypt on partition <filename>%1</filename>.", deviceNode);
|
||||||
|
|
||||||
cryptResizeCmd.start(-1);
|
if (m_KeyLocation == KeyLocation::keyring) {
|
||||||
if (m_KeyLocation == keyring) {
|
|
||||||
if (m_passphrase.isEmpty())
|
if (m_passphrase.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
cryptResizeCmd.write(m_passphrase.toLocal8Bit() + '\n');
|
cryptResizeCmd.write(m_passphrase.toLocal8Bit() + '\n');
|
||||||
}
|
}
|
||||||
cryptResizeCmd.waitFor();
|
if (!cryptResizeCmd.start(-1))
|
||||||
|
return false;
|
||||||
if ( cryptResizeCmd.exitCode() == 0 )
|
if ( cryptResizeCmd.exitCode() == 0 )
|
||||||
return m_innerFs->resize(report, mapperName(), m_PayloadSize);
|
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("--size"), QString::number(m_PayloadSize / 512), // FIXME, LUKS2 can have different sector sizes
|
||||||
QStringLiteral("resize"), mapperName() });
|
QStringLiteral("resize"), mapperName() });
|
||||||
report.line() << xi18nc("@info:progress", "Resizing LUKS crypt on partition <filename>%1</filename>.", deviceNode);
|
report.line() << xi18nc("@info:progress", "Resizing LUKS crypt on partition <filename>%1</filename>.", deviceNode);
|
||||||
cryptResizeCmd.start(-1);
|
if (m_KeyLocation == KeyLocation::keyring) {
|
||||||
if (m_KeyLocation == keyring) {
|
|
||||||
if (m_passphrase.isEmpty())
|
if (m_passphrase.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
cryptResizeCmd.write(m_passphrase.toLocal8Bit() + '\n');
|
cryptResizeCmd.write(m_passphrase.toLocal8Bit() + '\n');
|
||||||
}
|
}
|
||||||
cryptResizeCmd.waitFor();
|
if (!cryptResizeCmd.start(-1))
|
||||||
|
return false;
|
||||||
if ( cryptResizeCmd.exitCode() == 0 )
|
if ( cryptResizeCmd.exitCode() == 0 )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -127,16 +126,16 @@ bool luks2::resize(Report& report, const QString& deviceNode, qint64 newLength)
|
||||||
|
|
||||||
luks::KeyLocation luks2::keyLocation()
|
luks::KeyLocation luks2::keyLocation()
|
||||||
{
|
{
|
||||||
m_KeyLocation = unknown;
|
m_KeyLocation = KeyLocation::unknown;
|
||||||
ExternalCommand statusCmd(QStringLiteral("cryptsetup"), { QStringLiteral("status"), mapperName() });
|
ExternalCommand statusCmd(QStringLiteral("cryptsetup"), { QStringLiteral("status"), mapperName() });
|
||||||
if (statusCmd.run(-1) && statusCmd.exitCode() == 0) {
|
if (statusCmd.run(-1) && statusCmd.exitCode() == 0) {
|
||||||
QRegularExpression re(QStringLiteral("key location:\\s+(\\w+)"));
|
QRegularExpression re(QStringLiteral("key location:\\s+(\\w+)"));
|
||||||
QRegularExpressionMatch rem = re.match(statusCmd.output());
|
QRegularExpressionMatch rem = re.match(statusCmd.output());
|
||||||
if (rem.hasMatch()) {
|
if (rem.hasMatch()) {
|
||||||
if (rem.captured(1) == QStringLiteral("keyring"))
|
if (rem.captured(1) == QStringLiteral("keyring"))
|
||||||
m_KeyLocation = keyring;
|
m_KeyLocation = KeyLocation::keyring;
|
||||||
else if (rem.captured(1) == QStringLiteral("dm-crypt"))
|
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,
|
lvm2_pv::lvm2_pv(qint64 firstsector, qint64 lastsector,
|
||||||
qint64 sectorsused, const QString& label)
|
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_PESize(0)
|
||||||
, m_TotalPE(0)
|
, m_TotalPE(0)
|
||||||
, m_AllocatedPE(0)
|
, m_AllocatedPE(0)
|
||||||
|
@ -99,7 +99,7 @@ FileSystem::SupportTool lvm2_pv::supportToolName() const
|
||||||
|
|
||||||
qint64 lvm2_pv::maxCapacity() 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
|
qint64 lvm2_pv::readUsedCapacity(const QString& deviceNode) const
|
||||||
|
@ -270,10 +270,10 @@ QList<LvmPV> lvm2_pv::getPVinNode(const PartitionNode* parent)
|
||||||
partitions.append(getPVinNode(node));
|
partitions.append(getPVinNode(node));
|
||||||
|
|
||||||
// FIXME: reenable newly created PVs (before applying) once everything works
|
// 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));
|
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));
|
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)
|
LvmPV::LvmPV(const QString vgName, const Partition* p, bool isLuks)
|
||||||
: m_vgName(vgName)
|
: m_vgName(vgName)
|
||||||
|
|
|
@ -62,7 +62,22 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace LVM {
|
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
|
namespace FS
|
||||||
|
|
|
@ -47,7 +47,7 @@ FileSystem::CommandSupportType nilfs2::m_UpdateUUID = FileSystem::cmdSupportNone
|
||||||
FileSystem::CommandSupportType nilfs2::m_GetUUID = FileSystem::cmdSupportNone;
|
FileSystem::CommandSupportType nilfs2::m_GetUUID = FileSystem::cmdSupportNone;
|
||||||
|
|
||||||
nilfs2::nilfs2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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
|
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
|
qint64 nilfs2::maxCapacity() const
|
||||||
{
|
{
|
||||||
return Capacity::unitFactor(Capacity::Byte, Capacity::EiB);
|
return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nilfs2::maxLabelLength() const
|
int nilfs2::maxLabelLength() const
|
||||||
|
|
|
@ -50,7 +50,7 @@ FileSystem::CommandSupportType ntfs::m_UpdateUUID = FileSystem::cmdSupportNone;
|
||||||
FileSystem::CommandSupportType ntfs::m_GetUUID = FileSystem::cmdSupportNone;
|
FileSystem::CommandSupportType ntfs::m_GetUUID = FileSystem::cmdSupportNone;
|
||||||
|
|
||||||
ntfs::ntfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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
|
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
|
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
|
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)
|
bool ntfs::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel)
|
||||||
{
|
{
|
||||||
ExternalCommand writeCmd(report, QStringLiteral("ntfslabel"), { QStringLiteral("--force"), deviceNode, newLabel });
|
ExternalCommand writeCmd(report, QStringLiteral("ntfslabel"), { QStringLiteral("--force"), deviceNode, newLabel }, QProcess::SeparateChannels);
|
||||||
writeCmd.setProcessChannelMode(QProcess::SeparateChannels);
|
|
||||||
|
|
||||||
if (!writeCmd.run(-1))
|
if (!writeCmd.run(-1))
|
||||||
return false;
|
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
|
bool ntfs::updateUUID(Report& report, const QString& deviceNode) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(report);
|
Q_UNUSED(report)
|
||||||
ExternalCommand cmd(QStringLiteral("ntfslabel"), { QStringLiteral("--new-serial"), deviceNode });
|
ExternalCommand cmd(QStringLiteral("ntfslabel"), { QStringLiteral("--new-serial"), deviceNode });
|
||||||
|
|
||||||
return cmd.run(-1) && cmd.exitCode() == 0;
|
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") });
|
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()) {
|
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);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
cmd.write(QByteArray(s, sizeof(s)));
|
|
||||||
cmd.waitFor(-1);
|
|
||||||
|
|
||||||
// Also update backup NTFS boot sector located at the end of the partition
|
// 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
|
// NOTE: this should fail if filesystem does not span the whole partition
|
||||||
qint64 pos = (lastSector() - firstSector()) * sectorSize() + 28;
|
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) });
|
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()) {
|
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);
|
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;
|
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);
|
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;
|
FileSystem::CommandSupportType ocfs2::m_GetUUID = FileSystem::cmdSupportNone;
|
||||||
|
|
||||||
ocfs2::ocfs2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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
|
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
|
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
|
qint64 ocfs2::readUsedCapacity(const QString& deviceNode) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(deviceNode);
|
Q_UNUSED(deviceNode)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,15 +113,12 @@ bool ocfs2::create(Report& report, const QString& deviceNode)
|
||||||
{
|
{
|
||||||
ExternalCommand cmd(report, QStringLiteral("mkfs.ocfs2"), { deviceNode });
|
ExternalCommand cmd(report, QStringLiteral("mkfs.ocfs2"), { deviceNode });
|
||||||
|
|
||||||
if (cmd.start())
|
|
||||||
{
|
|
||||||
cmd.write("y\n");
|
cmd.write("y\n");
|
||||||
cmd.waitFor(-1);
|
if (!cmd.start())
|
||||||
|
return false;
|
||||||
|
|
||||||
return cmd.exitCode() == 0;
|
return cmd.exitCode() == 0;
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ocfs2::resize(Report& report, const QString& deviceNode, qint64 length) const
|
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;
|
FileSystem::CommandSupportType reiser4::m_Backup = FileSystem::cmdSupportNone;
|
||||||
|
|
||||||
reiser4::reiser4(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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
|
// looks like it's actually unknown. see
|
||||||
// http://en.wikipedia.org/wiki/Comparison_of_file_systems
|
// 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
|
int reiser4::maxLabelLength() const
|
||||||
|
|
|
@ -42,7 +42,7 @@ FileSystem::CommandSupportType reiserfs::m_UpdateUUID = FileSystem::cmdSupportNo
|
||||||
FileSystem::CommandSupportType reiserfs::m_GetUUID = FileSystem::cmdSupportNone;
|
FileSystem::CommandSupportType reiserfs::m_GetUUID = FileSystem::cmdSupportNone;
|
||||||
|
|
||||||
reiserfs::reiserfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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
|
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
|
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
|
int reiserfs::maxLabelLength() const
|
||||||
|
@ -154,15 +154,15 @@ bool reiserfs::resize(Report& report, const QString& deviceNode, qint64 length)
|
||||||
ExternalCommand cmd(report, QStringLiteral("resize_reiserfs"),
|
ExternalCommand cmd(report, QStringLiteral("resize_reiserfs"),
|
||||||
{ deviceNode, QStringLiteral("-q"), QStringLiteral("-s"), QString::number(length) });
|
{ deviceNode, QStringLiteral("-q"), QStringLiteral("-s"), QString::number(length) });
|
||||||
|
|
||||||
bool rval = cmd.start(-1);
|
bool rval = cmd.write(QByteArrayLiteral("y\n"));
|
||||||
|
|
||||||
if (!rval)
|
if (!rval)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (cmd.write("y\n", 2) != 2)
|
if (!cmd.start(-1))
|
||||||
return false;
|
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
|
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;
|
bool udf::oldMkudffsVersion = false;
|
||||||
|
|
||||||
udf::udf(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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;
|
FileSystem::CommandSupportType ufs::m_Backup = FileSystem::cmdSupportCore;
|
||||||
|
|
||||||
ufs::ufs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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;
|
FileSystem::CommandSupportType unformatted::m_Create = FileSystem::cmdSupportFileSystem;
|
||||||
|
|
||||||
unformatted::unformatted(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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
|
namespace FS
|
||||||
{
|
{
|
||||||
unknown::unknown(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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;
|
FileSystem::CommandSupportType xfs::m_SetLabel = FileSystem::cmdSupportNone;
|
||||||
|
|
||||||
xfs::xfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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
|
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
|
qint64 xfs::maxCapacity() const
|
||||||
{
|
{
|
||||||
return Capacity::unitFactor(Capacity::Byte, Capacity::EiB);
|
return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB);
|
||||||
}
|
}
|
||||||
|
|
||||||
int xfs::maxLabelLength() const
|
int xfs::maxLabelLength() const
|
||||||
|
|
|
@ -40,7 +40,7 @@ FileSystem::CommandSupportType zfs::m_UpdateUUID = FileSystem::cmdSupportNone;
|
||||||
FileSystem::CommandSupportType zfs::m_GetUUID = FileSystem::cmdSupportNone;
|
FileSystem::CommandSupportType zfs::m_GetUUID = FileSystem::cmdSupportNone;
|
||||||
|
|
||||||
zfs::zfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
|
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
|
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
|
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
|
bool zfs::remove(Report& report, const QString& deviceNode) const
|
||||||
|
|
|
@ -21,10 +21,10 @@
|
||||||
#include "fs/filesystem.h"
|
#include "fs/filesystem.h"
|
||||||
#include "util/capacity.h"
|
#include "util/capacity.h"
|
||||||
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QStyleOptionButton>
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QFontDatabase>
|
#include <QFontDatabase>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QStyleOptionButton>
|
||||||
|
|
||||||
/** Creates a new PartWidget
|
/** Creates a new PartWidget
|
||||||
@param parent pointer to the parent widget
|
@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;
|
m_fileSystemColorCode = colorCode;
|
||||||
repaint();
|
repaint();
|
||||||
|
@ -101,12 +101,12 @@ void PartWidget::paintEvent(QPaintEvent*)
|
||||||
|
|
||||||
if (partition()->roles().has(PartitionRole::Extended)) {
|
if (partition()->roles().has(PartitionRole::Extended)) {
|
||||||
drawGradient(&painter, activeColor(
|
drawGradient(&painter, activeColor(
|
||||||
m_fileSystemColorCode[ partition()->fileSystem().type() ]),
|
m_fileSystemColorCode[ static_cast<int>(partition()->fileSystem().type()) ]),
|
||||||
QRect(0, 0, width(), height()));
|
QRect(0, 0, width(), height()));
|
||||||
return;
|
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)) {
|
if (!partition()->roles().has(PartitionRole::Unallocated)) {
|
||||||
const QColor dark = base.darker(105);
|
const QColor dark = base.darker(105);
|
||||||
|
|
|
@ -26,8 +26,6 @@
|
||||||
|
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
|
|
||||||
#include <array>
|
|
||||||
|
|
||||||
class Partition;
|
class Partition;
|
||||||
|
|
||||||
class QPaintEvent;
|
class QPaintEvent;
|
||||||
|
@ -63,7 +61,7 @@ public:
|
||||||
return m_Partition; /**< @return the widget's Partition */
|
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:
|
protected:
|
||||||
void paintEvent(QPaintEvent* event);
|
void paintEvent(QPaintEvent* event);
|
||||||
|
@ -76,7 +74,7 @@ protected:
|
||||||
private:
|
private:
|
||||||
Partition* m_Partition;
|
Partition* m_Partition;
|
||||||
bool m_Active;
|
bool m_Active;
|
||||||
std::array< QColor, FileSystem::__lastType > m_fileSystemColorCode;
|
std::vector<QColor> m_fileSystemColorCode;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "core/copytargetfile.h"
|
#include "core/copytargetfile.h"
|
||||||
|
|
||||||
#include "fs/filesystem.h"
|
#include "fs/filesystem.h"
|
||||||
|
#include "util/externalcommand.h"
|
||||||
#include "util/report.h"
|
#include "util/report.h"
|
||||||
|
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue