From e65bce193de5615edbad0986def310372fa62719 Mon Sep 17 00:00:00 2001 From: zhouhaibing089 Date: Mon, 30 Oct 2023 16:59:40 -0700 Subject: [PATCH] snapshotter: use syncfs system call (#2816) `sync` system call triggers a full page cache sync which may not always work, especially in kubernetes environment where it is easy to be interfered by others. I have seen several cases where a broken nfs mount is blocking kaniko from doing its job. With `syncfs`, it only writes cache back to disk for the current filesystem that is used by kaniko which is supposed to be more reliable. --- pkg/snapshot/snapshot.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/pkg/snapshot/snapshot.go b/pkg/snapshot/snapshot.go index 018221ffcc..3da11f427f 100644 --- a/pkg/snapshot/snapshot.go +++ b/pkg/snapshot/snapshot.go @@ -22,6 +22,7 @@ import ( "io/ioutil" "os" "path/filepath" + "runtime" "sort" "syscall" @@ -31,6 +32,7 @@ import ( "github.com/GoogleContainerTools/kaniko/pkg/util" "github.com/sirupsen/logrus" + "golang.org/x/sys/unix" ) // For testing @@ -155,7 +157,20 @@ func (s *Snapshotter) scanFullFilesystem() ([]string, []string, error) { // for example the hashing function that determines if files are equal uses the mtime of the files, // which can lag if sync is not called. Unfortunately there can still be lag if too much data needs // to be flushed or the disk does its own caching/buffering. - syscall.Sync() + if runtime.GOOS == "linux" { + dir, err := os.Open(s.directory) + if err != nil { + return nil, nil, err + } + defer dir.Close() + _, _, errno := syscall.Syscall(unix.SYS_SYNCFS, dir.Fd(), 0, 0) + if errno != 0 { + return nil, nil, errno + } + } else { + // fallback to full page cache sync + syscall.Sync() + } s.l.Snapshot()