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.
This commit is contained in:
zhouhaibing089 2023-10-30 16:59:40 -07:00 committed by GitHub
parent 546191e1e5
commit e65bce193d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 16 additions and 1 deletions

View File

@ -22,6 +22,7 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"runtime"
"sort" "sort"
"syscall" "syscall"
@ -31,6 +32,7 @@ import (
"github.com/GoogleContainerTools/kaniko/pkg/util" "github.com/GoogleContainerTools/kaniko/pkg/util"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
) )
// For testing // 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, // 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 // 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. // 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() s.l.Snapshot()