File indexing completed on 2024-04-21 16:30:23
0001 // SPDX-FileCopyrightText: 2020 Simon Persson <simon.persson@mykolab.com> 0002 // 0003 // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 0005 #include "backupjob.h" 0006 #include "bupjob.h" 0007 #include "kupdaemon.h" 0008 #include "rsyncjob.h" 0009 0010 #include <unistd.h> 0011 #include <sys/resource.h> 0012 #ifdef Q_OS_LINUX 0013 #include <sys/syscall.h> 0014 #endif 0015 0016 #include <KLocalizedString> 0017 #include <QTimer> 0018 #include <utility> 0019 0020 BackupJob::BackupJob(BackupPlan &pBackupPlan, QString pDestinationPath, QString pLogFilePath, KupDaemon *pKupDaemon) 0021 :mBackupPlan(pBackupPlan), mDestinationPath(std::move(pDestinationPath)), mLogFilePath(std::move(pLogFilePath)), mKupDaemon(pKupDaemon) 0022 { 0023 mLogFile.setFileName(mLogFilePath); 0024 mLogFile.open(QIODevice::WriteOnly | QIODevice::Truncate); 0025 mLogStream.setDevice(&mLogFile); 0026 } 0027 0028 void BackupJob::start() { 0029 mKupDaemon->registerJob(this); 0030 QStringList lRemovedPaths; 0031 for(const QString &lPath: std::as_const(mBackupPlan.mPathsIncluded)) { 0032 if(!QFile::exists(lPath)) { 0033 lRemovedPaths << lPath; 0034 } 0035 } 0036 if(!lRemovedPaths.isEmpty()) { 0037 jobFinishedError(ErrorSourcesConfig, 0038 xi18ncp("@info notification", 0039 "One source folder no longer exists. Please open settings and confirm what to include in backup.<nl/>" 0040 "<filename>%2</filename>", 0041 "%1 source folders no longer exist. Please open settings and confirm what to include in backup.<nl/>" 0042 "<filename>%2</filename>", 0043 lRemovedPaths.length(), lRemovedPaths.join(QChar('\n')))); 0044 return; 0045 } 0046 QTimer::singleShot(0, this, &BackupJob::performJob); 0047 } 0048 0049 void BackupJob::makeNice(int pPid) { 0050 #ifdef Q_OS_LINUX 0051 // See linux documentation Documentation/block/ioprio.txt for details of the syscall 0052 syscall(SYS_ioprio_set, 1, pPid, 3 << 13 | 7); 0053 #endif 0054 setpriority(PRIO_PROCESS, static_cast<uint>(pPid), 19); 0055 } 0056 0057 QString BackupJob::quoteArgs(const QStringList &pCommand) { 0058 QString lResult; 0059 bool lFirst = true; 0060 foreach(const QString &lArg, pCommand) { 0061 if(lFirst) { 0062 lResult.append(lArg); 0063 lFirst = false; 0064 } else { 0065 lResult.append(QStringLiteral(" \"")); 0066 lResult.append(lArg); 0067 lResult.append(QStringLiteral("\"")); 0068 } 0069 } 0070 return lResult; 0071 } 0072 0073 void BackupJob::jobFinishedSuccess() { 0074 // unregistring a job will normally show a UI notification that it the job was completed 0075 // setting the error code to indicate that the user canceled the job makes the UI not show 0076 // any notification. We want that since we want to trigger our own notification which has 0077 // more buttons and stuff. 0078 setError(KilledJobError); 0079 mKupDaemon->unregisterJob(this); 0080 0081 // The error code is still used by our internal logic, for triggering our own notification. 0082 // So make sure to set it correctly. 0083 setError(NoError); 0084 emitResult(); 0085 } 0086 0087 void BackupJob::jobFinishedError(BackupJob::ErrorCodes pErrorCode, const QString &pErrorText) { 0088 // if job has already set the error that it was killed by the user then ignore any fault 0089 // we get here as that fault is surely about the process exit code was not zero. 0090 // And we don't want to report about that (with our notification) in this case. 0091 bool lWasKilled = (error() == KilledJobError); 0092 0093 setError(KilledJobError); 0094 mKupDaemon->unregisterJob(this); 0095 if(!lWasKilled) { 0096 setError(pErrorCode); 0097 setErrorText(pErrorText); 0098 } 0099 emitResult(); 0100 } 0101