File indexing completed on 2024-04-14 15:49:36

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 "buprepairjob.h"
0006 
0007 #include <QThread>
0008 
0009 #include <KLocalizedString>
0010 
0011 BupRepairJob::BupRepairJob(BackupPlan &pBackupPlan, const QString &pDestinationPath,
0012                                        const QString &pLogFilePath, KupDaemon *pKupDaemon)
0013    : BackupJob(pBackupPlan, pDestinationPath, pLogFilePath, pKupDaemon){
0014     mFsckProcess.setOutputChannelMode(KProcess::SeparateChannels);
0015 }
0016 
0017 void BupRepairJob::performJob() {
0018     KProcess lPar2Process;
0019     lPar2Process.setOutputChannelMode(KProcess::SeparateChannels);
0020     lPar2Process << QStringLiteral("bup") << QStringLiteral("fsck") << QStringLiteral("--par2-ok");
0021     int lExitCode = lPar2Process.execute();
0022     if(lExitCode < 0) {
0023         jobFinishedError(ErrorWithoutLog, xi18nc("@info notification",
0024                                                  "The <application>bup</application> program is needed but could not be found, "
0025                                                  "maybe it is not installed?"));
0026         return;
0027     }
0028     if(mBackupPlan.mGenerateRecoveryInfo && lExitCode != 0) {
0029         jobFinishedError(ErrorWithoutLog, xi18nc("@info notification",
0030                                                  "The <application>par2</application> program is needed but could not be found, "
0031                                                  "maybe it is not installed?"));
0032         return;
0033     }
0034 
0035     mLogStream << QStringLiteral("Kup is starting bup repair job at ")
0036                << QLocale().toString(QDateTime::currentDateTime())
0037                << Qt::endl << Qt::endl;
0038 
0039     mFsckProcess << QStringLiteral("bup");
0040     mFsckProcess << QStringLiteral("-d") << mDestinationPath;
0041     mFsckProcess << QStringLiteral("fsck") << QStringLiteral("-r");
0042     mFsckProcess << QStringLiteral("-j") << QString::number(qMin(4, QThread::idealThreadCount()));
0043 
0044     connect(&mFsckProcess, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(slotRepairDone(int,QProcess::ExitStatus)));
0045     connect(&mFsckProcess, SIGNAL(started()), SLOT(slotRepairStarted()));
0046     mLogStream << mFsckProcess.program().join(QStringLiteral(" ")) << Qt::endl;
0047     mFsckProcess.start();
0048 }
0049 
0050 void BupRepairJob::slotRepairStarted() {
0051     makeNice(mFsckProcess.processId());
0052 }
0053 
0054 void BupRepairJob::slotRepairDone(int pExitCode, QProcess::ExitStatus pExitStatus) {
0055     QString lErrors = QString::fromUtf8(mFsckProcess.readAllStandardError());
0056     if(!lErrors.isEmpty()) {
0057         mLogStream << lErrors << Qt::endl;
0058     }
0059     mLogStream << "Exit code: " << pExitCode << Qt::endl;
0060     if(pExitStatus != QProcess::NormalExit) {
0061         mLogStream << QStringLiteral("Repair failed (the repair process crashed). Your backups could be "
0062                                      "corrupted! See above for details.") << Qt::endl;
0063         jobFinishedError(ErrorWithLog, xi18nc("@info notification", "Backup repair failed. Your backups could be corrupted! "
0064                                                                     "See log file for more details."));
0065     } else if(pExitCode == 100) {
0066         mLogStream << QStringLiteral("Repair succeeded. See above for details.") << Qt::endl;
0067         jobFinishedError(ErrorWithLog, xi18nc("@info notification", "Success! Backup repair worked. See log file for more details."));
0068     } else if(pExitCode == 0) {
0069         mLogStream << QStringLiteral("Repair was not necessary. Your backups are fine. See "
0070                                      "above for details.") << Qt::endl;
0071         jobFinishedError(ErrorWithLog, xi18nc("@info notification", "Backup repair was not necessary. Your backups are not corrupted. "
0072                                                                     "See log file for more details."));
0073     } else {
0074         mLogStream << QStringLiteral("Repair failed. Your backups could still be "
0075                                      "corrupted! See above for details.") << Qt::endl;
0076         jobFinishedError(ErrorWithLog, xi18nc("@info notification", "Backup repair failed. Your backups could still be corrupted! "
0077                                                                     "See log file for more details."));
0078     }
0079 }