From 71bb0aa641ea50da9167441e99ce216c5d9393d7 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Mon, 18 Dec 2017 08:52:05 +0100 Subject: [PATCH] Use Fchmodat from x/sys/unix Replace the custom Fchmodat implementation in sysx by using Fchmodat from golang.org/x/sys/unix now that it supports Fchmodat on Linux, Darwin, FreeBSD and Solaris (i.e. all platforms containerd/continuity supports). Because chmod on symlinks (AT_SYMLINK_NOFOLLOW) is not supported on Linux, some additional checking is needed. Previously, driver.Lchmod just followed the symlink and applied the mode to the linked path. See golang/go#20130 and golang/sys@c23410a for details. Updates #63 Signed-off-by: Tobias Klauser --- driver/driver_unix.go | 14 +++++++++++++- sysx/chmod_darwin.go | 18 ------------------ sysx/chmod_darwin_386.go | 25 ------------------------- sysx/chmod_darwin_amd64.go | 25 ------------------------- sysx/chmod_freebsd.go | 17 ----------------- sysx/chmod_freebsd_amd64.go | 25 ------------------------- sysx/chmod_linux.go | 12 ------------ sysx/chmod_solaris.go | 11 ----------- sysx/xattr_darwin.go | 1 - 9 files changed, 13 insertions(+), 135 deletions(-) delete mode 100644 sysx/chmod_darwin.go delete mode 100644 sysx/chmod_darwin_386.go delete mode 100644 sysx/chmod_darwin_amd64.go delete mode 100644 sysx/chmod_freebsd.go delete mode 100644 sysx/chmod_freebsd_amd64.go delete mode 100644 sysx/chmod_linux.go delete mode 100644 sysx/chmod_solaris.go diff --git a/driver/driver_unix.go b/driver/driver_unix.go index d9ab1656..ce34ec9d 100644 --- a/driver/driver_unix.go +++ b/driver/driver_unix.go @@ -7,10 +7,12 @@ import ( "fmt" "os" "path/filepath" + "runtime" "sort" "github.com/containerd/continuity/devices" "github.com/containerd/continuity/sysx" + "golang.org/x/sys/unix" ) func (d *driver) Mknod(path string, mode os.FileMode, major, minor int) error { @@ -35,7 +37,17 @@ func (d *driver) Lchmod(path string, mode os.FileMode) (err error) { } } - return sysx.Fchmodat(0, path, uint32(mode), sysx.AtSymlinkNofollow) + flags := unix.AT_SYMLINK_NOFOLLOW + if runtime.GOOS == "linux" { + // Chmod on symlinks is not supported on Linux, i.e. unix.Fchmodat + // returns EOPNOTSUPP if AT_SYMLINK_NOFOLLOW is specified even + // if the path isn't a symlink (also see + // https://github.com/golang/go/issues/20130). + if mode&os.ModeSymlink == 0 { + flags = 0 + } + } + return unix.Fchmodat(0, path, uint32(mode), flags) } // Getxattr returns all of the extended attributes for the file at path p. diff --git a/sysx/chmod_darwin.go b/sysx/chmod_darwin.go deleted file mode 100644 index e3ae2b7b..00000000 --- a/sysx/chmod_darwin.go +++ /dev/null @@ -1,18 +0,0 @@ -package sysx - -const ( - // AtSymlinkNoFollow defined from AT_SYMLINK_NOFOLLOW in - AtSymlinkNofollow = 0x20 -) - -const ( - - // SYS_FCHMODAT defined from golang.org/sys/unix - SYS_FCHMODAT = 467 -) - -// These functions will be generated by generate.sh -// $ GOOS=darwin GOARCH=386 ./generate.sh chmod -// $ GOOS=darwin GOARCH=amd64 ./generate.sh chmod - -//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) diff --git a/sysx/chmod_darwin_386.go b/sysx/chmod_darwin_386.go deleted file mode 100644 index 5a8cf5b5..00000000 --- a/sysx/chmod_darwin_386.go +++ /dev/null @@ -1,25 +0,0 @@ -// mksyscall.pl -l32 chmod_darwin.go -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT - -package sysx - -import ( - "syscall" - "unsafe" -) - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = syscall.BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := syscall.Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - use(unsafe.Pointer(_p0)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} diff --git a/sysx/chmod_darwin_amd64.go b/sysx/chmod_darwin_amd64.go deleted file mode 100644 index 3287d1d5..00000000 --- a/sysx/chmod_darwin_amd64.go +++ /dev/null @@ -1,25 +0,0 @@ -// mksyscall.pl chmod_darwin.go -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT - -package sysx - -import ( - "syscall" - "unsafe" -) - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = syscall.BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := syscall.Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - use(unsafe.Pointer(_p0)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} diff --git a/sysx/chmod_freebsd.go b/sysx/chmod_freebsd.go deleted file mode 100644 index b64a708b..00000000 --- a/sysx/chmod_freebsd.go +++ /dev/null @@ -1,17 +0,0 @@ -package sysx - -const ( - // AtSymlinkNoFollow defined from AT_SYMLINK_NOFOLLOW in - AtSymlinkNofollow = 0x200 -) - -const ( - - // SYS_FCHMODAT defined from golang.org/sys/unix - SYS_FCHMODAT = 490 -) - -// These functions will be generated by generate.sh -// $ GOOS=freebsd GOARCH=amd64 ./generate.sh chmod - -//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) diff --git a/sysx/chmod_freebsd_amd64.go b/sysx/chmod_freebsd_amd64.go deleted file mode 100644 index 5a271abb..00000000 --- a/sysx/chmod_freebsd_amd64.go +++ /dev/null @@ -1,25 +0,0 @@ -// mksyscall.pl chmod_freebsd.go -// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT - -package sysx - -import ( - "syscall" - "unsafe" -) - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { - var _p0 *byte - _p0, err = syscall.BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := syscall.Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) - use(unsafe.Pointer(_p0)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} diff --git a/sysx/chmod_linux.go b/sysx/chmod_linux.go deleted file mode 100644 index 89df6d38..00000000 --- a/sysx/chmod_linux.go +++ /dev/null @@ -1,12 +0,0 @@ -package sysx - -import "syscall" - -const ( - // AtSymlinkNoFollow defined from AT_SYMLINK_NOFOLLOW in /usr/include/linux/fcntl.h - AtSymlinkNofollow = 0x100 -) - -func Fchmodat(dirfd int, path string, mode uint32, flags int) error { - return syscall.Fchmodat(dirfd, path, mode, flags) -} diff --git a/sysx/chmod_solaris.go b/sysx/chmod_solaris.go deleted file mode 100644 index 3ba6e5ed..00000000 --- a/sysx/chmod_solaris.go +++ /dev/null @@ -1,11 +0,0 @@ -package sysx - -import "golang.org/x/sys/unix" - -const ( - AtSymlinkNofollow = unix.AT_SYMLINK_NOFOLLOW -) - -func Fchmodat(dirfd int, path string, mode uint32, flags int) error { - return unix.Fchmodat(dirfd, path, mode, flags) -} diff --git a/sysx/xattr_darwin.go b/sysx/xattr_darwin.go index 1164a7d1..58da4307 100644 --- a/sysx/xattr_darwin.go +++ b/sysx/xattr_darwin.go @@ -8,7 +8,6 @@ package sysx //sys setxattr(path string, attr string, data []byte, flags int) (err error) //sys removexattr(path string, attr string, options int) (err error) //sys listxattr(path string, dest []byte, options int) (sz int, err error) -//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) const ( xattrNoFollow = 0x01