Browse Source

New Version: 3.3.1~272-gc9258f7-1

master
Alf Gaida 2 years ago
parent
commit
2c011dd925
100 changed files with 3553 additions and 1237 deletions
  1. 22
    12
      CMakeLists.txt
  2. 2
    10
      INSTALL
  3. 1
    1
      README.md
  4. 0
    57
      cmake/modules/FindLIBPARTED.cmake
  5. 12
    0
      debian/changelog
  6. 1
    1
      debian/control
  7. 8
    0
      debian/repository.spec
  8. 6
    3
      src/CMakeLists.txt
  9. 23
    5
      src/backend/corebackend.cpp
  10. 13
    27
      src/backend/corebackend.h
  11. 2
    18
      src/backend/corebackenddevice.h
  12. 19
    6
      src/backend/corebackendmanager.cpp
  13. 9
    8
      src/backend/corebackendmanager.h
  14. 7
    1
      src/core/CMakeLists.txt
  15. 2
    3
      src/core/copysource.h
  16. 5
    23
      src/core/copysourcedevice.cpp
  17. 7
    4
      src/core/copysourcedevice.h
  18. 0
    15
      src/core/copysourcefile.cpp
  19. 3
    1
      src/core/copysourcefile.h
  20. 0
    14
      src/core/copysourceshred.cpp
  21. 4
    1
      src/core/copysourceshred.h
  22. 2
    2
      src/core/copytarget.h
  23. 2
    24
      src/core/copytargetdevice.cpp
  24. 5
    3
      src/core/copytargetdevice.h
  25. 0
    18
      src/core/copytargetfile.cpp
  26. 4
    1
      src/core/copytargetfile.h
  27. 95
    26
      src/core/device.cpp
  28. 36
    64
      src/core/device.h
  29. 43
    0
      src/core/device_p.h
  30. 56
    9
      src/core/diskdevice.cpp
  31. 42
    30
      src/core/diskdevice.h
  32. 141
    64
      src/core/fstab.cpp
  33. 76
    51
      src/core/fstab.h
  34. 103
    31
      src/core/lvmdevice.cpp
  35. 11
    44
      src/core/lvmdevice.h
  36. 0
    13
      src/core/operationrunner.cpp
  37. 1
    1
      src/core/operationstack.cpp
  38. 4
    4
      src/core/partition.h
  39. 2
    2
      src/core/partitionalignment.cpp
  40. 25
    17
      src/core/partitiontable.cpp
  41. 7
    0
      src/core/raid/CMakeLists.txt
  42. 480
    0
      src/core/raid/softwareraid.cpp
  43. 103
    0
      src/core/raid/softwareraid.h
  44. 44
    46
      src/core/smartattribute.cpp
  45. 6
    8
      src/core/smartattribute.h
  46. 644
    0
      src/core/smartattributeparseddata.cpp
  47. 225
    0
      src/core/smartattributeparseddata.h
  48. 198
    0
      src/core/smartdiskinformation.cpp
  49. 175
    0
      src/core/smartdiskinformation.h
  50. 161
    0
      src/core/smartparser.cpp
  51. 31
    29
      src/core/smartparser.h
  52. 49
    160
      src/core/smartstatus.cpp
  53. 56
    33
      src/core/smartstatus.h
  54. 16
    3
      src/core/volumemanagerdevice.cpp
  55. 9
    12
      src/core/volumemanagerdevice.h
  56. 27
    0
      src/core/volumemanagerdevice_p.h
  57. 2
    0
      src/fs/CMakeLists.txt
  58. 3
    3
      src/fs/btrfs.cpp
  59. 4
    4
      src/fs/exfat.cpp
  60. 1
    1
      src/fs/ext2.cpp
  61. 1
    1
      src/fs/ext2.h
  62. 2
    2
      src/fs/ext3.cpp
  63. 2
    2
      src/fs/ext4.cpp
  64. 1
    1
      src/fs/extended.cpp
  65. 3
    3
      src/fs/f2fs.cpp
  66. 1
    2
      src/fs/f2fs.h
  67. 4
    9
      src/fs/fat12.cpp
  68. 4
    5
      src/fs/fat12.h
  69. 3
    3
      src/fs/fat16.cpp
  70. 8
    2
      src/fs/fat16.h
  71. 5
    10
      src/fs/fat32.cpp
  72. 113
    25
      src/fs/filesystem.cpp
  73. 83
    88
      src/fs/filesystem.h
  74. 36
    0
      src/fs/filesystem_p.h
  75. 63
    60
      src/fs/filesystemfactory.cpp
  76. 1
    2
      src/fs/filesystemfactory.h
  77. 2
    2
      src/fs/hfs.cpp
  78. 2
    2
      src/fs/hfsplus.cpp
  79. 2
    2
      src/fs/hpfs.cpp
  80. 1
    1
      src/fs/iso9660.cpp
  81. 4
    4
      src/fs/jfs.cpp
  82. 28
    0
      src/fs/linuxraidmember.cpp
  83. 41
    0
      src/fs/linuxraidmember.h
  84. 4
    4
      src/fs/linuxswap.cpp
  85. 26
    27
      src/fs/luks.cpp
  86. 5
    6
      src/fs/luks.h
  87. 14
    15
      src/fs/luks2.cpp
  88. 9
    5
      src/fs/lvm2_pv.cpp
  89. 16
    1
      src/fs/lvm2_pv.h
  90. 3
    3
      src/fs/nilfs2.cpp
  91. 7
    10
      src/fs/ntfs.cpp
  92. 9
    12
      src/fs/ocfs2.cpp
  93. 2
    2
      src/fs/reiser4.cpp
  94. 6
    6
      src/fs/reiserfs.cpp
  95. 1
    1
      src/fs/udf.cpp
  96. 1
    1
      src/fs/ufs.cpp
  97. 1
    1
      src/fs/unformatted.cpp
  98. 1
    1
      src/fs/unknown.cpp
  99. 3
    3
      src/fs/xfs.cpp
  100. 0
    0
      src/fs/zfs.cpp

+ 22
- 12
CMakeLists.txt View File

@@ -16,14 +16,22 @@

project(kpmcore)

cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
cmake_minimum_required(VERSION 3.1 FATAL_ERROR)

set(CMAKE_USE_RELATIVE_PATHS OFF)
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)

set(QT_MIN_VERSION "5.7.0")
# Dependencies
set(QT_MIN_VERSION "5.10.0")
set(KF5_MIN_VERSION "5.25")
set(BLKID_MIN_VERSION "2.32")
# Qca-qt5 (tested with botan and ossl backends)

# Runtime
# smartmontools 6.7

set(VERSION_MAJOR "3")
set(VERSION_MINOR "3")
set(VERSION_MINOR "50")
set(VERSION_RELEASE "0")
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_RELEASE})
set(SOVERSION "8")
@@ -32,7 +40,7 @@ add_definitions(-D'VERSION="${VERSION}"') #"
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(ECM 1.0.0 REQUIRED NO_MODULE)
find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/")

include(KDEInstallDirs)
@@ -41,7 +49,6 @@ include(KDECompilerSettings NO_POLICY_SCOPE)
include(FeatureSummary)
include(GenerateExportHeader)
include(ECMSetupVersion)
include(ECMPackageConfigHelpers)

ecm_setup_version(${VERSION} VARIABLE_PREFIX KPMCORE
VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/kpmcore_version.h"
@@ -56,12 +63,15 @@ find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
)

# Load the frameworks we need
find_package(KF5 REQUIRED
I18n
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED
Auth
CoreAddons
I18n
WidgetsAddons
)

find_package(Qca-qt5 REQUIRED)

# use sane compile flags
add_definitions(
-DQT_USE_QSTRINGBUILDER
@@ -76,10 +86,10 @@ add_definitions(
)
kde_enable_exceptions()

find_package(PkgConfig REQUIRED)
pkg_check_modules(BLKID REQUIRED blkid>=2.30)
pkg_check_modules(LIBATASMART REQUIRED libatasmart)
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
find_package(PkgConfig REQUIRED)
pkg_check_modules(BLKID REQUIRED blkid>=${BLKID_MIN_VERSION})
endif()

include_directories(${Qt5Core_INCLUDE_DIRS} ${UUID_INCLUDE_DIRS} ${BLKID_INCLUDE_DIRS} lib/ src/)

@@ -89,7 +99,7 @@ add_subdirectory(src)
set(INCLUDE_INSTALL_DIR "include/kpmcore/")
set(CMAKECONFIG_INSTALL_DIR "${CMAKECONFIG_INSTALL_PREFIX}/KPMcore")

ecm_configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/KPMcoreConfig.cmake.in"
configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/KPMcoreConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/KPMcoreConfig.cmake"
INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR}
PATH_VARS INCLUDE_INSTALL_DIR

+ 2
- 10
INSTALL View File

@@ -4,24 +4,16 @@ Building and installing KDE Partition Manager Core Library from source

1. Dependencies

libparted: Either get it from http://www.gnu.org/software/parted/download.shtml
and build it yourself or, preferably, install your distribution's packages
(don't forget the dev-package).

libblkid: Part of the util-linux project available at
https://github.com/karelzak/util-linux

libatasmart: Available from http://0pointer.de/blog/projects/being-smart.html
util-linux 2.32: available at https://github.com/karelzak/util-linux

KDE Frameworks: The minimum required version is 5.0.


2. Configure

KPMcore is built with cmake. It is recommended to build out of tree:
After unpacking the source, create a separate build directory and run cmake there:

$ tar xfj kpmcore-x.y.z.tar.bz2
$ tar xf kpmcore-x.y.z.tar.xz
$ cd kpmcore-x.y.z
$ mkdir build
$ cd build

+ 1
- 1
README.md View File

@@ -14,7 +14,7 @@ of storage devices on a system:
There are multiple backends so that KPMcore can support different
operating systems, although the only functional backend is the
one for Linux systems:
* libparted backend (Linux)
* sfdisk backend (Linux)
* null backend

## Using KPMcore

+ 0
- 57
cmake/modules/FindLIBPARTED.cmake View File

@@ -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)

+ 12
- 0
debian/changelog View File

@@ -1,3 +1,15 @@
kpmcore (3.3.1~272-gc9258f7-1) unstable; urgency=medium

* New Version: 3.3.1~272-gc9258f7-1

-- Alf Gaida <agaida@siduction.org> Sun, 05 Aug 2018 19:51:09 +0200

kpmcore (3.3.1~71-g79a6f5a-2) unstable; urgency=medium

* fixed standards and installation

-- Alf Gaida <agaida@siduction.org> Tue, 17 Jul 2018 17:33:12 +0200

kpmcore (3.3.1~71-g79a6f5a-1) unstable; urgency=medium

* New snapshot: v3.3.0-71-g79a6f5a

+ 1
- 1
debian/control View File

@@ -12,7 +12,7 @@ Build-Depends: cmake,
libkf5widgetsaddons-dev,
libparted-dev,
pkg-config
Standards-Version: 4.1.4
Standards-Version: 4.1.5
Homepage: https://github.com/KDE/kpmcore
Vcs-Browser: https://git.siduction.org/extra/kpmcore
Vcs-Git: https://git.siduction.org/extra/kpmcore.git

+ 8
- 0
debian/repository.spec View File

@@ -21,6 +21,14 @@ uploadrepo=extra

repository="git@github.com:KDE/kpmcore"

build="yes"
clean="yes"
gitcommit="yes"
push="yes"
upload="yes"
dryrun="no"


# cleanup function definiton
cleanup() {
echo ""

+ 6
- 3
src/CMakeLists.txt View File

@@ -39,14 +39,17 @@ set(kpmcore_SRCS
ki18n_wrap_ui(kpmcore_SRCS ${gui_UIFILES})

add_library(kpmcore SHARED ${kpmcore_SRCS})
target_link_libraries( kpmcore
${UUID_LIBRARIES}
target_link_libraries( kpmcore PUBLIC
Qt5::Core
PRIVATE
${BLKID_LIBRARIES}
${LIBATASMART_LIBRARIES}
Qt5::DBus
Qt5::Gui
qca-qt5
KF5::I18n
KF5::CoreAddons
KF5::WidgetsAddons
KF5::Auth
)

install(TARGETS kpmcore EXPORT KPMcoreTargets ${INSTALL_TARGETS_DEFAULT_ARGS})

+ 23
- 5
src/backend/corebackend.cpp View File

@@ -24,20 +24,18 @@

#include <QDebug>

class CoreBackend::CoreBackendPrivate
struct CoreBackendPrivate
{
public:
CoreBackendPrivate() {}
QString m_id, m_version;
};

CoreBackend::CoreBackend() :
d(new CoreBackendPrivate())
d(std::make_unique<CoreBackendPrivate>())
{
}

CoreBackend::~CoreBackend()
{
delete d;
}

void CoreBackend::emitProgress(int i)
@@ -59,3 +57,23 @@ void CoreBackend::setPartitionTableMaxPrimaries(PartitionTable& p, qint32 max_pr
{
p.setMaxPrimaries(max_primaries);
}

QString CoreBackend::id()
{
return d->m_id;
}

QString CoreBackend::version()
{
return d->m_version;
}

void CoreBackend::setId(const QString& id)
{
d->m_id = id;
}

void CoreBackend::setVersion(const QString& version)
{
d->m_version = version;
}

+ 13
- 27
src/backend/corebackend.h View File

@@ -23,11 +23,14 @@
#include "util/libpartitionmanagerexport.h"
#include "fs/filesystem.h"

#include <memory>

#include <QObject>
#include <QList>

class CoreBackendManager;
class CoreBackendDevice;
struct CoreBackendPrivate;
class Device;
class PartitionTable;

@@ -68,17 +71,13 @@ public:
* Return the plugin's unique Id from JSON metadata
* @return the plugin's unique Id from JSON metadata
*/
QString id() {
return m_id;
}
QString id();

/**
* Return the plugin's version from JSON metadata
* @return the plugin's version from JSON metadata
*/
QString version() {
return m_version;
}
QString version();

/**
* Initialize the plugin's FileSystem support
@@ -130,29 +129,23 @@ public:
/**
* Open a device for reading.
* @param deviceNode The path of the device that is to be opened (e.g. /dev/sda)
* @return a pointer to a CoreBackendDevice or nullptr if the open failed. If a pointer to
* an instance is returned, it's the caller's responsibility to delete the
* object.
* @return a pointer to a CoreBackendDevice or nullptr if the open failed.
*/
virtual CoreBackendDevice* openDevice(const Device& d) = 0;
virtual std::unique_ptr<CoreBackendDevice> openDevice(const Device& d) = 0;

/**
* Open a device in exclusive mode for writing.
* @param deviceNode The path of the device that is to be opened (e.g. /dev/sda)
* @return a pointer to a CoreBackendDevice or nullptr if the open failed. If a pointer to
* an instance is returned, it's the caller's responsibility to delete the
* object.
* @return a pointer to a CoreBackendDevice or nullptr if the open failed.
*/
virtual CoreBackendDevice* openDeviceExclusive(const Device& d) = 0;
virtual std::unique_ptr<CoreBackendDevice> openDeviceExclusive(const Device& d) = 0;

/**
* Close a CoreBackendDevice that has previously been opened.
* @param core_device Pointer to the CoreBackendDevice to be closed. Must not be nullptr.
* @return true if closing the CoreBackendDevice succeeded, otherwise false.
*
* This method does not delete the object.
*/
virtual bool closeDevice(CoreBackendDevice* core_device) = 0;
virtual bool closeDevice(std::unique_ptr<CoreBackendDevice> coreDevice) = 0;

/**
* Emit progress.
@@ -176,18 +169,11 @@ protected:
static void setPartitionTableMaxPrimaries(PartitionTable& p, qint32 max_primaries);

private:
void setId(const QString& id) {
m_id = id;
}
void setVersion(const QString& version) {
m_version = version;
}
void setId(const QString& id);
void setVersion(const QString& version);

private:
QString m_id, m_version;

class CoreBackendPrivate;
CoreBackendPrivate* d;
std::unique_ptr<CoreBackendPrivate> d;
};

#endif

+ 2
- 18
src/backend/corebackenddevice.h View File

@@ -19,6 +19,7 @@

#define KPMCORE_COREBACKENDDEVICE_H

#include <memory>
#include <QString>

class CoreBackendPartition;
@@ -81,7 +82,7 @@ public:
* @return a pointer to the CoreBackendPartitionTable for this device or nullptr in case
* of errors
*/
virtual CoreBackendPartitionTable* openPartitionTable() = 0;
virtual std::unique_ptr<CoreBackendPartitionTable> openPartitionTable() = 0;

/**
* Create a new partition table on this device.
@@ -91,23 +92,6 @@ public:
*/
virtual bool createPartitionTable(Report& report, const PartitionTable& ptable) = 0;

/**
* Read data from an opened device into a buffer.
* @param buffer the buffer to write the read data to
* @param offset offset byte where to start reading on the device
* @param size the number of bytes to read
* @return true on success
*/
virtual bool readData(QByteArray& buffer, qint64 offset, qint64 size) = 0;

/**
* Write data from a buffer to an exclusively opened device.
* @param buffer the buffer with the data
* @param offset offset byte where to start writing to the device
* @return true on success
*/
virtual bool writeData(QByteArray& buffer, qint64 offset) = 0;

protected:
void setExclusive(bool b) {
m_Exclusive = b;

+ 19
- 6
src/backend/corebackendmanager.cpp View File

@@ -1,7 +1,7 @@
/*************************************************************************
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de> *
* Copyright (C) 2015 by Teo Mrnjavac <teo@kde.org> *
* Copyright (C) 2016 by Andrius Štikonas <andrius@stikonas.eu> *
* Copyright (C) 2016-2018 by Andrius Štikonas <andrius@stikonas.eu> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
@@ -20,8 +20,8 @@
#include "backend/corebackendmanager.h"
#include "backend/corebackend.h"

#include <QCoreApplication>
#include <QDebug>
#include <QStringList>
#include <QString>
#include <QVector>

@@ -30,8 +30,17 @@
#include <KPluginLoader>
#include <KPluginMetaData>

struct CoreBackendManagerPrivate
{
CoreBackend *m_Backend;
};

CoreBackendManager::CoreBackendManager() :
m_Backend(nullptr)
d(std::make_unique<CoreBackendManagerPrivate>())
{
}

CoreBackendManager::~CoreBackendManager()
{
}

@@ -45,6 +54,11 @@ CoreBackendManager* CoreBackendManager::self()
return instance;
}

CoreBackend* CoreBackendManager::backend()
{
return d->m_Backend;
}

QVector<KPluginMetaData> CoreBackendManager::list() const
{
auto filter = [&](const KPluginMetaData &metaData) {
@@ -66,7 +80,7 @@ bool CoreBackendManager::load(const QString& name)
KPluginFactory* factory = loader.factory();

if (factory != nullptr) {
m_Backend = factory->create<CoreBackend>(nullptr);
d->m_Backend = factory->create<CoreBackend>(nullptr);

QString id = loader.metaData().toVariantMap().value(QStringLiteral("MetaData"))
.toMap().value(QStringLiteral("KPlugin")).toMap().value(QStringLiteral("Id")).toString();
@@ -78,6 +92,7 @@ bool CoreBackendManager::load(const QString& name)
backend()->setId(id);
backend()->setVersion(version);
qDebug() << "Loaded backend plugin: " << backend()->id();

return true;
}

@@ -87,6 +102,4 @@ bool CoreBackendManager::load(const QString& name)

void CoreBackendManager::unload()
{
delete m_Backend;
m_Backend = nullptr;
}

+ 9
- 8
src/backend/corebackendmanager.h View File

@@ -1,5 +1,6 @@
/*************************************************************************
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de> *
* Copyright (C) 2018 by Andrius Štikonas <andrius@stikonas.eu> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
@@ -15,18 +16,20 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
*************************************************************************/

#if !defined(KPMCORE_COREBACKENDMANAGER_H)

#ifndef KPMCORE_COREBACKENDMANAGER_H
#define KPMCORE_COREBACKENDMANAGER_H

#include "util/libpartitionmanagerexport.h"

#include <memory>

#include <QVector>

class QString;
class QStringList;
class KPluginMetaData;
class CoreBackend;
struct CoreBackendManagerPrivate;

/**
* The backend manager class.
@@ -37,8 +40,8 @@ class CoreBackend;
*/
class LIBKPMCORE_EXPORT CoreBackendManager
{
private:
CoreBackendManager();
~CoreBackendManager();

public:
/**
@@ -50,7 +53,7 @@ public:
* @return the name of the default backend plugin
*/
static QString defaultBackendName() {
return QStringLiteral("pmlibpartedbackendplugin");
return QStringLiteral("pmsfdiskbackendplugin");
}

/**
@@ -73,12 +76,10 @@ public:
/**
* @return a pointer to the currently loaded backend
*/
CoreBackend* backend() {
return m_Backend;
}
CoreBackend* backend();

private:
CoreBackend* m_Backend;
std::unique_ptr<CoreBackendManagerPrivate> d;
};

#endif

+ 7
- 1
src/core/CMakeLists.txt View File

@@ -1,3 +1,5 @@
include(core/raid/CMakeLists.txt)

set(CORE_SRC
core/copysource.cpp
core/copysourcedevice.cpp
@@ -20,7 +22,11 @@ set(CORE_SRC
core/partitiontable.cpp
core/smartstatus.cpp
core/smartattribute.cpp
core/smartparser.cpp
core/smartattributeparseddata.cpp
core/smartdiskinformation.cpp
core/volumemanagerdevice.cpp
${RAID_SRC}
)

set(CORE_LIB_HDRS
@@ -39,5 +45,5 @@ set(CORE_LIB_HDRS
core/smartattribute.h
core/smartstatus.h
core/volumemanagerdevice.h
${RAID_LIB_HDRS}
)


+ 2
- 3
src/core/copysource.h View File

@@ -22,6 +22,7 @@
#include <QtGlobal>

class CopyTarget;
class QString;

/** Base class for something to copy from.

@@ -41,14 +42,12 @@ protected:

public:
virtual bool open() = 0;
virtual bool readData(QByteArray& buffer, qint64 readOffset, qint64 size) = 0;
virtual QString path() const = 0;
virtual qint64 length() const = 0;
virtual bool overlaps(const CopyTarget& target) const = 0;

virtual qint64 firstByte() const = 0;
virtual qint64 lastByte() const = 0;

private:
};

#endif

+ 5
- 23
src/core/copysourcedevice.cpp View File

@@ -20,7 +20,6 @@

#include "backend/corebackend.h"
#include "backend/corebackendmanager.h"
#include "backend/corebackenddevice.h"

#include "core/copytarget.h"
#include "core/copytargetdevice.h"
@@ -40,12 +39,6 @@ CopySourceDevice::CopySourceDevice(Device& d, qint64 firstbyte, qint64 lastbyte)
{
}

/** Destructs a CopySourceDevice */
CopySourceDevice::~CopySourceDevice()
{
delete m_BackendDevice;
}

/** Opens the Device
@return true if the Device could be successfully opened
*/
@@ -63,22 +56,6 @@ qint64 CopySourceDevice::length() const
return lastByte() - firstByte() + 1;
}

/** Reads a given number of bytes from the Device into the given buffer.

Note that @p readOffset must be greater or equal than zero.

@param buffer the buffer to store the read bytes in
@param readOffset the offset to begin reading
@param size the number of bytes to read

@return true if successful
*/
bool CopySourceDevice::readData(QByteArray& buffer, qint64 readOffset, qint64 size)
{
Q_ASSERT(readOffset >= 0);
return m_BackendDevice->readData(buffer, readOffset, size);
}

/** Checks if this CopySourceDevice overlaps with the given CopyTarget
@param target the CopyTarget to check overlapping with
@return true if overlaps
@@ -103,3 +80,8 @@ bool CopySourceDevice::overlaps(const CopyTarget& target) const

return false;
}

QString CopySourceDevice::path() const
{
return m_Device.deviceNode();
}

+ 7
- 4
src/core/copysourcedevice.h View File

@@ -19,14 +19,18 @@

#define KPMCORE_COPYSOURCEDEVICE_H

#include "backend/corebackenddevice.h"
#include "core/copysource.h"
#include "util/libpartitionmanagerexport.h"

#include <memory>

#include <QtGlobal>

class Device;
class CopyTarget;
class CoreBackendDevice;
class QString;

/** A Device to copy from.

@@ -40,11 +44,9 @@ class CopySourceDevice : public CopySource

public:
CopySourceDevice(Device& d, qint64 firstbyte, qint64 lastbyte);
~CopySourceDevice();

public:
bool open() override;
bool readData(QByteArray& buffer, qint64 readOffset, qint64 size) override;
qint64 length() const override;
bool overlaps(const CopyTarget& target) const override;

@@ -62,12 +64,13 @@ public:
return m_Device; /**< @return Device to copy from */
}

QString path() const override;

protected:
Device& m_Device;
const qint64 m_FirstByte;
const qint64 m_LastByte;
CoreBackendDevice* m_BackendDevice
;
std::unique_ptr<CoreBackendDevice> m_BackendDevice;
};

#endif

+ 0
- 15
src/core/copysourcefile.cpp View File

@@ -45,18 +45,3 @@ qint64 CopySourceFile::length() const
{
return QFileInfo(file()).size();
}

/** Reads the given number of bytes from the file into the given buffer.
@param buffer buffer to store the bytes read in
@param readOffset offset where to begin reading
@param size the number of bytes to read
@return true on success
*/
bool CopySourceFile::readData(QByteArray& buffer, qint64 readOffset, qint64 size)
{
if (!file().seek(readOffset))
return false;

buffer = file().read(size);
return !buffer.isEmpty();
}

+ 3
- 1
src/core/copysourcefile.h View File

@@ -40,7 +40,6 @@ public:

public:
bool open() override;
bool readData(QByteArray& buffer, qint64 readOffset, qint64 size) override;
qint64 length() const override;

bool overlaps(const CopyTarget&) const override {
@@ -52,6 +51,9 @@ public:
qint64 lastByte() const override {
return length(); /**< @return equal to length for file. @see length() */
}
QString path() const override {
return m_File.fileName();
}

protected:
QFile& file() {

+ 0
- 14
src/core/copysourceshred.cpp View File

@@ -43,17 +43,3 @@ qint64 CopySourceShred::length() const
{
return size();
}

/** Reads the given number of bytes from the source into the given buffer.
@param buffer buffer to store the data read in
@param readOffset offset where to begin reading (unused)
@param size the number of bytes to read
@return true on success
*/
bool CopySourceShred::readData(QByteArray& buffer, qint64 readOffset, qint64 size)
{
Q_UNUSED(readOffset);

buffer = sourceFile().read(size);
return !buffer.isEmpty();
}

+ 4
- 1
src/core/copysourceshred.h View File

@@ -24,6 +24,7 @@
#include <QFile>

class CopyTarget;
class QString;

/** A source for securely overwriting a partition (shredding).

@@ -38,7 +39,6 @@ public:

public:
bool open() override;
bool readData(QByteArray& buffer, qint64 readOffset, qint64 size) override;
qint64 length() const override;

bool overlaps(const CopyTarget&) const override {
@@ -50,6 +50,9 @@ public:
qint64 lastByte() const override {
return length(); /**< @return equal to length for shred source. @see length() */
}
QString path() const override {
return m_SourceFile.fileName();
}

protected:
QFile& sourceFile() {

+ 2
- 2
src/core/copytarget.h View File

@@ -21,6 +21,7 @@

#include <QtGlobal>

class QString;

/** Base class for something to copy to.

@@ -40,10 +41,9 @@ protected:

public:
virtual bool open() = 0;
virtual bool writeData(QByteArray& buffer, qint64 writeOffset) = 0;
virtual qint64 firstByte() const = 0;
virtual qint64 lastByte() const = 0;
virtual QString path() const = 0;
qint64 bytesWritten() const {
return m_BytesWritten;
}

+ 2
- 24
src/core/copytargetdevice.cpp View File

@@ -19,11 +19,9 @@

#include "backend/corebackend.h"
#include "backend/corebackendmanager.h"
#include "backend/corebackenddevice.h"

#include "core/device.h"


/** Constructs a device to copy to.
@param d the Device to copy to
@param firstbyte the first byte on the Device to write to
@@ -38,12 +36,6 @@ CopyTargetDevice::CopyTargetDevice(Device& d, qint64 firstbyte, qint64 lastbyte)
{
}

/** Destructs a CopyTargetDevice */
CopyTargetDevice::~CopyTargetDevice()
{
delete m_BackendDevice;
}

/** Opens a CopyTargetDevice for writing to.
@return true on success
*/
@@ -53,21 +45,7 @@ bool CopyTargetDevice::open()
return m_BackendDevice != nullptr;
}

/** Writes the given number of bytes to the Device.

Note that @p writeOffset must be greater or equal than zero.

@param buffer the data to write
@param writeOffset where to start writing on the Device
@return true on success
*/
bool CopyTargetDevice::writeData(QByteArray& buffer, qint64 writeOffset)
QString CopyTargetDevice::path() const
{
Q_ASSERT(writeOffset >= 0);
bool rval = m_BackendDevice->writeData(buffer, writeOffset);

if (rval)
setBytesWritten(bytesWritten() + buffer.size());

return rval;
return m_Device.deviceNode();
}

+ 5
- 3
src/core/copytargetdevice.h View File

@@ -19,9 +19,12 @@

#define KPMCORE_COPYTARGETDEVICE_H

#include "backend/corebackenddevice.h"
#include "core/copytarget.h"
#include "util/libpartitionmanagerexport.h"

#include <memory>

#include <QtGlobal>

class Device;
@@ -42,11 +45,9 @@ class CopyTargetDevice : public CopyTarget

public:
CopyTargetDevice(Device& d, qint64 firstbyte, qint64 lastbyte);
~CopyTargetDevice();

public:
bool open() override;
bool writeData(QByteArray& buffer, qint64 writeOffset) override;
qint64 firstByte() const override {
return m_FirstByte; /**< @return the first byte to write to */
}
@@ -60,10 +61,11 @@ public:
const Device& device() const {
return m_Device; /**< @return the Device to write to */
}
QString path() const override;

protected:
Device& m_Device;
CoreBackendDevice* m_BackendDevice;
std::unique_ptr<CoreBackendDevice> m_BackendDevice;
const qint64 m_FirstByte;
const qint64 m_LastByte;
};

+ 0
- 18
src/core/copytargetfile.cpp View File

@@ -33,21 +33,3 @@ bool CopyTargetFile::open()
{
return file().open(QIODevice::WriteOnly | QIODevice::Truncate);
}

/** Writes the given number of bytes from the given buffer to the file.
@param buffer the data to write
@param writeOffset where in the file to start writing
@return true on success
*/
bool CopyTargetFile::writeData(QByteArray& buffer, qint64 writeOffset)
{
if (!file().seek(writeOffset))
return false;

bool rval = file().write(buffer) == buffer.size();

if (rval)
setBytesWritten(bytesWritten() + buffer.size());

return rval;
}

+ 4
- 1
src/core/copytargetfile.h View File

@@ -40,7 +40,6 @@ public:

public:
bool open() override;
bool writeData(QByteArray& buffer, qint64 writeOffset) override;

qint64 firstByte() const override {
return 0; /**< @return always 0 for a file */
@@ -49,6 +48,10 @@ public:
return bytesWritten(); /**< @return the number of bytes written so far */
}

QString path() const override {
return m_File.fileName();
}

protected:
QFile& file() {
return m_File;

+ 95
- 26
src/core/device.cpp View File

@@ -1,6 +1,6 @@
/*************************************************************************
* Copyright (C) 2008 by Volker Lanz <vl@fidra.de> *
* Copyright (C) 2016 by Andrius Štikonas <andrius@stikonas.eu> *
* Copyright (C) 2016-2018 by Andrius Štikonas <andrius@stikonas.eu> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
@@ -17,6 +17,7 @@
*************************************************************************/

#include "core/device.h"
#include "core/device_p.h"
#include "core/partitiontable.h"
#include "core/smartstatus.h"

@@ -28,22 +29,24 @@
@param name the Device's name, usually some string defined by the manufacturer
@param deviceNode the Device's node, for example "/dev/sda"
*/
Device::Device(const QString& name,
Device::Device(std::shared_ptr<DevicePrivate> d_ptr,
const QString& name,
const QString& deviceNode,
const qint64 logicalSize,
const qint64 totalLogical,
const qint64 logicalSectorSize,
const qint64 totalLogicalSectors,
const QString& iconName,
Device::Type type)
: QObject()
, m_Name(name.length() > 0 ? name : i18n("Unknown Device"))
, m_DeviceNode(deviceNode)
, m_LogicalSize(logicalSize)
, m_TotalLogical(totalLogical)
, m_PartitionTable(nullptr)
, m_IconName(iconName.isEmpty() ? QStringLiteral("drive-harddisk") : iconName)
, m_SmartStatus(type == Device::Disk_Device ? new SmartStatus(deviceNode) : nullptr)
, m_Type(type)
, d(d_ptr)
{
d->m_Name = name.length() > 0 ? name : i18n("Unknown Device");
d->m_DeviceNode = deviceNode;
d->m_LogicalSectorSize = logicalSectorSize;
d->m_TotalLogical = totalLogicalSectors;
d->m_PartitionTable = nullptr;
d->m_IconName = iconName.isEmpty() ? QStringLiteral("drive-harddisk") : iconName;
d->m_SmartStatus = type == Device::Type::Disk_Device ? std::make_shared<SmartStatus>(deviceNode) : nullptr;
d->m_Type = type;
}

/** Copy constructor for Device.
@@ -51,30 +54,31 @@ Device::Device(const QString& name,
*/
Device::Device(const Device& other)
: QObject()
, m_Name(other.m_Name)
, m_DeviceNode(other.m_DeviceNode)
, m_LogicalSize(other.m_LogicalSize)
, m_TotalLogical(other.m_TotalLogical)
, m_PartitionTable(nullptr)
, m_IconName(other.m_IconName)
, m_SmartStatus(nullptr)
, m_Type(other.m_Type)
, d(std::make_shared<DevicePrivate>())
{
if (other.m_PartitionTable)
m_PartitionTable = new PartitionTable(*other.m_PartitionTable);
if (other.m_SmartStatus)
m_SmartStatus = new SmartStatus(*other.m_SmartStatus);
d->m_Name = other.d->m_Name;
d->m_DeviceNode = other.d->m_DeviceNode;
d->m_LogicalSectorSize = other.d->m_LogicalSectorSize;
d->m_TotalLogical = other.d->m_TotalLogical;
d->m_PartitionTable = nullptr;
d->m_IconName = other.d->m_IconName;
d->m_SmartStatus = nullptr;
d->m_Type = other.d->m_Type;
d->m_SmartStatus = other.d->m_SmartStatus;

if (other.d->m_PartitionTable)
d->m_PartitionTable = new PartitionTable(*other.d->m_PartitionTable);
}

/** Destructs a Device. */
Device::~Device()
{
delete m_PartitionTable;
delete d->m_PartitionTable;
}

bool Device::operator==(const Device& other) const
{
return m_DeviceNode == other.m_DeviceNode;
return d->m_DeviceNode == other.d->m_DeviceNode;
}

bool Device::operator!=(const Device& other) const
@@ -86,3 +90,68 @@ QString Device::prettyName() const
{
return xi18nc("@item:inlistbox Device name – Capacity (device node)", "%1 – %2 (%3)", name(), Capacity::formatByteSize(capacity()), deviceNode());
}

QString& Device::name()
{
return d->m_Name;
}

const QString& Device::name() const
{
return d->m_Name;
}

const QString& Device::deviceNode() const
{
return d->m_DeviceNode;
}

qint64 Device::logicalSize() const
{
return d->m_LogicalSectorSize;
}

qint64 Device::totalLogical() const
{
return d->m_TotalLogical;
}

PartitionTable* Device::partitionTable()
{
return d->m_PartitionTable;
}

const PartitionTable* Device::partitionTable() const
{
return d->m_PartitionTable;
}

void Device::setPartitionTable(PartitionTable* ptable)
{
d->m_PartitionTable = ptable;
}

const QString& Device::iconName() const
{
return d->m_IconName;
}

void Device::setIconName(const QString& name)
{
d->m_IconName = name;
}

SmartStatus& Device::smartStatus()
{
return *(d->m_SmartStatus);
}

const SmartStatus& Device::smartStatus() const
{
return *(d->m_SmartStatus);
}

Device::Type Device::type() const
{
return d->m_Type;
}

+ 36
- 64
src/core/device.h View File

@@ -15,8 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
*************************************************************************/

#if !defined(KPMCORE_DEVICE_H)

#ifndef KPMCORE_DEVICE_H
#define KPMCORE_DEVICE_H

#include "util/libpartitionmanagerexport.h"
@@ -24,10 +23,13 @@
#include <QString>
#include <QObject>

#include <memory>

class PartitionTable;
class CreatePartitionTableOperation;
class CoreBackend;
class SmartStatus;
class DevicePrivate;

/** A device description.

@@ -48,96 +50,66 @@ class LIBKPMCORE_EXPORT Device : public QObject
friend class CoreBackend;

public:
enum Type {
Disk_Device = 0,
LVM_Device = 1, /* VG */
RAID_Device = 2, /* software RAID device */
Unknown_Device = 4
enum class Type {
Unknown_Device,
Disk_Device,
LVM_Device, /* VG */
SoftwareRAID_Device, /* software RAID device, i.e. mdraid */
FakeRAID_Device, /* fake RAID device, i.e. dmraid */
};

protected:
explicit Device(const QString& name, const QString& deviceNode, const qint64 logicalSize, const qint64 totalLogical, const QString& iconName = QString(), Device::Type type = Device::Disk_Device);
explicit Device(std::shared_ptr<DevicePrivate> d_ptr, const QString& name, const QString& deviceNode, const qint64 logicalSectorSize, const qint64 totalLogicalSectors, const QString& iconName = QString(), Device::Type type = Device::Type::Disk_Device);

public:
explicit Device(const Device& other);
virtual ~Device();

public:
virtual bool operator==(const Device& other) const;
virtual bool operator!=(const Device& other) const;

virtual QString& name() {
return m_Name; /**< @return the Device's name, usually some manufacturer string */
}

virtual const QString& name() const {
return m_Name; /**< @return the Device's name, usually some manufacturer string */
}

virtual const QString& deviceNode() const {
return m_DeviceNode; /**< @return the Device's node, for example "/dev/sda" */
}

virtual PartitionTable* partitionTable() {
return m_PartitionTable; /**< @return the Device's PartitionTable */
}

virtual const PartitionTable* partitionTable() const {
return m_PartitionTable; /**< @return the Device's PartitionTable */
}

virtual qint64 capacity() const { /**< @return the Device's capacity in bytes */
return logicalSize() * totalLogical();
}
/**< @return the Device's name, usually some manufacturer string */
virtual QString& name();
virtual const QString& name() const;

virtual void setIconName(const QString& name) {
m_IconName = name;
}
/**< @return the Device's node, for example "/dev/sda" */
virtual const QString& deviceNode() const;

virtual const QString& iconName() const {
return m_IconName; /**< @return suggested icon name for this Device */
}
/**< @return the logical sector size the Device uses (would be extent size for e.g. LVM devices) */
virtual qint64 logicalSize() const;

virtual SmartStatus& smartStatus() {
return *m_SmartStatus;
}
/**< @return the total number of logical sectors on the device */
virtual qint64 totalLogical() const;

virtual const SmartStatus& smartStatus() const {
return *m_SmartStatus;
}
/**< @return the Device's PartitionTable */
virtual PartitionTable* partitionTable();
virtual const PartitionTable* partitionTable() const;

/**
* Change the description of the partition table for different one.
* The device itself is not changed; use CreatePartitionTableOperation
* for that. The Device instance becomes the owner of @p ptable .
*/
virtual void setPartitionTable(PartitionTable* ptable) {
m_PartitionTable = ptable;
}
virtual void setPartitionTable(PartitionTable* ptable);

virtual qint64 logicalSize() const {
return m_LogicalSize;
virtual qint64 capacity() const { /**< @return the Device's capacity in bytes */
return logicalSize() * totalLogical();
}

virtual qint64 totalLogical() const {
return m_TotalLogical;
}
/**< @return suggested icon name for this Device */
virtual const QString& iconName() const;

virtual Device::Type type() const {
return m_Type;
}
/**< @param name set the new Icon for this Device */
virtual void setIconName(const QString& name);

virtual SmartStatus& smartStatus();
virtual const SmartStatus& smartStatus() const;

virtual Device::Type type() const;

virtual QString prettyName() const;

protected:
QString m_Name;
QString m_DeviceNode;
qint64 m_LogicalSize;
qint64 m_TotalLogical;
PartitionTable* m_PartitionTable;
QString m_IconName;
SmartStatus* m_SmartStatus;
Device::Type m_Type;
std::shared_ptr<DevicePrivate> d;
};

#endif

+ 43
- 0
src/core/device_p.h View File

@@ -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

+ 56
- 9
src/core/diskdevice.cpp View File

@@ -1,6 +1,6 @@
/*************************************************************************
* Copyright (C) 2008 by Volker Lanz <vl@fidra.de> *
* Copyright (C) 2016 by Andrius Štikonas <andrius@stikonas.eu> *
* Copyright (C) 2016-2018 by Andrius Štikonas <andrius@stikonas.eu> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
@@ -17,6 +17,7 @@
*************************************************************************/

#include "core/diskdevice.h"
#include "core/device_p.h"

#include "core/partitiontable.h"
#include "core/smartstatus.h"
@@ -39,14 +40,25 @@
#define BLKPBSZGET _IO(0x12,123)/* get block physical sector size */
#endif

#define d_ptr std::static_pointer_cast<DiskDevicePrivate>(d)

class DiskDevicePrivate : public DevicePrivate
{
public:
qint32 m_Heads;
qint32 m_SectorsPerTrack;
qint32 m_Cylinders;
qint64 m_LogicalSectorSize;
qint64 m_PhysicalSectorSize;
};

static qint64 getPhysicalSectorSize(const QString& device_node)
{
/*
* possible ways of getting the physical sector size for a drive:
* - ioctl(BLKPBSZGET) -- supported with Linux 2.6.32 and later
* - /sys/block/sda/queue/physical_block_size
* - libblkid from util-linux-ng 2.17 or later
* TODO: implement the blkid method
* - libblkid from util-linux 2.17 or later (not implemented)
*/

#if defined(BLKPBSZGET)
@@ -87,11 +99,46 @@ DiskDevice::DiskDevice(const QString& name,
qint32 cylinders,
qint64 sectorSize,
const QString& iconName)
: Device(name, deviceNode, sectorSize, (static_cast<qint64>(heads) * cylinders * numSectors), iconName, Device::Disk_Device)
, m_Heads(heads)
, m_SectorsPerTrack(numSectors)
, m_Cylinders(cylinders)
, m_LogicalSectorSize(sectorSize)
, m_PhysicalSectorSize(getPhysicalSectorSize(deviceNode))
: Device(std::make_shared<DiskDevicePrivate>(), name, deviceNode, sectorSize, (static_cast<qint64>(heads) * cylinders * numSectors), iconName, Device::Type::Disk_Device)
{
d_ptr->m_Heads = heads;
d_ptr->m_SectorsPerTrack = numSectors;
d_ptr->m_Cylinders = cylinders;
d_ptr->m_LogicalSectorSize = sectorSize;
d_ptr->m_PhysicalSectorSize = getPhysicalSectorSize(deviceNode);
}

qint32 DiskDevice::heads() const
{
return d_ptr->m_Heads;
}

qint32 DiskDevice::cylinders() const
{
return d_ptr->m_Cylinders;
}

qint32 DiskDevice::sectorsPerTrack() const
{
return d_ptr->m_SectorsPerTrack;
}

qint64 DiskDevice::physicalSectorSize() const
{
return d_ptr->m_PhysicalSectorSize;
}

qint64 DiskDevice::logicalSectorSize() const
{
return d_ptr->m_LogicalSectorSize;
}

qint64 DiskDevice::totalSectors() const
{
return static_cast<qint64>(d_ptr->m_Heads) * d_ptr->m_Cylinders * d_ptr->m_SectorsPerTrack;
}

qint64 DiskDevice::cylinderSize() const
{
return static_cast<qint64>(d_ptr->m_Heads) * d_ptr->m_SectorsPerTrack;
}

+ 42
- 30
src/core/diskdevice.h View File

@@ -1,5 +1,6 @@
/*************************************************************************
* Copyright (C) 2008 by Volker Lanz <vl@fidra.de> *
* Copyright (C) 2018 by Andrius Štikonas <andrius@stikonas.eu> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
@@ -15,13 +16,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
*************************************************************************/

#if !defined(KPMCORE_DISKDEVICE_H)

#ifndef KPMCORE_DISKDEVICE_H
#define KPMCORE_DISKDEVICE_H

#include "util/libpartitionmanagerexport.h"
#include "core/device.h"

#include <memory>

#include <QString>
#include <QObject>
#include <QtGlobal>
@@ -30,6 +32,7 @@ class PartitionTable;
class CreatePartitionTableOperation;
class CoreBackend;
class SmartStatus;
class DiskDevicePrivate;

/** A disk device.

@@ -40,6 +43,7 @@ class SmartStatus;
@see PartitionTable, Partition
@author Volker Lanz <vl@fidra.de>
*/

class LIBKPMCORE_EXPORT DiskDevice : public Device
{
Q_DISABLE_COPY(DiskDevice)
@@ -51,34 +55,42 @@ public:
DiskDevice(const QString& name, const QString& deviceNode, qint32 heads, qint32 numSectors, qint32 cylinders, qint64 sectorSize, const QString& iconName = QString());

public:
qint32 heads() const {
return m_Heads; /**< @return the number of heads on the Device in CHS notation */
}
qint32 cylinders() const {
return m_Cylinders; /**< @return the number of cylinders on the Device in CHS notation */
}
qint32 sectorsPerTrack() const {
return m_SectorsPerTrack; /**< @return the number of sectors on the Device in CHS notation */
}
qint64 physicalSectorSize() const {
return m_PhysicalSectorSize; /**< @return the physical sector size the Device uses or -1 if unknown */
}
qint64 logicalSectorSize() const {
return m_LogicalSectorSize; /**< @return the logical sector size the Device uses */
}
qint64 totalSectors() const {
return static_cast<qint64>(heads()) * cylinders() * sectorsPerTrack(); /**< @return the total number of sectors on the device */
}
qint64 cylinderSize() const {
return static_cast<qint64>(heads()) * sectorsPerTrack(); /**< @return the size of a cylinder on this Device in sectors */
}

private:
qint32 m_Heads;
qint32 m_SectorsPerTrack;
qint32 m_Cylinders;
qint64 m_LogicalSectorSize;
qint64 m_PhysicalSectorSize;
/**
* @return the number of heads on the Device in CHS notation
*/
[[deprecated]]
qint32 heads() const;

/**
* @return the number of cylinders on the Device in CHS notation
*/
[[deprecated]]
qint32 cylinders() const;

/**
* @return the number of sectors on the Device in CHS notation
*/
qint32 sectorsPerTrack() const;

/**
* @return the physical sector size the Device uses or -1 if unknown
*/
qint64 physicalSectorSize() const;

/**
* @return the logical sector size the Device uses
*/
qint64 logicalSectorSize() const;

/**
* @return the total number of sectors on the device
*/
qint64 totalSectors() const;

/**
* @return the size of a cylinder on this Device in sectors
*/
qint64 cylinderSize() const;
};

#endif

+ 141
- 64
src/core/fstab.cpp View File

@@ -18,38 +18,47 @@
*************************************************************************/

#include "core/fstab.h"
#include "util/externalcommand.h"

#include <blkid/blkid.h>
#if defined(Q_OS_LINUX)
#include <blkid/blkid.h>
#endif

#include <QChar>
#include <QDebug>
#include <QFile>
#include <QFileInfo>
#include <QRegularExpression>
#include <QTemporaryFile>
#include <QTextStream>

static void parseFsSpec(const QString& m_fsSpec, FstabEntryType& m_entryType, QString& m_deviceNode);
static QString findBlkIdDevice(const QString& token, const QString& value);
static void parseFsSpec(const QString& m_fsSpec, FstabEntry::Type& m_entryType, QString& m_deviceNode);
static QString findBlkIdDevice(const char *token, const QString& value);

FstabEntry::FstabEntry(const QString& fsSpec, const QString& mountPoint, const QString& type, const QString& options, int dumpFreq, int passNumber, const QString& comment)
: m_fsSpec(fsSpec)
, m_mountPoint(mountPoint)
, m_type(type)
, m_dumpFreq(dumpFreq)
, m_passNumber(passNumber)
, m_comment(comment)
struct FstabEntryPrivate
{
m_options = options.split(QLatin1Char(','));
parseFsSpec(m_fsSpec, m_entryType, m_deviceNode);
}
QString m_fsSpec;
QString m_deviceNode;
QString m_mountPoint;
QString m_type;
QStringList m_options;
int m_dumpFreq;
int m_passNumber;
QString m_comment;
FstabEntry::Type m_entryType;
};

/**
@param s the new value for the fs_spec field of fstab entry
*/
void FstabEntry::setFsSpec(const QString& s)
FstabEntry::FstabEntry(const QString& fsSpec, const QString& mountPoint, const QString& type, const QString& options, int dumpFreq, int passNumber, const QString& comment) :
d(std::make_unique<FstabEntryPrivate>())
{
m_fsSpec = s;
parseFsSpec(m_fsSpec, m_entryType, m_deviceNode);
d->m_fsSpec = fsSpec;
d->m_mountPoint = mountPoint;
d->m_type = type;
d->m_dumpFreq = dumpFreq;
d->m_passNumber = passNumber;
d->m_comment = comment;

d->m_options = options.split(QLatin1Char(','));
parseFsSpec(d->m_fsSpec, d->m_entryType, d->m_deviceNode);
}

FstabEntryList readFstabEntries( const QString& fstabPath )
@@ -63,7 +72,7 @@ FstabEntryList readFstabEntries( const QString& fstabPath )
{
QString line = rawLine.trimmed();
if ( line.startsWith( QLatin1Char('#') ) || line.isEmpty()) {
fstabEntries.append( { {}, {}, {}, {}, {}, {}, line } );
fstabEntries.push_back( { {}, {}, {}, {}, {}, {}, line } );
continue;
}

@@ -80,27 +89,98 @@ FstabEntryList readFstabEntries( const QString& fstabPath )
// (#) comment (optional).
switch (splitLine.length()) {
case 4:
fstabEntries.append( {splitLine.at(0), splitLine.at(1), splitLine.at(2), splitLine.at(3) } );
fstabEntries.push_back( {splitLine.at(0), splitLine.at(1), splitLine.at(2), splitLine.at(3) } );
break;
case 5:
fstabEntries.append( {splitLine.at(0), splitLine.at(1), splitLine.at(2), splitLine.at(3), splitLine.at(4).toInt() } );
fstabEntries.push_back( {splitLine.at(0), splitLine.at(1), splitLine.at(2), splitLine.at(3), splitLine.at(4).toInt() } );
break;
case 6:
fstabEntries.append( {splitLine.at(0), splitLine.at(1), splitLine.at(2), splitLine.at(3), splitLine.at(4).toInt(), splitLine.at(5).toInt(), comment.isEmpty() ? QString() : QLatin1Char('#') + comment } );
fstabEntries.push_back( {splitLine.at(0), splitLine.at(1), splitLine.at(2), splitLine.at(3), splitLine.at(4).toInt(), splitLine.at(5).toInt(), comment.isEmpty() ? QString() : QLatin1Char('#') + comment } );
break;
default:
fstabEntries.append( { {}, {}, {}, {}, {}, {}, QLatin1Char('#') + line } );
fstabEntries.push_back( { {}, {}, {}, {}, {}, {}, QLatin1Char('#') + line } );
}
}

fstabFile.close();
if (fstabEntries.last().entryType() == comment && fstabEntries.last().comment().isEmpty())
fstabEntries.removeLast();
if (fstabEntries.back().entryType() == FstabEntry::Type::comment && fstabEntries.back().comment().isEmpty())
fstabEntries.pop_back();
}

return fstabEntries;
}

void FstabEntry::setFsSpec(const QString& s)
{
d->m_fsSpec = s;
parseFsSpec(d->m_fsSpec, d->m_entryType, d->m_deviceNode);
}

const QString& FstabEntry::fsSpec() const
{
return d->m_fsSpec;
}

const QString& FstabEntry::deviceNode() const
{
return d->m_deviceNode;
}

const QString& FstabEntry::mountPoint() const
{
return d->m_mountPoint;
}

const QString& FstabEntry::type() const
{
return d->m_type;
}

const QStringList& FstabEntry::options() const
{
return d->m_options;
}

int FstabEntry::dumpFreq() const
{
return d->m_dumpFreq;
}

int FstabEntry::passNumber() const
{
return d->m_passNumber;
}

const QString& FstabEntry::comment() const
{
return d->m_comment;
}

FstabEntry::Type FstabEntry::entryType() const
{
return d->m_entryType;
}

void FstabEntry::setMountPoint(const QString& s)
{
d->m_mountPoint = s;
}

void FstabEntry::setOptions(const QStringList& s)
{
d->m_options = s;
}

void FstabEntry::setDumpFreq(int s)
{
d->m_dumpFreq = s;
}

void FstabEntry::setPassNumber(int s)
{
d->m_passNumber = s;
}

QStringList possibleMountPoints(const QString& deviceNode, const QString& fstabPath)
{
QStringList mountPoints;
@@ -113,40 +193,37 @@ QStringList possibleMountPoints(const QString& deviceNode, const QString& fstabP
return mountPoints;
}

static QString findBlkIdDevice(const QString& token, const QString& value)
static QString findBlkIdDevice(const char *token, const QString& value)
{
blkid_cache cache;
QString rval;

if (blkid_get_cache(&cache, nullptr) == 0) {
if (char* c = blkid_evaluate_tag(token.toLocal8Bit().constData(), value.toLocal8Bit().constData(), &cache)) {
rval = QString::fromLocal8Bit(c);
free(c);
}

blkid_put_cache(cache);
#if defined(Q_OS_LINUX)
if (char* c = blkid_evaluate_tag(token, value.toLocal8Bit().constData(), nullptr)) {
rval = QString::fromLocal8Bit(c);
free(c);
}
#endif

return rval;
}

static void parseFsSpec(const QString& m_fsSpec, FstabEntryType& m_entryType, QString& m_deviceNode)
static void parseFsSpec(const QString& m_fsSpec, FstabEntry::Type& m_entryType, QString& m_deviceNode)
{
m_entryType = FstabEntryType::comment;
m_entryType = FstabEntry::Type::comment;
if (m_fsSpec.startsWith(QStringLiteral("UUID="))) {
m_entryType = FstabEntryType::uuid;
m_deviceNode = findBlkIdDevice(QStringLiteral("UUID"), QString(m_fsSpec).remove(QStringLiteral("UUID=")));
m_entryType = FstabEntry::Type::uuid;
m_deviceNode = findBlkIdDevice("UUID", QString(m_fsSpec).remove(QStringLiteral("UUID=")));
} else if (m_fsSpec.startsWith(QStringLiteral("LABEL="))) {
m_entryType = FstabEntryType::label;
m_deviceNode = findBlkIdDevice(QStringLiteral("LABEL"), QString(m_fsSpec).remove(QStringLiteral("LABEL=")));
m_entryType = FstabEntry::Type::label;
m_deviceNode = findBlkIdDevice("LABEL", QString(m_fsSpec).remove(QStringLiteral("LABEL=")));
} else if (m_fsSpec.startsWith(QStringLiteral("PARTUUID="))) {
m_entryType = FstabEntryType::uuid;
m_deviceNode = findBlkIdDevice(QStringLiteral("PARTUUID"), QString(m_fsSpec).remove(QStringLiteral("PARTUUID=")));
m_entryType = FstabEntry::Type::uuid;
m_deviceNode = findBlkIdDevice("PARTUUID", QString(m_fsSpec).remove(QStringLiteral("PARTUUID=")));
} else if (m_fsSpec.startsWith(QStringLiteral("PARTLABEL="))) {
m_entryType = FstabEntryType::label;
m_deviceNode = findBlkIdDevice(QStringLiteral("PARTLABEL"), QString(m_fsSpec).remove(QStringLiteral("PARTLABEL=")));
m_entryType = FstabEntry::Type::label;
m_deviceNode = findBlkIdDevice("PARTLABEL", QString(m_fsSpec).remove(QStringLiteral("PARTLABEL=")));
} else if (m_fsSpec.startsWith(QStringLiteral("/"))) {
m_entryType = FstabEntryType::deviceNode;
m_entryType = FstabEntry::Type::deviceNode;
m_deviceNode = m_fsSpec;
}
}
@@ -154,7 +231,7 @@ static void parseFsSpec(const QString& m_fsSpec, FstabEntryType& m_entryType, QS
static void writeEntry(QFile& output, const FstabEntry& entry)
{
QTextStream s(&output);
if (entry.entryType() == FstabEntryType::comment) {
if (entry.entryType() == FstabEntry::Type::comment) {
s << entry.comment() << "\n";
return;
}
@@ -177,34 +254,34 @@ static void writeEntry(QFile& output, const FstabEntry& entry)
<< entry.comment() << "\n";
}

bool writeMountpoints(const FstabEntryList fstabEntries, const QString& filename)
bool writeMountpoints(const FstabEntryList& fstabEntries, const QString& filename)
{
bool rval = true;
const QString newFilename = QStringLiteral("%1.new").arg(filename);
QFile out(newFilename);
QTemporaryFile out;
out.setAutoRemove(false);

if (!out.open(QFile::ReadWrite | QFile::Truncate)) {
qWarning() << "could not open output file " << newFilename;
rval = false;
if (!out.open()) {
qWarning() << "could not open output file " << out.fileName();
return false;
} else {
for (const auto &e : fstabEntries)
writeEntry(out, e);

out.close();

const QString bakFilename = QStringLiteral("%1.bak").arg(filename);
QFile::remove(bakFilename);
ExternalCommand mvCmd(QStringLiteral("mv"), { filename, bakFilename } );

if (QFile::exists(filename) && !QFile::rename(filename, bakFilename)) {
qWarning() << "could not rename " << filename << " to " << bakFilename;
rval = false;
if ( !(mvCmd.run(-1) && mvCmd.exitCode() == 0) ) {
qWarning() << "could not backup " << filename << " to " << bakFilename;
return false;
}

if (rval && !QFile::rename(newFilename, filename)) {
qWarning() << "could not rename " << newFilename << " to " << filename;
rval = false;
ExternalCommand mvCmd2(QStringLiteral("mv"), { out.fileName(), filename } );

if ( !(mvCmd2.run(-1) && mvCmd2.exitCode() == 0) ) {
qWarning() << "could not move " << out.fileName() << " to " << filename;
return false;
}
}

return rval;
return true;
}

+ 76
- 51
src/core/fstab.h View File

@@ -1,5 +1,5 @@
/*************************************************************************
* Copyright (C) 2017 by Andrius Štikonas <andrius@stikonas.eu> *
* Copyright (C) 2017-2018 by Andrius Štikonas <andrius@stikonas.eu> *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
@@ -20,10 +20,12 @@

#include "util/libpartitionmanagerexport.h"

#include <memory>

#include <QList>
#include <QString>

enum FstabEntryType { deviceNode, uuid, label, partlabel, partuuid, comment };
struct FstabEntryPrivate;

/** Base class for fstab handling.

@@ -35,65 +37,88 @@ enum FstabEntryType { deviceNode, uuid, label, partlabel, partuuid, comment };
class LIBKPMCORE_EXPORT FstabEntry
{
public:
enum class Type { deviceNode, uuid, label, partlabel, partuuid, comment };

FstabEntry(const QString& fsSpec, const QString& mountPoint, const QString& type, const QString& options, int dumpFreq = 0, int passNumber = 0, const QString& comment = QString());

const QString& fsSpec() const {
return m_fsSpec; /**< @return the fs_spec field of fstab entry */
}
const QString& deviceNode() const {
return m_deviceNode; /**< @return the device node corresponding to fs_spec entry */
}
const QString& mountPoint() const {
return m_mountPoint; /**< @return the mount point (target) for the file system */
}
const QString& type() const {
return m_type; /**< @return the type of the file system */
}
const QStringList& options() const {
return m_options; /**< @return the mount options associated with the file system */
}
int dumpFreq() const {
return m_dumpFreq; /**< @return the fs_freq field of fstab entry */
}
int passNumber() const {
return m_passNumber; /**< @return the fs_passno field of fstab entry */
}
const QString& comment() const {
return m_comment; /**< @return commented part of the line in fstab file */
}
FstabEntryType entryType() const {
return m_entryType; /**< @return the type of fstab entry, e.g. device node or UUID or comment only */
}
/**
* @return the fs_spec field of fstab entry
*/
const QString& fsSpec() const;

/**
* @return the device node corresponding to fs_spec entry
*/
const QString& deviceNode() const;

/**
* @return the mount point (target) for the file system
*/
const QString& mountPoint() const;

/**
* @return the type of the file system
*/
const QString& type() const;

/**
* @return the mount options associated with the file system
*/
const QStringList& options() const;

/**
* @return the fs_freq field of fstab entry
*/
int dumpFreq() const;

/**
* @return the fs_passno field of fstab entry
*/
int passNumber() const;

/**
* @return commented part of the line in fstab file
*/
const QString& comment() const;

/**
* @return the type of fstab entry, e.g. device node or UUID or comment only
*/
Type entryType() const;

/**
* @param s the new value for the fs_spec field of fstab entry
*/
void setFsSpec(const QString& s);
void setMountPoint(const QString& s) {
m_mountPoint = s; /**< @param s the new value for the mount point */
}
void setOptions(const QStringList& s) {
m_options = s; /**< @param s the new list with the mount options */
}
void setDumpFreq(int s) {
m_dumpFreq = s; /**< @param s the new value for the dump frequency */
}
void setPassNumber(int s) {
m_passNumber = s; /**< @param s the new value for the pass number */
}

/**
* @param s the new value for the mount point
*/
void setMountPoint(const QString& s);

/**
* @param s the new list with the mount options
*/
void setOptions(const QStringList& s);

/**
* @param s the new value for the dump frequency
*/
void setDumpFreq(int s);

/**
* @param s the new value for the pass number
*/
void setPassNumber(int s);

private:
QString m_fsSpec;
QString m_deviceNode;
QString m_mountPoint;
QString m_type;
QStringList m_options;
int m_dumpFreq;
int m_passNumber;
QString m_comment;
FstabEntryType m_entryType;
std::shared_ptr<FstabEntryPrivate> d;
};

typedef QList<FstabEntry> FstabEntryList;

LIBKPMCORE_EXPORT FstabEntryList readFstabEntries(const QString& fstabPath = QStringLiteral("/etc/fstab"));
LIBKPMCORE_EXPORT QStringList possibleMountPoints(const QString& deviceNode, const QString& fstabPath = QStringLiteral("/etc/fstab"));
LIBKPMCORE_EXPORT bool writeMountpoints(const FstabEntryList fstabEntries, const QString& filename = QStringLiteral("/etc/fstab"));
LIBKPMCORE_EXPORT bool writeMountpoints(const FstabEntryList& fstabEntries, const QString& filename = QStringLiteral("/etc/fstab"));

#endif

+ 103
- 31
src/core/lvmdevice.cpp View File