1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
// SPDX-FileCopyrightText: 2020 Simon Persson <simon.persson@mykolab.com>
//
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#include "backupjob.h"
#include "bupjob.h"
#include "kupdaemon.h"
#include "rsyncjob.h"
#include <sys/resource.h>
#include <unistd.h>
#ifdef Q_OS_LINUX
#include <sys/syscall.h>
#endif
#include <KLocalizedString>
#include <QTimer>
#include <utility>
BackupJob::BackupJob(BackupPlan &pBackupPlan, QString pDestinationPath, QString pLogFilePath, KupDaemon *pKupDaemon)
: mBackupPlan(pBackupPlan)
, mDestinationPath(std::move(pDestinationPath))
, mLogFilePath(std::move(pLogFilePath))
, mKupDaemon(pKupDaemon)
{
mLogFile.setFileName(mLogFilePath);
mLogFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
mLogStream.setDevice(&mLogFile);
}
void BackupJob::start()
{
mKupDaemon->registerJob(this);
QStringList lRemovedPaths;
for (const QString &lPath : std::as_const(mBackupPlan.mPathsIncluded)) {
if (!QFile::exists(lPath)) {
lRemovedPaths << lPath;
}
}
if (!lRemovedPaths.isEmpty()) {
jobFinishedError(ErrorSourcesConfig,
xi18ncp("@info notification",
"One source folder no longer exists. Please open settings and confirm what to include in backup.<nl/>"
"<filename>%2</filename>",
"%1 source folders no longer exist. Please open settings and confirm what to include in backup.<nl/>"
"<filename>%2</filename>",
lRemovedPaths.length(),
lRemovedPaths.join(QChar('\n'))));
return;
}
QTimer::singleShot(0, this, &BackupJob::performJob);
}
void BackupJob::makeNice(int pPid)
{
#ifdef Q_OS_LINUX
// See linux documentation Documentation/block/ioprio.txt for details of the syscall
syscall(SYS_ioprio_set, 1, pPid, 3 << 13 | 7);
#endif
setpriority(PRIO_PROCESS, static_cast<uint>(pPid), 19);
}
QString BackupJob::quoteArgs(const QStringList &pCommand)
{
QString lResult;
bool lFirst = true;
foreach (const QString &lArg, pCommand) {
if (lFirst) {
lResult.append(lArg);
lFirst = false;
} else {
lResult.append(QStringLiteral(" \""));
lResult.append(lArg);
lResult.append(QStringLiteral("\""));
}
}
return lResult;
}
void BackupJob::jobFinishedSuccess()
{
// unregistring a job will normally show a UI notification that it the job was completed
// setting the error code to indicate that the user canceled the job makes the UI not show
// any notification. We want that since we want to trigger our own notification which has
// more buttons and stuff.
setError(KilledJobError);
mKupDaemon->unregisterJob(this);
// The error code is still used by our internal logic, for triggering our own notification.
// So make sure to set it correctly.
setError(NoError);
emitResult();
}
void BackupJob::jobFinishedError(BackupJob::ErrorCodes pErrorCode, const QString &pErrorText)
{
// if job has already set the error that it was killed by the user then ignore any fault
// we get here as that fault is surely about the process exit code was not zero.
// And we don't want to report about that (with our notification) in this case.
bool lWasKilled = (error() == KilledJobError);
setError(KilledJobError);
mKupDaemon->unregisterJob(this);
if (!lWasKilled) {
setError(pErrorCode);
setErrorText(pErrorText);
}
emitResult();
}
|