Commit 82f373d9 authored by Simon Persson's avatar Simon Persson

Add bup archive verification as an optional feature.

Run before backing up to make sure it does not interfere with a possible par2 generation.
parent 1a0db45e
......@@ -28,16 +28,17 @@
BupJob::BupJob(const BackupPlan &pBackupPlan, const QString &pDestinationPath, const QString &pLogFilePath)
:BackupJob(pBackupPlan, pDestinationPath, pLogFilePath)
{
mFsckProcess.setOutputChannelMode(KProcess::SeparateChannels);
mIndexProcess.setOutputChannelMode(KProcess::SeparateChannels);
mSaveProcess.setOutputChannelMode(KProcess::SeparateChannels);
mFsckProcess.setOutputChannelMode(KProcess::SeparateChannels);
mPar2Process.setOutputChannelMode(KProcess::SeparateChannels);
}
void BupJob::start() {
QTimer::singleShot(0, this, SLOT(startIndexing()));
QTimer::singleShot(0, this, SLOT(startJob()));
}
void BupJob::startIndexing() {
void BupJob::startJob() {
KProcess lVersionProcess;
lVersionProcess.setOutputChannelMode(KProcess::SeparateChannels);
lVersionProcess << QLatin1String("bup") << QLatin1String("version");
......@@ -72,6 +73,36 @@ void BupJob::startIndexing() {
return;
}
if(mBackupPlan.mCheckBackups) {
mFsckProcess << QLatin1String("bup");
mFsckProcess << QLatin1String("-d") << mDestinationPath;
mFsckProcess << QLatin1String("fsck") << QLatin1String("--quick");
connect(&mFsckProcess, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(slotCheckingDone(int,QProcess::ExitStatus)));
connect(&mFsckProcess, SIGNAL(started()), SLOT(slotCheckingStarted()));
mLogStream << mFsckProcess.program().join(QLatin1String(" ")) << endl;
mFsckProcess.start();
} else {
slotCheckingDone(0, QProcess::NormalExit);
}
}
void BupJob::slotCheckingStarted() {
makeNice(mFsckProcess.pid());
}
void BupJob::slotCheckingDone(int pExitCode, QProcess::ExitStatus pExitStatus) {
mLogStream << QString::fromUtf8(mFsckProcess.readAllStandardError());
if(pExitStatus != QProcess::NormalExit || pExitCode != 0) {
mLogStream << endl << QLatin1String("Kup did not successfully complete the bup backup job: "
"failed integrity check. Your backups could be "
"corrupted! See above for details.") << endl;
setErrorText(i18nc("notification", "Failed backup integrity check. Your backups could be corrupted! "
"See log file for more details."));
setError(ErrorWithLog);
emitResult();
return;
}
mIndexProcess << QLatin1String("bup");
mIndexProcess << QLatin1String("-d") << mDestinationPath;
mIndexProcess << QLatin1String("index") << QLatin1String("-u");
......@@ -130,15 +161,14 @@ void BupJob::slotSavingDone(int pExitCode, QProcess::ExitStatus pExitStatus) {
return;
}
if(mBackupPlan.mGenerateRecoveryInfo) {
mFsckProcess << QLatin1String("bup");
mFsckProcess << QLatin1String("-d") << mDestinationPath;
mFsckProcess << QLatin1String("fsck");
mFsckProcess << QLatin1String("-g");
connect(&mFsckProcess, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(slotRecoveryInfoDone(int,QProcess::ExitStatus)));
connect(&mFsckProcess, SIGNAL(started()), SLOT(slotRecoveryInfoStarted()));
mLogStream << mFsckProcess.program().join(QLatin1String(" ")) << endl;
mFsckProcess.start();
mPar2Process << QLatin1String("bup");
mPar2Process << QLatin1String("-d") << mDestinationPath;
mPar2Process << QLatin1String("fsck") << QLatin1String("-g");
connect(&mPar2Process, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(slotRecoveryInfoDone(int,QProcess::ExitStatus)));
connect(&mPar2Process, SIGNAL(started()), SLOT(slotRecoveryInfoStarted()));
mLogStream << mPar2Process.program().join(QLatin1String(" ")) << endl;
mPar2Process.start();
} else {
mLogStream << endl << QLatin1String("Kup successfully completed the bup backup job.") << endl;
emitResult();
......@@ -146,11 +176,11 @@ void BupJob::slotSavingDone(int pExitCode, QProcess::ExitStatus pExitStatus) {
}
void BupJob::slotRecoveryInfoStarted() {
makeNice(mFsckProcess.pid());
makeNice(mPar2Process.pid());
}
void BupJob::slotRecoveryInfoDone(int pExitCode, QProcess::ExitStatus pExitStatus) {
mLogStream << QString::fromUtf8(mFsckProcess.readAllStandardError());
mLogStream << QString::fromUtf8(mPar2Process.readAllStandardError());
if(pExitStatus != QProcess::NormalExit || pExitCode != 0) {
mLogStream << endl << QLatin1String("Kup did not successfully complete the bup backup job: "
"failed to generate recovery info.") << endl;
......
......@@ -34,7 +34,9 @@ public:
virtual void start();
protected slots:
void startIndexing();
void startJob();
void slotCheckingStarted();
void slotCheckingDone(int pExitCode, QProcess::ExitStatus pExitStatus);
void slotIndexingStarted();
void slotIndexingDone(int pExitCode, QProcess::ExitStatus pExitStatus);
void slotSavingStarted();
......@@ -43,9 +45,10 @@ protected slots:
void slotRecoveryInfoDone(int pExitCode, QProcess::ExitStatus pExitStatus);
protected:
KProcess mFsckProcess;
KProcess mIndexProcess;
KProcess mSaveProcess;
KProcess mFsckProcess;
KProcess mPar2Process;
QString mBupVersion;
};
......
......@@ -541,8 +541,28 @@ KPageWidgetItem *BackupPlanWidget::createAdvancedPage() {
lRecoveryWidget->setLayout(lRecoveryLayout);
connect(mVersionedRadio, SIGNAL(toggled(bool)), lRecoveryWidget, SLOT(setVisible(bool)));
QWidget *lVerificationWidget = new QWidget;
QCheckBox *lVerificationCheckBox = new QCheckBox(i18nc("@option:check", "Verify integrity of backups"));
lVerificationCheckBox->setObjectName(QLatin1String("kcfg_Check backups"));
QLabel *lVerificationLabel = new QLabel(i18nc("@info", "Checks the whole backup archive for corruption "
"every time you save new data. Saving backups will take a "
"little bit longer time but it allows you to catch corruption "
"problems sooner than at the time you need to use a backup, "
"at that time it could be too late."));
lVerificationLabel->setWordWrap(true);
QGridLayout *lVerificationLayout = new QGridLayout;
lVerificationLayout->setContentsMargins(0, 0, 0, 0);
lVerificationLayout->setSpacing(0);
lVerificationLayout->setColumnMinimumWidth(0, lIndentation);
lVerificationLayout->addWidget(lVerificationCheckBox,0, 0, 1, 2);
lVerificationLayout->addWidget(lVerificationLabel, 1, 1);
lVerificationWidget->setLayout(lVerificationLayout);
connect(mVersionedRadio, SIGNAL(toggled(bool)), lVerificationWidget, SLOT(setVisible(bool)));
lAdvancedLayout->addWidget(lShowHiddenCheckBox);
lAdvancedLayout->addLayout(lShowHiddenLayout);
lAdvancedLayout->addWidget(lVerificationWidget);
lAdvancedLayout->addWidget(lRecoveryWidget);
lAdvancedLayout->addStretch();
lAdvancedWidget->setLayout(lAdvancedLayout);
......
......@@ -75,6 +75,7 @@ BackupPlan::BackupPlan(int pPlanNumber, KSharedConfigPtr pConfig, QObject *pPare
addItemBool(QLatin1String("Show hidden folders"), mShowHiddenFolders);
addItemBool(QLatin1String("Generate recovery info"), mGenerateRecoveryInfo);
addItemBool(QLatin1String("Check backups"), mCheckBackups);
addItemDateTime(QLatin1String("Last complete backup"), mLastCompleteBackup);
addItemDouble(QLatin1String("Last backup size"), mLastBackupSize);
......
......@@ -60,6 +60,7 @@ public:
bool mShowHiddenFolders;
bool mGenerateRecoveryInfo;
bool mCheckBackups;
QDateTime mLastCompleteBackup;
// Size of the last backup in bytes.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment