Bad file descriptor error on NFS filesystem
Description of the bug
Seems git-branchless breaks when the git repo is on a NFS filesystem.
My first guess was the db.sqlite file, since it's well known that sqlite doesn't play well with NFS, but even trying moving just that file on a standard fs (symlinking it to the .git/branchless folder) doesn't help.
The issue is quite easy to reproduce, just clone a repo, initialize git-branchless and commit anything.
Running git sl then will show the error instead of the smartlog output.
Expected behavior
The smartlog output.
Actual behavior
The application panicked (crashed). Message: A fatal error occurred: 0: Bad file descriptor (os error 9)
Location: git-branchless-lib/src/core/dag.rs:277
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BACKTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1: __libc_start_call_main
Run with COLORBT_SHOW_HIDDEN=1 environment variable to disable frame filtering. Location: git-branchless/src/commands/mod.rs:468
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BACKTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1: __libc_start_call_main
Version of rustc
No response
Automated bug report
Software version
git-branchless 0.7.0-pre.1 (v0.3.6-nixos.0-641-g6efd6de)
Operating system
Linux 6.0.5-200.fc36.x86_64
Command-line
/home/melko/bin/git-branchless bug-report
Environment variables
SHELL=/bin/bash
EDITOR=/usr/bin/vim
Git version
> git version
git version 2.38.1
Hooks
Show 6 hooks
Hook post-commit
#!/bin/sh
## START BRANCHLESS CONFIG
git branchless hook-post-commit "$@"
## END BRANCHLESS CONFIG
Hook post-merge
#!/bin/sh
## START BRANCHLESS CONFIG
git branchless hook-post-merge "$@"
## END BRANCHLESS CONFIG
Hook post-rewrite
#!/bin/sh
## START BRANCHLESS CONFIG
git branchless hook-post-rewrite "$@"
## END BRANCHLESS CONFIG
Hook post-checkout
#!/bin/sh
## START BRANCHLESS CONFIG
git branchless hook-post-checkout "$@"
## END BRANCHLESS CONFIG
Hook pre-auto-gc
#!/bin/sh
## START BRANCHLESS CONFIG
git branchless hook-pre-auto-gc "$@"
## END BRANCHLESS CONFIG
Hook reference-transaction
#!/bin/sh
## START BRANCHLESS CONFIG
# Avoid canceling the reference transaction in the case that `branchless` fails
# for whatever reason.
git branchless hook-reference-transaction "$@" || (
echo 'branchless: Failed to process reference transaction!'
echo 'branchless: Some events (e.g. branch updates) may have been lost.'
echo 'branchless: This is a bug. Please report it.'
)
## END BRANCHLESS CONFIG
Events
Error: Bad file descriptor (os error 9)
Version of git-branchless
No response
Version of git
No response
Hi @melko, thanks for reporting! Unfortunately, I am running on macOS, and it seems like it would be quite a hassle to get an NFS filesystem running to reproduce this.
The line git-branchless-lib/src/core/dag.rs:277 seems to refer to the add_heads_and_flush call:
https://github.com/arxanas/git-branchless/blob/a3e4fcbe71bf57682fffa6d5848449184fb4d2fa/git-branchless-lib/src/core/dag.rs#L277-L281
This functionality is provided by the DAG library from Sapling. The code in question tries to ensure concurrency-safe operations on disk, so it makes sense that it might not function on NFS. Unfortunately, I don't think it's likely that we'll be able to fix this easily, since presumably it's not easy to ensure concurrency-safe operations on NFS. (Also, the DAG library as used in git-branchless is somewhat out-of-date, but I don't see anything which suggests that the upstream version has been updated to be NFS-compatible.)
The DAG data is stored under .git/branchless/dag. It might be possible to add a feature to git-branchless to use a different directory on disk for the .git/branchless directory, although at that point, perhaps you would be able to simply relocate the entire Git repository to a non-NFS store? I'm curious what your use-case for storing the repository on NFS is. Is it a virtual filesystem exposed by NFS?
yeah I can can confirm the same issue with sapling as well:
abort: internal storage is corrupted
"/home/melko/testrepo/.sl/store/metalog/roots/rlock": cannot lock (exclusive: false, non_blocking: false)
in log::OpenOptions::open(Filesystem("/home/melko/testrepo/.sl/store/metalog/roots"))
Caused by 1 errors:
- Bad file descriptor (os error 9)
I do not think adding a feature to have .git/branchless somewhere else is worth, as you say, one can just relocate the whole repo elsewhere. Having repo files sparsely located among different filesystems sounds like looking for troubles.
My use case is that at work, we have a central storage server which hosts the homedirs and user authentication, so my home is accessible from any machine in the lan.