Deadlock when JGit config is in a different drive [message #1824524] |
Thu, 16 April 2020 16:45  |
Eclipse User |
|
|
|
v5.6.1.202002131546-r
Description
If a git repository and JGit's configuration file are located in different drives, JGit will fail to save the filesystem's attributes when it runs for the first time.
The problem is that there is a deadlock involving the configuration file's lock and the generation of both filesystem's attributes.
Here is how the deadlock happens:
1) JGit tries to create a FileSnapshot for the repository's index
2) Doesn't have the FS attributes saved for that drive, so generates it
3) Proceeds to save it in the configuration file located in the other drive
4) Next it creates a lock file for the configuration file
5) Tries to create a FileSnapshot for the lock file.
6) Repeates steps 2-4 for the attributes of the other drive, and step 4 fails because the lock file already exists.
Impact
Note that it still manages to save the filesystem attributes for 1 of the drives, so next time it runs it will successfully save the attributes for the other drive. A warning is logged but it shouldn't directly impact applications using the library.
Using 2 drives might sound like a corner case but turns out that CI pipelines with Atlassian and GitLab have this kind of setup in their worker nodes. This is impacting users of sonarqube scanners, which uses JGit.
Reproducer
You'll need 2 drives, let's call them /d1 and /d2.
1) Place a git repository in /d1, let's say /d1/repo.
2) Set the environment variable XDG_CONFIG_HOME=/d2
3) Run the following.
@Test
public void reproduce() throws IOException {
try (Repository repo = new RepositoryBuilder()
.findGitDir(new File("/d1/repo")
.setMustExist(true).build()) {
}
}
Workaround
Setting FS.setAsyncFileStoreAttributes(true) breaks the deadlock loop.
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 1.16629 seconds