Compare commits

...

13 Commits

Author SHA1 Message Date
Andrius Štikonas 27b85117c4 Rename blockSize to chunkSize to avoid confusion with physical blocks. 2022-02-20 14:41:31 +00:00
Andrius Štikonas d9ceb50238 Add a few more comments explaining copy direction. 2022-02-20 14:41:31 +00:00
l10n daemon script 237d246457 GIT_SILENT made messages (after extraction) 2022-02-20 00:48:23 +00:00
Laurent Montel 8a209e9616 Fix building against qt6 we need kf5.90 2022-02-18 07:22:57 +01:00
l10n daemon script 3f1949f477 GIT_SILENT made messages (after extraction) 2022-02-18 00:48:05 +00:00
Andrius Štikonas c05bb54bc5 Set "false" as the default return value and change it to "true" on success.
Please enter the commit message for your changes. Lines starting
2022-02-15 19:56:46 +00:00
Andrius Štikonas fb1708b958 Fix a typo in definition of MiB constant. 2022-02-15 19:14:19 +00:00
l10n daemon script 94c1ff7133 GIT_SILENT made messages (after extraction) 2022-02-13 00:46:08 +00:00
l10n daemon script b4f5faed58 GIT_SILENT made messages (after extraction) 2022-02-12 00:46:25 +00:00
l10n daemon script 49900e80bf GIT_SILENT made messages (after extraction) 2022-02-11 00:47:29 +00:00
l10n daemon script e0d6c1ce43 GIT_SILENT made messages (after extraction) 2022-02-10 00:46:44 +00:00
l10n daemon script cff0f16a7d GIT_SILENT made messages (after extraction) 2022-02-09 00:50:22 +00:00
Andrius Štikonas 5717c3aa0b Update description of polkit helper. 2022-02-08 21:39:18 +00:00
4 changed files with 46 additions and 57 deletions

View File

@ -23,7 +23,7 @@ set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
# Dependencies
set(QT_MIN_VERSION "5.15.0")
set(KF5_MIN_VERSION "5.88")
set(KF5_MIN_VERSION "5.90")
set(BLKID_MIN_VERSION "2.33.2")
# PolkitQt5-1

View File

@ -1,5 +1,5 @@
/*
SPDX-FileCopyrightText: 2017-2020 Andrius Štikonas <andrius@stikonas.eu>
SPDX-FileCopyrightText: 2017-2022 Andrius Štikonas <andrius@stikonas.eu>
SPDX-FileCopyrightText: 2018 Huzaifa Faruqui <huzaifafaruqui@gmail.com>
SPDX-FileCopyrightText: 2018 Caio Jordão Carvalho <caiojcarvalho@gmail.com>
SPDX-FileCopyrightText: 2018-2019 Harald Sitter <sitter@kde.org>
@ -156,19 +156,19 @@ bool ExternalCommandHelper::CreateFile(const QString &filePath, const QByteArray
}
// If targetDevice is empty then return QByteArray with data that was read from disk.
QVariantMap ExternalCommandHelper::CopyFileData(const QString& sourceDevice, const qint64 sourceOffset, const qint64 sourceLength, const QString& targetDevice, const qint64 targetOffset, const qint64 blockSize)
QVariantMap ExternalCommandHelper::CopyFileData(const QString& sourceDevice, const qint64 sourceOffset, const qint64 sourceLength, const QString& targetDevice, const qint64 targetOffset, const qint64 chunkSize)
{
if (!isCallerAuthorized()) {
return {};
}
// Avoid division by zero further down
if (!blockSize) {
if (!chunkSize) {
return {};
}
// Prevent some out of memory situations
if (blockSize > 100 * MiB) {
if (chunkSize > 100 * MiB) {
return {};
}
@ -187,38 +187,41 @@ QVariantMap ExternalCommandHelper::CopyFileData(const QString& sourceDevice, con
QVariantMap reply;
reply[QStringLiteral("success")] = true;
// This enum specified whether individual blocks are moved left or right
// When partition is moved to the left, we start with the leftmost block,
// and move it further left, then second leftmost block and so on.
// But when we move partition to the right, we start with rightmost block.
// This enum specified whether individual data chunks are moved left or right
// When source and target devices are the same we have to be careful not to overwrite
// source data with newly written data. We don't have to do this if sourceDevice is not
// targetDevice but there are no disadvantages in applying the same scheme.
// When partition is moved to the left, we start with the leftmost chunk,
// and move it further left, then second leftmost chunk and so on.
// But when we move partition to the right, we start with rightmost chunk.
// To account for this difference, we introduce CopyDirection variable which takes
// care of some of the differences between these two cases.
// care of some of the differences in offset calculation between these two cases.
enum CopyDirection : qint8 {
Left = 1,
Right = -1,
};
qint8 copyDirection = targetOffset > sourceOffset ? CopyDirection::Right : CopyDirection::Left;
// Let readOffset (r) and writeOffset (w) be the offsets of the first block that we move.
// Let readOffset (r) and writeOffset (w) be the offsets of the first chunk that we move.
// When we move data to the left:
// ______target______ ______source______
// r <- w=================
qint64 readOffset = sourceOffset;
qint64 writeOffset = targetOffset;
// When we move data to the right, we start moving data from the last block
// When we move data to the right, we start moving data from the last chunk
// ______source______ ______target______
// =================r -> w
if (copyDirection == CopyDirection::Right) {
readOffset = sourceOffset + sourceLength - blockSize;
writeOffset = targetOffset + sourceLength - blockSize;
readOffset = sourceOffset + sourceLength - chunkSize;
writeOffset = targetOffset + sourceLength - chunkSize;
}
const qint64 blocksToCopy = sourceLength / blockSize;
const qint64 lastBlock = sourceLength % blockSize;
const qint64 chunksToCopy = sourceLength / chunkSize;
const qint64 lastBlock = sourceLength % chunkSize;
qint64 bytesWritten = 0;
qint64 blocksCopied = 0;
qint64 chunksCopied = 0;
QByteArray buffer;
int percent = 0;
@ -226,7 +229,7 @@ QVariantMap ExternalCommandHelper::CopyFileData(const QString& sourceDevice, con
timer.start();
QString reportText = xi18nc("@info:progress", "Copying %1 blocks (%2 bytes) from %3 to %4, direction: %5.", blocksToCopy,
QString reportText = xi18nc("@info:progress", "Copying %1 chunks (%2 bytes) from %3 to %4, direction: %5.", chunksToCopy,
sourceLength, readOffset, writeOffset, copyDirection == CopyDirection::Left ? i18nc("direction: left", "left")
: i18nc("direction: right", "right"));
Q_EMIT report(reportText);
@ -235,20 +238,20 @@ QVariantMap ExternalCommandHelper::CopyFileData(const QString& sourceDevice, con
QFile target(targetDevice);
QFile source(sourceDevice);
while (blocksCopied < blocksToCopy) {
if (!(rval = readData(source, buffer, readOffset + blockSize * blocksCopied * copyDirection, blockSize)))
while (chunksCopied < chunksToCopy) {
if (!(rval = readData(source, buffer, readOffset + chunkSize * chunksCopied * copyDirection, chunkSize)))
break;
if (!(rval = writeData(target, buffer, writeOffset + blockSize * blocksCopied * copyDirection)))
if (!(rval = writeData(target, buffer, writeOffset + chunkSize * chunksCopied * copyDirection)))
break;
bytesWritten += buffer.size();
if (++blocksCopied * 100 / blocksToCopy != percent) {
percent = blocksCopied * 100 / blocksToCopy;
if (++chunksCopied * 100 / chunksToCopy != percent) {
percent = chunksCopied * 100 / chunksToCopy;
if (percent % 5 == 0 && timer.elapsed() > 1000) {
const qint64 mibsPerSec = (blocksCopied * blockSize / 1024 / 1024) / (timer.elapsed() / 1000);
const qint64 mibsPerSec = (chunksCopied * chunkSize / 1024 / 1024) / (timer.elapsed() / 1000);
const qint64 estSecsLeft = (100 - percent) * timer.elapsed() / percent / 1000;
reportText = xi18nc("@info:progress", "Copying %1 MiB/second, estimated time left: %2", mibsPerSec, QTime(0, 0).addSecs(estSecsLeft).toString());
Q_EMIT report(reportText);
@ -259,11 +262,11 @@ QVariantMap ExternalCommandHelper::CopyFileData(const QString& sourceDevice, con
// copy the remainder
if (rval && lastBlock > 0) {
Q_ASSERT(lastBlock < blockSize);
Q_ASSERT(lastBlock < chunkSize);
const qint64 lastBlockReadOffset = copyDirection == CopyDirection::Left ? readOffset + blockSize * blocksCopied : sourceOffset;
const qint64 lastBlockWriteOffset = copyDirection == CopyDirection::Left ? writeOffset + blockSize * blocksCopied : targetOffset;
reportText = xi18nc("@info:progress", "Copying remainder of block size %1 from %2 to %3.", lastBlock, lastBlockReadOffset, lastBlockWriteOffset);
const qint64 lastBlockReadOffset = copyDirection == CopyDirection::Left ? readOffset + chunkSize * chunksCopied : sourceOffset;
const qint64 lastBlockWriteOffset = copyDirection == CopyDirection::Left ? writeOffset + chunkSize * chunksCopied : targetOffset;
reportText = xi18nc("@info:progress", "Copying remainder of chunk size %1 from %2 to %3.", lastBlock, lastBlockReadOffset, lastBlockWriteOffset);
Q_EMIT report(reportText);
rval = readData(source, buffer, lastBlockReadOffset, lastBlock);
@ -277,7 +280,7 @@ QVariantMap ExternalCommandHelper::CopyFileData(const QString& sourceDevice, con
}
}
reportText = 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));
reportText = xi18ncp("@info:progress argument 2 is a string such as 7 bytes (localized accordingly)", "Copying 1 chunk (%2) finished.", "Copying %1 chunks (%2) finished.", chunksCopied, i18np("1 byte", "%1 bytes", bytesWritten));
Q_EMIT report(reportText);
reply[QStringLiteral("success")] = rval;
@ -339,10 +342,9 @@ QVariantMap ExternalCommandHelper::RunCommand(const QString& command, const QStr
#endif
QVariantMap reply;
reply[QStringLiteral("success")] = true;
reply[QStringLiteral("success")] = false;
if (command.isEmpty()) {
reply[QStringLiteral("success")] = false;
return reply;
}
@ -350,7 +352,6 @@ QVariantMap ExternalCommandHelper::RunCommand(const QString& command, const QStr
QString basename = command.mid(command.lastIndexOf(QLatin1Char('/')) + 1);
if (allowedCommands.find(basename) == allowedCommands.end()) { // TODO: C++20: replace with contains
qInfo() << command <<" command is not one of the whitelisted command";
reply[QStringLiteral("success")] = false;
return reply;
}
@ -360,7 +361,6 @@ QVariantMap ExternalCommandHelper::RunCommand(const QString& command, const QStr
cmd.setEnvironment( { QStringLiteral("LVM_SUPPRESS_FD_WARNINGS=1") } );
if((processChannelMode != QProcess::SeparateChannels) && (processChannelMode != QProcess::MergedChannels)) {
reply[QStringLiteral("success")] = false;
return reply;
}
cmd.setProcessChannelMode(static_cast<QProcess::ProcessChannelMode>(processChannelMode));
@ -372,6 +372,7 @@ QVariantMap ExternalCommandHelper::RunCommand(const QString& command, const QStr
reply[QStringLiteral("output")] = output;
reply[QStringLiteral("exitCode")] = cmd.exitCode();
reply[QStringLiteral("success")] = true;
return reply;
}

View File

@ -21,7 +21,7 @@
#include <QString>
class QDBusServiceWatcher;
constexpr qint64 MiB = 1 << 30;
constexpr qint64 MiB = 1 << 20;
class ExternalCommandHelper : public QObject, public QDBusContext
{

View File

@ -9,29 +9,17 @@ SPDX-License-Identifier: CC0-1.0
<policyconfig>
<icon_name>partitionmanager</icon_name>
<action id="org.kde.kpmcore.externalcommand.init" >
<description>Start external command daemon</description>
<description xml:lang="ast">Aniciu del degorriu de comandos esternos</description>
<description xml:lang="ca">Inicia el dimoni d'ordres externes</description>
<description xml:lang="ca@valencia">Inicia el dimoni d'ordres externes</description>
<description xml:lang="cs">Spustit démona externích příkazů</description>
<description xml:lang="de">Externen Befehlsdienst starten</description>
<description xml:lang="el">Εκκίνηση διεργασίας με εξωτερική εντολή</description>
<description xml:lang="en_GB">Start external command daemon</description>
<description xml:lang="es">Iniciar el demonio de órdenes externas</description>
<description xml:lang="fr">Lancer le démon externe de commandes</description>
<description xml:lang="hu">Külső parancsdémon indítása</description>
<description xml:lang="it">Avvia demone per comando esterno</description>
<description xml:lang="ko">외부 명령 데몬 시작</description>
<description xml:lang="lt">Paleisti išorinių komandų tarnybą</description>
<description xml:lang="nl">Start externe opdrachtdaemon</description>
<description xml:lang="pl">Rozpocznij usługę zewnętrznego polecenia</description>
<description xml:lang="pt">Iniciar o servidor de comandos externos</description>
<description xml:lang="pt_BR">Iniciar comando externo do daemon</description>
<description xml:lang="sk">Spustiť démona externých príkazov</description>
<description xml:lang="sl">Zaženi demon za zunanje ukaze</description>
<description xml:lang="sv">Starta extern kommandodemon</description>
<description xml:lang="uk">Запуск фонової служби зовнішньої команди</description>
<description xml:lang="zh_CN">启动外部命令进程守护</description>
<description>Run privileged partition manager helper</description>
<description xml:lang="ca">Executa l'ajudant del gestor de particions amb privilegis</description>
<description xml:lang="en_GB">Run privileged partition manager helper</description>
<description xml:lang="es">Ejecutar la aplicación auxiliar de gestión de particiones con privilegios</description>
<description xml:lang="fr">Lancer l'assistant de gestionnaire de partition en mode administrateur</description>
<description xml:lang="it">Esegui l'helper per la gestione delle partizioni privilegiate</description>
<description xml:lang="nl">Hulpprogramma voor partitiebeheerder met extra rechten uitvoeren</description>
<description xml:lang="pl">Uruchom uprzywilejowane zarządzanie partycjami</description>
<description xml:lang="sl">Zaženi pooblaščenega pomočnika skrbnika particij</description>
<description xml:lang="sv">Kör hjälpverktyg för privilegierad partitionshanterare</description>
<description xml:lang="uk">Запуск привілейованої допоміжної програми з керування розділами</description>
<message>Administrative privileges are required to manage disks</message>
<message xml:lang="ast">Ríquense los privilexos alministrativos pa xestionar discos</message>
<message xml:lang="ca">Es requereixen privilegis d'administrador per a gestionar els discs</message>