Commit 627de08d authored by Simon Persson's avatar Simon Persson

Add option to generate par2 recovery info for bup backups.

Possible improvements would be to check if par2 is indeed available, and to detect failures in file digger and automatically try to repair pack files if par2 is available.
Closes #19.
parent 98ef3fdb
......@@ -26,11 +26,13 @@
#include <QTimer>
BupJob::BupJob(const QStringList &pPathsIncluded, const QStringList &pPathsExcluded,
const QString &pDestinationPath, const QString &pLogFilePath)
:BackupJob(pPathsIncluded, pPathsExcluded, pDestinationPath, pLogFilePath)
const QString &pDestinationPath, const QString &pLogFilePath, bool pGenerateRecoveryInfo)
:BackupJob(pPathsIncluded, pPathsExcluded, pDestinationPath, pLogFilePath),
mGenerateRecoveryInfo(pGenerateRecoveryInfo)
{
mIndexProcess.setOutputChannelMode(KProcess::SeparateChannels);
mSaveProcess.setOutputChannelMode(KProcess::SeparateChannels);
mFsckProcess.setOutputChannelMode(KProcess::SeparateChannels);
}
void BupJob::start() {
......@@ -94,9 +96,9 @@ void BupJob::slotIndexingStarted() {
void BupJob::slotIndexingDone(int pExitCode, QProcess::ExitStatus pExitStatus) {
mLogStream << QString::fromUtf8(mIndexProcess.readAllStandardError()) << endl;
if(pExitStatus != QProcess::NormalExit || pExitCode != 0) {
mLogStream << QLatin1String("Kup is aborting the bup backup job.") << endl;
mLogStream << QLatin1String("Kup did not successfully complete the bup backup job: failed to index everything.") << endl;
setError(ErrorWithLog);
setErrorText(i18nc("notification", "Indexing of file system did not complete successfully. "
setErrorText(i18nc("notification", "Failed to index the file system. "
"See log file for more details."));
emitResult();
return;
......@@ -121,9 +123,39 @@ void BupJob::slotSavingStarted() {
void BupJob::slotSavingDone(int pExitCode, QProcess::ExitStatus pExitStatus) {
mLogStream << QString::fromUtf8(mSaveProcess.readAllStandardError()) << endl;
if(pExitStatus != QProcess::NormalExit || pExitCode != 0) {
mLogStream << QLatin1String("Kup did not successfully complete the bup backup job.") << endl;
mLogStream << QLatin1String("Kup did not successfully complete the bup backup job: failed to save everything.") << endl;
setError(ErrorWithLog);
setErrorText(i18nc("notification", "Failed to save the complete backup. "
"See log file for more details."));
emitResult();
return;
}
if(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();
} else {
mLogStream << QLatin1String("Kup successfully completed the bup backup job.") << endl;
emitResult();
}
}
void BupJob::slotRecoveryInfoStarted() {
makeNice(mFsckProcess.pid());
}
void BupJob::slotRecoveryInfoDone(int pExitCode, QProcess::ExitStatus pExitStatus) {
mLogStream << QString::fromUtf8(mFsckProcess.readAllStandardError()) << endl;
if(pExitStatus != QProcess::NormalExit || pExitCode != 0) {
mLogStream << QLatin1String("Kup did not successfully complete the bup backup job: failed to generate recovery info.") << endl;
setError(ErrorWithLog);
setErrorText(i18nc("notification", "Saving backup did not complete successfully. "
setErrorText(i18nc("notification", "Failed to generate recovery info for the backup. "
"See log file for more details."));
} else {
mLogStream << QLatin1String("Kup successfully completed the bup backup job.") << endl;
......
......@@ -31,7 +31,7 @@ class BupJob : public BackupJob
public:
BupJob(const QStringList &pPathsIncluded, const QStringList &pPathsExcluded,
const QString &pDestinationPath, const QString &pLogFilePath);
const QString &pDestinationPath, const QString &pLogFilePath, bool pGenerateRecoveryInfo);
virtual void start();
protected slots:
......@@ -40,11 +40,15 @@ protected slots:
void slotIndexingDone(int pExitCode, QProcess::ExitStatus pExitStatus);
void slotSavingStarted();
void slotSavingDone(int pExitCode, QProcess::ExitStatus pExitStatus);
void slotRecoveryInfoStarted();
void slotRecoveryInfoDone(int pExitCode, QProcess::ExitStatus pExitStatus);
protected:
KProcess mIndexProcess;
KProcess mSaveProcess;
KProcess mFsckProcess;
QString mBupVersion;
bool mGenerateRecoveryInfo;
};
#endif /*BUPJOB_H*/
......@@ -269,7 +269,8 @@ void PlanExecutor::showFilesClicked() {
BackupJob *PlanExecutor::createBackupJob() {
if(mPlan->mBackupType == BackupPlan::BupType) {
return new BupJob(mPlan->mPathsIncluded, mPlan->mPathsExcluded, mDestinationPath, mLogFilePath);
return new BupJob(mPlan->mPathsIncluded, mPlan->mPathsExcluded, mDestinationPath, mLogFilePath,
mPlan->mGenerateRecoveryInfo);
} else if(mPlan->mBackupType == BackupPlan::RsyncType) {
return new RsyncJob(mPlan->mPathsIncluded, mPlan->mPathsExcluded, mDestinationPath, mLogFilePath);
}
......
......@@ -522,8 +522,28 @@ KPageWidgetItem *BackupPlanWidget::createAdvancedPage() {
lShowHiddenLayout->setContentsMargins(0, 0, 0, 0);
lShowHiddenLayout->setColumnMinimumWidth(0, lIndentation);
lShowHiddenLayout->addWidget(lShowHiddenLabel, 0, 1);
QWidget *lRecoveryWidget = new QWidget;
QCheckBox *lRecoveryCheckBox = new QCheckBox(i18nc("@option:check", "Generate recovery information"));
lRecoveryCheckBox->setObjectName(QLatin1String("kcfg_Generate recovery info"));
QLabel *lRecoveryLabel = new QLabel(i18nc("@info", "This will make your backups use around 10% more storage "
"space and saving backups will take slightly longer time. In "
"return it will be possible to recover from a partially corrupted "
"backup."));
lRecoveryLabel->setWordWrap(true);
QGridLayout *lRecoveryLayout = new QGridLayout;
lRecoveryLayout->setContentsMargins(0, 0, 0, 0);
lRecoveryLayout->setSpacing(0);
lRecoveryLayout->setColumnMinimumWidth(0, lIndentation);
lRecoveryLayout->addWidget(lRecoveryCheckBox,0, 0, 1, 2);
lRecoveryLayout->addWidget(lRecoveryLabel, 1, 1);
lRecoveryWidget->setLayout(lRecoveryLayout);
connect(mVersionedRadio, SIGNAL(toggled(bool)), lRecoveryWidget, SLOT(setVisible(bool)));
lAdvancedLayout->addWidget(lShowHiddenCheckBox);
lAdvancedLayout->addLayout(lShowHiddenLayout);
lAdvancedLayout->addWidget(lRecoveryWidget);
lAdvancedLayout->addStretch();
lAdvancedWidget->setLayout(lAdvancedLayout);
KPageWidgetItem *lPage = new KPageWidgetItem(lAdvancedWidget);
......
......@@ -74,6 +74,7 @@ BackupPlan::BackupPlan(int pPlanNumber, KSharedConfigPtr pConfig, QObject *pPare
addItemInt(QLatin1String("External partitions count"), mExternalPartitionsOnDrive);
addItemBool(QLatin1String("Show hidden folders"), mShowHiddenFolders);
addItemBool(QLatin1String("Generate recovery info"), mGenerateRecoveryInfo);
addItemDateTime(QLatin1String("Last complete backup"), mLastCompleteBackup);
addItemDouble(QLatin1String("Last backup size"), mLastBackupSize);
......
......@@ -59,6 +59,7 @@ public:
qulonglong mExternalVolumeCapacity;
bool mShowHiddenFolders;
bool mGenerateRecoveryInfo;
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