diff --git a/src/backend/corebackenddevice.h b/src/backend/corebackenddevice.h index 0629f33..79c0f85 100644 --- a/src/backend/corebackenddevice.h +++ b/src/backend/corebackenddevice.h @@ -1,105 +1,105 @@ /************************************************************************* * Copyright (C) 2010 by Volker Lanz * * * * 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 .* *************************************************************************/ #if !defined(KPMCORE_COREBACKENDDEVICE_H) #define KPMCORE_COREBACKENDDEVICE_H #include #include class CoreBackendPartition; class CoreBackendPartitionTable; class Partition; class PartitionTable; class Report; /** * Interface class for devices in the backend plugin. * For a device description, see Device. This * CoreBackendDevice can be used for (read- and) write * operations on the raw device. * * @author Volker Lanz */ class CoreBackendDevice { public: - CoreBackendDevice(const QString& deviceNode); + explicit CoreBackendDevice(const QString& deviceNode); virtual ~CoreBackendDevice() {} public: /** * Get the device path for this device (e.g. "/dev/sda") * @return the device path */ virtual const QString& deviceNode() const { return m_DeviceNode; } /** * Determine if this device is opened in exclusive mode. * @return true if it is opened in exclusive mode, otherwise false */ virtual bool isExclusive() const { return m_Exclusive; } /** * Open the backend device * @return true if successful */ virtual bool open() = 0; /** * Open the backend device in exclusive mode * @return true if successful */ virtual bool openExclusive() = 0; /** * Close the backend device * @return true if successful */ virtual bool close() = 0; /** * Open this backend device's partition table * @return a pointer to the CoreBackendPartitionTable for this device or nullptr in case * of errors */ virtual std::unique_ptr openPartitionTable() = 0; /** * Create a new partition table on this device. * @param report the Report to write information to * @param ptable the PartitionTable to create on this backend device * @return true if successful */ virtual bool createPartitionTable(Report& report, const PartitionTable& ptable) = 0; protected: void setExclusive(bool b) { m_Exclusive = b; } private: const QString m_DeviceNode; bool m_Exclusive; }; #endif diff --git a/src/core/copysourcefile.h b/src/core/copysourcefile.h index 3a5cebd..458b161 100644 --- a/src/core/copysourcefile.h +++ b/src/core/copysourcefile.h @@ -1,70 +1,70 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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 .* *************************************************************************/ #if !defined(KPMCORE_COPYSOURCEFILE_H) #define KPMCORE_COPYSOURCEFILE_H #include "core/copysource.h" #include #include class QString; class CopyTarget; /** A file to copy from. Represents a file to copy from. Used to restore a FileSystem from a backup file. @author Volker Lanz */ class CopySourceFile : public CopySource { public: - CopySourceFile(const QString& filename); + explicit CopySourceFile(const QString& filename); public: bool open() override; qint64 length() const override; bool overlaps(const CopyTarget&) const override { return false; /**< @return false for file */ } qint64 firstByte() const override { return 0; /**< @return 0 for file */ } 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() { return m_File; } const QFile& file() const { return m_File; } protected: QFile m_File; }; #endif diff --git a/src/core/copytargetbytearray.h b/src/core/copytargetbytearray.h index 709fa9a..4c4a38a 100644 --- a/src/core/copytargetbytearray.h +++ b/src/core/copytargetbytearray.h @@ -1,58 +1,58 @@ /************************************************************************* * Copyright (C) 2018 by Andrius Štikonas * * * * 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 .* *************************************************************************/ #ifndef KPMCORE_COPYTARGETBYTEARRAY_H #define KPMCORE_COPYTARGETBYTEARRAY_H #include "core/copytarget.h" #include #include #include /** A file to copy to. Represents a target file to copy to. Used to back up a FileSystem to a file. @see CopySourceFile, CopyTargetDevice @author Volker Lanz */ class CopyTargetByteArray : public CopyTarget { public: - CopyTargetByteArray(QByteArray& array); + explicit CopyTargetByteArray(QByteArray& array); public: bool open() override { return true; } QString path() const override { return QString(); } qint64 firstByte() const override { return 0; /**< @return always 0 for QByteArray */ } qint64 lastByte() const override { return bytesWritten(); /**< @return the number of bytes written so far */ } QByteArray& m_Array; }; #endif diff --git a/src/core/copytargetfile.h b/src/core/copytargetfile.h index 258a403..53c32d7 100644 --- a/src/core/copytargetfile.h +++ b/src/core/copytargetfile.h @@ -1,67 +1,67 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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 .* *************************************************************************/ #if !defined(KPMCORE_COPYTARGETFILE_H) #define KPMCORE_COPYTARGETFILE_H #include "core/copytarget.h" #include #include class QString; /** A file to copy to. Repesents a target file to copy to. Used to back up a FileSystem to a file. @see CopySourceFile, CopyTargetDevice @author Volker Lanz */ class CopyTargetFile : public CopyTarget { public: - CopyTargetFile(const QString& filename); + explicit CopyTargetFile(const QString& filename); public: bool open() override; qint64 firstByte() const override { return 0; /**< @return always 0 for a file */ } qint64 lastByte() const override { return bytesWritten(); /**< @return the number of bytes written so far */ } QString path() const override { return m_File.fileName(); } protected: QFile& file() { return m_File; } const QFile& file() const { return m_File; } protected: QFile m_File; }; #endif diff --git a/src/core/lvmdevice.cpp b/src/core/lvmdevice.cpp index 3ee126c..1df14e5 100644 --- a/src/core/lvmdevice.cpp +++ b/src/core/lvmdevice.cpp @@ -1,572 +1,572 @@ /************************************************************************* * Copyright (C) 2016 by Chantara Tith * * Copyright (C) 2016-2018 by Andrius Štikonas * * * * 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 .* *************************************************************************/ #include "core/lvmdevice.h" #include "core/partition.h" #include "core/partitiontable.h" #include "core/volumemanagerdevice_p.h" #include "fs/filesystem.h" #include "fs/lvm2_pv.h" #include "fs/luks.h" #include "fs/filesystemfactory.h" #include "util/externalcommand.h" #include "util/helpers.h" #include "util/globallog.h" #include "util/report.h" #include #include #include #include #define d_ptr std::static_pointer_cast(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 m_PVs; mutable std::unique_ptr> m_LVSizeMap; }; /** Constructs a representation of LVM device with initialized LV as Partitions * * @param vgName Volume Group name * @param iconName Icon representing LVM Volume group */ LvmDevice::LvmDevice(const QString& vgName, const QString& iconName) : VolumeManagerDevice(std::make_shared(), vgName, (QStringLiteral("/dev/") + vgName), getPeSize(vgName), getTotalPE(vgName), iconName, Device::Type::LVM_Device) { d_ptr->m_peSize = logicalSize(); d_ptr->m_totalPE = totalLogical(); d_ptr->m_freePE = getFreePE(vgName); d_ptr->m_allocPE = d_ptr->m_totalPE - d_ptr->m_freePE; d_ptr->m_UUID = getUUID(vgName); d_ptr->m_LVPathList = getLVs(vgName); d_ptr->m_LVSizeMap = std::make_unique>(); initPartitions(); } /** * shared list of PV's paths that will be added to any VGs. * (have been added to an operation, but not yet applied) */ QVector LvmDevice::s_DirtyPVs; /** * shared list of PVs paths that are member of VGs that will be deleted soon. */ QVector LvmDevice::s_OrphanPVs; LvmDevice::~LvmDevice() { } void LvmDevice::initPartitions() { qint64 firstUsable = 0; qint64 lastUsable = totalPE() - 1; PartitionTable* pTable = new PartitionTable(PartitionTable::vmd, firstUsable, lastUsable); for (const auto &p : scanPartitions(pTable)) { LVSizeMap()->insert(p->partitionPath(), p->length()); pTable->append(p); } if (pTable) pTable->updateUnallocated(*this); else pTable = new PartitionTable(PartitionTable::vmd, firstUsable, lastUsable); setPartitionTable(pTable); } /** * Scan LVM LV Partitions * * @param pTable Virtual PartitionTable of LVM device * @return an initialized Partition(LV) list */ const QList LvmDevice::scanPartitions(PartitionTable* pTable) const { QList pList; for (const auto &lvPath : partitionNodes()) { Partition *p = scanPartition(lvPath, pTable); pList.append(p); } return pList; } /** scan and construct a partition(LV) at a given path * * NOTE: * LVM partition has 2 different start and end sector values * 1. representing the actual LV start from 0 -> size of LV - 1 * 2. representing abstract LV's sector inside a VG partitionTable * start from last sector + 1 of last Partitions -> size of LV - 1 * Reason for this is for the LV Partition to work nicely with other parts of the codebase * without too many special cases. * * @param lvPath LVM Logical Volume path * @param pTable Abstract partition table representing partitions of LVM Volume Group * @return initialized Partition(LV) */ Partition* LvmDevice::scanPartition(const QString& lvPath, PartitionTable* pTable) const { activateLV(lvPath); qint64 lvSize = getTotalLE(lvPath); qint64 startSector = mappedSector(lvPath, 0); qint64 endSector = startSector + lvSize - 1; FileSystem::Type type = FileSystem::detectFileSystem(lvPath); FileSystem* fs = FileSystemFactory::create(type, 0, lvSize - 1, logicalSize()); fs->scan(lvPath); PartitionRole::Roles r = PartitionRole::Lvm_Lv; QString mountPoint; bool mounted; // Handle LUKS partition if (fs->type() == FileSystem::Type::Luks) { r |= PartitionRole::Luks; FS::luks* luksFs = static_cast(fs); luksFs->initLUKS(); QString mapperNode = luksFs->mapperName(); mountPoint = FileSystem::detectMountPoint(fs, mapperNode); mounted = FileSystem::detectMountStatus(fs, mapperNode); } else { mountPoint = FileSystem::detectMountPoint(fs, lvPath); mounted = FileSystem::detectMountStatus(fs, lvPath); - if (mountPoint != QString() && fs->type() != FileSystem::Type::LinuxSwap) { + if (!mountPoint.isEmpty() && fs->type() != FileSystem::Type::LinuxSwap) { const QStorageInfo storage = QStorageInfo(mountPoint); if (logicalSize() > 0 && fs->type() != FileSystem::Type::Luks && mounted && storage.isValid()) fs->setSectorsUsed( (storage.bytesTotal() - storage.bytesFree()) / logicalSize() ); } else if (fs->supportGetUsed() == FileSystem::cmdSupportFileSystem) fs->setSectorsUsed(qCeil(fs->readUsedCapacity(lvPath) / static_cast(logicalSize()))); } if (fs->supportGetLabel() != FileSystem::cmdSupportNone) { fs->setLabel(fs->readLabel(lvPath)); } if (fs->supportGetUUID() != FileSystem::cmdSupportNone) fs->setUUID(fs->readUUID(lvPath)); Partition* part = new Partition(pTable, *this, PartitionRole(r), fs, startSector, endSector, lvPath, PartitionTable::Flag::None, mountPoint, mounted); return part; } /** scan and construct list of initialized LvmDevice objects. * * @param devices list of initialized Devices */ void LvmDevice::scanSystemLVM(QList& devices) { LvmDevice::s_OrphanPVs.clear(); QList lvmList; for (const auto &vgName : getVGs()) { lvmList.append(new LvmDevice(vgName)); } // Some LVM operations require additional information about LVM physical volumes which we store in LVM::pvList::list() LVM::pvList::list().clear(); LVM::pvList::list().append(FS::lvm2_pv::getPVs(devices)); // Look for LVM physical volumes in LVM VGs for (const auto &d : lvmList) { devices.append(d); LVM::pvList::list().append(FS::lvm2_pv::getPVinNode(d->partitionTable())); } // Inform LvmDevice about which physical volumes form that particular LvmDevice for (const auto &d : lvmList) for (const auto &p : qAsConst(LVM::pvList::list())) if (p.vgName() == d->name()) d->physicalVolumes().append(p.partition()); } qint64 LvmDevice::mappedSector(const QString& lvPath, qint64 sector) const { qint64 mSector = 0; QStringList lvpathList = partitionNodes(); qint32 devIndex = lvpathList.indexOf(lvPath); if (devIndex) { for (int i = 0; i < devIndex; i++) { mSector += LVSizeMap()->value(lvpathList[i]); } mSector += sector; } return mSector; } const QStringList LvmDevice::deviceNodes() const { QStringList pvList; for (const auto &p : physicalVolumes()) { if (p->roles().has(PartitionRole::Luks)) pvList << static_cast(&p->fileSystem())->mapperName(); else pvList << p->partitionPath(); } return pvList; } const QStringList& LvmDevice::partitionNodes() const { return d_ptr->m_LVPathList; } qint64 LvmDevice::partitionSize(QString& partitionPath) const { return LVSizeMap()->value(partitionPath); } const QStringList LvmDevice::getVGs() { QStringList vgList; QString output = getField(QStringLiteral("vg_name")); if (!output.isEmpty()) { const QStringList vgNameList = output.split(QLatin1Char('\n'), QString::SkipEmptyParts); for (const auto &vgName : vgNameList) { vgList.append(vgName.trimmed()); } } return vgList; } const QStringList LvmDevice::getLVs(const QString& vgName) { QStringList lvPathList; QString cmdOutput = getField(QStringLiteral("lv_path"), vgName); if (cmdOutput.size()) { const QStringList tempPathList = cmdOutput.split(QLatin1Char('\n'), QString::SkipEmptyParts); for (const auto &lvPath : tempPathList) { lvPathList.append(lvPath.trimmed()); } } return lvPathList; } qint64 LvmDevice::getPeSize(const QString& vgName) { QString val = getField(QStringLiteral("vg_extent_size"), vgName); return val.isEmpty() ? -1 : val.toLongLong(); } qint64 LvmDevice::getTotalPE(const QString& vgName) { QString val = getField(QStringLiteral("vg_extent_count"), vgName); return val.isEmpty() ? -1 : val.toInt(); } qint64 LvmDevice::getAllocatedPE(const QString& vgName) { return getTotalPE(vgName) - getFreePE(vgName); } qint64 LvmDevice::getFreePE(const QString& vgName) { QString val = getField(QStringLiteral("vg_free_count"), vgName); return val.isEmpty() ? -1 : val.toInt(); } QString LvmDevice::getUUID(const QString& vgName) { QString val = getField(QStringLiteral("vg_uuid"), vgName); return val.isEmpty() ? QStringLiteral("---") : val; } /** Get LVM vgs command output with field name * * @param fieldName LVM field name * @param vgName the name of LVM Volume Group * @return raw output of command output, usually with many spaces within the returned string * */ QString LvmDevice::getField(const QString& fieldName, const QString& vgName) { QStringList args = { QStringLiteral("vgs"), QStringLiteral("--foreign"), QStringLiteral("--readonly"), QStringLiteral("--noheadings"), QStringLiteral("--units"), QStringLiteral("B"), QStringLiteral("--nosuffix"), QStringLiteral("--options"), fieldName }; if (!vgName.isEmpty()) { args << vgName; } ExternalCommand cmd(QStringLiteral("lvm"), args, QProcess::ProcessChannelMode::SeparateChannels); if (cmd.run(-1) && cmd.exitCode() == 0) { return cmd.output().trimmed(); } return QString(); } qint64 LvmDevice::getTotalLE(const QString& lvPath) { ExternalCommand cmd(QStringLiteral("lvm"), { QStringLiteral("lvdisplay"), lvPath}); if (cmd.run(-1) && cmd.exitCode() == 0) { QRegularExpression re(QStringLiteral("Current LE\\h+(\\d+)")); QRegularExpressionMatch match = re.match(cmd.output()); if (match.hasMatch()) { return match.captured(1).toInt(); } } Log(Log::Level::error) << xi18nc("@info:status", "An error occurred while running lvdisplay."); return -1; } bool LvmDevice::removeLV(Report& report, LvmDevice& d, Partition& p) { ExternalCommand cmd(report, QStringLiteral("lvm"), { QStringLiteral("lvremove"), QStringLiteral("--yes"), p.partitionPath()}); if (cmd.run(-1) && cmd.exitCode() == 0) { d.partitionTable()->remove(&p); return true; } return false; } bool LvmDevice::createLV(Report& report, LvmDevice& d, Partition& p, const QString& lvName) { ExternalCommand cmd(report, QStringLiteral("lvm"), { QStringLiteral("lvcreate"), QStringLiteral("--yes"), QStringLiteral("--extents"), QString::number(p.length()), QStringLiteral("--name"), lvName, d.name()}); return (cmd.run(-1) && cmd.exitCode() == 0); } bool LvmDevice::createLVSnapshot(Report& report, Partition& p, const QString& name, const qint64 extents) { QString numExtents = (extents > 0) ? QString::number(extents) : QString::number(p.length()); ExternalCommand cmd(report, QStringLiteral("lvm"), { QStringLiteral("lvcreate"), QStringLiteral("--yes"), QStringLiteral("--extents"), numExtents, QStringLiteral("--snapshot"), QStringLiteral("--name"), name, p.partitionPath() }); return (cmd.run(-1) && cmd.exitCode() == 0); } bool LvmDevice::resizeLV(Report& report, Partition& p) { ExternalCommand cmd(report, QStringLiteral("lvm"), { QStringLiteral("lvresize"), QStringLiteral("--force"), QStringLiteral("--yes"), QStringLiteral("--extents"), QString::number(p.length()), p.partitionPath()}); return (cmd.run(-1) && cmd.exitCode() == 0); } bool LvmDevice::removePV(Report& report, LvmDevice& d, const QString& pvPath) { ExternalCommand cmd(report, QStringLiteral("lvm"), { QStringLiteral("vgreduce"), d.name(), pvPath}); return (cmd.run(-1) && cmd.exitCode() == 0); } bool LvmDevice::insertPV(Report& report, LvmDevice& d, const QString& pvPath) { ExternalCommand cmd(report, QStringLiteral("lvm"), { QStringLiteral("vgextend"), QStringLiteral("--yes"), d.name(), pvPath}); return (cmd.run(-1) && cmd.exitCode() == 0); } bool LvmDevice::movePV(Report& report, const QString& pvPath, const QStringList& destinations) { if (FS::lvm2_pv::getAllocatedPE(pvPath) <= 0) return true; QStringList args = { QStringLiteral("pvmove") }; args << pvPath; if (!destinations.isEmpty()) for (const auto &destPath : destinations) args << destPath.trimmed(); ExternalCommand cmd(report, QStringLiteral("lvm"), args); return (cmd.run(-1) && cmd.exitCode() == 0); } bool LvmDevice::createVG(Report& report, const QString vgName, const QVector& pvList, const qint32 peSize) { QStringList args = { QStringLiteral("vgcreate"), QStringLiteral("--physicalextentsize"), QString::number(peSize) }; args << vgName; for (const auto &p : pvList) { if (p->roles().has(PartitionRole::Luks)) args << static_cast(&p->fileSystem())->mapperName(); else args << p->partitionPath(); } ExternalCommand cmd(report, QStringLiteral("lvm"), args); return (cmd.run(-1) && cmd.exitCode() == 0); } bool LvmDevice::removeVG(Report& report, LvmDevice& d) { bool deactivated = deactivateVG(report, d); ExternalCommand cmd(report, QStringLiteral("lvm"), { QStringLiteral("vgremove"), QStringLiteral("--force"), d.name() }); return (deactivated && cmd.run(-1) && cmd.exitCode() == 0); } bool LvmDevice::deactivateVG(Report& report, const LvmDevice& d) { ExternalCommand deactivate(report, QStringLiteral("lvm"), { QStringLiteral("vgchange"), QStringLiteral("--activate"), QStringLiteral("n"), d.name() }); return deactivate.run(-1) && deactivate.exitCode() == 0; } bool LvmDevice::deactivateLV(Report& report, const Partition& p) { ExternalCommand deactivate(report, QStringLiteral("lvm"), { QStringLiteral("lvchange"), QStringLiteral("--activate"), QStringLiteral("n"), p.partitionPath() }); return deactivate.run(-1) && deactivate.exitCode() == 0; } bool LvmDevice::activateVG(Report& report, const LvmDevice& d) { ExternalCommand deactivate(report, QStringLiteral("lvm"), { QStringLiteral("vgchange"), QStringLiteral("--activate"), QStringLiteral("y"), d.name() }); return deactivate.run(-1) && deactivate.exitCode() == 0; } bool LvmDevice::activateLV(const QString& lvPath) { ExternalCommand deactivate(QStringLiteral("lvm"), { QStringLiteral("lvchange"), QStringLiteral("--activate"), QStringLiteral("y"), lvPath }); return deactivate.run(-1) && deactivate.exitCode() == 0; } qint64 LvmDevice::peSize() const { return d_ptr->m_peSize; } qint64 LvmDevice::totalPE() const { return d_ptr->m_totalPE; } qint64 LvmDevice::allocatedPE() const { return d_ptr->m_allocPE; } qint64 LvmDevice::freePE() const { return d_ptr->m_freePE; } void LvmDevice::setFreePE(qint64 freePE) const { d_ptr->m_freePE = freePE; d_ptr->m_allocPE = d_ptr->m_totalPE - freePE; } QString LvmDevice::UUID() const { return d_ptr->m_UUID; } QVector & LvmDevice::physicalVolumes() { return d_ptr->m_PVs; } const QVector & LvmDevice::physicalVolumes() const { return d_ptr->m_PVs; } std::unique_ptr>& LvmDevice::LVSizeMap() const { return d_ptr->m_LVSizeMap; } diff --git a/src/core/lvmdevice.h b/src/core/lvmdevice.h index 922ed01..16d1cc0 100644 --- a/src/core/lvmdevice.h +++ b/src/core/lvmdevice.h @@ -1,113 +1,113 @@ /************************************************************************* * Copyright (C) 2016 by Chantara Tith * * Copyright (C) 2016 by Andrius Štikonas * * * * 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 .* *************************************************************************/ #ifndef KPMCORE_LVMDEVICE_H #define KPMCORE_LVMDEVICE_H #include "core/device.h" #include "core/volumemanagerdevice.h" #include "util/libpartitionmanagerexport.h" #include #include #include #include #include #include class PartitionTable; class Report; class Partition; class SmartStatus; /** Representation of LVM Volume Group(VG). Devices are the outermost entity; they contain a PartitionTable that itself contains Partitions. @see Device, VolumeManagerDevice, PartitionTable, Partition */ class LIBKPMCORE_EXPORT LvmDevice : public VolumeManagerDevice { Q_DISABLE_COPY(LvmDevice) friend class VolumeManagerDevice; public: - LvmDevice(const QString& name, const QString& iconName = QString()); + explicit LvmDevice(const QString& name, const QString& iconName = QString()); ~LvmDevice(); public: const QStringList deviceNodes() const override; const QStringList& partitionNodes() const override; qint64 partitionSize(QString& partitionPath) const override; static QVector s_DirtyPVs; static QVector s_OrphanPVs; static const QStringList getVGs(); static const QStringList getLVs(const QString& vgName); static qint64 getPeSize(const QString& vgName); static qint64 getTotalPE(const QString& vgName); static qint64 getAllocatedPE(const QString& vgName); static qint64 getFreePE(const QString& vgName); static QString getUUID(const QString& vgName); static QString getField(const QString& fieldName, const QString& vgName = QString()); static qint64 getTotalLE(const QString& lvPath); static bool removeLV(Report& report, LvmDevice& d, Partition& p); static bool createLV(Report& report, LvmDevice& d, Partition& p, const QString& lvName); static bool createLVSnapshot(Report& report, Partition& p, const QString& name, const qint64 extents = 0); static bool resizeLV(Report& report, Partition& p); static bool deactivateLV(Report& report, const Partition& p); static bool activateLV(const QString& deviceNode); static bool removePV(Report& report, LvmDevice& d, const QString& pvPath); static bool insertPV(Report& report, LvmDevice& d, const QString& pvPath); static bool movePV(Report& report, const QString& pvPath, const QStringList& destinations = QStringList()); static bool removeVG(Report& report, LvmDevice& d); static bool createVG(Report& report, const QString vgName, const QVector& pvList, const qint32 peSize = 4); // peSize in megabytes static bool deactivateVG(Report& report, const LvmDevice& d); static bool activateVG(Report& report, const LvmDevice& d); protected: void initPartitions() override; const QList scanPartitions(PartitionTable* pTable) const; Partition* scanPartition(const QString& lvPath, PartitionTable* pTable) const; qint64 mappedSector(const QString& lvPath, qint64 sector) const override; public: qint64 peSize() const; qint64 totalPE() const; qint64 allocatedPE() const; qint64 freePE() const; void setFreePE(qint64 freePE) const; QString UUID() const; QVector & physicalVolumes(); const QVector & physicalVolumes() const; protected: std::unique_ptr>& LVSizeMap() const; private: static void scanSystemLVM(QList& devices); }; #endif diff --git a/src/core/operationstack.h b/src/core/operationstack.h index ccf2897..7276dd4 100644 --- a/src/core/operationstack.h +++ b/src/core/operationstack.h @@ -1,109 +1,109 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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 .* *************************************************************************/ #if !defined(KPMCORE_OPERATIONSTACK_H) #define KPMCORE_OPERATIONSTACK_H #include "util/libpartitionmanagerexport.h" #include #include #include #include class Device; class Partition; class Operation; class DeviceScanner; /** The list of Operations the user wants to have performed. OperationStack also handles the Devices that were found on this computer and the merging of Operations, e.g., when the user first creates a Partition, then deletes it. @author Volker Lanz */ class LIBKPMCORE_EXPORT OperationStack : public QObject { Q_OBJECT Q_DISABLE_COPY(OperationStack) friend class DeviceScanner; public: typedef QList Devices; typedef QList Operations; public: - OperationStack(QObject* parent = nullptr); + explicit OperationStack(QObject* parent = nullptr); ~OperationStack(); Q_SIGNALS: void operationsChanged(); void devicesChanged(); public: void push(Operation* o); void pop(); bool contains(const Partition* p) const; void clearOperations(); int size() const { return operations().size(); /**< @return number of operations */ } Devices& previewDevices() { return m_PreviewDevices; /**< @return the list of Devices */ } const Devices& previewDevices() const { return m_PreviewDevices; /**< @return the list of Devices */ } Operations& operations() { return m_Operations; /**< @return the list of operations */ } const Operations& operations() const { return m_Operations; /**< @return the list of operations */ } Device* findDeviceForPartition(const Partition* p); QReadWriteLock& lock() { return m_Lock; } protected: void clearDevices(); void addDevice(Device* d); void sortDevices(); bool mergeNewOperation(Operation*& currentOp, Operation*& pushedOp); bool mergeCopyOperation(Operation*& currentOp, Operation*& pushedOp); bool mergeRestoreOperation(Operation*& currentOp, Operation*& pushedOp); bool mergePartFlagsOperation(Operation*& currentOp, Operation*& pushedOp); bool mergePartLabelOperation(Operation*& currentOp, Operation*& pushedOp); bool mergeCreatePartitionTableOperation(Operation*& currentOp, Operation*& pushedOp); bool mergeResizeVolumeGroupResizeOperation(Operation*& pushedOp); private: Operations m_Operations; mutable Devices m_PreviewDevices; QReadWriteLock m_Lock; }; #endif diff --git a/src/core/raid/softwareraid.h b/src/core/raid/softwareraid.h index 447856b..0789ec2 100644 --- a/src/core/raid/softwareraid.h +++ b/src/core/raid/softwareraid.h @@ -1,105 +1,105 @@ /************************************************************************* * Copyright (C) 2018 by Caio Carvalho * * * * 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 .* *************************************************************************/ #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) friend class VolumeManagerDevice; public: enum class Status { Active, Inactive, Resync, Recovery, }; - SoftwareRAID(const QString& name, + explicit 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 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 void scanSoftwareRAID(QList& devices); static QString getDetail(const QString& path); static QString getRAIDConfiguration(const QString& configurationPath); }; #endif // SOFTWARERAID_H diff --git a/src/core/smartattribute.h b/src/core/smartattribute.h index 2df9ae9..7df36a4 100644 --- a/src/core/smartattribute.h +++ b/src/core/smartattribute.h @@ -1,105 +1,105 @@ /************************************************************************* * Copyright (C) 2010 by Volker Lanz * * * * 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 .* *************************************************************************/ #ifndef KPMCORE_SMARTATTRIBUTE_H #define KPMCORE_SMARTATTRIBUTE_H #include "util/libpartitionmanagerexport.h" #include class SmartAttributeParsedData; class LIBKPMCORE_EXPORT SmartAttribute { public: enum class FailureType { PreFailure, OldAge }; enum class UpdateType { Online, Offline }; enum class Assessment { NotApplicable, Failing, HasFailed, Warning, Good }; public: - SmartAttribute(const SmartAttributeParsedData& a); + explicit SmartAttribute(const SmartAttributeParsedData& a); public: qint32 id() const { return m_Id; } const QString& name() const { return m_Name; } const QString& desc() const { return m_Desc; } FailureType failureType() const { return m_FailureType; } UpdateType updateType() const { return m_UpdateType; } qint32 current() const { return m_Current; } qint32 worst() const { return m_Worst; } qint32 threshold() const { return m_Threshold; } const QString& raw() const { return m_Raw; } Assessment assessment() const { return m_Assessment; } const QString& value() const { return m_Value; } QString assessmentToString() const { return assessmentToString(assessment()); } static QString assessmentToString(Assessment a); private: qint32 m_Id; QString m_Name; QString m_Desc; FailureType m_FailureType; UpdateType m_UpdateType; qint32 m_Current; qint32 m_Worst; qint32 m_Threshold; QString m_Raw; Assessment m_Assessment; QString m_Value; }; #endif diff --git a/src/core/smartparser.h b/src/core/smartparser.h index 6869c01..115fbd5 100644 --- a/src/core/smartparser.h +++ b/src/core/smartparser.h @@ -1,64 +1,64 @@ /************************************************************************* * Copyright (C) 2018 by Caio Carvalho * * * * 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 .* *************************************************************************/ #ifndef KPMCORE_SMARTPARSER_H #define KPMCORE_SMARTPARSER_H #include #include class SmartDiskInformation; /** A parser to SMART JSON output. Responsible to execute smartctl and parse its output. @author Caio Carvalho */ class SmartParser { public: - SmartParser(const QString &device_path); + explicit SmartParser(const QString &device_path); ~SmartParser(); public: bool init(); public: const QString &devicePath() const { return m_DevicePath; /**< @return the device path that SMART must analyze */ } SmartDiskInformation *diskInformation() const { return m_DiskInformation; /**< @return a reference to parsed disk information */ } protected: void loadSmartOutput(); void loadAttributes(); private: const QString m_DevicePath; QJsonDocument m_SmartOutput; SmartDiskInformation *m_DiskInformation; }; #endif // SMARTPARSER_H diff --git a/src/core/smartstatus.h b/src/core/smartstatus.h index 06defe8..d480cd2 100644 --- a/src/core/smartstatus.h +++ b/src/core/smartstatus.h @@ -1,186 +1,186 @@ /************************************************************************* * Copyright (C) 2010 by Volker Lanz * * * * 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 .* *************************************************************************/ #ifndef KPMCORE_SMARTSTATUS_H #define KPMCORE_SMARTSTATUS_H #include "util/libpartitionmanagerexport.h" #include "core/smartattribute.h" #include #include #include struct SkSmartAttributeParsedData; struct SkDisk; class LIBKPMCORE_EXPORT SmartStatus { public: enum class Overall { Good, BadPast, BadSectors, BadNow, BadSectorsMany, Bad }; enum class SelfTestStatus { Success, Aborted, Interrupted, Fatal, ErrorUnknown, ErrorEletrical, ErrorServo, ErrorRead, ErrorHandling, InProgress = 15, }; public: typedef QList Attributes; public: - SmartStatus(const QString &device_path); + explicit SmartStatus(const QString &device_path); public: void update(); const QString &devicePath() const { return m_DevicePath; } bool isValid() const { return m_InitSuccess; } bool status() const { return m_Status; } const QString &modelName() const { return m_ModelName; } const QString &serial() const { return m_Serial; } const QString &firmware() const { return m_Firmware; } quint64 temp() const { return m_Temp; } quint64 badSectors() const { return m_BadSectors; } quint64 powerCycles() const { return m_PowerCycles; } quint64 poweredOn() const { return m_PoweredOn; } const Attributes &attributes() const { return m_Attributes; } Overall overall() const { return m_Overall; } SelfTestStatus selfTestStatus() const { return m_SelfTestStatus; } void addAttributes(QList attr); static QString tempToString(quint64 mkelvin); static QString overallAssessmentToString(Overall o); static QString selfTestStatusToString(SmartStatus::SelfTestStatus s); private: void setStatus(bool s) { m_Status = s; } void setModelName(const QString &name) { m_ModelName = name; } void setSerial(const QString &s) { m_Serial = s; } void setFirmware(const QString &f) { m_Firmware = f; } void setTemp(quint64 t) { m_Temp = t; } void setInitSuccess(bool b) { m_InitSuccess = b; } void setBadSectors(quint64 s) { m_BadSectors = s; } void setPowerCycles(quint64 p) { m_PowerCycles = p; } void setPoweredOn(quint64 t) { m_PoweredOn = t; } void setOverall(Overall o) { m_Overall = o; } void setSelfTestStatus(SelfTestStatus s) { m_SelfTestStatus = s; } private: const QString m_DevicePath; bool m_InitSuccess; bool m_Status; QString m_ModelName; QString m_Serial; QString m_Firmware; Overall m_Overall; SelfTestStatus m_SelfTestStatus; quint64 m_Temp; quint64 m_BadSectors; quint64 m_PowerCycles; quint64 m_PoweredOn; Attributes m_Attributes; }; #endif diff --git a/src/core/volumemanagerdevice.cpp b/src/core/volumemanagerdevice.cpp index 68036d1..3e87dc3 100644 --- a/src/core/volumemanagerdevice.cpp +++ b/src/core/volumemanagerdevice.cpp @@ -1,57 +1,57 @@ /************************************************************************* * Copyright (C) 2016 by Chantara Tith * * Copyright (C) 2018 by Andrius Štikonas * * * * 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 .* *************************************************************************/ -#include "core/device_p.h" #include "core/volumemanagerdevice.h" #include "core/volumemanagerdevice_p.h" +#include "core/device_p.h" #include "core/lvmdevice.h" #include "core/raid/softwareraid.h" /** Constructs an abstract Volume Manager Device with an empty PartitionTable. * * @param name the Device's name * @param deviceNode the Device's node * @param logicalExtentSize the logical extent size that device uses */ VolumeManagerDevice::VolumeManagerDevice(std::shared_ptr d, const QString& name, const QString& deviceNode, const qint64 logicalExtentSize, const qint64 totalLogical, const QString& iconName, Device::Type type) : Device(std::static_pointer_cast(d), name, deviceNode, logicalExtentSize, totalLogical, iconName, type) { } void VolumeManagerDevice::scanDevices(QList& devices) { SoftwareRAID::scanSoftwareRAID(devices); LvmDevice::scanSystemLVM(devices); // LVM scanner needs all other devices, so should be last } QString VolumeManagerDevice::prettyDeviceNodeList() const { return deviceNodes().join(QStringLiteral(", ")); } void VolumeManagerDevice::setTotalLogical(qint64 n) { Q_ASSERT(n > 0); d->m_TotalLogical = n; } diff --git a/src/fs/filesystem.cpp b/src/fs/filesystem.cpp index 8b795f0..141c13d 100644 --- a/src/fs/filesystem.cpp +++ b/src/fs/filesystem.cpp @@ -1,695 +1,695 @@ /************************************************************************* * Copyright (C) 2012 by Volker Lanz * * Copyright (C) 2015 by Teo Mrnjavac * * Copyright (C) 2016-2018 by Andrius Štikonas * * * * 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 .* *************************************************************************/ +#include "fs/filesystem.h" #include "core/fstab.h" -#include "fs/filesystem.h" #include "fs/lvm2_pv.h" #include "backend/corebackend.h" #include "backend/corebackendmanager.h" #include "util/externalcommand.h" #include "util/capacity.h" #include "util/helpers.h" #include #include #include #include #include const std::vector FileSystem::defaultColorCode = { { QColor( 220,205,175 ), // unknown QColor( 187,249,207 ), // extended QColor( 102,121,150 ), // ext2 QColor( 122,145,180 ), // ext3 QColor( 143,170,210 ), // ext4 QColor( 155,155,130 ), // swap QColor( 204,179,215 ), // fat16 QColor( 229,201,240 ), // fat32 QColor( 244,214,255 ), // ntfs QColor( 216,220,135 ), // reiser QColor( 251,255,157 ), // reiser4 QColor( 200,255,254 ), // xfs QColor( 137,200,198 ), // jfs QColor( 210,136,142 ), // hfs QColor( 240,165,171 ), // hfs+ QColor( 151,220,134 ), // ufs QColor( 220,205,175 ), // unformatted QColor( 173,205,255 ), // btrfs QColor( 176,155,185 ), // hpfs QColor( 170,30,77 ), // luks QColor( 96,140,85 ), // ocfs2 QColor( 33,137,108 ), // zfs QColor( 250,230,255 ), // exfat QColor( 242,155,104 ), // nilfs2 QColor( 160,210,180 ), // lvm2 pv QColor( 255,170,0 ), // f2fs QColor( 170,120,255 ), // udf QColor( 177,82,69 ), // iso9660 QColor( 223,39,104 ), // luks2 QColor( 204,179,255 ), // fat12 QColor( 255,100,100 ), // linux_raid_member QColor( 110,20,50 ), // bitlocker QColor( 255,155,174 ), // apfs QColor( 0,170,255 ), // minix } }; struct FileSystemPrivate { FileSystem::Type m_Type; qint64 m_FirstSector; qint64 m_LastSector; qint64 m_SectorSize; qint64 m_SectorsUsed; QString m_Label; QString m_UUID; QList m_AvailableFeatures; QList m_Features; }; /** Creates a new FileSystem object @param firstsector the first sector used by this FileSystem on the Device @param lastsector the last sector used by this FileSystem on the Device @param sectorsused the number of sectors in use on the FileSystem @param label the FileSystem label @param type the FileSystem type */ FileSystem::FileSystem(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type type) : d(std::make_unique()) { d->m_Type = type; d->m_FirstSector = firstsector; d->m_LastSector = lastsector; d->m_SectorsUsed = sectorsused; d->m_Label = label; d->m_UUID = QString(); } /** Creates a new FileSystem object @param firstsector the first sector used by this FileSystem on the Device @param lastsector the last sector used by this FileSystem on the Device @param sectorsused the number of sectors in use on the FileSystem @param label the FileSystem label @param features the FileSystem features @param type the FileSystem type */ FileSystem::FileSystem(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QList& features, FileSystem::Type type) : d(std::make_unique()) { d->m_Type = type; d->m_FirstSector = firstsector; d->m_LastSector = lastsector; d->m_SectorsUsed = sectorsused; d->m_Label = label; d->m_Features = features; d->m_UUID = QString(); } FileSystem::~FileSystem() { } /** Reads the capacity in use on this FileSystem @param deviceNode the device node for the Partition the FileSystem is on @return the used capacity in bytes or -1 in case of an error */ qint64 FileSystem::readUsedCapacity(const QString& deviceNode) const { Q_UNUSED(deviceNode) return -1; } FileSystem::Type FileSystem::detectFileSystem(const QString& partitionPath) { return CoreBackendManager::self()->backend()->detectFileSystem(partitionPath); } QString FileSystem::detectMountPoint(FileSystem* fs, const QString& partitionPath) { if (fs->type() == FileSystem::Type::Lvm2_PV) return FS::lvm2_pv::getVGName(partitionPath); if (partitionPath.isEmpty()) // Happens when during initial scan LUKS is closed return QString(); QStringList mountPoints; QFileInfo partitionPathFileInfo(partitionPath); QString partitionCanonicalPath = partitionPathFileInfo.canonicalFilePath(); const QList mountedVolumes = QStorageInfo::mountedVolumes(); for (const QStorageInfo &storage : mountedVolumes) { if (partitionCanonicalPath == QFileInfo(QString::fromLocal8Bit(storage.device())).canonicalFilePath() ) { mountPoints.append(storage.rootPath()); } } mountPoints.append(possibleMountPoints(partitionPath)); return mountPoints.isEmpty() ? QString() : mountPoints.first(); } bool FileSystem::detectMountStatus(FileSystem* fs, const QString& partitionPath) { bool mounted = false; if (fs->type() == FileSystem::Type::Lvm2_PV) { - mounted = FS::lvm2_pv::getVGName(partitionPath) != QString(); + mounted = !FS::lvm2_pv::getVGName(partitionPath).isEmpty(); } else { mounted = isMounted(partitionPath); } return mounted; } /** Reads the label for this FileSystem @param deviceNode the device node for the Partition the FileSystem is on @return the FileSystem label or an empty string in case of error */ QString FileSystem::readLabel(const QString& deviceNode) const { return CoreBackendManager::self()->backend()->readLabel(deviceNode); } /** Creates a new FileSystem @param report Report to write status information to @param deviceNode the device node for the Partition to create the FileSystem on @return true if successful */ bool FileSystem::create(Report& report, const QString& deviceNode) { Q_UNUSED(report) Q_UNUSED(deviceNode) return true; } /** Creates a new FileSystem with a specified Label @param report Report to write status information to @param deviceNode the device node for the Partition to create the FileSystem on @param label the new label for the FileSystem @return true if successful */ bool FileSystem::createWithLabel(Report& report, const QString& deviceNode, const QString& label) { Q_UNUSED(report) Q_UNUSED(deviceNode) Q_UNUSED(label) return true; } /** Scans a new FileSystem and load file system specific class variables. * @param deviceNode the device node for the Partition to create the FileSystem on */ void FileSystem::scan(const QString& deviceNode) { Q_UNUSED(deviceNode) } /** Resize a FileSystem to a given new length @param report Report to write status information to @param deviceNode the device node for the Partition the FileSystem is on @param newLength the new length for the FileSystem in bytes @return true on success */ bool FileSystem::resize(Report& report, const QString& deviceNode, qint64 newLength) const { Q_UNUSED(report) Q_UNUSED(deviceNode) Q_UNUSED(newLength) return true; } /** Resize a mounted FileSystem to a given new length @param report Report to write status information to @param deviceNode the device node for the Partition the FileSystem is on @param mountPoint the mount point where FileSystem is mounted on @param newLength the new length for the FileSystem in bytes @return true on success */ bool FileSystem::resizeOnline(Report& report, const QString& deviceNode, const QString& mountPoint, qint64 newLength) const { Q_UNUSED(report) Q_UNUSED(deviceNode) Q_UNUSED(mountPoint) Q_UNUSED(newLength) return true; } /** Move a FileSystem to a new start sector @param report Report to write status information to @param deviceNode the device node for the Partition the FileSystem is on @param newStartSector the new start sector for the FileSystem @return true on success */ bool FileSystem::move(Report& report, const QString& deviceNode, qint64 newStartSector) const { Q_UNUSED(report) Q_UNUSED(deviceNode) Q_UNUSED(newStartSector) return true; } /** Writes a label for the FileSystem to disk @param report Report to write status information to @param deviceNode the device node for the Partition the FileSystem is on @param newLabel the new label for the FileSystem @return true on success */ bool FileSystem::writeLabel(Report& report, const QString& deviceNode, const QString& newLabel) { Q_UNUSED(report) Q_UNUSED(deviceNode) Q_UNUSED(newLabel) return true; } /** Writes a label for the FileSystem to disk @param report Report to write status information to @param deviceNode the device node for the Partition the FileSystem is on @param mountPoint the mount point where FileSystem is mounted on @param newLabel the new label for the FileSystem @return true on success */ bool FileSystem::writeLabelOnline(Report& report, const QString& deviceNode, const QString& mountPoint, const QString& newLabel) { Q_UNUSED(report) Q_UNUSED(deviceNode) Q_UNUSED(mountPoint) Q_UNUSED(newLabel) return true; } /** Copies a FileSystem from one Partition to another @param report Report to write status information to @param targetDeviceNode device node of the target Partition @param sourceDeviceNode device node of the source Partition @return true on success */ bool FileSystem::copy(Report& report, const QString& targetDeviceNode, const QString& sourceDeviceNode) const { Q_UNUSED(report) Q_UNUSED(targetDeviceNode) Q_UNUSED(sourceDeviceNode) return true; } /** Backs up a FileSystem to a file @param report Report to write status information to @param sourceDevice Device the source FileSystem is on @param deviceNode device node of the source Partition @param filename name of the file to backup to @return true on success */ bool FileSystem::backup(Report& report, const Device& sourceDevice, const QString& deviceNode, const QString& filename) const { Q_UNUSED(report) Q_UNUSED(sourceDevice) Q_UNUSED(deviceNode) Q_UNUSED(filename) return false; } /** Removes a FileSystem @param report Report to write status information to @param deviceNode the device node for the Partition the FileSystem is on @return true if FileSystem is removed */ bool FileSystem::remove(Report& report, const QString& deviceNode) const { Q_UNUSED(report) Q_UNUSED(deviceNode) return true; } /** Checks a FileSystem for errors @param report Report to write status information to @param deviceNode the device node for the Partition the FileSystem is on @return true if FileSystem is error-free */ bool FileSystem::check(Report& report, const QString& deviceNode) const { Q_UNUSED(report) Q_UNUSED(deviceNode) return true; } /** Updates a FileSystem UUID on disk @param report Report to write status information to @param deviceNode the device node for the Partition the FileSystem is on @return true on success */ bool FileSystem::updateUUID(Report& report, const QString& deviceNode) const { Q_UNUSED(report) Q_UNUSED(deviceNode) return true; } /** Returns the FileSystem UUID by calling a FileSystem-specific helper program @param deviceNode the device node for the Partition the FileSystem is on @return the UUID or an empty string if the FileSystem does not support UUIDs */ QString FileSystem::readUUID(const QString& deviceNode) const { return CoreBackendManager::self()->backend()->readUUID(deviceNode); } /** Give implementations of FileSystem a chance to update the boot sector after the file system has been moved or copied. @param report Report to write status information to @param deviceNode the device node for the Partition the FileSystem is on @return true on success */ bool FileSystem::updateBootSector(Report& report, const QString& deviceNode) const { Q_UNUSED(report) Q_UNUSED(deviceNode) return true; } /** @return the minimum capacity valid for this FileSystem in bytes */ qint64 FileSystem::minCapacity() const { return 8 * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB); } /** @return the maximum capacity valid for this FileSystem in bytes */ qint64 FileSystem::maxCapacity() const { return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB); } /** @return the maximum label length valid for this FileSystem */ int FileSystem::maxLabelLength() const { return 16; } /** Validates the label for this FileSystem * @param parent the parent widget passed to the QObject constructor * @return QValidator to validate the file system label line edit input */ QValidator* FileSystem::labelValidator(QObject *parent) const { Q_UNUSED(parent) return nullptr; } /** @return this FileSystem's type as printable name */ QString FileSystem::name(const QStringList& languages) const { return nameForType(type(), languages); } FileSystem::Type FileSystem::type() const { return d->m_Type; } /** @return a pointer to a QString C array with all FileSystem names */ static const KLocalizedString* typeNames() { static const KLocalizedString s[] = { kxi18nc("@item filesystem name", "unknown"), kxi18nc("@item filesystem name", "extended"), kxi18nc("@item filesystem name", "ext2"), kxi18nc("@item filesystem name", "ext3"), kxi18nc("@item filesystem name", "ext4"), kxi18nc("@item filesystem name", "linuxswap"), kxi18nc("@item filesystem name", "fat16"), kxi18nc("@item filesystem name", "fat32"), kxi18nc("@item filesystem name", "ntfs"), kxi18nc("@item filesystem name", "reiser"), kxi18nc("@item filesystem name", "reiser4"), kxi18nc("@item filesystem name", "xfs"), kxi18nc("@item filesystem name", "jfs"), kxi18nc("@item filesystem name", "hfs"), kxi18nc("@item filesystem name", "hfsplus"), kxi18nc("@item filesystem name", "ufs"), kxi18nc("@item filesystem name", "unformatted"), kxi18nc("@item filesystem name", "btrfs"), kxi18nc("@item filesystem name", "hpfs"), kxi18nc("@item filesystem name", "luks"), kxi18nc("@item filesystem name", "ocfs2"), kxi18nc("@item filesystem name", "zfs"), kxi18nc("@item filesystem name", "exfat"), kxi18nc("@item filesystem name", "nilfs2"), kxi18nc("@item filesystem name", "lvm2 pv"), kxi18nc("@item filesystem name", "f2fs"), kxi18nc("@item filesystem name", "udf"), kxi18nc("@item filesystem name", "iso9660"), kxi18nc("@item filesystem name", "luks2"), kxi18nc("@item filesystem name", "fat12"), kxi18nc("@item filesystem name", "linux_raid_member"), kxi18nc("@item filesystem name", "BitLocker"), kxi18nc("@item filesystem name", "apfs"), kxi18nc("@item filesystem name", "minix"), }; return s; } /** @param t the type to get the name for @return the printable name for the given type */ QString FileSystem::nameForType(FileSystem::Type t, const QStringList& languages) { Q_ASSERT(t < Type::__lastType); return typeNames()[static_cast(t)].toString(languages); } /** @param s the name to get the type for @return the type for the name or FileSystem::Unknown if not found */ FileSystem::Type FileSystem::typeForName(const QString& s, const QStringList& languages ) { for (quint32 i = 0; i < static_cast(Type::__lastType); i++) if (typeNames()[i].toString(languages) == s) return static_cast(i); return Type::Unknown; } /** @return a QList of all known types */ QList FileSystem::types() { QList result; int i = static_cast(Type::Ext2); // first "real" filesystem while (i != static_cast(Type::__lastType)) result.append(static_cast(i++)); return result; } /** @return printable menu title for mounting this FileSystem */ QString FileSystem::mountTitle() const { return xi18nc("@title:menu", "Mount"); } /** @return printable menu title for unmounting this FileSystem */ QString FileSystem::unmountTitle() const { return xi18nc("@title:menu", "Unmount"); } /** Moves a FileSystem to a new start sector. @param newStartSector where the FileSystem should be moved to */ void FileSystem::move(qint64 newStartSector) { const qint64 savedLength = length(); setFirstSector(newStartSector); setLastSector(newStartSector + savedLength - 1); } bool FileSystem::canMount(const QString& deviceNode, const QString& mountPoint) const { Q_UNUSED(deviceNode) // cannot mount if we have no mount points return !mountPoint.isEmpty(); } /** Attempt to mount this FileSystem on a given mount point @param report the report to write information to @param deviceNode the path to the device that is to be unmounted @param mountPoint the mount point to mount the FileSystem on @return true on success */ bool FileSystem::mount(Report& report, const QString &deviceNode, const QString &mountPoint) { ExternalCommand mountCmd( report, QStringLiteral("mount"), { QStringLiteral("--verbose"), deviceNode, mountPoint }); if (mountCmd.run() && mountCmd.exitCode() == 0) { return true; } return false; } /** Attempt to unmount this FileSystem @param report the report to write information to @param deviceNode the path to the device that is to be unmounted @return true on success */ bool FileSystem::unmount(Report& report, const QString& deviceNode) { ExternalCommand umountCmd( report, QStringLiteral("umount"), { QStringLiteral("--verbose"), QStringLiteral("--all-targets"), deviceNode }); if ( umountCmd.run() && umountCmd.exitCode() == 0 ) return true; 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) { QString cmdFullPath = QStandardPaths::findExecutable(cmdName); if (cmdFullPath.isEmpty()) cmdFullPath = QStandardPaths::findExecutable(cmdName, { QStringLiteral("/sbin/"), QStringLiteral("/usr/sbin/"), QStringLiteral("/usr/local/sbin/") }); if (cmdFullPath.isEmpty()) return false; ExternalCommand cmd(cmdFullPath, args); if (!cmd.run()) return false; return cmd.exitCode() == 0 || cmd.exitCode() == expectedCode; } void FileSystem::addAvailableFeature(const FSFeature& feature) { d->m_AvailableFeatures.append(feature); } void FileSystem::addAvailableFeature(const QString& name, FSFeature::Type type) { d->m_AvailableFeatures.append(FSFeature(name, type)); } void FileSystem::addFeature(const FSFeature& feature) { d->m_Features.append(feature); } void FileSystem::addFeatures(const QList& features) { d->m_Features.append(features); } bool FileSystem::supportToolFound() const { return false; } FileSystem::SupportTool FileSystem::supportToolName() const { return SupportTool(); } void FileSystem::setFirstSector(qint64 s) { d->m_FirstSector = s; } void FileSystem::setLastSector(qint64 s) { d->m_LastSector = s; } const QString& FileSystem::label() const { return d->m_Label; } const QList& FileSystem::availableFeatures() const { return d->m_AvailableFeatures; } const QList& FileSystem::features() const { return d->m_Features; } 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; } diff --git a/src/gui/partresizerwidget.h b/src/gui/partresizerwidget.h index dbbd57d..41d8e4a 100644 --- a/src/gui/partresizerwidget.h +++ b/src/gui/partresizerwidget.h @@ -1,217 +1,217 @@ /************************************************************************* * Copyright (C) 2008, 2010 by Volker Lanz * * * * 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 .* *************************************************************************/ #if !defined(KPMCORE_PARTRESIZERWIDGET_H) #define KPMCORE_PARTRESIZERWIDGET_H #include "core/partition.h" #include "util/libpartitionmanagerexport.h" #include #include class PartWidget; class Device; class NewDialog; class QPaintEvent; class QResizeEvent; class QMouseEvent; /** Widget that allows the user to resize a Partition. @author Volker Lanz */ class LIBKPMCORE_EXPORT PartResizerWidget : public QWidget { friend class NewDialog; Q_OBJECT Q_DISABLE_COPY(PartResizerWidget) public: - PartResizerWidget(QWidget* parent); + explicit PartResizerWidget(QWidget* parent); public: void init(Device& d, Partition& p, qint64 minFirst, qint64 maxLast, bool read_only = false, bool move_allowed = true); qint64 totalSectors() const { return maximumLastSector() - minimumFirstSector() + 1; /**< @return total sectors (free + Partition's length) */ } qint64 minimumFirstSector(bool aligned = false) const; /**< @return the lowest allowed first sector */ void setMinimumFirstSector(qint64 s) { m_MinimumFirstSector = s; /**< @param s the new lowest allowed first sector */ } qint64 maximumFirstSector(bool aligned = false) const; /**< @return the highest allowed first sector */ void setMaximumFirstSector(qint64 s) { m_MaximumFirstSector = s; /**< @param s the new highest allowed first sector */ } qint64 minimumLastSector(bool aligned = false) const; /**< @return the lowest allowed last sector */ void setMinimumLastSector(qint64 s) { m_MinimumLastSector = s; /**< @param s the new lowest allowed last sector */ } qint64 maximumLastSector(bool aligned = false) const; /**< @return the highest allowed last sector */ void setMaximumLastSector(qint64 s) { m_MaximumLastSector = s; /**< @param s the new highest allowed last sector */ } void setMinimumLength(qint64 s); qint64 minimumLength() const { return m_MinimumLength; /**< @return minimum length for Partition */ } void setMaximumLength(qint64 s); qint64 maximumLength() const { return m_MaximumLength; /**< @return maximum length for the Partition */ } void setMoveAllowed(bool b); bool moveAllowed() const { return m_MoveAllowed; /**< @return true if moving the Partition is allowed */ } bool readOnly() const { return m_ReadOnly; /**< @return true if the widget is read only */ } void setReadOnly(bool b) { m_ReadOnly = b; /**< @param b the new value for read only */ } bool align() const { if (partition().isMounted()) return false; return m_Align; /**< @return true if the Partition is to be aligned */ } void setAlign(bool b) { m_Align = b; /**< @param b the new value for aligning the Partition */ } qint32 handleWidth() const; /**< @return the handle width in pixels */ static qint32 handleHeight() { return m_HandleHeight; /**< @return the handle height in pixels */ } Q_SIGNALS: void firstSectorChanged(qint64); void lastSectorChanged(qint64); public: bool updateFirstSector(qint64 newFirstSector); bool updateLastSector(qint64 newLastSector); bool movePartition(qint64 newFirstSector); protected: Partition& partition() { Q_ASSERT(m_Partition); return *m_Partition; } const Partition& partition() const { Q_ASSERT(m_Partition); return *m_Partition; } void setPartition(Partition& p) { m_Partition = &p; } Device& device() { Q_ASSERT(m_Device); return *m_Device; } const Device& device() const { Q_ASSERT(m_Device); return *m_Device; } void setDevice(Device& d) { m_Device = &d; } void paintEvent(QPaintEvent* event) override; void resizeEvent(QResizeEvent* event) override; void mousePressEvent(QMouseEvent* event) override; void mouseMoveEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override; PartWidget& partWidget() { Q_ASSERT(m_PartWidget); return *m_PartWidget; } const PartWidget& partWidget() const { Q_ASSERT(m_PartWidget); return *m_PartWidget; } void updatePositions(); int partWidgetStart() const; int partWidgetWidth() const; QLabel& leftHandle() { return m_LeftHandle; } QLabel& rightHandle() { return m_RightHandle; } long double sectorsPerPixel() const; void set(qint64 newCap, qint64 newFreeBefore, qint64 newFreeAfter); void resizeLogicals(qint64 deltaFirst, qint64 deltaLast, bool force = false); bool checkAlignment(const Partition& child, qint64 delta) const; QWidget* draggedWidget() { return m_DraggedWidget; } const QWidget* draggedWidget() const { return m_DraggedWidget; } bool checkConstraints(qint64 first, qint64 last) const; private: Device* m_Device; Partition* m_Partition; PartWidget* m_PartWidget; qint64 m_MinimumFirstSector; qint64 m_MaximumFirstSector; qint64 m_MinimumLastSector; qint64 m_MaximumLastSector; qint64 m_MinimumLength; qint64 m_MaximumLength; QLabel m_LeftHandle; QLabel m_RightHandle; QWidget* m_DraggedWidget; int m_Hotspot; bool m_MoveAllowed; bool m_ReadOnly; bool m_Align; static const qint32 m_HandleHeight; }; #endif diff --git a/src/jobs/checkfilesystemjob.h b/src/jobs/checkfilesystemjob.h index 815d88d..e79e7f7 100644 --- a/src/jobs/checkfilesystemjob.h +++ b/src/jobs/checkfilesystemjob.h @@ -1,53 +1,53 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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 .* *************************************************************************/ #if !defined(KPMCORE_CHECKFILESYSTEMJOB_H) #define KPMCORE_CHECKFILESYSTEMJOB_H #include "jobs/job.h" class Partition; class Report; class QString; /** Check a FileSystem. @author Volker Lanz */ class CheckFileSystemJob : public Job { public: - CheckFileSystemJob(Partition& p); + explicit CheckFileSystemJob(Partition& p); public: bool run(Report& parent) override; QString description() const override; protected: Partition& partition() { return m_Partition; } const Partition& partition() const { return m_Partition; } private: Partition& m_Partition; }; #endif diff --git a/src/jobs/createpartitionjob.cpp b/src/jobs/createpartitionjob.cpp index e6fb374..6f20ecd 100644 --- a/src/jobs/createpartitionjob.cpp +++ b/src/jobs/createpartitionjob.cpp @@ -1,93 +1,93 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * Copyright (C) 2016 by Andrius Štikonas * * * * 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 .* *************************************************************************/ #include "jobs/createpartitionjob.h" #include "backend/corebackend.h" #include "backend/corebackendmanager.h" #include "backend/corebackenddevice.h" #include "backend/corebackendpartitiontable.h" #include "core/partition.h" #include "core/device.h" #include "core/lvmdevice.h" #include "util/report.h" #include /** Creates a new CreatePartitionJob @param d the Device the Partition to be created will be on @param p the Partition to create */ CreatePartitionJob::CreatePartitionJob(Device& d, Partition& p) : Job(), m_Device(d), m_Partition(p) { } bool CreatePartitionJob::run(Report& parent) { Q_ASSERT(partition().devicePath() == device().deviceNode()); bool rval = false; Report* report = jobStarted(parent); if (device().type() == Device::Type::Disk_Device || device().type() == Device::Type::SoftwareRAID_Device) { std::unique_ptr backendDevice = CoreBackendManager::self()->backend()->openDevice(device()); if (backendDevice) { std::unique_ptr backendPartitionTable = backendDevice->openPartitionTable(); if (backendPartitionTable) { QString partitionPath = backendPartitionTable->createPartition(*report, partition()); - if (partitionPath != QString()) { + if (!partitionPath.isEmpty()) { rval = true; partition().setPartitionPath(partitionPath); partition().setState(Partition::State::None); backendPartitionTable->commit(); } else report->line() << xi18nc("@info/plain", "Failed to add partition %1 to device %2.", partition().deviceNode(), device().deviceNode()); } else report->line() << xi18nc("@info:progress", "Could not open partition table on device %1 to create new partition %2.", device().deviceNode(), partition().deviceNode()); } else report->line() << xi18nc("@info:progress", "Could not open device %1 to create new partition %2.", device().deviceNode(), partition().deviceNode()); } else if (device().type() == Device::Type::LVM_Device) { LvmDevice& dev = dynamic_cast(device()); partition().setState(Partition::State::None); QString partPath = partition().partitionPath(); QString lvname = partPath.right(partPath.length() - partPath.lastIndexOf(QStringLiteral("/")) - 1); rval = LvmDevice::createLV(*report, dev, partition(), lvname); } jobFinished(*report, rval); return rval; } QString CreatePartitionJob::description() const { if (partition().number() > 0) return xi18nc("@info:progress", "Create new partition %1", partition().deviceNode()); return xi18nc("@info:progress", "Create new partition on device %1", device().deviceNode()); } diff --git a/src/jobs/createpartitiontablejob.h b/src/jobs/createpartitiontablejob.h index 0888b1a..de34ee5 100644 --- a/src/jobs/createpartitiontablejob.h +++ b/src/jobs/createpartitiontablejob.h @@ -1,53 +1,53 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * * * 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 .* *************************************************************************/ #if !defined(KPMCORE_CREATEPARTITIONTABLEJOB_H) #define KPMCORE_CREATEPARTITIONTABLEJOB_H #include "jobs/job.h" class Device; class Report; class QString; /** Create a PartitionTable. @author Volker Lanz */ class CreatePartitionTableJob : public Job { public: - CreatePartitionTableJob(Device& d); + explicit CreatePartitionTableJob(Device& d); public: bool run(Report& parent) override; QString description() const override; protected: Device& device() { return m_Device; } const Device& device() const { return m_Device; } private: Device& m_Device; }; #endif diff --git a/src/jobs/deactivatelogicalvolumejob.h b/src/jobs/deactivatelogicalvolumejob.h index 8437977..e5d8da6 100644 --- a/src/jobs/deactivatelogicalvolumejob.h +++ b/src/jobs/deactivatelogicalvolumejob.h @@ -1,53 +1,53 @@ /************************************************************************* * Copyright (C) 2016 by Chantara Tith * * * * 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 .* *************************************************************************/ #if !defined(KPMCORE_DEACTIVATELOGICALVOLUMEJOB_H) #define KPMCORE_DEACTIVATELOGICALVOLUMEJOB_H #include "jobs/job.h" class VolumeManagerDevice; class Partition; class Report; class QString; class DeactivateLogicalVolumeJob : public Job { public: - DeactivateLogicalVolumeJob(const VolumeManagerDevice& dev, const QStringList lvPaths = {}); + explicit DeactivateLogicalVolumeJob(const VolumeManagerDevice& dev, const QStringList lvPaths = {}); public: bool run(Report& parent) override; QString description() const override; protected: const VolumeManagerDevice& device() const { return m_Device; } QStringList LVList() const { return m_LVList; } private: const VolumeManagerDevice& m_Device; const QStringList m_LVList; }; #endif diff --git a/src/jobs/deactivatevolumegroupjob.h b/src/jobs/deactivatevolumegroupjob.h index a7886b9..308df1b 100644 --- a/src/jobs/deactivatevolumegroupjob.h +++ b/src/jobs/deactivatevolumegroupjob.h @@ -1,51 +1,51 @@ /************************************************************************* * Copyright (C) 2016 by Chantara Tith * * * * 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 .* *************************************************************************/ #if !defined(KPMCORE_DEACTIVATEVOLUMEGROUPJOB_H) #define KPMCORE_DEACTIVATEVOLUMEGROUPJOB_H #include "jobs/job.h" class VolumeManagerDevice; class Partition; class Report; class QString; class DeactivateVolumeGroupJob : public Job { public: - DeactivateVolumeGroupJob(VolumeManagerDevice& dev); + explicit DeactivateVolumeGroupJob(VolumeManagerDevice& dev); public: bool run(Report& parent) override; QString description() const override; protected: VolumeManagerDevice& device() { return m_Device; } const VolumeManagerDevice& device() const { return m_Device; } private: VolumeManagerDevice& m_Device; }; #endif diff --git a/src/ops/deactivatevolumegroupoperation.h b/src/ops/deactivatevolumegroupoperation.h index e0b2b00..bb4d722 100644 --- a/src/ops/deactivatevolumegroupoperation.h +++ b/src/ops/deactivatevolumegroupoperation.h @@ -1,83 +1,83 @@ /************************************************************************* * Copyright (C) 2016 by Chantara Tith * * * * 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 .* *************************************************************************/ #if !defined(KPMCORE_DEACTIVATEVOLUMEGROUPOPERATION_H) #define KPMCORE_DEACTIVATEVOLUMEGROUPOPERATION_H #include "util/libpartitionmanagerexport.h" #include "ops/operation.h" #include class DeactivateLogicalVolumeJob; class DeactivateVolumeGroupJob; class VolumeManagerDevice; class OperationStack; class PartitionTable; class LIBKPMCORE_EXPORT DeactivateVolumeGroupOperation : public Operation { Q_DISABLE_COPY(DeactivateVolumeGroupOperation) friend class OperationStack; public: - DeactivateVolumeGroupOperation(VolumeManagerDevice& d); + explicit DeactivateVolumeGroupOperation(VolumeManagerDevice& d); public: QString iconName() const override { return QStringLiteral("edit-delete"); } QString description() const override; virtual bool targets(const Device&) const override { return true; } virtual bool targets(const Partition&) const override { return false; } virtual void preview() override; virtual void undo() override; static bool isDeactivatable(const VolumeManagerDevice* dev); protected: DeactivateVolumeGroupJob* deactivateVolumeGroupJob() { return m_DeactivateVolumeGroupJob; } DeactivateLogicalVolumeJob* deactivateLogicalVolumeJob() { return m_DeactivateLogicalVolumeJob; } VolumeManagerDevice& device() { return m_Device; } private: DeactivateVolumeGroupJob* m_DeactivateVolumeGroupJob; DeactivateLogicalVolumeJob* m_DeactivateLogicalVolumeJob; VolumeManagerDevice& m_Device; PartitionTable* m_PartitionTable; }; #endif diff --git a/src/ops/removevolumegroupoperation.h b/src/ops/removevolumegroupoperation.h index 12e78a1..5bc8901 100644 --- a/src/ops/removevolumegroupoperation.h +++ b/src/ops/removevolumegroupoperation.h @@ -1,76 +1,76 @@ /************************************************************************* * Copyright (C) 2016 by Chantara Tith * * * * 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 .* *************************************************************************/ #if !defined(KPMCORE_REMOVEVOLUMEGROUPOPERATION_H) #define KPMCORE_REMOVEVOLUMEGROUPOPERATION_H #include "util/libpartitionmanagerexport.h" #include "ops/operation.h" #include class PartitionTable; class RemoveVolumeGroupJob; class VolumeManagerDevice; class OperationStack; class LIBKPMCORE_EXPORT RemoveVolumeGroupOperation : public Operation { Q_DISABLE_COPY(RemoveVolumeGroupOperation) friend class OperationStack; public: - RemoveVolumeGroupOperation(VolumeManagerDevice& d); + explicit RemoveVolumeGroupOperation(VolumeManagerDevice& d); public: QString iconName() const override { return QStringLiteral("edit-delete"); } QString description() const override; virtual bool targets(const Device&) const override { return true; } virtual bool targets(const Partition&) const override { return false; } virtual void preview() override; virtual void undo() override; static bool isRemovable(const VolumeManagerDevice* dev); protected: RemoveVolumeGroupJob* removeVolumeGroupJob() { return m_RemoveVolumeGroupJob; } VolumeManagerDevice& device() { return m_Device; } private: RemoveVolumeGroupJob* m_RemoveVolumeGroupJob; VolumeManagerDevice& m_Device; PartitionTable* m_PartitionTable; }; #endif diff --git a/src/plugins/dummy/dummydevice.h b/src/plugins/dummy/dummydevice.h index 746c346..322a227 100644 --- a/src/plugins/dummy/dummydevice.h +++ b/src/plugins/dummy/dummydevice.h @@ -1,49 +1,49 @@ /************************************************************************* * Copyright (C) 2010 by Volker Lanz * * * * 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 .* *************************************************************************/ #if !defined(KPMCORE_DUMMYDEVICE_H) #define KPMCORE_DUMMYDEVICE_H #include "backend/corebackenddevice.h" #include class Partition; class PartitionTable; class Report; class CoreBackendPartitionTable; class DummyDevice : public CoreBackendDevice { Q_DISABLE_COPY(DummyDevice) public: - DummyDevice(const QString& deviceNode); + explicit DummyDevice(const QString& deviceNode); ~DummyDevice(); public: bool open() override; bool openExclusive() override; bool close() override; std::unique_ptr openPartitionTable() override; bool createPartitionTable(Report& report, const PartitionTable& ptable) override; }; #endif diff --git a/src/plugins/sfdisk/sfdiskdevice.h b/src/plugins/sfdisk/sfdiskdevice.h index eab4a12..ad83625 100644 --- a/src/plugins/sfdisk/sfdiskdevice.h +++ b/src/plugins/sfdisk/sfdiskdevice.h @@ -1,53 +1,53 @@ /************************************************************************* * Copyright (C) 2017 by Andrius Štikonas * * * * 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 .* *************************************************************************/ #if !defined(SFDISKDEVICE__H) #define SFDISKDEVICE__H #include "backend/corebackenddevice.h" #include "core/device.h" #include class Partition; class PartitionTable; class Report; class CoreBackendPartitionTable; class SfdiskDevice : public CoreBackendDevice { Q_DISABLE_COPY(SfdiskDevice); public: - SfdiskDevice(const Device& d); + explicit SfdiskDevice(const Device& d); ~SfdiskDevice(); public: bool open() override; bool openExclusive() override; bool close() override; std::unique_ptr openPartitionTable() override; bool createPartitionTable(Report& report, const PartitionTable& ptable) override; private: const Device *m_device; }; #endif diff --git a/src/plugins/sfdisk/sfdiskpartitiontable.h b/src/plugins/sfdisk/sfdiskpartitiontable.h index 9d0de1e..577ab34 100644 --- a/src/plugins/sfdisk/sfdiskpartitiontable.h +++ b/src/plugins/sfdisk/sfdiskpartitiontable.h @@ -1,56 +1,56 @@ /************************************************************************* * Copyright (C) 2017 by Andrius Štikonas * * * * 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 .* *************************************************************************/ #if !defined(SFDISKPARTITIONTABLE__H) #define SFDISKPARTITIONTABLE__H #include "backend/corebackendpartitiontable.h" #include "fs/filesystem.h" #include class CoreBackendPartition; class Report; class Partition; class SfdiskPartitionTable : public CoreBackendPartitionTable { public: - SfdiskPartitionTable(const Device *d); + explicit SfdiskPartitionTable(const Device *d); ~SfdiskPartitionTable(); public: bool open() override; bool commit(quint32 timeout = 10) override; QString createPartition(Report& report, const Partition& partition) override; bool deletePartition(Report& report, const Partition& partition) override; bool updateGeometry(Report& report, const Partition& partition, qint64 sector_start, qint64 sector_end) override; bool clobberFileSystem(Report& report, const Partition& partition) override; bool resizeFileSystem(Report& report, const Partition& partition, qint64 newLength) override; FileSystem::Type detectFileSystemBySector(Report& report, const Device& device, qint64 sector) override; bool setPartitionSystemType(Report& report, const Partition& partition) override; bool setFlag(Report& report, const Partition& partition, PartitionTable::Flag flag, bool state) override; private: const Device *m_device; }; #endif diff --git a/src/util/externalcommand.cpp b/src/util/externalcommand.cpp index 0568bb6..9ba2fac 100644 --- a/src/util/externalcommand.cpp +++ b/src/util/externalcommand.cpp @@ -1,396 +1,396 @@ /************************************************************************* * Copyright (C) 2008 by Volker Lanz * * Copyright (C) 2016-2018 by Andrius Štikonas * * * * 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 .* *************************************************************************/ +#include "util/externalcommand.h" #include "backend/corebackendmanager.h" #include "core/device.h" #include "core/copysource.h" #include "core/copytarget.h" #include "core/copytargetbytearray.h" #include "core/copysourcedevice.h" #include "core/copytargetdevice.h" #include "util/globallog.h" -#include "util/externalcommand.h" #include "util/report.h" #include "externalcommandhelper_interface.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include struct ExternalCommandPrivate { Report *m_Report; QString m_Command; QStringList m_Args; int m_ExitCode; QByteArray m_Output; QByteArray m_Input; DBusThread *m_thread; QProcess::ProcessChannelMode processChannelMode; }; KAuth::ExecuteJob* ExternalCommand::m_job; bool ExternalCommand::helperStarted = false; QWidget* ExternalCommand::parent; /** Creates a new ExternalCommand instance without Report. @param cmd the command to run @param args the arguments to pass to the command */ ExternalCommand::ExternalCommand(const QString& cmd, const QStringList& args, const QProcess::ProcessChannelMode processChannelMode) : d(std::make_unique()) { d->m_Report = nullptr; d->m_Command = cmd; d->m_Args = args; d->m_ExitCode = -1; d->m_Output = QByteArray(); if (!helperStarted) if(!startHelper()) Log(Log::Level::error) << xi18nc("@info:status", "Could not obtain administrator privileges."); d->processChannelMode = processChannelMode; } /** Creates a new ExternalCommand instance with Report. @param report the Report to write output to. @param cmd the command to run @param args the arguments to pass to the command */ ExternalCommand::ExternalCommand(Report& report, const QString& cmd, const QStringList& args, const QProcess::ProcessChannelMode processChannelMode) : d(std::make_unique()) { d->m_Report = report.newChild(); d->m_Command = cmd; d->m_Args = args; d->m_ExitCode = -1; d->m_Output = QByteArray(); d->processChannelMode = processChannelMode; } ExternalCommand::~ExternalCommand() { } /* void ExternalCommand::setup() { connect(this, qOverload(&QProcess::finished), this, &ExternalCommand::onFinished); connect(this, &ExternalCommand::readyReadStandardOutput, this, &ExternalCommand::onReadOutput); } */ /** Executes the external command. @param timeout timeout to wait for the process to start @return true on success */ bool ExternalCommand::start(int timeout) { Q_UNUSED(timeout) if (command().isEmpty()) return false; if (!QDBusConnection::systemBus().isConnected()) { qWarning() << QDBusConnection::systemBus().lastError().message(); return false; } if (report()) report()->setCommand(xi18nc("@info:status", "Command: %1 %2", command(), args().join(QStringLiteral(" ")))); if ( qEnvironmentVariableIsSet( "KPMCORE_DEBUG" )) qDebug() << xi18nc("@info:status", "Command: %1 %2", command(), args().join(QStringLiteral(" "))); QString cmd = QStandardPaths::findExecutable(command()); if (cmd.isEmpty()) cmd = QStandardPaths::findExecutable(command(), { QStringLiteral("/sbin/"), QStringLiteral("/usr/sbin/"), QStringLiteral("/usr/local/sbin/") }); auto *interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"), QStringLiteral("/Helper"), QDBusConnection::systemBus(), this); interface->setTimeout(10 * 24 * 3600 * 1000); // 10 days bool rval = false; QDBusPendingCall pcall = interface->start(cmd, args(), d->m_Input, d->processChannelMode); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this); QEventLoop loop; auto exitLoop = [&] (QDBusPendingCallWatcher *watcher) { loop.exit(); if (watcher->isError()) qWarning() << watcher->error(); else { QDBusPendingReply reply = *watcher; d->m_Output = reply.value()[QStringLiteral("output")].toByteArray(); setExitCode(reply.value()[QStringLiteral("exitCode")].toInt()); rval = reply.value()[QStringLiteral("success")].toBool(); } }; connect(watcher, &QDBusPendingCallWatcher::finished, exitLoop); loop.exec(); return rval; } bool ExternalCommand::copyBlocks(const CopySource& source, CopyTarget& target) { bool rval = true; const qint64 blockSize = 10 * 1024 * 1024; // number of bytes per block to copy if (!QDBusConnection::systemBus().isConnected()) { qWarning() << QDBusConnection::systemBus().lastError().message(); return false; } // TODO KF6:Use new signal-slot syntax connect(m_job, SIGNAL(percent(KJob*, unsigned long)), this, SLOT(emitProgress(KJob*, unsigned long))); connect(m_job, &KAuth::ExecuteJob::newData, this, &ExternalCommand::emitReport); auto *interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"), QStringLiteral("/Helper"), QDBusConnection::systemBus(), this); interface->setTimeout(10 * 24 * 3600 * 1000); // 10 days QDBusPendingCall pcall = interface->copyblocks(source.path(), source.firstByte(), source.length(), target.path(), target.firstByte(), blockSize); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this); QEventLoop loop; auto exitLoop = [&] (QDBusPendingCallWatcher *watcher) { loop.exit(); if (watcher->isError()) qWarning() << watcher->error(); else { QDBusPendingReply reply = *watcher; rval = reply.value()[QStringLiteral("success")].toBool(); CopyTargetByteArray *byteArrayTarget = dynamic_cast(&target); if (byteArrayTarget) byteArrayTarget->m_Array = reply.value()[QStringLiteral("targetByteArray")].toByteArray(); } setExitCode(!rval); }; connect(watcher, &QDBusPendingCallWatcher::finished, exitLoop); loop.exec(); return rval; } bool ExternalCommand::writeData(Report& commandReport, const QByteArray& buffer, const QString& deviceNode, const quint64 firstByte) { d->m_Report = commandReport.newChild(); if (report()) report()->setCommand(xi18nc("@info:status", "Command: %1 %2", command(), args().join(QStringLiteral(" ")))); bool rval = true; if (!QDBusConnection::systemBus().isConnected()) { qWarning() << QDBusConnection::systemBus().lastError().message(); return false; } auto *interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"), QStringLiteral("/Helper"), QDBusConnection::systemBus(), this); interface->setTimeout(10 * 24 * 3600 * 1000); // 10 days QDBusPendingCall pcall = interface->writeData(buffer, deviceNode, firstByte); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this); QEventLoop loop; auto exitLoop = [&] (QDBusPendingCallWatcher *watcher) { loop.exit(); if (watcher->isError()) qWarning() << watcher->error(); else { QDBusPendingReply reply = *watcher; rval = reply.argumentAt<0>(); } setExitCode(!rval); }; connect(watcher, &QDBusPendingCallWatcher::finished, exitLoop); loop.exec(); return rval; } bool ExternalCommand::write(const QByteArray& input) { if ( qEnvironmentVariableIsSet( "KPMCORE_DEBUG" )) qDebug() << "Command input:" << QString::fromLocal8Bit(input); d->m_Input = input; return true; } /** Runs the command. @param timeout timeout to use for waiting when starting and when waiting for the process to finish @return true on success */ bool ExternalCommand::run(int timeout) { return start(timeout) /* && exitStatus() == 0*/; } void ExternalCommand::onReadOutput() { // const QByteArray s = readAllStandardOutput(); // // if(m_Output.length() > 10*1024*1024) { // prevent memory overflow for badly corrupted file systems // if (report()) // report()->line() << xi18nc("@info:status", "(Command is printing too much output)"); // return; // } // // m_Output += s; // // if (report()) // *report() << QString::fromLocal8Bit(s); } void ExternalCommand::setCommand(const QString& cmd) { d->m_Command = cmd; } const QString& ExternalCommand::command() const { return d->m_Command; } const QStringList& ExternalCommand::args() const { return d->m_Args; } void ExternalCommand::addArg(const QString& s) { d->m_Args << s; } void ExternalCommand::setArgs(const QStringList& args) { d->m_Args = args; } int ExternalCommand::exitCode() const { return d->m_ExitCode; } const QString ExternalCommand::output() const { return QString::fromLocal8Bit(d->m_Output); } const QByteArray& ExternalCommand::rawOutput() const { return d->m_Output; } Report* ExternalCommand::report() { return d->m_Report; } void ExternalCommand::setExitCode(int i) { d->m_ExitCode = i; } bool ExternalCommand::startHelper() { if (!QDBusConnection::systemBus().isConnected()) { qWarning() << QDBusConnection::systemBus().lastError().message(); return false; } QDBusInterface iface(QStringLiteral("org.kde.kpmcore.helperinterface"), QStringLiteral("/Helper"), QStringLiteral("org.kde.kpmcore.externalcommand"), QDBusConnection::systemBus()); if (iface.isValid()) { exit(0); } d->m_thread = new DBusThread; d->m_thread->start(); KAuth::Action action = KAuth::Action(QStringLiteral("org.kde.kpmcore.externalcommand.init")); action.setHelperId(QStringLiteral("org.kde.kpmcore.externalcommand")); action.setTimeout(10 * 24 * 3600 * 1000); // 10 days action.setParentWidget(parent); QVariantMap arguments; action.setArguments(arguments); m_job = action.execute(); m_job->start(); // Wait until ExternalCommand Helper is ready (helper sends newData signal just before it enters event loop) QEventLoop loop; auto exitLoop = [&] () { loop.exit(); }; auto conn = QObject::connect(m_job, &KAuth::ExecuteJob::newData, exitLoop); QObject::connect(m_job, &KJob::finished, [=] () { if(m_job->error()) exitLoop(); } ); loop.exec(); QObject::disconnect(conn); helperStarted = true; return true; } void ExternalCommand::stopHelper() { auto *interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"), QStringLiteral("/Helper"), QDBusConnection::systemBus()); interface->exit(); } void DBusThread::run() { if (!QDBusConnection::systemBus().registerService(QStringLiteral("org.kde.kpmcore.applicationinterface")) || !QDBusConnection::systemBus().registerObject(QStringLiteral("/Application"), this, QDBusConnection::ExportAllSlots)) { qWarning() << QDBusConnection::systemBus().lastError().message(); return; } QEventLoop loop; loop.exec(); } diff --git a/test/testdevice.cpp b/test/testdevice.cpp index 43a424b..d74e1c3 100644 --- a/test/testdevice.cpp +++ b/test/testdevice.cpp @@ -1,124 +1,124 @@ /************************************************************************* * Copyright (C) 2019 by Shubham * * * * 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 .* *************************************************************************/ // SPDX-License-Identifier: GPL-3.0+ -#include "helpers.h" #include "testdevice.h" +#include "helpers.h" #include "backend/corebackend.h" #include "backend/corebackendmanager.h" #include #include #include int main(int argc, char **argv) { QCoreApplication app(argc, argv); KPMCoreInitializer init; if (argc == 2) init = KPMCoreInitializer(argv[1]); return init.isValid() ? EXIT_SUCCESS : EXIT_FAILURE; CoreBackend *backend = CoreBackendManager::self()->backend(); if (!backend) { qWarning() << "Failed to load backend plugin"; return EXIT_FAILURE; } TestDevice device; device.testDeviceName(); device.testDeviceNode(); device.testDeviceSize(); device.testDeviceTotalSectors(); return app.exec(); } TestDevice::TestDevice() { operationStack = new OperationStack(); deviceScanner = new DeviceScanner(nullptr, *operationStack); deviceScanner->scan(); // Get list of available devices on the system devices = operationStack->previewDevices(); } TestDevice::~TestDevice() { delete operationStack; delete deviceScanner; // Delete the list of devices qDeleteAll(devices.begin(), devices.end()); devices.clear(); } void TestDevice::testDeviceName() { if (devices.isEmpty()) { exit(EXIT_FAILURE); } else { for (const auto &device : devices) { - if (device->name() == QString()) + if (device->name().isEmpty()) exit(EXIT_FAILURE); } } } void TestDevice::testDeviceNode() { if (devices.isEmpty()) { exit(EXIT_FAILURE); } else { for (const auto &device : devices) { if (device->deviceNode() == QString()) exit(EXIT_FAILURE); } } } void TestDevice::testDeviceSize() { if (devices.isEmpty()) { exit(EXIT_FAILURE); } else { for (const auto &device : devices) { if (device->logicalSize() < 0) exit(EXIT_FAILURE); } } } void TestDevice::testDeviceTotalSectors() { if (devices.isEmpty()) { exit(EXIT_FAILURE); } else { for (const auto &device : devices) { if (device->totalLogical() < 0) exit(EXIT_FAILURE); } } }