aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@protonmail.com>2020-05-28 17:25:45 +0200
committerWladimir J. van der Laan <laanwj@protonmail.com>2020-05-28 17:55:20 +0200
commitea3e9e0b84c57df4110ca9e5ccced65c5bbe4611 (patch)
tree7436aa7a3c0d8825afb25e3e7374ef87d484661b /src
parent082a417abcce6a2d6e0a52ccad5cca9657cec64b (diff)
parente8fa0a3d2025509fcddc59fc618e91371542cf87 (diff)
Merge #18700: Fix locking on WSL using flock instead of fcntl
e8fa0a3d2025509fcddc59fc618e91371542cf87 Fix WSL file locking by using flock instead of fcntl (Samuel Dobson) Pull request description: Fixes #18622 A bug in WSL means that fcntl does not exclusively lock files, allowing multiple instances of bitcoin to use the same datadir. If we instead use flock, it works correctly. Passes Travis, but testing on some OS variety would be sensible. From what I can tell, flock and fcntl don't work with each other on linux, so it would still be possible to run a node with this code change and a node before it with the same datadir (this isn't true for Mac/FreeBSD). flock also doesn't support NFS on MacOS and linux<2.6.12 while fcntl did. See here for example: https://gavv.github.io/articles/file-locks/ If changing to flock for all systems is inadvisable, it would also be possible to just detect WSL and use flock when on that platform to avoid the bug. ACKs for top commit: laanwj: Code review ACK e8fa0a3d2025509fcddc59fc618e91371542cf87 Tree-SHA512: ca1009e171970101f1dc2332c5e998717aee00eebc80bb586b826927a74bd0d4c94712e46d1396821bc30533d76deac391b6e1c406c406865661f57fa062c702
Diffstat (limited to 'src')
-rw-r--r--src/fs.cpp37
1 files changed, 29 insertions, 8 deletions
diff --git a/src/fs.cpp b/src/fs.cpp
index 066c6c10d3..e68c97b3ca 100644
--- a/src/fs.cpp
+++ b/src/fs.cpp
@@ -6,6 +6,9 @@
#ifndef WIN32
#include <fcntl.h>
+#include <string>
+#include <sys/file.h>
+#include <sys/utsname.h>
#else
#ifndef NOMINMAX
#define NOMINMAX
@@ -47,20 +50,38 @@ FileLock::~FileLock()
}
}
+static bool IsWSL()
+{
+ struct utsname uname_data;
+ return uname(&uname_data) == 0 && std::string(uname_data.version).find("Microsoft") != std::string::npos;
+}
+
bool FileLock::TryLock()
{
if (fd == -1) {
return false;
}
- struct flock lock;
- lock.l_type = F_WRLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = 0;
- lock.l_len = 0;
- if (fcntl(fd, F_SETLK, &lock) == -1) {
- reason = GetErrorReason();
- return false;
+
+ // Exclusive file locking is broken on WSL using fcntl (issue #18622)
+ // This workaround can be removed once the bug on WSL is fixed
+ static const bool is_wsl = IsWSL();
+ if (is_wsl) {
+ if (flock(fd, LOCK_EX | LOCK_NB) == -1) {
+ reason = GetErrorReason();
+ return false;
+ }
+ } else {
+ struct flock lock;
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = 0;
+ lock.l_len = 0;
+ if (fcntl(fd, F_SETLK, &lock) == -1) {
+ reason = GetErrorReason();
+ return false;
+ }
}
+
return true;
}
#else