From: Christian Kamm Date: Thu, 13 Jun 2019 07:59:01 +0000 (+0200) Subject: FolderWatcher: Become unreliable if test notification fails #7241 X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~12^2~22^2~47^2~3 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=e97fc430bfb0ffb420162a835462a8c254f6ccab;p=nextcloud-desktop.git FolderWatcher: Become unreliable if test notification fails #7241 Necessary for some filesystems on windows that don't have full file watching capabilities. --- diff --git a/src/gui/folder.cpp b/src/gui/folder.cpp index aad3c0b6f..d6f84937e 100644 --- a/src/gui/folder.cpp +++ b/src/gui/folder.cpp @@ -1040,6 +1040,7 @@ void Folder::registerFolderWatcher() connect(_folderWatcher.data(), &FolderWatcher::becameUnreliable, this, &Folder::slotWatcherUnreliable); _folderWatcher->init(path()); + _folderWatcher->startNotificatonTest(path() + QLatin1String(".owncloudsync.log")); } void Folder::slotAboutToRemoveAllFiles(SyncFileItem::Direction dir, bool *cancel) diff --git a/src/gui/folderwatcher.cpp b/src/gui/folderwatcher.cpp index 68aa57e9c..6151b1116 100644 --- a/src/gui/folderwatcher.cpp +++ b/src/gui/folderwatcher.cpp @@ -33,6 +33,7 @@ #endif #include "folder.h" +#include "filesystem.h" namespace OCC { @@ -86,6 +87,26 @@ void FolderWatcher::appendSubPaths(QDir dir, QStringList& subPaths) { } } +void FolderWatcher::startNotificatonTest(const QString &path) +{ + Q_ASSERT(_testNotificationPath.isEmpty()); + _testNotificationPath = path; + + if (QFile::exists(path)) { + auto mtime = FileSystem::getModTime(path); + FileSystem::setModTime(path, mtime + 1); + } else { + QFile f(path); + f.open(QIODevice::WriteOnly | QIODevice::Append); + } + + QTimer::singleShot(5000, this, [&]() { + if (!_testNotificationPath.isEmpty()) + emit becameUnreliable(tr("The watcher did not receive a test notification.")); + _testNotificationPath.clear(); + }); +} + int FolderWatcher::testLinuxWatchCount() const { #ifdef Q_OS_LINUX @@ -127,6 +148,10 @@ void FolderWatcher::changeDetected(const QStringList &paths) // ------- handle ignores: for (int i = 0; i < paths.size(); ++i) { QString path = paths[i]; + if (!_testNotificationPath.isEmpty() + && Utility::fileNamesEqual(path, _testNotificationPath)) { + _testNotificationPath.clear(); + } if (pathIsIgnored(path)) { continue; } diff --git a/src/gui/folderwatcher.h b/src/gui/folderwatcher.h index 0a30ef482..ef1a7c394 100644 --- a/src/gui/folderwatcher.h +++ b/src/gui/folderwatcher.h @@ -72,6 +72,14 @@ public: */ bool isReliable() const; + /** + * Triggers a change in the path and verifies a notification arrives. + * + * If no notification is seen, the folderwatcher marks itself as unreliable. + * The path must be ignored by the watcher. + */ + void startNotificatonTest(const QString &path); + /// For testing linux behavior only int testLinuxWatchCount() const; @@ -113,6 +121,9 @@ private: void appendSubPaths(QDir dir, QStringList& subPaths); + /** Path of the expected test notification */ + QString _testNotificationPath; + friend class FolderWatcherPrivate; }; } diff --git a/src/gui/folderwatcher_linux.cpp b/src/gui/folderwatcher_linux.cpp index 2feda4e5e..d8316c81d 100644 --- a/src/gui/folderwatcher_linux.cpp +++ b/src/gui/folderwatcher_linux.cpp @@ -169,9 +169,10 @@ void FolderWatcherPrivate::slotReceivedNotification(int fd) if (event->len == 0 || event->wd <= -1) continue; QByteArray fileName(event->name); + // Filter out journal changes - redundant with filtering in + // FolderWatcher::pathIsIgnored. if (fileName.startsWith("._sync_") || fileName.startsWith(".csync_journal.db") - || fileName.startsWith(".owncloudsync.log") || fileName.startsWith(".sync_")) { continue; }