New Discovery algorithm

Some error handling. In particular for the case where there is a conflict
between files and directories.

SyncEngineTest and SyncMoveTest passes
This commit is contained in:
Olivier Goffart 2018-07-16 18:35:35 +02:00 committed by Kevin Ottens
parent a384a2d1cb
commit d54e00488a
No known key found for this signature in database
GPG key ID: 074BBBCB8DECC9E2
4 changed files with 41 additions and 21 deletions

View file

@ -547,17 +547,10 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
}
/* permission denied */
ctx->status_code = csync_errno_to_status(errno, CSYNC_STATUS_OPENDIR_ERROR);
if (errno == EACCES) {
qCWarning(lcUpdate, "Permission denied.");
if (mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_PERMISSION_DENIED)) {
return 0;
}
} else if(errno == ENOENT) {
ctx->error_string = QString::fromUtf8(uri);
}
// 403 Forbidden can be sent by the server if the file firewall is active.
// A file or directory should be ignored and sync must continue. See #3490
else if(errno == ERRNO_FORBIDDEN) {
if (errno == ERRNO_FORBIDDEN) {
qCWarning(lcUpdate, "Directory access Forbidden (File Firewall?)");
if( mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_FORBIDDEN) ) {
return 0;

View file

@ -64,8 +64,9 @@ void ProcessDirectoryJob::start()
{
qCInfo(lcDisco) << "STARTING" << _currentFolder._server << _queryServer << _currentFolder._local << _queryLocal;
DiscoverServerJob *serverJob = nullptr;
if (_queryServer == NormalQuery) {
auto serverJob = new DiscoverServerJob(_discoveryData->_account, _discoveryData->_remoteFolder + _currentFolder._server, this);
serverJob = new DiscoverServerJob(_discoveryData->_account, _discoveryData->_remoteFolder + _currentFolder._server, this);
connect(serverJob, &DiscoverServerJob::finished, this, [this](const auto &results) {
if (results) {
_serverEntries = *results;
@ -92,9 +93,36 @@ void ProcessDirectoryJob::start()
}*/
auto dh = csync_vio_local_opendir((_discoveryData->_localDir + _currentFolder._local).toUtf8());
if (!dh) {
qDebug() << "COULD NOT OPEN" << (_discoveryData->_localDir + _currentFolder._local);
qFatal("TODO: ERROR HANDLING");
// should be the same as in csync_update;
qCInfo(lcDisco) << "Error while opening directory" << (_discoveryData->_localDir + _currentFolder._local) << errno;
serverJob->abort();
QString errorString = tr("Error while opening directory %1").arg(_discoveryData->_localDir + _currentFolder._local);
if (errno == EACCES) {
errorString = tr("Directory not accessible on client, permission denied");
if (_dirItem) {
_dirItem->_instruction = CSYNC_INSTRUCTION_IGNORE;
_dirItem->_errorString = errorString;
emit finished();
return;
}
} else if (errno == ENOENT) {
errorString = tr("Directory not found: %1").arg(_discoveryData->_localDir + _currentFolder._local);
if (_dirItem) {
_dirItem->_instruction = CSYNC_INSTRUCTION_IGNORE;
_dirItem->_errorString = errorString;
emit finished();
return;
}
} else if (errno == ENOTDIR) {
// Not a directory..
// Just consider it is empty
_hasLocalEntries = true;
if (_hasServerEntries)
process();
return;
}
emit _discoveryData->fatalError(errorString);
emit finished();
return;
}
while (auto dirent = csync_vio_local_readdir(dh)) {
LocalInfo i;
@ -434,12 +462,12 @@ void ProcessDirectoryJob::processFile(PathTuple path,
qCInfo(lcDisco) << "Local file does not exist anymore." << originalPath;
return;
}
if (buf.modtime != base._modtime || buf.size != base._fileSize) {
if (buf.modtime != base._modtime || buf.size != base._fileSize || buf.type != ItemTypeFile) {
qCInfo(lcDisco) << "File has changed locally, not a rename." << originalPath;
return;
}
} else {
if (!QFile::exists(_discoveryData->_localDir + originalPath)) {
if (!QFileInfo(_discoveryData->_localDir + originalPath).isDir()) {
qCInfo(lcDisco) << "Local directory does not exist anymore." << originalPath;
return;
}

View file

@ -123,7 +123,7 @@ public:
QString adjustRenamedPath(const QString &original) const;
signals:
void finished(int result);
void fatalError(const QString &errorString);
void folderDiscovered(bool local, QString folderUrl);
// A new folder was discovered and was not synced because of the confirmation feature

View file

@ -558,10 +558,6 @@ int SyncEngine::treewalkFile(csync_file_stat_t * /*file*/, csync_file_stat_t * /
item->_status = SyncFileItem::SoftError;
_temporarilyUnavailablePaths.insert(item->_file);
break;
case CSYNC_STATUS_PERMISSION_DENIED:
item->_errorString = QLatin1String("Directory not accessible on client, permission denied.");
item->_status = SyncFileItem::SoftError;
break;
}
@ -920,7 +916,10 @@ void SyncEngine::slotStartDiscovery()
connect(_discoveryPhase.data(), &DiscoveryPhase::folderDiscovered, this, &SyncEngine::slotFolderDiscovered);
connect(_discoveryPhase.data(), &DiscoveryPhase::newBigFolder, this, &SyncEngine::newBigFolder);
connect(_discoveryPhase.data(), &DiscoveryPhase::fatalError, this, [this](const QString &errorString) {
csyncError(errorString);
finalize(false);
});
_discoveryJob = new ProcessDirectoryJob(SyncFileItemPtr(), ProcessDirectoryJob::NormalQuery, ProcessDirectoryJob::NormalQuery,
_discoveryPhase.data(), this);