diff --git a/archive/archive.go b/archive/archive.go index 72bd31a281..5d6c020438 100644 --- a/archive/archive.go +++ b/archive/archive.go @@ -6,6 +6,7 @@ import ( "compress/gzip" "errors" "fmt" + "github.com/dotcloud/docker/pkg/system" "github.com/dotcloud/docker/utils" "github.com/dotcloud/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar" "io" @@ -168,7 +169,7 @@ func addTarFile(path, name string, tw *tar.Writer) error { } - capability, _ := Lgetxattr(path, "security.capability") + capability, _ := system.Lgetxattr(path, "security.capability") if capability != nil { hdr.Xattrs = make(map[string]string) hdr.Xattrs["security.capability"] = string(capability) @@ -259,7 +260,7 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader) e } for key, value := range hdr.Xattrs { - if err := Lsetxattr(path, key, []byte(value), 0); err != nil { + if err := system.Lsetxattr(path, key, []byte(value), 0); err != nil { return err } } @@ -275,11 +276,11 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader) e ts := []syscall.Timespec{timeToTimespec(hdr.AccessTime), timeToTimespec(hdr.ModTime)} // syscall.UtimesNano doesn't support a NOFOLLOW flag atm, and if hdr.Typeflag != tar.TypeSymlink { - if err := UtimesNano(path, ts); err != nil { + if err := system.UtimesNano(path, ts); err != nil { return err } } else { - if err := LUtimesNano(path, ts); err != nil { + if err := system.LUtimesNano(path, ts); err != nil { return err } } diff --git a/archive/changes.go b/archive/changes.go index a397a1cf8b..723e4a7425 100644 --- a/archive/changes.go +++ b/archive/changes.go @@ -3,6 +3,7 @@ package archive import ( "bytes" "fmt" + "github.com/dotcloud/docker/pkg/system" "github.com/dotcloud/docker/utils" "github.com/dotcloud/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar" "io" @@ -202,7 +203,7 @@ func (info *FileInfo) addChanges(oldInfo *FileInfo, changes *[]Change) { oldStat.Rdev != newStat.Rdev || // Don't look at size for dirs, its not a good measure of change (oldStat.Size != newStat.Size && oldStat.Mode&syscall.S_IFDIR != syscall.S_IFDIR) || - !sameFsTimeSpec(getLastModification(oldStat), getLastModification(newStat)) || + !sameFsTimeSpec(system.GetLastModification(oldStat), system.GetLastModification(newStat)) || bytes.Compare(oldChild.capability, newChild.capability) != 0 { change := Change{ Path: newChild.path(), @@ -278,7 +279,7 @@ func collectFileInfo(sourceDir string) (*FileInfo, error) { return err } - info.capability, _ = Lgetxattr(path, "security.capability") + info.capability, _ = system.Lgetxattr(path, "security.capability") parent.children[info.name] = info diff --git a/archive/stat_unsupported.go b/archive/stat_unsupported.go deleted file mode 100644 index 99f1fbc7da..0000000000 --- a/archive/stat_unsupported.go +++ /dev/null @@ -1,29 +0,0 @@ -// +build !linux - -package archive - -import "syscall" - -func getLastAccess(stat *syscall.Stat_t) syscall.Timespec { - return stat.Atimespec -} - -func getLastModification(stat *syscall.Stat_t) syscall.Timespec { - return stat.Mtimespec -} - -func LUtimesNano(path string, ts []syscall.Timespec) error { - return ErrNotImplemented -} - -func UtimesNano(path string, ts []syscall.Timespec) error { - return ErrNotImplemented -} - -func Lgetxattr(path string, attr string) ([]byte, error) { - return nil, ErrNotImplemented -} - -func Lsetxattr(path string, attr string, data []byte, flags int) error { - return ErrNotImplemented -} diff --git a/pkg/system/stat_linux.go b/pkg/system/stat_linux.go new file mode 100644 index 0000000000..e702200360 --- /dev/null +++ b/pkg/system/stat_linux.go @@ -0,0 +1,13 @@ +package system + +import ( + "syscall" +) + +func GetLastAccess(stat *syscall.Stat_t) syscall.Timespec { + return stat.Atim +} + +func GetLastModification(stat *syscall.Stat_t) syscall.Timespec { + return stat.Mtim +} diff --git a/pkg/system/stat_unsupported.go b/pkg/system/stat_unsupported.go new file mode 100644 index 0000000000..4686a4c346 --- /dev/null +++ b/pkg/system/stat_unsupported.go @@ -0,0 +1,13 @@ +// +build !linux + +package system + +import "syscall" + +func GetLastAccess(stat *syscall.Stat_t) syscall.Timespec { + return stat.Atimespec +} + +func GetLastModification(stat *syscall.Stat_t) syscall.Timespec { + return stat.Mtimespec +} diff --git a/pkg/system/utimes_linux.go b/pkg/system/utimes_linux.go new file mode 100644 index 0000000000..c00f4026a5 --- /dev/null +++ b/pkg/system/utimes_linux.go @@ -0,0 +1,31 @@ +package system + +import ( + "syscall" + "unsafe" +) + +func LUtimesNano(path string, ts []syscall.Timespec) error { + // These are not currently available in syscall + AT_FDCWD := -100 + AT_SYMLINK_NOFOLLOW := 0x100 + + var _path *byte + _path, err := syscall.BytePtrFromString(path) + if err != nil { + return err + } + + if _, _, err := syscall.Syscall6(syscall.SYS_UTIMENSAT, uintptr(AT_FDCWD), uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), uintptr(AT_SYMLINK_NOFOLLOW), 0, 0); err != 0 && err != syscall.ENOSYS { + return err + } + + return nil +} + +func UtimesNano(path string, ts []syscall.Timespec) error { + if err := syscall.UtimesNano(path, ts); err != nil { + return err + } + return nil +} diff --git a/pkg/system/utimes_unsupported.go b/pkg/system/utimes_unsupported.go new file mode 100644 index 0000000000..d247ba283e --- /dev/null +++ b/pkg/system/utimes_unsupported.go @@ -0,0 +1,13 @@ +// +build !linux + +package system + +import "syscall" + +func LUtimesNano(path string, ts []syscall.Timespec) error { + return ErrNotSupportedPlatform +} + +func UtimesNano(path string, ts []syscall.Timespec) error { + return ErrNotSupportedPlatform +} diff --git a/archive/stat_linux.go b/pkg/system/xattrs_linux.go similarity index 65% rename from archive/stat_linux.go rename to pkg/system/xattrs_linux.go index 2910ce5bab..00edb201b5 100644 --- a/archive/stat_linux.go +++ b/pkg/system/xattrs_linux.go @@ -1,43 +1,10 @@ -package archive +package system import ( "syscall" "unsafe" ) -func getLastAccess(stat *syscall.Stat_t) syscall.Timespec { - return stat.Atim -} - -func getLastModification(stat *syscall.Stat_t) syscall.Timespec { - return stat.Mtim -} - -func LUtimesNano(path string, ts []syscall.Timespec) error { - // These are not currently available in syscall - AT_FDCWD := -100 - AT_SYMLINK_NOFOLLOW := 0x100 - - var _path *byte - _path, err := syscall.BytePtrFromString(path) - if err != nil { - return err - } - - if _, _, err := syscall.Syscall6(syscall.SYS_UTIMENSAT, uintptr(AT_FDCWD), uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), uintptr(AT_SYMLINK_NOFOLLOW), 0, 0); err != 0 && err != syscall.ENOSYS { - return err - } - - return nil -} - -func UtimesNano(path string, ts []syscall.Timespec) error { - if err := syscall.UtimesNano(path, ts); err != nil { - return err - } - return nil -} - // Returns a nil slice and nil error if the xattr is not set func Lgetxattr(path string, attr string) ([]byte, error) { pathBytes, err := syscall.BytePtrFromString(path) diff --git a/pkg/system/xattrs_unsupported.go b/pkg/system/xattrs_unsupported.go new file mode 100644 index 0000000000..0060c167dc --- /dev/null +++ b/pkg/system/xattrs_unsupported.go @@ -0,0 +1,11 @@ +// +build !linux + +package system + +func Lgetxattr(path string, attr string) ([]byte, error) { + return nil, ErrNotSupportedPlatform +} + +func Lsetxattr(path string, attr string, data []byte, flags int) error { + return ErrNotSupportedPlatform +}