Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <psteinhardt@gitlab.com>2022-04-26 09:10:00 +0300
committerPatrick Steinhardt <psteinhardt@gitlab.com>2022-04-26 11:14:22 +0300
commitc89c8002131dabee677cce9c0551801a8e272570 (patch)
tree1f1ade01373f5918534e2182688da96bdd5c40fc
parente1f0e5a5ffc31387cb1137c41db538f22e0153de (diff)
git: Fix corruption of refs on hard-resetspks-git-core.fsync-compatibility
In the past, we had several incidents where repositories ended up with corrupted loose references immediately after a server was experiencing a hard shut-down. The root cause of this is that Git historically didn't flush the contents of loose references to disk before renaming them into place. This usage is explicitly documented to be invalid by various filesystems in the Linux kernel. Most importantly, documentation of the ext4 filesystem says that: Many broken applications don't use fsync() when replacing existing files via patterns such as fd = open("foo.new")/write(fd,..)/close(fd)/ rename("foo.new", "foo"), or worse yet, fd = open("foo", O_TRUNC)/write(fd,..)/close(fd). With Git v2.36.0 new infrastructure was introduced that provides finer grained control of exactly what data should be flushed to disk via the new `core.fsync` option. As part of that effort we have also upstreamed patches which give us the ability to also flush references to disk before they're renamed into place. So let's finally fix this source of corruption on newer Git versions by enabling fsync(3P) for references. Changelog: fixed
-rw-r--r--internal/git/command_factory.go8
1 files changed, 4 insertions, 4 deletions
diff --git a/internal/git/command_factory.go b/internal/git/command_factory.go
index a328e1415..a9544a46c 100644
--- a/internal/git/command_factory.go
+++ b/internal/git/command_factory.go
@@ -465,10 +465,10 @@ func (cf *ExecCommandFactory) combineArgs(ctx context.Context, gitConfig []confi
if gitVersion.HasGranularFsyncConfig() {
combinedGlobals = append(
combinedGlobals,
- // For now, we only fsync what Git versions previous to v2.36.0 have fsynced
- // when `core.fsyncObjectFiles=true`. Later, we'll want to expand this to
- // also sync references to disk to fix a long-standing issue.
- ConfigPair{Key: "core.fsync", Value: "objects,derived-metadata"},
+ // This is the same as below, but in addition we're also syncing packed-refs
+ // and loose refs to disk. This fixes a long-standing issue we've had where
+ // hard reboots of a server could end up corrupting loose references.
+ ConfigPair{Key: "core.fsync", Value: "objects,derived-metadata,reference"},
ConfigPair{Key: "core.fsyncMethod", Value: "fsync"},
)
} else {