fs: Change CopyDir's utimes call to not follow symlinks

Following symlinks does not look like it was intended behavior here,
and fails if the symlink target has not been copied yet.

Signed-off-by: Nick Santos <nicholas.j.santos@gmail.com>
This commit is contained in:
Nick Santos 2017-05-08 12:57:45 -04:00
parent 73466a200d
commit e509da9c7d
2 changed files with 17 additions and 1 deletions

View File

@ -7,6 +7,7 @@ import (
"github.com/containerd/continuity/sysx" "github.com/containerd/continuity/sysx"
"github.com/pkg/errors" "github.com/pkg/errors"
"golang.org/x/sys/unix"
) )
func copyFileInfo(fi os.FileInfo, name string) error { func copyFileInfo(fi os.FileInfo, name string) error {
@ -21,7 +22,8 @@ func copyFileInfo(fi os.FileInfo, name string) error {
} }
} }
if err := syscall.UtimesNano(name, []syscall.Timespec{st.Atim, st.Mtim}); err != nil { timespec := []unix.Timespec{unix.Timespec(st.Atim), unix.Timespec(st.Mtim)}
if err := unix.UtimesNanoAt(unix.AT_FDCWD, name, timespec, unix.AT_SYMLINK_NOFOLLOW); err != nil {
return errors.Wrapf(err, "failed to utime %s", name) return errors.Wrapf(err, "failed to utime %s", name)
} }

View File

@ -32,6 +32,20 @@ func TestCopyDirectory(t *testing.T) {
} }
} }
// This test used to fail because link-no-nothing.txt would be copied first,
// then file operations in dst during the CopyDir would follow the symlink and
// fail.
func TestCopyDirectoryWithLocalSymlink(t *testing.T) {
apply := fstest.Apply(
fstest.CreateFile("nothing.txt", []byte{0x00, 0x00}, 0755),
fstest.Symlink("nothing.txt", "link-no-nothing.txt"),
)
if err := testCopy(apply); err != nil {
t.Fatalf("Copy test failed: %+v", err)
}
}
func testCopy(apply fstest.Applier) error { func testCopy(apply fstest.Applier) error {
t1, err := ioutil.TempDir("", "test-copy-src-") t1, err := ioutil.TempDir("", "test-copy-src-")
if err != nil { if err != nil {