diff options
author | Sami Hiltunen <shiltunen@gitlab.com> | 2023-06-30 12:51:44 +0300 |
---|---|---|
committer | Sami Hiltunen <shiltunen@gitlab.com> | 2023-07-06 12:10:22 +0300 |
commit | f4062b3334864a3b6e8960d961f322c2015a9675 (patch) | |
tree | 01611cf726734f92123f9f7860c1321e0f4ecc4b | |
parent | 2a437ee28b9ff4a4b2a88ad1ce5065e8cedece53 (diff) |
Sync repository creations to disk
Repository creations are currently not flushed to disk. This can lead
to data loss if the host crashes before the writes have been persisted
to disks. Sync the writes the the disk prior to acknowleding a repository
creations to avoid this. As we don't know whether the directory hierarchy
in the storage existed, we sync them always regardless, and assume that
the root storage directory's entry in the parent directroy is synced
already.
Changelog: fixed
-rw-r--r-- | internal/gitaly/repoutil/create.go | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/internal/gitaly/repoutil/create.go b/internal/gitaly/repoutil/create.go index faade627f..650996a75 100644 --- a/internal/gitaly/repoutil/create.go +++ b/internal/gitaly/repoutil/create.go @@ -14,6 +14,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v16/internal/git/stats" "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage" "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/v16/internal/safe" "gitlab.com/gitlab-org/gitaly/v16/internal/structerr" "gitlab.com/gitlab-org/gitaly/v16/internal/tempdir" "gitlab.com/gitlab-org/gitaly/v16/internal/transaction/voting" @@ -219,12 +220,26 @@ func Create( return structerr.NewFailedPrecondition("preparatory vote: %w", err) } + syncer := safe.NewSyncer() + if err := syncer.SyncRecursive(newRepoDir.Path()); err != nil { + return fmt.Errorf("sync recursive: %w", err) + } + // Now that we have locked the repository and all Gitalies have agreed that they // want to do the same change we can move the repository into place. if err := os.Rename(newRepoDir.Path(), targetPath); err != nil { return fmt.Errorf("moving repository into place: %w", err) } + storagePath, err := locator.GetStorageByName(repository.GetStorageName()) + if err != nil { + return fmt.Errorf("get storage by name: %w", err) + } + + if err := syncer.SyncHierarchy(storagePath, repository.GetRelativePath()); err != nil { + return fmt.Errorf("sync hierarchy: %w", err) + } + if err := transaction.VoteOnContext(ctx, txManager, vote, voting.Committed); err != nil { return structerr.NewFailedPrecondition("committing vote: %w", err) } |