Skip to content

Commit ea3e9e0

Browse files
committed
Merge bitcoin#18700: Fix locking on WSL using flock instead of fcntl
e8fa0a3 Fix WSL file locking by using flock instead of fcntl (Samuel Dobson) Pull request description: Fixes bitcoin#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 e8fa0a3 Tree-SHA512: ca1009e171970101f1dc2332c5e998717aee00eebc80bb586b826927a74bd0d4c94712e46d1396821bc30533d76deac391b6e1c406c406865661f57fa062c702
2 parents 082a417 + e8fa0a3 commit ea3e9e0

File tree

1 file changed

+29
-8
lines changed

1 file changed

+29
-8
lines changed

src/fs.cpp

+29-8
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77
#ifndef WIN32
88
#include <fcntl.h>
9+
#include <string>
10+
#include <sys/file.h>
11+
#include <sys/utsname.h>
912
#else
1013
#ifndef NOMINMAX
1114
#define NOMINMAX
@@ -47,20 +50,38 @@ FileLock::~FileLock()
4750
}
4851
}
4952

53+
static bool IsWSL()
54+
{
55+
struct utsname uname_data;
56+
return uname(&uname_data) == 0 && std::string(uname_data.version).find("Microsoft") != std::string::npos;
57+
}
58+
5059
bool FileLock::TryLock()
5160
{
5261
if (fd == -1) {
5362
return false;
5463
}
55-
struct flock lock;
56-
lock.l_type = F_WRLCK;
57-
lock.l_whence = SEEK_SET;
58-
lock.l_start = 0;
59-
lock.l_len = 0;
60-
if (fcntl(fd, F_SETLK, &lock) == -1) {
61-
reason = GetErrorReason();
62-
return false;
64+
65+
// Exclusive file locking is broken on WSL using fcntl (issue #18622)
66+
// This workaround can be removed once the bug on WSL is fixed
67+
static const bool is_wsl = IsWSL();
68+
if (is_wsl) {
69+
if (flock(fd, LOCK_EX | LOCK_NB) == -1) {
70+
reason = GetErrorReason();
71+
return false;
72+
}
73+
} else {
74+
struct flock lock;
75+
lock.l_type = F_WRLCK;
76+
lock.l_whence = SEEK_SET;
77+
lock.l_start = 0;
78+
lock.l_len = 0;
79+
if (fcntl(fd, F_SETLK, &lock) == -1) {
80+
reason = GetErrorReason();
81+
return false;
82+
}
6383
}
84+
6485
return true;
6586
}
6687
#else

0 commit comments

Comments
 (0)