From 046f17fa68ed4a41b15581bccf570e7f349cdc27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Sat, 1 Sep 2018 18:40:10 +0100 Subject: [PATCH 01/26] sfdisk: Make FlagEsp alias for FlagBoot --- src/plugins/sfdisk/sfdiskbackend.cpp | 15 +++++++++------ src/plugins/sfdisk/sfdiskpartitiontable.cpp | 20 +++++++++++--------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/plugins/sfdisk/sfdiskbackend.cpp b/src/plugins/sfdisk/sfdiskbackend.cpp index 810f59e..1e464f0 100644 --- a/src/plugins/sfdisk/sfdiskbackend.cpp +++ b/src/plugins/sfdisk/sfdiskbackend.cpp @@ -225,12 +225,14 @@ void SfdiskBackend::scanDevicePartitions(Device& d, const QJsonArray& jsonPartit const qint64 start = partitionObject[QLatin1String("start")].toVariant().toLongLong(); const qint64 size = partitionObject[QLatin1String("size")].toVariant().toLongLong(); const QString partitionType = partitionObject[QLatin1String("type")].toString(); - PartitionTable::Flag activeFlags = partitionObject[QLatin1String("bootable")].toBool() ? PartitionTable::FlagBoot : PartitionTable::FlagNone; + PartitionTable::Flags activeFlags = partitionObject[QLatin1String("bootable")].toBool() ? PartitionTable::FlagBoot : PartitionTable::FlagNone; - if (partitionType == QStringLiteral("C12A7328-F81F-11D2-BA4B-00A0C93EC93B")) - activeFlags = PartitionTable::FlagEsp; + if (partitionType == QStringLiteral("C12A7328-F81F-11D2-BA4B-00A0C93EC93B")) { + activeFlags |= PartitionTable::FlagBoot; + activeFlags |= PartitionTable::FlagEsp; + } else if (partitionType == QStringLiteral("21686148-6449-6E6F-744E-656564454649")) - activeFlags = PartitionTable::FlagBiosGrub; + activeFlags |= PartitionTable::FlagBiosGrub; FileSystem::Type type = FileSystem::Type::Unknown; type = detectFileSystem(partitionNode); @@ -476,8 +478,9 @@ PartitionTable::Flags SfdiskBackend::availableFlags(PartitionTable::TableType ty if (type == PartitionTable::gpt) { // These are not really flags but for now keep them for compatibility // We should implement changing partition type - flags = PartitionTable::FlagBiosGrub | - PartitionTable::FlagEsp; + flags = PartitionTable::Flag::FlagBiosGrub | + PartitionTable::Flag::FlagEsp | + PartitionTable::Flag::FlagBoot; } else if (type == PartitionTable::msdos || type == PartitionTable::msdos_sectorbased) flags = PartitionTable::FlagBoot; diff --git a/src/plugins/sfdisk/sfdiskpartitiontable.cpp b/src/plugins/sfdisk/sfdiskpartitiontable.cpp index 470e783..81f8965 100644 --- a/src/plugins/sfdisk/sfdiskpartitiontable.cpp +++ b/src/plugins/sfdisk/sfdiskpartitiontable.cpp @@ -195,11 +195,11 @@ static QLatin1String getPartitionType(FileSystem::Type t, PartitionTable::TableT { quint8 type; switch (tableType) { - case PartitionTable::gpt: + case PartitionTable::TableType::gpt: type = 0; break; - case PartitionTable::msdos: - case PartitionTable::msdos_sectorbased: + case PartitionTable::TableType::msdos: + case PartitionTable::TableType::msdos_sectorbased: type = 1; break; default:; @@ -225,20 +225,22 @@ bool SfdiskPartitionTable::setPartitionSystemType(Report& report, const Partitio bool SfdiskPartitionTable::setFlag(Report& report, const Partition& partition, PartitionTable::Flag flag, bool state) { // We only allow setting one active partition per device - if (flag == PartitionTable::FlagBoot && state == true) { + if ((m_device->partitionTable()->type() == PartitionTable::TableType::msdos || + m_device->partitionTable()->type() == PartitionTable::TableType::msdos_sectorbased) && + flag == PartitionTable::Flag::FlagBoot && state == true) { ExternalCommand sfdiskCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--activate"), m_device->deviceNode(), QString::number(partition.number()) } ); if (sfdiskCommand.run(-1) && sfdiskCommand.exitCode() == 0) return true; else return false; - } else if (flag == PartitionTable::FlagBoot && state == false) { + } else if (flag == PartitionTable::Flag::FlagBoot && state == false) { ExternalCommand sfdiskCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--activate"), m_device->deviceNode(), QStringLiteral("-") } ); if (sfdiskCommand.run(-1) && sfdiskCommand.exitCode() == 0) return true; // FIXME: Do not return false since we have no way of checking if partition table is MBR } - if (flag == PartitionTable::FlagEsp && state == true) { + if ((flag == PartitionTable::Flag::FlagEsp || flag == PartitionTable::Flag::FlagBoot) && state == true) { ExternalCommand sfdiskCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--part-type"), m_device->deviceNode(), QString::number(partition.number()), QStringLiteral("C12A7328-F81F-11D2-BA4B-00A0C93EC93B") } ); if (sfdiskCommand.run(-1) && sfdiskCommand.exitCode() == 0) @@ -246,10 +248,10 @@ bool SfdiskPartitionTable::setFlag(Report& report, const Partition& partition, P else return false; } - if (flag == PartitionTable::FlagEsp && state == false) + if ((flag == PartitionTable::Flag::FlagEsp || flag == PartitionTable::Flag::FlagBoot) && state == false) setPartitionSystemType(report, partition); - if (flag == PartitionTable::FlagBiosGrub && state == true) { + if (flag == PartitionTable::Flag::FlagBiosGrub && state == true) { ExternalCommand sfdiskCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--part-type"), m_device->deviceNode(), QString::number(partition.number()), QStringLiteral("21686148-6449-6E6F-744E-656564454649") } ); if (sfdiskCommand.run(-1) && sfdiskCommand.exitCode() == 0) @@ -257,7 +259,7 @@ bool SfdiskPartitionTable::setFlag(Report& report, const Partition& partition, P else return false; } - if (flag == PartitionTable::FlagBiosGrub && state == false) + if (flag == PartitionTable::Flag::FlagBiosGrub && state == false) setPartitionSystemType(report, partition); return true; From f4cd7dd9535e775e6d9e79f99a4ac16cc2a9f2e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Sat, 1 Sep 2018 18:52:15 +0100 Subject: [PATCH 02/26] Use C++14 style deprecated attributes. --- src/core/partition.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/partition.h b/src/core/partition.h index 63f604d..5b46afc 100644 --- a/src/core/partition.h +++ b/src/core/partition.h @@ -80,10 +80,10 @@ public: New, /**< from a NewOperation */ Copy, /**< from a CopyOperation */ Restore, /**< from a RestoreOperation */ - StateNone __attribute__((deprecated("Use Partition::State::None"))) = None, - StateNew __attribute__((deprecated("Use Partition::State::New"))) = New, - StateCopy __attribute__((deprecated("Use Partition::State::Copy"))) = Copy, - StateRestore __attribute__((deprecated("Use Partition::State::Restore"))) = Restore + StateNone [[deprecated("Use Partition::State::None")]] = None, + StateNew [[deprecated("Use Partition::State::New")]] = New, + StateCopy [[deprecated("Use Partition::State::Copy")]] = Copy, + StateRestore [[deprecated("Use Partition::State::Restore")]] = Restore }; Partition(PartitionNode* parent, const Device& device, const PartitionRole& role, FileSystem* fs, qint64 sectorStart, qint64 sectorEnd, QString partitionPath, PartitionTable::Flags availableFlags = PartitionTable::FlagNone, const QString& mountPoint = QString(), bool mounted = false, PartitionTable::Flags activeFlags = PartitionTable::FlagNone, State state = State::None); From 4080eef0bab6a9334fb6d36f2f337fc43a64797e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Sat, 1 Sep 2018 21:27:05 +0100 Subject: [PATCH 03/26] Set FlagBoot = FlagEsp and deprecate it. --- src/core/partitiontable.cpp | 3 -- src/core/partitiontable.h | 2 +- src/plugins/sfdisk/sfdiskbackend.cpp | 5 +-- src/plugins/sfdisk/sfdiskpartitiontable.cpp | 34 +++++++++++---------- 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/core/partitiontable.cpp b/src/core/partitiontable.cpp index 72c0693..dd0b4be 100644 --- a/src/core/partitiontable.cpp +++ b/src/core/partitiontable.cpp @@ -216,8 +216,6 @@ QString PartitionTable::flagName(Flag f) return xi18nc("@item partition flag", "msft-data"); case PartitionTable::FlagIrst: return xi18nc("@item partition flag", "irst"); - case PartitionTable::FlagEsp: - return xi18nc("@item partition flag", "esp"); default: break; } @@ -247,7 +245,6 @@ const QList PartitionTable::flagList() rval.append(PartitionTable::FlagLegacyBoot); rval.append(PartitionTable::FlagMsftData); rval.append(PartitionTable::FlagIrst); - rval.append(PartitionTable::FlagEsp); return rval; } diff --git a/src/core/partitiontable.h b/src/core/partitiontable.h index d0ba741..de5f3ef 100644 --- a/src/core/partitiontable.h +++ b/src/core/partitiontable.h @@ -88,7 +88,7 @@ public: FlagLegacyBoot = 16384, FlagMsftData = 32768, FlagIrst = 65536, - FlagEsp = 131072 + FlagEsp [[deprecated]] = FlagBoot }; Q_DECLARE_FLAGS(Flags, Flag) diff --git a/src/plugins/sfdisk/sfdiskbackend.cpp b/src/plugins/sfdisk/sfdiskbackend.cpp index 1e464f0..a563250 100644 --- a/src/plugins/sfdisk/sfdiskbackend.cpp +++ b/src/plugins/sfdisk/sfdiskbackend.cpp @@ -227,10 +227,8 @@ void SfdiskBackend::scanDevicePartitions(Device& d, const QJsonArray& jsonPartit const QString partitionType = partitionObject[QLatin1String("type")].toString(); PartitionTable::Flags activeFlags = partitionObject[QLatin1String("bootable")].toBool() ? PartitionTable::FlagBoot : PartitionTable::FlagNone; - if (partitionType == QStringLiteral("C12A7328-F81F-11D2-BA4B-00A0C93EC93B")) { + if (partitionType == QStringLiteral("C12A7328-F81F-11D2-BA4B-00A0C93EC93B")) activeFlags |= PartitionTable::FlagBoot; - activeFlags |= PartitionTable::FlagEsp; - } else if (partitionType == QStringLiteral("21686148-6449-6E6F-744E-656564454649")) activeFlags |= PartitionTable::FlagBiosGrub; @@ -479,7 +477,6 @@ PartitionTable::Flags SfdiskBackend::availableFlags(PartitionTable::TableType ty // These are not really flags but for now keep them for compatibility // We should implement changing partition type flags = PartitionTable::Flag::FlagBiosGrub | - PartitionTable::Flag::FlagEsp | PartitionTable::Flag::FlagBoot; } else if (type == PartitionTable::msdos || type == PartitionTable::msdos_sectorbased) diff --git a/src/plugins/sfdisk/sfdiskpartitiontable.cpp b/src/plugins/sfdisk/sfdiskpartitiontable.cpp index 81f8965..426eb8b 100644 --- a/src/plugins/sfdisk/sfdiskpartitiontable.cpp +++ b/src/plugins/sfdisk/sfdiskpartitiontable.cpp @@ -224,23 +224,25 @@ bool SfdiskPartitionTable::setPartitionSystemType(Report& report, const Partitio bool SfdiskPartitionTable::setFlag(Report& report, const Partition& partition, PartitionTable::Flag flag, bool state) { - // We only allow setting one active partition per device - if ((m_device->partitionTable()->type() == PartitionTable::TableType::msdos || - m_device->partitionTable()->type() == PartitionTable::TableType::msdos_sectorbased) && - flag == PartitionTable::Flag::FlagBoot && state == true) { - ExternalCommand sfdiskCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--activate"), m_device->deviceNode(), QString::number(partition.number()) } ); - if (sfdiskCommand.run(-1) && sfdiskCommand.exitCode() == 0) - return true; - else - return false; - } else if (flag == PartitionTable::Flag::FlagBoot && state == false) { - ExternalCommand sfdiskCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--activate"), m_device->deviceNode(), QStringLiteral("-") } ); - if (sfdiskCommand.run(-1) && sfdiskCommand.exitCode() == 0) - return true; - // FIXME: Do not return false since we have no way of checking if partition table is MBR + if (m_device->partitionTable()->type() == PartitionTable::TableType::msdos || + m_device->partitionTable()->type() == PartitionTable::TableType::msdos_sectorbased) { + // We only allow setting one active partition per device + if (flag == PartitionTable::Flag::FlagBoot && state == true) { + ExternalCommand sfdiskCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--activate"), m_device->deviceNode(), QString::number(partition.number()) } ); + if (sfdiskCommand.run(-1) && sfdiskCommand.exitCode() == 0) + return true; + else + return false; + } else if (flag == PartitionTable::Flag::FlagBoot && state == false) { + ExternalCommand sfdiskCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--activate"), m_device->deviceNode(), QStringLiteral("-") } ); + if (sfdiskCommand.run(-1) && sfdiskCommand.exitCode() == 0) + return true; + else + return false; + } } - if ((flag == PartitionTable::Flag::FlagEsp || flag == PartitionTable::Flag::FlagBoot) && state == true) { + if (flag == PartitionTable::Flag::FlagBoot && state == true) { ExternalCommand sfdiskCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--part-type"), m_device->deviceNode(), QString::number(partition.number()), QStringLiteral("C12A7328-F81F-11D2-BA4B-00A0C93EC93B") } ); if (sfdiskCommand.run(-1) && sfdiskCommand.exitCode() == 0) @@ -248,7 +250,7 @@ bool SfdiskPartitionTable::setFlag(Report& report, const Partition& partition, P else return false; } - if ((flag == PartitionTable::Flag::FlagEsp || flag == PartitionTable::Flag::FlagBoot) && state == false) + if (flag == PartitionTable::Flag::FlagBoot && state == false) setPartitionSystemType(report, partition); if (flag == PartitionTable::Flag::FlagBiosGrub && state == true) { From 911d43be57e38d477081d9772a6d8f69bb7b5d82 Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Sun, 7 Oct 2018 06:01:12 +0200 Subject: [PATCH 04/26] SVN_SILENT made messages (.desktop file) - always resolve ours In case of conflict in i18n, keep the version of the branch "ours" To resolve a particular conflict, "git checkout --ours path/to/file.desktop" --- src/util/org.kde.kpmcore.externalcommand.actions | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/org.kde.kpmcore.externalcommand.actions b/src/util/org.kde.kpmcore.externalcommand.actions index 7c8fbdd..4771e7d 100644 --- a/src/util/org.kde.kpmcore.externalcommand.actions +++ b/src/util/org.kde.kpmcore.externalcommand.actions @@ -19,6 +19,7 @@ Name[sv]=Starta extern kommandodemon Name[uk]=Запуск фонової служби зовнішньої команди Name[x-test]=xxStart external command daemonxx Description=Administrative privileges are required to manage disks +Description[ast]=Ríquense los privilexos alministrativos pa xestionar discos Description[ca]=Es requereixen privilegis d'administrador per gestionar discs Description[ca@valencia]=Es requereixen privilegis d'administrador per gestionar discs Description[cs]=Pro správu disků jsou potřeba práva administrátora From 5dc4986bc967c4d7fa4e56a0e26c5e63a89ad5d2 Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Wed, 10 Oct 2018 06:21:45 +0200 Subject: [PATCH 05/26] SVN_SILENT made messages (.desktop file) - always resolve ours In case of conflict in i18n, keep the version of the branch "ours" To resolve a particular conflict, "git checkout --ours path/to/file.desktop" --- src/util/org.kde.kpmcore.externalcommand.actions | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/util/org.kde.kpmcore.externalcommand.actions b/src/util/org.kde.kpmcore.externalcommand.actions index 4771e7d..a1626db 100644 --- a/src/util/org.kde.kpmcore.externalcommand.actions +++ b/src/util/org.kde.kpmcore.externalcommand.actions @@ -6,6 +6,7 @@ Name=Start external command daemon Name[ca]=Inicia el dimoni d'ordres externes Name[ca@valencia]=Inicia el dimoni d'ordres externes Name[cs]=Spustit démona externích příkazů +Name[de]=Externen Befehlsdienst starten Name[en_GB]=Start external command daemon Name[es]=Iniciar el demonio de órdenes externas Name[fi]=Käynnistä ulkoinen komentopalvelu @@ -19,10 +20,10 @@ Name[sv]=Starta extern kommandodemon Name[uk]=Запуск фонової служби зовнішньої команди Name[x-test]=xxStart external command daemonxx Description=Administrative privileges are required to manage disks -Description[ast]=Ríquense los privilexos alministrativos pa xestionar discos Description[ca]=Es requereixen privilegis d'administrador per gestionar discs Description[ca@valencia]=Es requereixen privilegis d'administrador per gestionar discs Description[cs]=Pro správu disků jsou potřeba práva administrátora +Description[de]=Systemverwalterrechte sind zur Verwaltung von Festplatten erforderlich Description[en_GB]=Administrative privileges are required to manage disks Description[es]=Se necesitan permisos de administrador para gestionar discos Description[fi]=Levyjen hallinta vaatii pääkäyttäjäoikeuksia From 3e31ec1431a45029c5050746012066e1b1101b57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Sun, 14 Oct 2018 00:02:06 +0100 Subject: [PATCH 06/26] Fix free space handling when resizing LVM LVs. BUG: 399772 --- src/core/lvmdevice.cpp | 5 +++++ src/core/lvmdevice.h | 1 + src/ops/resizeoperation.cpp | 12 +++++++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/core/lvmdevice.cpp b/src/core/lvmdevice.cpp index 203fb0b..d6b4a24 100644 --- a/src/core/lvmdevice.cpp +++ b/src/core/lvmdevice.cpp @@ -545,6 +545,11 @@ qint64 LvmDevice::freePE() const return d_ptr->m_freePE; } +void LvmDevice::setFreePE(qint64 freePE) const +{ + d_ptr->m_freePE = freePE; +} + QString LvmDevice::UUID() const { return d_ptr->m_UUID; diff --git a/src/core/lvmdevice.h b/src/core/lvmdevice.h index 089719b..18b546f 100644 --- a/src/core/lvmdevice.h +++ b/src/core/lvmdevice.h @@ -98,6 +98,7 @@ public: qint64 totalPE() const; qint64 allocatedPE() const; qint64 freePE() const; + void setFreePE(qint64 freePE) const; QString UUID() const; QVector & physicalVolumes(); const QVector & physicalVolumes() const; diff --git a/src/ops/resizeoperation.cpp b/src/ops/resizeoperation.cpp index 249f2b1..fee9207 100644 --- a/src/ops/resizeoperation.cpp +++ b/src/ops/resizeoperation.cpp @@ -67,7 +67,7 @@ ResizeOperation::ResizeOperation(Device& d, Partition& p, qint64 newfirst, qint6 m_GrowSetGeomJob(nullptr), m_CheckResizedJob(nullptr) { - if(CheckOperation::canCheck(&partition())) + if (CheckOperation::canCheck(&partition())) addJob(checkOriginalJob()); if (partition().roles().has(PartitionRole::Extended)) { @@ -121,6 +121,11 @@ bool ResizeOperation::targets(const Partition& p) const void ResizeOperation::preview() { + if (targetDevice().type() == Device::Type::LVM_Device) { + const LvmDevice& lvm = static_cast(targetDevice()); + lvm.setFreePE(lvm.freePE() + partition().lastSector() - newLastSector()); + } + // If the operation has already been executed, the partition will of course have newFirstSector and // newLastSector as first and last sector. But to remove it from its original position, we need to // temporarily set these values back to where they were before the operation was executed. @@ -139,6 +144,11 @@ void ResizeOperation::preview() void ResizeOperation::undo() { + if (targetDevice().type() == Device::Type::LVM_Device) { + const LvmDevice& lvm = static_cast(targetDevice()); + lvm.setFreePE(lvm.freePE() - origLastSector() + partition().lastSector()); + } + removePreviewPartition(targetDevice(), partition()); partition().setFirstSector(origFirstSector()); partition().setLastSector(origLastSector()); From fe27ca6f291c15de24040e84a99a8ae357e4681c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Sun, 14 Oct 2018 01:11:57 +0100 Subject: [PATCH 07/26] Also update allocated PE number when resizing LVM LVs. --- src/core/lvmdevice.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/lvmdevice.cpp b/src/core/lvmdevice.cpp index d6b4a24..9ac375a 100644 --- a/src/core/lvmdevice.cpp +++ b/src/core/lvmdevice.cpp @@ -548,6 +548,7 @@ qint64 LvmDevice::freePE() const void LvmDevice::setFreePE(qint64 freePE) const { d_ptr->m_freePE = freePE; + d_ptr->m_allocPE = d_ptr->m_totalPE - freePE; } QString LvmDevice::UUID() const From 9fa2d194ae21c3cbd4367095722737e59888f574 Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Mon, 15 Oct 2018 05:37:46 +0200 Subject: [PATCH 08/26] SVN_SILENT made messages (.desktop file) - always resolve ours In case of conflict in i18n, keep the version of the branch "ours" To resolve a particular conflict, "git checkout --ours path/to/file.desktop" --- src/util/org.kde.kpmcore.externalcommand.actions | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/util/org.kde.kpmcore.externalcommand.actions b/src/util/org.kde.kpmcore.externalcommand.actions index a1626db..dd8d677 100644 --- a/src/util/org.kde.kpmcore.externalcommand.actions +++ b/src/util/org.kde.kpmcore.externalcommand.actions @@ -14,6 +14,7 @@ Name[fr]=Lancer le démon de la commande externe Name[ko]=외부 명령 데몬 시작 Name[lt]=Paleisti išorinių komandų tarnybą Name[nl]=Start externe opdrachtdaemon +Name[pl]=Rozpocznij usługę zewnętrznego polecenia Name[pt]=Iniciar o servidor de comandos externos Name[sk]=Spustiť externé démony príkazov Name[sv]=Starta extern kommandodemon @@ -31,6 +32,7 @@ Description[fr]=Vous devez disposer des privilèges d'administrateur pour gérer Description[ko]=디스크를 관리하려면 권한이 필요함 Description[lt]=Diskų tvarkymui reikalingos administratoriaus teisės Description[nl]=Er zijn administratieve rechten vereist om schijven te beheren +Description[pl]=Do zarządzania dyskami wymagane są uprawnienia administratora Description[pt]=São necessários privilégios de administrador para gerir os discos Description[sv]=Administratörsprivilegier krävs för att hantera diskar Description[uk]=Для керування дисками потрібні права доступу адміністратора (root) From b06af11357a57bc582e3ee571053a0bd5f070028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Fri, 19 Oct 2018 19:55:35 +0100 Subject: [PATCH 09/26] Fix free space handling with LVM LVs. The previous commit worked for resizing LVM. However, it is better to do special handling of LVMs in insert/removePreviewPartition. BUG: 399772 --- src/ops/operation.cpp | 13 ++++++++++++- src/ops/resizeoperation.cpp | 10 ---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/ops/operation.cpp b/src/ops/operation.cpp index c837f29..d575fb9 100644 --- a/src/ops/operation.cpp +++ b/src/ops/operation.cpp @@ -20,6 +20,7 @@ #include "core/partition.h" #include "core/device.h" +#include "core/lvmdevice.h" #include "jobs/job.h" @@ -51,6 +52,10 @@ void Operation::insertPreviewPartition(Device& device, Partition& p) device.partitionTable()->removeUnallocated(); p.parent()->insert(&p); + if (device.type() == Device::Type::LVM_Device) { + const LvmDevice& lvm = static_cast(device); + lvm.setFreePE(lvm.freePE() - p.length()); + } device.partitionTable()->updateUnallocated(device); } @@ -59,8 +64,14 @@ void Operation::removePreviewPartition(Device& device, Partition& p) { Q_ASSERT(device.partitionTable()); - if (p.parent()->remove(&p)) + if (p.parent()->remove(&p)) { + if (device.type() == Device::Type::LVM_Device) { + const LvmDevice& lvm = static_cast(device); + lvm.setFreePE(lvm.freePE() + p.length()); + } + device.partitionTable()->updateUnallocated(device); + } else qWarning() << "failed to remove partition " << p.deviceNode() << " at " << &p << " from preview."; } diff --git a/src/ops/resizeoperation.cpp b/src/ops/resizeoperation.cpp index fee9207..3527a96 100644 --- a/src/ops/resizeoperation.cpp +++ b/src/ops/resizeoperation.cpp @@ -121,11 +121,6 @@ bool ResizeOperation::targets(const Partition& p) const void ResizeOperation::preview() { - if (targetDevice().type() == Device::Type::LVM_Device) { - const LvmDevice& lvm = static_cast(targetDevice()); - lvm.setFreePE(lvm.freePE() + partition().lastSector() - newLastSector()); - } - // If the operation has already been executed, the partition will of course have newFirstSector and // newLastSector as first and last sector. But to remove it from its original position, we need to // temporarily set these values back to where they were before the operation was executed. @@ -144,11 +139,6 @@ void ResizeOperation::preview() void ResizeOperation::undo() { - if (targetDevice().type() == Device::Type::LVM_Device) { - const LvmDevice& lvm = static_cast(targetDevice()); - lvm.setFreePE(lvm.freePE() - origLastSector() + partition().lastSector()); - } - removePreviewPartition(targetDevice(), partition()); partition().setFirstSector(origFirstSector()); partition().setLastSector(origLastSector()); From d17615532a5bce4e32f58c60a5f9f2ca55cb9c4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Fri, 19 Oct 2018 20:18:39 +0100 Subject: [PATCH 10/26] Check if PartitionNode::insert returns success. --- src/ops/operation.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/ops/operation.cpp b/src/ops/operation.cpp index d575fb9..485b58b 100644 --- a/src/ops/operation.cpp +++ b/src/ops/operation.cpp @@ -51,11 +51,14 @@ void Operation::insertPreviewPartition(Device& device, Partition& p) device.partitionTable()->removeUnallocated(); - p.parent()->insert(&p); - if (device.type() == Device::Type::LVM_Device) { - const LvmDevice& lvm = static_cast(device); - lvm.setFreePE(lvm.freePE() - p.length()); + if (p.parent()->insert(&p)) { + if (device.type() == Device::Type::LVM_Device) { + const LvmDevice& lvm = static_cast(device); + lvm.setFreePE(lvm.freePE() - p.length()); + } } + else + qWarning() << "failed to insert preview partition " << p.deviceNode() << " at " << &p << "."; device.partitionTable()->updateUnallocated(device); } From 3c52bcf9ab9adc56fa2f4cd30586720b79511c63 Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Sun, 21 Oct 2018 05:48:52 +0200 Subject: [PATCH 11/26] SVN_SILENT made messages (.desktop file) - always resolve ours In case of conflict in i18n, keep the version of the branch "ours" To resolve a particular conflict, "git checkout --ours path/to/file.desktop" --- src/util/org.kde.kpmcore.externalcommand.actions | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/util/org.kde.kpmcore.externalcommand.actions b/src/util/org.kde.kpmcore.externalcommand.actions index dd8d677..7590e14 100644 --- a/src/util/org.kde.kpmcore.externalcommand.actions +++ b/src/util/org.kde.kpmcore.externalcommand.actions @@ -11,6 +11,7 @@ Name[en_GB]=Start external command daemon Name[es]=Iniciar el demonio de órdenes externas Name[fi]=Käynnistä ulkoinen komentopalvelu Name[fr]=Lancer le démon de la commande externe +Name[gl]=Iniciar o servizo de orde externa Name[ko]=외부 명령 데몬 시작 Name[lt]=Paleisti išorinių komandų tarnybą Name[nl]=Start externe opdrachtdaemon @@ -29,6 +30,7 @@ Description[en_GB]=Administrative privileges are required to manage disks Description[es]=Se necesitan permisos de administrador para gestionar discos Description[fi]=Levyjen hallinta vaatii pääkäyttäjäoikeuksia Description[fr]=Vous devez disposer des privilèges d'administrateur pour gérer les disques +Description[gl]=Requírense privilexios de administración para xestionar discos. Description[ko]=디스크를 관리하려면 권한이 필요함 Description[lt]=Diskų tvarkymui reikalingos administratoriaus teisės Description[nl]=Er zijn administratieve rechten vereist om schijven te beheren From f260247422972eb1fdbe9d3e531aba1eda84eb11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Sun, 21 Oct 2018 17:50:00 +0100 Subject: [PATCH 12/26] Simplify return value logic. --- src/jobs/job.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/jobs/job.cpp b/src/jobs/job.cpp index d850b3d..c6708be 100644 --- a/src/jobs/job.cpp +++ b/src/jobs/job.cpp @@ -45,11 +45,7 @@ bool Job::copyBlocks(Report& report, CopyTarget& target, CopySource& source) ExternalCommand copyCmd; connect(©Cmd, &ExternalCommand::progress, this, &Job::progress, Qt::QueuedConnection); connect(©Cmd, &ExternalCommand::reportSignal, this, &Job::updateReport, Qt::QueuedConnection); - if (copyCmd.copyBlocks(source, target)) { - return true; - } - - return false; + return copyCmd.copyBlocks(source, target); } bool Job::rollbackCopyBlocks(Report& report, CopyTarget& origTarget, CopySource& origSource) From 9ca63ab501b9a6f1e878754c2ff3b0196070ecaa Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Wed, 24 Oct 2018 05:56:19 +0200 Subject: [PATCH 13/26] SVN_SILENT made messages (.desktop file) - always resolve ours In case of conflict in i18n, keep the version of the branch "ours" To resolve a particular conflict, "git checkout --ours path/to/file.desktop" --- src/plugins/dummy/pmdummybackendplugin.json | 24 ++++++++++++++++++- src/plugins/sfdisk/pmsfdiskbackendplugin.json | 24 ++++++++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/plugins/dummy/pmdummybackendplugin.json b/src/plugins/dummy/pmdummybackendplugin.json index eb3cd61..022c33f 100644 --- a/src/plugins/dummy/pmdummybackendplugin.json +++ b/src/plugins/dummy/pmdummybackendplugin.json @@ -4,7 +4,27 @@ { "Email": "vl@fidra.de", "Name": "Volker Lanz", - "Name[x-test]": "xxVolker Lanzxx" + "Name[ca@valencia]": "Volker Lanz", + "Name[ca]": "Volker Lanz", + "Name[cs]": "Volker Lanz", + "Name[de]": "Volker Lanz", + "Name[en_GB]": "Volker Lanz", + "Name[es]": "Volker Lanz", + "Name[fi]": "Volker Lanz", + "Name[fr]": "Volker Lanz", + "Name[gl]": "Volker Lanz", + "Name[it]": "Volker Lanz", + "Name[ko]": "Volker Lanz", + "Name[lt]": "Volker Lanz", + "Name[nl]": "Volker Lanz", + "Name[pl]": "Volker Lanz", + "Name[pt]": "Volker Lanz", + "Name[pt_BR]": "Volker Lanz", + "Name[sk]": "Volker Lanz", + "Name[sv]": "Volker Lanz", + "Name[uk]": "Volker Lanz", + "Name[x-test]": "xxVolker Lanzxx", + "Name[zh_CN]": "Volker Lanz" } ], "Category": "BackendPlugin", @@ -13,6 +33,7 @@ "Description[ca]": "Un dorsal fals del gestor de particions del KDE amb la finalitat de fer proves.", "Description[cs]": "Falešná podpůrná vrstva pro správce diskových oddílů KDE pro testovací účely.", "Description[de]": "Ein Dummy-Backend für die KDE-Partitionsverwaltung zu Testzwecken.", + "Description[en_GB]": "A KDE Partition Manager dummy backend for testing purposes.", "Description[es]": "Un motor de simulación para el gestor de particiones de KDE para hacer pruebas.", "Description[fi]": "KDE:n osionhallinnan valetaustaosa testaustarkoituksiin.", "Description[fr]": "Un moteur de test pour le gestionnaire de partitions de KDE pour faire des essais.", @@ -37,6 +58,7 @@ "Name[ca]": "Dorsal fals del gestor de particions del KDE", "Name[cs]": "Podpůrná vrstva pro správce diskových oddílů pro KDE", "Name[de]": "KDE-Partitionsverwaltung Dummy-Backend", + "Name[en_GB]": "KDE Partition Manager Dummy Backend", "Name[es]": "Motor de simulación para el gestor de particiones de KDE", "Name[fi]": "KDE:n osionhallinnan valetaustaosa", "Name[fr]": "Moteur de test pour le gestionnaire de partitions de KDE", diff --git a/src/plugins/sfdisk/pmsfdiskbackendplugin.json b/src/plugins/sfdisk/pmsfdiskbackendplugin.json index e06a2d2..130c61e 100644 --- a/src/plugins/sfdisk/pmsfdiskbackendplugin.json +++ b/src/plugins/sfdisk/pmsfdiskbackendplugin.json @@ -4,7 +4,27 @@ { "Email": "andrius@stikonas.eu", "Name": "Andrius Štikonas", - "Name[x-test]": "xxAndrius Štikonasxx" + "Name[ca@valencia]": "Andrius Štikonas", + "Name[ca]": "Andrius Štikonas", + "Name[cs]": "Andrius Štikonas", + "Name[de]": "Andrius Štikonas", + "Name[en_GB]": "Andrius Štikonas", + "Name[es]": "Andrius Štikonas", + "Name[fi]": "Andrius Štikonas", + "Name[fr]": "Andrius Štikonas", + "Name[gl]": "Andrius Štikonas", + "Name[it]": "Andrius Štikonas", + "Name[ko]": "Andrius Štikonas", + "Name[lt]": "Andrius Štikonas", + "Name[nl]": "Andrius Štikonas", + "Name[pl]": "Andrius Štikonas", + "Name[pt]": "Andrius Štikonas", + "Name[pt_BR]": "Andrius Štikonas", + "Name[sk]": "Andrius Štikonas", + "Name[sv]": "Andrius Štikonas", + "Name[uk]": "Andrius Štikonas", + "Name[x-test]": "xxAndrius Štikonasxx", + "Name[zh_CN]": "Andrius Štikonas" } ], "Category": "BackendPlugin", @@ -13,6 +33,7 @@ "Description[ca]": "Un dorsal «sfdisk» del gestor de particions del KDE.", "Description[cs]": "Podpůrná vrstva sfdisk pro správce diskových oddílů pro KDE.", "Description[de]": "Ein sfdisk-Backend für die KDE-Partitionsverwaltung.", + "Description[en_GB]": "A KDE Partition Manager sfdisk backend.", "Description[es]": "Motor sfdisk para el gestor de particiones de KDE.", "Description[fi]": "KDE:n osionhallinnan sfdisk-taustaosa", "Description[fr]": "Moteur sfdisk pour le gestionnaire de partitions de KDE.", @@ -36,6 +57,7 @@ "Name[ca]": "Dorsal «sfdisk» del gestor de particions del KDE", "Name[cs]": "Podpůrná vrstva sfdisk pro správce diskových oddílů pro KDE", "Name[de]": "KDE-Partitionsverwaltung sfdisk-Backend", + "Name[en_GB]": "KDE Partition Manager sfdisk Backend", "Name[es]": "Motor sfdisk para el gestor de particiones de KDE", "Name[fi]": "KDE:n osionhallinnan sfdisk-taustaosa", "Name[fr]": "Moteur sfdisk pour le gestionnaire de partitions de KDE", From 2007f2b8ea9054b92e08247e68b5b4a6df87d881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Sun, 28 Oct 2018 17:22:12 +0000 Subject: [PATCH 14/26] Allow copyblocks to be used together with small QByteArrays. Add CopyTargetByteArray. CopySourceByteArray is not implemented yet. This is only suitable for reading small amount of data such as GPT header or FAT boot sector location. Not meant for copying whole partition because data has to be transfered over DBus. Differential Revision: https://phabricator.kde.org/D16487 --- src/core/CMakeLists.txt | 1 + src/core/copytargetbytearray.cpp | 29 ++++++++++++++ src/core/copytargetbytearray.h | 58 ++++++++++++++++++++++++++++ src/plugins/sfdisk/CMakeLists.txt | 3 ++ src/plugins/sfdisk/sfdiskbackend.cpp | 13 ++++--- src/util/externalcommand.cpp | 9 ++++- src/util/externalcommandhelper.cpp | 25 ++++++++---- src/util/externalcommandhelper.h | 2 +- 8 files changed, 125 insertions(+), 15 deletions(-) create mode 100644 src/core/copytargetbytearray.cpp create mode 100644 src/core/copytargetbytearray.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 719ec3a..578f37c 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -6,6 +6,7 @@ set(CORE_SRC core/copysourcefile.cpp core/copysourceshred.cpp core/copytarget.cpp + core/copytargetbytearray.cpp core/copytargetdevice.cpp core/copytargetfile.cpp core/device.cpp diff --git a/src/core/copytargetbytearray.cpp b/src/core/copytargetbytearray.cpp new file mode 100644 index 0000000..8728049 --- /dev/null +++ b/src/core/copytargetbytearray.cpp @@ -0,0 +1,29 @@ +/************************************************************************* + * 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/copytargetbytearray.h" + +/** This class is for reading disk data into QByteArray + It is only suitable for reading small amount of data such as GPT header or + FAT boot sector. DBus is too slow for copying data of the whole partition. + @param QByteArray to write to +*/ +CopyTargetByteArray::CopyTargetByteArray(QByteArray& array) : + CopyTarget(), + m_Array(array) +{ +} diff --git a/src/core/copytargetbytearray.h b/src/core/copytargetbytearray.h new file mode 100644 index 0000000..709fa9a --- /dev/null +++ b/src/core/copytargetbytearray.h @@ -0,0 +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); + +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/plugins/sfdisk/CMakeLists.txt b/src/plugins/sfdisk/CMakeLists.txt index d910c3f..c7b137d 100644 --- a/src/plugins/sfdisk/CMakeLists.txt +++ b/src/plugins/sfdisk/CMakeLists.txt @@ -18,6 +18,9 @@ set (pmsfdiskbackendplugin_SRCS sfdiskdevice.cpp sfdiskpartitiontable.cpp ${CMAKE_SOURCE_DIR}/src/backend/corebackenddevice.cpp + ${CMAKE_SOURCE_DIR}/src/core/copysourcedevice.cpp + ${CMAKE_SOURCE_DIR}/src/core/copytargetdevice.cpp + ${CMAKE_SOURCE_DIR}/src/core/copytargetbytearray.cpp ) add_library(pmsfdiskbackendplugin SHARED ${pmsfdiskbackendplugin_SRCS}) diff --git a/src/plugins/sfdisk/sfdiskbackend.cpp b/src/plugins/sfdisk/sfdiskbackend.cpp index a563250..6b54384 100644 --- a/src/plugins/sfdisk/sfdiskbackend.cpp +++ b/src/plugins/sfdisk/sfdiskbackend.cpp @@ -21,6 +21,8 @@ #include "plugins/sfdisk/sfdiskbackend.h" #include "plugins/sfdisk/sfdiskdevice.h" +#include "core/copysourcedevice.h" +#include "core/copytargetbytearray.h" #include "core/diskdevice.h" #include "core/lvmdevice.h" #include "core/partitiontable.h" @@ -332,11 +334,12 @@ bool SfdiskBackend::updateDevicePartitionTable(Device &d, const QJsonObject &jso { // Read the maximum number of GPT partitions qint32 maxEntries; - ExternalCommand ddCommand(QStringLiteral("dd"), - { QStringLiteral("skip=1"), QStringLiteral("count=1"), (QStringLiteral("if=") + d.deviceNode()) }, - QProcess::SeparateChannels); - if (ddCommand.run(-1) && ddCommand.exitCode() == 0 ) { - QByteArray gptHeader = ddCommand.rawOutput(); + QByteArray gptHeader; + CopySourceDevice source(d, 512, 1023); + CopyTargetByteArray target(gptHeader); + + ExternalCommand copyCmd; + if (copyCmd.copyBlocks(source, target)) { QByteArray gptMaxEntries = gptHeader.mid(80, 4); QDataStream stream(&gptMaxEntries, QIODevice::ReadOnly); stream.setByteOrder(QDataStream::LittleEndian); diff --git a/src/util/externalcommand.cpp b/src/util/externalcommand.cpp index 14194d5..21bb2bb 100644 --- a/src/util/externalcommand.cpp +++ b/src/util/externalcommand.cpp @@ -20,6 +20,7 @@ #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" @@ -222,8 +223,12 @@ bool ExternalCommand::copyBlocks(CopySource& source, CopyTarget& target) if (watcher->isError()) qWarning() << watcher->error(); else { - QDBusPendingReply reply = *watcher; - rval = reply.argumentAt<0>(); + 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); }; diff --git a/src/util/externalcommandhelper.cpp b/src/util/externalcommandhelper.cpp index 0c701e2..87edade 100644 --- a/src/util/externalcommandhelper.cpp +++ b/src/util/externalcommandhelper.cpp @@ -152,12 +152,17 @@ bool ExternalCommandHelper::writeData(const QString &targetDevice, const QByteAr return true; } -bool ExternalCommandHelper::copyblocks(const QByteArray& signature, const quint64 nonce, const QString& sourceDevice, const qint64 sourceFirstByte, const qint64 sourceLength, const QString& targetDevice, const qint64 targetFirstByte, const qint64 blockSize) +QVariantMap ExternalCommandHelper::copyblocks(const QByteArray& signature, const quint64 nonce, const QString& sourceDevice, const qint64 sourceFirstByte, const qint64 sourceLength, const QString& targetDevice, const qint64 targetFirstByte, const qint64 blockSize) { + QVariantMap reply; + reply[QStringLiteral("success")] = true; + if (m_Nonces.find(nonce) != m_Nonces.end()) m_Nonces.erase( nonce ); - else - return false; + else { + reply[QStringLiteral("success")] = false; + return reply; + } QByteArray request; @@ -172,7 +177,8 @@ bool ExternalCommandHelper::copyblocks(const QByteArray& signature, const quint6 QByteArray hash = QCryptographicHash::hash(request, QCryptographicHash::Sha512); if (!m_publicKey.verifyMessage(hash, signature, QCA::EMSA3_Raw)) { qCritical() << xi18n("Invalid cryptographic signature"); - return false; + reply[QStringLiteral("success")] = false; + return reply; } const qint64 blocksToCopy = sourceLength / blockSize; @@ -239,8 +245,12 @@ bool ExternalCommandHelper::copyblocks(const QByteArray& signature, const quint6 HelperSupport::progressStep(report); rval = readData(sourceDevice, buffer, lastBlockReadOffset, lastBlock); - if (rval) - rval = writeData(targetDevice, buffer, lastBlockWriteOffset); + if (rval) { + if (targetDevice.isEmpty()) + reply[QStringLiteral("targetByteArray")] = buffer; + else + rval = writeData(targetDevice, buffer, lastBlockWriteOffset); + } if (rval) { HelperSupport::progressStep(100); @@ -251,7 +261,8 @@ bool ExternalCommandHelper::copyblocks(const QByteArray& signature, const quint6 report[QStringLiteral("report")] = xi18ncp("@info:progress argument 2 is a string such as 7 bytes (localized accordingly)", "Copying 1 block (%2) finished.", "Copying %1 blocks (%2) finished.", blocksCopied, i18np("1 byte", "%1 bytes", bytesWritten)); HelperSupport::progressStep(report); - return rval; + reply[QStringLiteral("success")] = rval; + return reply; } QVariantMap ExternalCommandHelper::start(const QByteArray& signature, const quint64 nonce, const QString& command, const QStringList& arguments, const QByteArray& input, const int processChannelMode) diff --git a/src/util/externalcommandhelper.h b/src/util/externalcommandhelper.h index 0ab9ef9..3f7959c 100644 --- a/src/util/externalcommandhelper.h +++ b/src/util/externalcommandhelper.h @@ -49,7 +49,7 @@ public Q_SLOTS: ActionReply init(const QVariantMap& args); Q_SCRIPTABLE quint64 getNonce(); Q_SCRIPTABLE QVariantMap start(const QByteArray& signature, const quint64 nonce, const QString& command, const QStringList& arguments, const QByteArray& input, const int processChannelMode); - Q_SCRIPTABLE bool copyblocks(const QByteArray& signature, const quint64 nonce, const QString& sourceDevice, const qint64 sourceFirstByte, const qint64 sourceLength, const QString& targetDevice, const qint64 targetFirstByte, const qint64 blockSize); + Q_SCRIPTABLE QVariantMap copyblocks(const QByteArray& signature, const quint64 nonce, const QString& sourceDevice, const qint64 sourceFirstByte, const qint64 sourceLength, const QString& targetDevice, const qint64 targetFirstByte, const qint64 blockSize); Q_SCRIPTABLE void exit(const QByteArray& signature, const quint64 nonce); private: From 4f3a9db3487b5c7f1cf88ae95ed4bfb2cf03192d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Mon, 12 Nov 2018 00:22:24 +0000 Subject: [PATCH 15/26] Print commands that are being run if KPMCORE_DEBUG is set --- src/util/externalcommand.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/util/externalcommand.cpp b/src/util/externalcommand.cpp index 21bb2bb..76b480c 100644 --- a/src/util/externalcommand.cpp +++ b/src/util/externalcommand.cpp @@ -125,9 +125,11 @@ bool ExternalCommand::start(int timeout) if (command().isEmpty()) return false; - if (report()) { + 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()) From 53d84f3d34fac988cd40a97f08836fcc6532ebbd Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Wed, 14 Nov 2018 06:03:26 +0100 Subject: [PATCH 16/26] SVN_SILENT made messages (.desktop file) - always resolve ours In case of conflict in i18n, keep the version of the branch "ours" To resolve a particular conflict, "git checkout --ours path/to/file.desktop" --- src/util/org.kde.kpmcore.externalcommand.actions | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/org.kde.kpmcore.externalcommand.actions b/src/util/org.kde.kpmcore.externalcommand.actions index 7590e14..bba0030 100644 --- a/src/util/org.kde.kpmcore.externalcommand.actions +++ b/src/util/org.kde.kpmcore.externalcommand.actions @@ -36,6 +36,7 @@ Description[lt]=Diskų tvarkymui reikalingos administratoriaus teisės Description[nl]=Er zijn administratieve rechten vereist om schijven te beheren Description[pl]=Do zarządzania dyskami wymagane są uprawnienia administratora Description[pt]=São necessários privilégios de administrador para gerir os discos +Description[pt_BR]=São necessários privilégios administrativos para gerenciar discos Description[sv]=Administratörsprivilegier krävs för att hantera diskar Description[uk]=Для керування дисками потрібні права доступу адміністратора (root) Description[x-test]=xxAdministrative privileges are required to manage disksxx From b22be9ad9a39fb423509eda5948b6280558f1f7c Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Wed, 21 Nov 2018 05:40:59 +0100 Subject: [PATCH 17/26] SVN_SILENT made messages (.desktop file) - always resolve ours In case of conflict in i18n, keep the version of the branch "ours" To resolve a particular conflict, "git checkout --ours path/to/file.desktop" --- src/util/org.kde.kpmcore.externalcommand.actions | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/util/org.kde.kpmcore.externalcommand.actions b/src/util/org.kde.kpmcore.externalcommand.actions index bba0030..28c4c7d 100644 --- a/src/util/org.kde.kpmcore.externalcommand.actions +++ b/src/util/org.kde.kpmcore.externalcommand.actions @@ -12,6 +12,7 @@ Name[es]=Iniciar el demonio de órdenes externas Name[fi]=Käynnistä ulkoinen komentopalvelu Name[fr]=Lancer le démon de la commande externe Name[gl]=Iniciar o servizo de orde externa +Name[it]=Avvia demone per comando esterno Name[ko]=외부 명령 데몬 시작 Name[lt]=Paleisti išorinių komandų tarnybą Name[nl]=Start externe opdrachtdaemon @@ -31,6 +32,7 @@ Description[es]=Se necesitan permisos de administrador para gestionar discos Description[fi]=Levyjen hallinta vaatii pääkäyttäjäoikeuksia Description[fr]=Vous devez disposer des privilèges d'administrateur pour gérer les disques Description[gl]=Requírense privilexios de administración para xestionar discos. +Description[it]=Per gestire il disco sono richiesti privilegi di amministratore Description[ko]=디스크를 관리하려면 권한이 필요함 Description[lt]=Diskų tvarkymui reikalingos administratoriaus teisės Description[nl]=Er zijn administratieve rechten vereist om schijven te beheren From 0e4fca8de63da94279cf83b4442267a07faa395c Mon Sep 17 00:00:00 2001 From: Caio Carvalho Date: Sat, 24 Nov 2018 21:45:48 -0300 Subject: [PATCH 18/26] Getting lsblk kname in the cases where the model name isn't available Summary: lsblk command does not return model name as output in some specific cases, specially when you have a micro SD in your computer (perhaps it should happen with a normal SD card as well, but I haven't tested it). So I included a verification in SfdiskBackend::scanDevice to check for kname in lsblk and use it as the name in these cases. Reviewers: stikonas Reviewed By: stikonas Tags: #kde_partition_manager Differential Revision: https://phabricator.kde.org/D16577 --- src/plugins/sfdisk/sfdiskbackend.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/plugins/sfdisk/sfdiskbackend.cpp b/src/plugins/sfdisk/sfdiskbackend.cpp index 6b54384..899a264 100644 --- a/src/plugins/sfdisk/sfdiskbackend.cpp +++ b/src/plugins/sfdisk/sfdiskbackend.cpp @@ -169,12 +169,23 @@ Device* SfdiskBackend::scanDevice(const QString& deviceNode) if ( d == nullptr && modelCommand.run(-1) && modelCommand.exitCode() == 0 ) { - QString modelName = modelCommand.output(); - modelName = modelName.left(modelName.length() - 1); + QString name = modelCommand.output(); + name = name.left(name.length() - 1); - Log(Log::Level::information) << xi18nc("@info:status", "Device found: %1", modelName); + if (name.trimmed().isEmpty()) { + // Get 'lsblk --output kname' in the cases where the model name is not available. + // As lsblk doesn't have an option to include a separator in its output, it is + // necessary to run it again getting only the kname as output. + ExternalCommand kname(QStringLiteral("lsblk"), {QStringLiteral("--nodeps"), QStringLiteral("--noheadings"), QStringLiteral("--output"), QStringLiteral("kname"), + deviceNode}); - d = new DiskDevice(modelName, deviceNode, 255, 63, deviceSize / logicalSectorSize / 255 / 63, logicalSectorSize); + if (kname.run(-1) && kname.exitCode() == 0) + name = kname.output(); + } + + Log(Log::Level::information) << xi18nc("@info:status", "Device found: %1", name); + + d = new DiskDevice(name, deviceNode, 255, 63, deviceSize / logicalSectorSize / 255 / 63, logicalSectorSize); } if ( d ) From 09e4d47e0711a800be858fdd6691f59838bc3003 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Sun, 25 Nov 2018 20:50:22 +0000 Subject: [PATCH 19/26] Do not use external process dd. BUG: 398154 --- src/fs/fat12.cpp | 8 ++--- src/fs/fat32.cpp | 11 +++---- src/fs/ntfs.cpp | 7 ++-- src/util/externalcommand.cpp | 49 ++++++++++++++++++++++++++++ src/util/externalcommand.h | 1 + src/util/externalcommand_whitelist.h | 1 - src/util/externalcommandhelper.cpp | 30 ++++++++++++++++- src/util/externalcommandhelper.h | 1 + 8 files changed, 90 insertions(+), 18 deletions(-) diff --git a/src/fs/fat12.cpp b/src/fs/fat12.cpp index 8124c4a..dbad427 100644 --- a/src/fs/fat12.cpp +++ b/src/fs/fat12.cpp @@ -157,7 +157,7 @@ bool fat12::create(Report& report, const QString& deviceNode) bool fat12::updateUUID(Report& report, const QString& deviceNode) const { - qint64 t = time(nullptr); + long int t = time(nullptr); char uuid[4]; for (auto &u : uuid) { @@ -165,9 +165,7 @@ bool fat12::updateUUID(Report& report, const QString& deviceNode) const t >>= 8; } - ExternalCommand cmd(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode , QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=39") }); - - cmd.write(QByteArray(uuid, sizeof(uuid))); - return cmd.start(); + ExternalCommand cmd; + return cmd.writeData(report, QByteArray(uuid, sizeof(uuid)), deviceNode, 39); } } diff --git a/src/fs/fat32.cpp b/src/fs/fat32.cpp index b54e4fa..2bb6b34 100644 --- a/src/fs/fat32.cpp +++ b/src/fs/fat32.cpp @@ -14,6 +14,7 @@ * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* *************************************************************************/ + #include "fs/fat32.h" #include "util/externalcommand.h" @@ -48,7 +49,8 @@ bool fat32::create(Report& report, const QString& deviceNode) bool fat32::updateUUID(Report& report, const QString& deviceNode) const { - qint64 t = time(nullptr); + // HACK: replace this hack with fatlabel "-i" (dosfstools 4.2) + long int t = time(nullptr); char uuid[4]; for (auto &u : uuid) { @@ -56,10 +58,7 @@ bool fat32::updateUUID(Report& report, const QString& deviceNode) const t >>= 8; } - // HACK: replace this hack with fatlabel "-i" (dosfstools 4.2) - ExternalCommand cmd(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode, QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=67") }); - - cmd.write(QByteArray(uuid, sizeof(uuid))); - return cmd.start(); + ExternalCommand cmd; + return cmd.writeData(report, QByteArray(uuid, sizeof(uuid)), deviceNode, 67); } } diff --git a/src/fs/ntfs.cpp b/src/fs/ntfs.cpp index 471638a..0c08c6c 100644 --- a/src/fs/ntfs.cpp +++ b/src/fs/ntfs.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -188,10 +187,8 @@ bool ntfs::updateBootSector(Report& report, const QString& deviceNode) const std::swap(s[1], s[2]); #endif - ExternalCommand cmd(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode , QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=28") }); - - cmd.write(QByteArray(s, sizeof(s))); - if (!cmd.start()) { + ExternalCommand cmd; + if (!cmd.writeData(report, QByteArray(s, sizeof(s)), deviceNode, 28)) { Log() << xi18nc("@info:progress", "Could not write new start sector to partition %1 when trying to update the NTFS boot sector.", deviceNode); return false; } diff --git a/src/util/externalcommand.cpp b/src/util/externalcommand.cpp index 76b480c..72b1b14 100644 --- a/src/util/externalcommand.cpp +++ b/src/util/externalcommand.cpp @@ -241,6 +241,55 @@ bool ExternalCommand::copyBlocks(CopySource& source, CopyTarget& target) 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() << "Could not connect to DBus system bus"; + 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 + QByteArray request; + + const quint64 nonce = interface->getNonce(); + request.setNum(nonce); + request.append(buffer); + request.append(deviceNode.toUtf8()); + request.append(QByteArray::number(firstByte)); + + QByteArray hash = QCryptographicHash::hash(request, QCryptographicHash::Sha512); + + QDBusPendingCall pcall = interface->writeData(privateKey->signMessage(hash, QCA::EMSA3_Raw), nonce, + 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) { diff --git a/src/util/externalcommand.h b/src/util/externalcommand.h index 35b1a81..c1abba2 100644 --- a/src/util/externalcommand.h +++ b/src/util/externalcommand.h @@ -69,6 +69,7 @@ public: public: bool copyBlocks(CopySource& source, CopyTarget& target); + bool writeData(Report& report, const QByteArray& buffer, const QString& deviceNode, const quint64 firstByte); // same as copyBlocks but from QByteArray /**< @param cmd the command to run */ void setCommand(const QString& cmd); diff --git a/src/util/externalcommand_whitelist.h b/src/util/externalcommand_whitelist.h index 79160aa..7ae4240 100644 --- a/src/util/externalcommand_whitelist.h +++ b/src/util/externalcommand_whitelist.h @@ -21,7 +21,6 @@ QString allowedCommands[] = { // TODO try to remove these later QStringLiteral("mv"), -QStringLiteral("dd"), // TODO no root needed QStringLiteral("lsblk"), diff --git a/src/util/externalcommandhelper.cpp b/src/util/externalcommandhelper.cpp index 87edade..c5687cf 100644 --- a/src/util/externalcommandhelper.cpp +++ b/src/util/externalcommandhelper.cpp @@ -152,6 +152,7 @@ bool ExternalCommandHelper::writeData(const QString &targetDevice, const QByteAr return true; } +// If targetDevice is empty then return QByteArray with data that was read from disk. QVariantMap ExternalCommandHelper::copyblocks(const QByteArray& signature, const quint64 nonce, const QString& sourceDevice, const qint64 sourceFirstByte, const qint64 sourceLength, const QString& targetDevice, const qint64 targetFirstByte, const qint64 blockSize) { QVariantMap reply; @@ -213,7 +214,7 @@ QVariantMap ExternalCommandHelper::copyblocks(const QByteArray& signature, const bool rval = true; - while (blocksCopied < blocksToCopy) { + while (blocksCopied < blocksToCopy && !targetDevice.isEmpty()) { if (!(rval = readData(sourceDevice, buffer, readOffset + blockSize * blocksCopied * copyDirection, blockSize))) break; @@ -265,6 +266,33 @@ QVariantMap ExternalCommandHelper::copyblocks(const QByteArray& signature, const return reply; } +bool ExternalCommandHelper::writeData(const QByteArray& signature, const quint64 nonce, const QByteArray buffer, const QString& targetDevice, const qint64 targetFirstByte) +{ + if (m_Nonces.find(nonce) != m_Nonces.end()) + m_Nonces.erase( nonce ); + else + return false; + + QByteArray request; + request.setNum(nonce); + request.append(buffer); + request.append(targetDevice.toUtf8()); + request.append(QByteArray::number(targetFirstByte)); + + // Do not allow using this helper for writing to arbitrary location + if ( targetDevice.left(5) != QStringLiteral("/dev/") && !targetDevice.contains(QStringLiteral("/etc/fstab"))) + return false; + + QByteArray hash = QCryptographicHash::hash(request, QCryptographicHash::Sha512); + if (!m_publicKey.verifyMessage(hash, signature, QCA::EMSA3_Raw)) { + qCritical() << xi18n("Invalid cryptographic signature"); + return false; + } + + return writeData(targetDevice, buffer, targetFirstByte); +} + + QVariantMap ExternalCommandHelper::start(const QByteArray& signature, const quint64 nonce, const QString& command, const QStringList& arguments, const QByteArray& input, const int processChannelMode) { QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); diff --git a/src/util/externalcommandhelper.h b/src/util/externalcommandhelper.h index 3f7959c..d73d085 100644 --- a/src/util/externalcommandhelper.h +++ b/src/util/externalcommandhelper.h @@ -50,6 +50,7 @@ public Q_SLOTS: Q_SCRIPTABLE quint64 getNonce(); Q_SCRIPTABLE QVariantMap start(const QByteArray& signature, const quint64 nonce, const QString& command, const QStringList& arguments, const QByteArray& input, const int processChannelMode); Q_SCRIPTABLE QVariantMap copyblocks(const QByteArray& signature, const quint64 nonce, const QString& sourceDevice, const qint64 sourceFirstByte, const qint64 sourceLength, const QString& targetDevice, const qint64 targetFirstByte, const qint64 blockSize); + Q_SCRIPTABLE bool writeData(const QByteArray& signature, const quint64 nonce, const QByteArray buffer, const QString& targetDevice, const qint64 targetFirstByte); Q_SCRIPTABLE void exit(const QByteArray& signature, const quint64 nonce); private: From 80f5a32dc04c4150d3b32c46526b6489f8fa853c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Thu, 29 Nov 2018 22:32:07 +0000 Subject: [PATCH 20/26] Remove remaining cases of call to dd binary. BUG: 398154 --- src/fs/fat12.cpp | 2 +- src/fs/fat16.cpp | 2 +- src/fs/ntfs.cpp | 5 +---- src/util/externalcommandhelper.cpp | 2 +- src/util/externalcommandhelper.h | 2 +- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/fs/fat12.cpp b/src/fs/fat12.cpp index dbad427..b4917fe 100644 --- a/src/fs/fat12.cpp +++ b/src/fs/fat12.cpp @@ -59,7 +59,7 @@ void fat12::init() m_Move = cmdSupportCore; m_Copy = cmdSupportCore; m_Backup = cmdSupportCore; - m_UpdateUUID = findExternal(QStringLiteral("dd")) ? cmdSupportFileSystem : cmdSupportNone; + m_UpdateUUID = cmdSupportCore; m_GetUUID = cmdSupportCore; } diff --git a/src/fs/fat16.cpp b/src/fs/fat16.cpp index 2c768b0..3c9fa1e 100644 --- a/src/fs/fat16.cpp +++ b/src/fs/fat16.cpp @@ -50,7 +50,7 @@ void fat16::init() m_Move = cmdSupportCore; m_Copy = cmdSupportCore; m_Backup = cmdSupportCore; - m_UpdateUUID = findExternal(QStringLiteral("dd")) ? cmdSupportFileSystem : cmdSupportNone; + m_UpdateUUID = cmdSupportCore; m_Grow = findExternal(QStringLiteral("fatresize")) ? cmdSupportFileSystem : cmdSupportNone; m_Shrink = findExternal(QStringLiteral("fatresize")) ? cmdSupportFileSystem : cmdSupportNone; m_GetUUID = cmdSupportCore; diff --git a/src/fs/ntfs.cpp b/src/fs/ntfs.cpp index 0c08c6c..8639383 100644 --- a/src/fs/ntfs.cpp +++ b/src/fs/ntfs.cpp @@ -196,10 +196,7 @@ bool ntfs::updateBootSector(Report& report, const QString& deviceNode) const // Also update backup NTFS boot sector located at the end of the partition // NOTE: this should fail if filesystem does not span the whole partition qint64 pos = (lastSector() - firstSector()) * sectorSize() + 28; - ExternalCommand cmd2(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode , QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=") + QString::number(pos) }); - - cmd2.write(QByteArray(s, sizeof(s))); - if (!cmd2.start()) { + if (!cmd.writeData(report, QByteArray(s, sizeof(s)), deviceNode, pos)) { Log() << xi18nc("@info:progress", "Could not write new start sector to partition %1 when trying to update the NTFS boot sector.", deviceNode); return false; } diff --git a/src/util/externalcommandhelper.cpp b/src/util/externalcommandhelper.cpp index c5687cf..008c4c9 100644 --- a/src/util/externalcommandhelper.cpp +++ b/src/util/externalcommandhelper.cpp @@ -266,7 +266,7 @@ QVariantMap ExternalCommandHelper::copyblocks(const QByteArray& signature, const return reply; } -bool ExternalCommandHelper::writeData(const QByteArray& signature, const quint64 nonce, const QByteArray buffer, const QString& targetDevice, const qint64 targetFirstByte) +bool ExternalCommandHelper::writeData(const QByteArray& signature, const quint64 nonce, const QByteArray& buffer, const QString& targetDevice, const qint64 targetFirstByte) { if (m_Nonces.find(nonce) != m_Nonces.end()) m_Nonces.erase( nonce ); diff --git a/src/util/externalcommandhelper.h b/src/util/externalcommandhelper.h index d73d085..6cb14c8 100644 --- a/src/util/externalcommandhelper.h +++ b/src/util/externalcommandhelper.h @@ -50,7 +50,7 @@ public Q_SLOTS: Q_SCRIPTABLE quint64 getNonce(); Q_SCRIPTABLE QVariantMap start(const QByteArray& signature, const quint64 nonce, const QString& command, const QStringList& arguments, const QByteArray& input, const int processChannelMode); Q_SCRIPTABLE QVariantMap copyblocks(const QByteArray& signature, const quint64 nonce, const QString& sourceDevice, const qint64 sourceFirstByte, const qint64 sourceLength, const QString& targetDevice, const qint64 targetFirstByte, const qint64 blockSize); - Q_SCRIPTABLE bool writeData(const QByteArray& signature, const quint64 nonce, const QByteArray buffer, const QString& targetDevice, const qint64 targetFirstByte); + Q_SCRIPTABLE bool writeData(const QByteArray& signature, const quint64 nonce, const QByteArray& buffer, const QString& targetDevice, const qint64 targetFirstByte); Q_SCRIPTABLE void exit(const QByteArray& signature, const quint64 nonce); private: From d4f3ac62ae0dbafd3f0a8c5d6a84b3512506f1af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Thu, 6 Dec 2018 01:23:27 +0000 Subject: [PATCH 21/26] Use drive-removable-media-usb icon for USB devices. --- src/plugins/sfdisk/sfdiskbackend.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/plugins/sfdisk/sfdiskbackend.cpp b/src/plugins/sfdisk/sfdiskbackend.cpp index 899a264..a980689 100644 --- a/src/plugins/sfdisk/sfdiskbackend.cpp +++ b/src/plugins/sfdisk/sfdiskbackend.cpp @@ -183,9 +183,16 @@ Device* SfdiskBackend::scanDevice(const QString& deviceNode) name = kname.output(); } + ExternalCommand transport(QStringLiteral("lsblk"), {QStringLiteral("--nodeps"), QStringLiteral("--noheadings"), QStringLiteral("--output"), QStringLiteral("tran"), + deviceNode}); + QString icon; + if (transport.run(-1) && transport.exitCode() == 0) + if (transport.output().trimmed() == QStringLiteral("usb")) + icon = QStringLiteral("drive-removable-media-usb"); + Log(Log::Level::information) << xi18nc("@info:status", "Device found: %1", name); - d = new DiskDevice(name, deviceNode, 255, 63, deviceSize / logicalSectorSize / 255 / 63, logicalSectorSize); + d = new DiskDevice(name, deviceNode, 255, 63, deviceSize / logicalSectorSize / 255 / 63, logicalSectorSize, icon); } if ( d ) From 8d980b56eda5e1c27f339fca56c16352baba468f Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Wed, 19 Dec 2018 05:44:22 +0100 Subject: [PATCH 22/26] SVN_SILENT made messages (.desktop file) - always resolve ours In case of conflict in i18n, keep the version of the branch "ours" To resolve a particular conflict, "git checkout --ours path/to/file.desktop" --- src/plugins/dummy/pmdummybackendplugin.json | 3 +++ src/plugins/sfdisk/pmsfdiskbackendplugin.json | 3 +++ src/util/org.kde.kpmcore.externalcommand.actions | 2 ++ 3 files changed, 8 insertions(+) diff --git a/src/plugins/dummy/pmdummybackendplugin.json b/src/plugins/dummy/pmdummybackendplugin.json index 022c33f..740aafe 100644 --- a/src/plugins/dummy/pmdummybackendplugin.json +++ b/src/plugins/dummy/pmdummybackendplugin.json @@ -8,6 +8,7 @@ "Name[ca]": "Volker Lanz", "Name[cs]": "Volker Lanz", "Name[de]": "Volker Lanz", + "Name[el]": "Volker Lanz", "Name[en_GB]": "Volker Lanz", "Name[es]": "Volker Lanz", "Name[fi]": "Volker Lanz", @@ -33,6 +34,7 @@ "Description[ca]": "Un dorsal fals del gestor de particions del KDE amb la finalitat de fer proves.", "Description[cs]": "Falešná podpůrná vrstva pro správce diskových oddílů KDE pro testovací účely.", "Description[de]": "Ein Dummy-Backend für die KDE-Partitionsverwaltung zu Testzwecken.", + "Description[el]": "Ένα εικονικό σύστημα υποστήριξης διαχειριστή κατατμήσεων του KDE για δοκιμές.", "Description[en_GB]": "A KDE Partition Manager dummy backend for testing purposes.", "Description[es]": "Un motor de simulación para el gestor de particiones de KDE para hacer pruebas.", "Description[fi]": "KDE:n osionhallinnan valetaustaosa testaustarkoituksiin.", @@ -58,6 +60,7 @@ "Name[ca]": "Dorsal fals del gestor de particions del KDE", "Name[cs]": "Podpůrná vrstva pro správce diskových oddílů pro KDE", "Name[de]": "KDE-Partitionsverwaltung Dummy-Backend", + "Name[el]": "KDE Εικονικό σύστημα υποστήριξης διαχειριστή κατατμήσεων", "Name[en_GB]": "KDE Partition Manager Dummy Backend", "Name[es]": "Motor de simulación para el gestor de particiones de KDE", "Name[fi]": "KDE:n osionhallinnan valetaustaosa", diff --git a/src/plugins/sfdisk/pmsfdiskbackendplugin.json b/src/plugins/sfdisk/pmsfdiskbackendplugin.json index 130c61e..45d9371 100644 --- a/src/plugins/sfdisk/pmsfdiskbackendplugin.json +++ b/src/plugins/sfdisk/pmsfdiskbackendplugin.json @@ -8,6 +8,7 @@ "Name[ca]": "Andrius Štikonas", "Name[cs]": "Andrius Štikonas", "Name[de]": "Andrius Štikonas", + "Name[el]": "Andrius Štikonas", "Name[en_GB]": "Andrius Štikonas", "Name[es]": "Andrius Štikonas", "Name[fi]": "Andrius Štikonas", @@ -33,6 +34,7 @@ "Description[ca]": "Un dorsal «sfdisk» del gestor de particions del KDE.", "Description[cs]": "Podpůrná vrstva sfdisk pro správce diskových oddílů pro KDE.", "Description[de]": "Ein sfdisk-Backend für die KDE-Partitionsverwaltung.", + "Description[el]": "Σύστημα υποστήριξης sfdisk διαχειριστή κατατμήσεων του KDE.", "Description[en_GB]": "A KDE Partition Manager sfdisk backend.", "Description[es]": "Motor sfdisk para el gestor de particiones de KDE.", "Description[fi]": "KDE:n osionhallinnan sfdisk-taustaosa", @@ -57,6 +59,7 @@ "Name[ca]": "Dorsal «sfdisk» del gestor de particions del KDE", "Name[cs]": "Podpůrná vrstva sfdisk pro správce diskových oddílů pro KDE", "Name[de]": "KDE-Partitionsverwaltung sfdisk-Backend", + "Name[el]": "KDE Σύστημα υποστήριξης sfdisk διαχειριστή κατατμήσεων", "Name[en_GB]": "KDE Partition Manager sfdisk Backend", "Name[es]": "Motor sfdisk para el gestor de particiones de KDE", "Name[fi]": "KDE:n osionhallinnan sfdisk-taustaosa", diff --git a/src/util/org.kde.kpmcore.externalcommand.actions b/src/util/org.kde.kpmcore.externalcommand.actions index 28c4c7d..e0f4bba 100644 --- a/src/util/org.kde.kpmcore.externalcommand.actions +++ b/src/util/org.kde.kpmcore.externalcommand.actions @@ -7,6 +7,7 @@ Name[ca]=Inicia el dimoni d'ordres externes Name[ca@valencia]=Inicia el dimoni d'ordres externes Name[cs]=Spustit démona externích příkazů Name[de]=Externen Befehlsdienst starten +Name[el]=Εκκίνηση διεργασίας με εξωτερική εντολή Name[en_GB]=Start external command daemon Name[es]=Iniciar el demonio de órdenes externas Name[fi]=Käynnistä ulkoinen komentopalvelu @@ -27,6 +28,7 @@ Description[ca]=Es requereixen privilegis d'administrador per gestionar discs Description[ca@valencia]=Es requereixen privilegis d'administrador per gestionar discs Description[cs]=Pro správu disků jsou potřeba práva administrátora Description[de]=Systemverwalterrechte sind zur Verwaltung von Festplatten erforderlich +Description[el]=Απαιτούνται δικαιώματα διαχειριστή για τη διαχείριση δίσκων Description[en_GB]=Administrative privileges are required to manage disks Description[es]=Se necesitan permisos de administrador para gestionar discos Description[fi]=Levyjen hallinta vaatii pääkäyttäjäoikeuksia From faca8f7f0d5494ea1346bd10a7cb0aef43ed67da Mon Sep 17 00:00:00 2001 From: Anthony Fieroni Date: Wed, 19 Dec 2018 23:18:49 +0000 Subject: [PATCH 23/26] S.M.A.R.T. attribute 178 is same as 179 smartctl --all /dev/sda 178 Used_Rsvd_Blk_Cnt_Chip 0x0013 100 100 010 Pre-fail Always Differential Revision: https://phabricator.kde.org/D17683 --- src/core/smartattribute.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/smartattribute.cpp b/src/core/smartattribute.cpp index f27bb07..fc0e9a5 100644 --- a/src/core/smartattribute.cpp +++ b/src/core/smartattribute.cpp @@ -128,6 +128,7 @@ static const AttrDetails* attrDetails() { 175, i18nc("SMART attr name", "SSD Power Loss Protection Failure"), i18nc("SMART attr description", "Last test result, saturated at its maximum value. Bytes 0-1: last test result as microseconds to discharge cap in range [25, 5000000], lower indicates specific error code. Bytes 2-3: minutes since last test. Bytes 4-5: lifetime number of tests. Normalized value is set to 1 on test failure or 11 if the capacitor has been tested in an excessive temperature condition, otherwise 100.") }, { 176, i18nc("SMART attr name", "SSD Erase Fail Count (chip)"), i18nc("SMART attr description", "Number of flash erase command failures.") }, { 177, i18nc("SMART attr name", "SSD Wear Range Delta"), i18nc("SMART attr description", "Delta between most-worn and least-worn flash blocks.") }, + { 178, i18nc("SMART attr name", "SSD Used Reserved Block Count Total"), i18nc("SMART attr description", "\"Pre-Fail\" Samsung attribute.") }, { 179, i18nc("SMART attr name", "SSD Used Reserved Block Count Total"), i18nc("SMART attr description", "\"Pre-Fail\" Samsung attribute.") }, { 180, i18nc("SMART attr name", "SSD Unused Reserved Block Count Total"), i18nc("SMART attr description", "\"Pre-Fail\" HP attribute.") }, { 181, i18nc("SMART attr name", "SSD Program Fail Count Total or Non-4K Aligned Access Count"), i18nc("SMART attr description", "Number of flash program operation failures since the drive was deployed.") }, From 66ded3229dad56687cd47441330a50fb1d7f332f Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Tue, 1 Jan 2019 05:26:53 +0100 Subject: [PATCH 24/26] SVN_SILENT made messages (.desktop file) - always resolve ours In case of conflict in i18n, keep the version of the branch "ours" To resolve a particular conflict, "git checkout --ours path/to/file.desktop" --- src/plugins/dummy/pmdummybackendplugin.json | 1 + src/plugins/sfdisk/pmsfdiskbackendplugin.json | 1 + 2 files changed, 2 insertions(+) diff --git a/src/plugins/dummy/pmdummybackendplugin.json b/src/plugins/dummy/pmdummybackendplugin.json index 740aafe..93919b3 100644 --- a/src/plugins/dummy/pmdummybackendplugin.json +++ b/src/plugins/dummy/pmdummybackendplugin.json @@ -4,6 +4,7 @@ { "Email": "vl@fidra.de", "Name": "Volker Lanz", + "Name[ast]": "Volker Lanz", "Name[ca@valencia]": "Volker Lanz", "Name[ca]": "Volker Lanz", "Name[cs]": "Volker Lanz", diff --git a/src/plugins/sfdisk/pmsfdiskbackendplugin.json b/src/plugins/sfdisk/pmsfdiskbackendplugin.json index 45d9371..4ccb803 100644 --- a/src/plugins/sfdisk/pmsfdiskbackendplugin.json +++ b/src/plugins/sfdisk/pmsfdiskbackendplugin.json @@ -4,6 +4,7 @@ { "Email": "andrius@stikonas.eu", "Name": "Andrius Štikonas", + "Name[ast]": "Andrius Štikonas", "Name[ca@valencia]": "Andrius Štikonas", "Name[ca]": "Andrius Štikonas", "Name[cs]": "Andrius Štikonas", From 47cdc9e40505e4125ff7ee2287474ee280a58b18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Tue, 1 Jan 2019 21:29:32 +0000 Subject: [PATCH 25/26] Update smartmontool (runtime) dependency. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b7d3efd..86a89da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,7 @@ set(BLKID_MIN_VERSION "2.32") # Qca-qt5 (tested with botan and ossl backends) # Runtime -# smartmontools 6.7 +# smartmontools 7.0 # Qca plugin (botan or ossl) set(VERSION_MAJOR "3") From 734ae3670534333b4cc32bfa4a99859e0ceba2dc Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Wed, 2 Jan 2019 05:38:52 +0100 Subject: [PATCH 26/26] SVN_SILENT made messages (.desktop file) - always resolve ours In case of conflict in i18n, keep the version of the branch "ours" To resolve a particular conflict, "git checkout --ours path/to/file.desktop" --- src/util/org.kde.kpmcore.externalcommand.actions | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/org.kde.kpmcore.externalcommand.actions b/src/util/org.kde.kpmcore.externalcommand.actions index e0f4bba..4117d5f 100644 --- a/src/util/org.kde.kpmcore.externalcommand.actions +++ b/src/util/org.kde.kpmcore.externalcommand.actions @@ -24,6 +24,7 @@ Name[sv]=Starta extern kommandodemon Name[uk]=Запуск фонової служби зовнішньої команди Name[x-test]=xxStart external command daemonxx Description=Administrative privileges are required to manage disks +Description[ast]=Ríquense los privilexos alministrativos pa xestionar discos Description[ca]=Es requereixen privilegis d'administrador per gestionar discs Description[ca@valencia]=Es requereixen privilegis d'administrador per gestionar discs Description[cs]=Pro správu disků jsou potřeba práva administrátora