SourceList: determine most recent backup of source when making next backup (MB #7708)

This is one half of reusing old backup data. SourceList determines the
most recent backup made when syncing with any peer in the same
context. These peers share the same sources, therefore they can also
share backup data.

The "after" dump is checked first, because it is the more recent one.
The "before" dump of the same session is used when creating
the "after" dump.

This patch also prevents creating empty backup dirs when the backup
operation is not supported by the backend. Because all backends supported
this so far, this wasn't a problem.
This commit is contained in:
Patrick Ohly 2010-02-05 19:17:44 +01:00
parent 78800710fe
commit bc89b9c32c

View file

@ -747,15 +747,47 @@ public:
*/
void dumpDatabases(const string &suffix,
BackupReport SyncSourceReport::*report) {
// Identify all logdirs of current context, of any peer. Used
// to search for previous backups of each source, if
// necessary.
string peer = m_client.getConfigName();
string peerName, contextName;
SyncConfig::splitConfigString(peer, peerName, contextName);
SyncContext context(string("@") + contextName);
LogDir logdir(context);
vector<string> dirs;
logdir.previousLogdirs(dirs);
BOOST_FOREACH(SyncSource *source, *this) {
string dir = databaseName(*source, suffix);
boost::shared_ptr<ConfigNode> node = ConfigNode::createFileNode(dir + ".ini");
SE_LOG_DEBUG(NULL, NULL, "creating %s", dir.c_str());
rm_r(dir);
mkdir_p(dir);
BackupReport dummy;
if (source->getOperations().m_backupData) {
source->getOperations().m_backupData(SyncSource::Operations::ConstBackupInfo(),
SyncSource::Operations::ConstBackupInfo oldBackup;
// Now look for a backup of the current source,
// starting with the most recent one.
for (vector<string>::const_reverse_iterator it = dirs.rbegin();
it != dirs.rend();
++it) {
const string &sessiondir = *it;
string oldBackupDir;
oldBackupDir = databaseName(*source, "after", sessiondir);
if (!isDir(oldBackupDir)) {
oldBackupDir = databaseName(*source, "before", sessiondir);
if (!isDir(oldBackupDir)) {
// try next session
continue;
}
}
oldBackup.m_dirname = oldBackupDir;
oldBackup.m_node = ConfigNode::createFileNode(oldBackupDir + ".ini");
break;
}
mkdir_p(dir);
source->getOperations().m_backupData(oldBackup,
SyncSource::Operations::BackupInfo(dir, node),
report ? source->*report : dummy);
SE_LOG_DEBUG(NULL, NULL, "%s created", dir.c_str());