From 4a6a2b9db086eaeaabf173254d17a865a04d4093 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 9 Aug 2017 11:30:08 +0200 Subject: [PATCH 1/2] Switch from package syscall to golang.org/x/sys The syscall package is locked down and the comment in [1] advises to switch code to use the corresponding package from golang.org/x/sys. Do so and replace usage of package syscall with package golang.org/x/sys/{unix,windows} where applicable. [1] https://github.com/golang/go/blob/master/src/syscall/syscall.go#L21-L24 This will also allow to get updates and fixes for syscall wrappers without having to use a new go version. Errno, Signal and SysProcAttr aren't changed as they haven't been implemented in x/sys/. Stat_t from syscall is used if standard library packages (e.g. os) require it. syscall.ENOTSUP, syscall.SIGKILL and syscall.SIGTERM are used for cross-platform files. Signed-off-by: Tobias Klauser --- archive/tar_unix.go | 15 ++++++++------- archive/time_windows.go | 19 ++++++++++--------- cmd/containerd-shim/shim_linux.go | 4 ++-- cmd/containerd/main_windows.go | 7 ++++--- cmd/ctr/utils_unix.go | 8 ++++---- container_linux_test.go | 6 +++--- fs/copy_linux.go | 4 ++-- fs/copy_unix.go | 3 ++- fs/diff_unix.go | 5 +++-- 9 files changed, 38 insertions(+), 33 deletions(-) diff --git a/archive/tar_unix.go b/archive/tar_unix.go index 2fa59a41e..2d60f9207 100644 --- a/archive/tar_unix.go +++ b/archive/tar_unix.go @@ -11,6 +11,7 @@ import ( "github.com/dmcgowan/go-tar" "github.com/opencontainers/runc/libcontainer/system" "github.com/pkg/errors" + "golang.org/x/sys/unix" ) func tarName(p string) (string, error) { @@ -64,9 +65,9 @@ func mkdirAll(path string, perm os.FileMode) error { func prepareApply() func() { // Unset unmask before doing an apply operation, // restore unmask when complete - oldmask := syscall.Umask(0) + oldmask := unix.Umask(0) return func() { - syscall.Umask(oldmask) + unix.Umask(oldmask) } } @@ -95,14 +96,14 @@ func handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error { mode := uint32(hdr.Mode & 07777) switch hdr.Typeflag { case tar.TypeBlock: - mode |= syscall.S_IFBLK + mode |= unix.S_IFBLK case tar.TypeChar: - mode |= syscall.S_IFCHR + mode |= unix.S_IFCHR case tar.TypeFifo: - mode |= syscall.S_IFIFO + mode |= unix.S_IFIFO } - return syscall.Mknod(path, mode, int(mkdev(hdr.Devmajor, hdr.Devminor))) + return unix.Mknod(path, mode, int(mkdev(hdr.Devmajor, hdr.Devminor))) } func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error { @@ -122,7 +123,7 @@ func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error { func getxattr(path, attr string) ([]byte, error) { b, err := sysx.LGetxattr(path, attr) - if err == syscall.ENOTSUP || err == sysx.ENODATA { + if err == unix.ENOTSUP || err == unix.ENODATA { return nil, nil } return b, err diff --git a/archive/time_windows.go b/archive/time_windows.go index a17f6acb0..0b18c348d 100644 --- a/archive/time_windows.go +++ b/archive/time_windows.go @@ -1,25 +1,26 @@ package archive import ( - "syscall" "time" + + "golang.org/x/sys/windows" ) // chtimes will set the create time on a file using the given modtime. // This requires calling SetFileTime and explicitly including the create time. func chtimes(path string, atime, mtime time.Time) error { - ctimespec := syscall.NsecToTimespec(mtime.UnixNano()) - pathp, e := syscall.UTF16PtrFromString(path) + ctimespec := windows.NsecToTimespec(mtime.UnixNano()) + pathp, e := windows.UTF16PtrFromString(path) if e != nil { return e } - h, e := syscall.CreateFile(pathp, - syscall.FILE_WRITE_ATTRIBUTES, syscall.FILE_SHARE_WRITE, nil, - syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0) + h, e := windows.CreateFile(pathp, + windows.FILE_WRITE_ATTRIBUTES, windows.FILE_SHARE_WRITE, nil, + windows.OPEN_EXISTING, windows.FILE_FLAG_BACKUP_SEMANTICS, 0) if e != nil { return e } - defer syscall.Close(h) - c := syscall.NsecToFiletime(syscall.TimespecToNsec(ctimespec)) - return syscall.SetFileTime(h, &c, nil, nil) + defer windows.Close(h) + c := windows.NsecToFiletime(windows.TimespecToNsec(ctimespec)) + return windows.SetFileTime(h, &c, nil, nil) } diff --git a/cmd/containerd-shim/shim_linux.go b/cmd/containerd-shim/shim_linux.go index 43ab3db1b..390a37037 100644 --- a/cmd/containerd-shim/shim_linux.go +++ b/cmd/containerd-shim/shim_linux.go @@ -4,12 +4,12 @@ import ( "net" "os" "os/signal" - "syscall" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "golang.org/x/net/context" + "golang.org/x/sys/unix" "github.com/containerd/containerd/reaper" "github.com/containerd/containerd/sys" @@ -60,7 +60,7 @@ func (u *unixSocketCredentials) ServerHandshake(c net.Conn) (net.Conn, credentia if err != nil { return nil, nil, errors.Wrap(err, "unixSocketCredentials: failed to retrieve connection underlying fd") } - pcred, err := syscall.GetsockoptUcred(int(f.Fd()), syscall.SOL_SOCKET, syscall.SO_PEERCRED) + pcred, err := unix.GetsockoptUcred(int(f.Fd()), unix.SOL_SOCKET, unix.SO_PEERCRED) if err != nil { return nil, nil, errors.Wrap(err, "unixSocketCredentials: failed to retrieve socket peer credentials") } diff --git a/cmd/containerd/main_windows.go b/cmd/containerd/main_windows.go index f1206bc09..0ca795fa7 100644 --- a/cmd/containerd/main_windows.go +++ b/cmd/containerd/main_windows.go @@ -4,17 +4,18 @@ import ( "context" "os" "path/filepath" - "syscall" "github.com/containerd/containerd/log" "github.com/containerd/containerd/server" + + "golang.org/x/sys/windows" ) var ( defaultConfigPath = filepath.Join(os.Getenv("programfiles"), "containerd", "config.toml") handledSignals = []os.Signal{ - syscall.SIGTERM, - syscall.SIGINT, + windows.SIGTERM, + windows.SIGINT, } ) diff --git a/cmd/ctr/utils_unix.go b/cmd/ctr/utils_unix.go index 213fafdd5..0ef7b8dd3 100644 --- a/cmd/ctr/utils_unix.go +++ b/cmd/ctr/utils_unix.go @@ -9,12 +9,12 @@ import ( "net" "os" "sync" - "syscall" "time" "github.com/containerd/fifo" "github.com/pkg/errors" "github.com/urfave/cli" + "golang.org/x/sys/unix" "google.golang.org/grpc" ) @@ -22,7 +22,7 @@ func prepareStdio(stdin, stdout, stderr string, console bool) (wg *sync.WaitGrou wg = &sync.WaitGroup{} ctx := gocontext.Background() - f, err := fifo.OpenFifo(ctx, stdin, syscall.O_WRONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700) + f, err := fifo.OpenFifo(ctx, stdin, unix.O_WRONLY|unix.O_CREAT|unix.O_NONBLOCK, 0700) if err != nil { return nil, err } @@ -36,7 +36,7 @@ func prepareStdio(stdin, stdout, stderr string, console bool) (wg *sync.WaitGrou w.Close() }(f) - f, err = fifo.OpenFifo(ctx, stdout, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700) + f, err = fifo.OpenFifo(ctx, stdout, unix.O_RDONLY|unix.O_CREAT|unix.O_NONBLOCK, 0700) if err != nil { return nil, err } @@ -52,7 +52,7 @@ func prepareStdio(stdin, stdout, stderr string, console bool) (wg *sync.WaitGrou wg.Done() }(f) - f, err = fifo.OpenFifo(ctx, stderr, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700) + f, err = fifo.OpenFifo(ctx, stderr, unix.O_RDONLY|unix.O_CREAT|unix.O_NONBLOCK, 0700) if err != nil { return nil, err } diff --git a/container_linux_test.go b/container_linux_test.go index 98ee83f28..42323fa11 100644 --- a/container_linux_test.go +++ b/container_linux_test.go @@ -4,12 +4,12 @@ package containerd import ( "context" - "syscall" "testing" "github.com/containerd/cgroups" "github.com/containerd/containerd/linux/runcopts" specs "github.com/opencontainers/runtime-spec/specs-go" + "golang.org/x/sys/unix" ) func TestContainerUpdate(t *testing.T) { @@ -93,7 +93,7 @@ func TestContainerUpdate(t *testing.T) { if int64(stat.Memory.Usage.Limit) != limit { t.Errorf("expected memory limit to be set to %d but received %d", limit, stat.Memory.Usage.Limit) } - if err := task.Kill(ctx, syscall.SIGKILL); err != nil { + if err := task.Kill(ctx, unix.SIGKILL); err != nil { t.Error(err) return } @@ -168,7 +168,7 @@ func TestShimInCgroup(t *testing.T) { if len(processes) == 0 { t.Errorf("created cgroup should have atleast one process inside: %d", len(processes)) } - if err := task.Kill(ctx, syscall.SIGKILL); err != nil { + if err := task.Kill(ctx, unix.SIGKILL); err != nil { t.Error(err) return } diff --git a/fs/copy_linux.go b/fs/copy_linux.go index acc56f67d..d1a5e48cb 100644 --- a/fs/copy_linux.go +++ b/fs/copy_linux.go @@ -39,7 +39,7 @@ func copyFileContent(dst, src *os.File) error { n, err := sysx.CopyFileRange(src.Fd(), nil, dst.Fd(), nil, int(st.Size()), 0) if err != nil { - if err != syscall.ENOSYS && err != syscall.EXDEV { + if err != unix.ENOSYS && err != unix.EXDEV { return errors.Wrap(err, "copy file range failed") } @@ -79,5 +79,5 @@ func copyDevice(dst string, fi os.FileInfo) error { if !ok { return errors.New("unsupported stat type") } - return syscall.Mknod(dst, uint32(fi.Mode()), int(st.Rdev)) + return unix.Mknod(dst, uint32(fi.Mode()), int(st.Rdev)) } diff --git a/fs/copy_unix.go b/fs/copy_unix.go index 3ddbc5f93..6234f3da3 100644 --- a/fs/copy_unix.go +++ b/fs/copy_unix.go @@ -10,6 +10,7 @@ import ( "github.com/containerd/containerd/sys" "github.com/containerd/continuity/sysx" "github.com/pkg/errors" + "golang.org/x/sys/unix" ) func copyFileInfo(fi os.FileInfo, name string) error { @@ -63,5 +64,5 @@ func copyDevice(dst string, fi os.FileInfo) error { if !ok { return errors.New("unsupported stat type") } - return syscall.Mknod(dst, uint32(fi.Mode()), int(st.Rdev)) + return unix.Mknod(dst, uint32(fi.Mode()), int(st.Rdev)) } diff --git a/fs/diff_unix.go b/fs/diff_unix.go index 36a0f3fde..0b860e7f9 100644 --- a/fs/diff_unix.go +++ b/fs/diff_unix.go @@ -11,6 +11,7 @@ import ( "github.com/containerd/continuity/sysx" "github.com/pkg/errors" + "golang.org/x/sys/unix" ) // whiteouts are files with a special meaning for the layered filesystem. @@ -83,11 +84,11 @@ func compareSysStat(s1, s2 interface{}) (bool, error) { func compareCapabilities(p1, p2 string) (bool, error) { c1, err := sysx.LGetxattr(p1, "security.capability") - if err != nil && err != sysx.ENODATA { + if err != nil && err != unix.ENODATA { return false, errors.Wrapf(err, "failed to get xattr for %s", p1) } c2, err := sysx.LGetxattr(p2, "security.capability") - if err != nil && err != sysx.ENODATA { + if err != nil && err != unix.ENODATA { return false, errors.Wrapf(err, "failed to get xattr for %s", p2) } return bytes.Equal(c1, c2), nil From f2bed8ffb9db5a591880bb753301ba695e839b71 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 9 Aug 2017 11:41:44 +0200 Subject: [PATCH 2/2] Use CopyFileRange from golang.org/x/sys/unix Use the CopyFileRange and Lsetxattr from golang.org/x/sys/unix instead of their counterparts from github.com/containerd/continuity/sysx. These are 1:1 replacements (except for the fd parameter types in CopyFileRange). This will eventually allow to remove these functions there as well. Signed-off-by: Tobias Klauser --- fs/copy_linux.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/copy_linux.go b/fs/copy_linux.go index d1a5e48cb..efe4753e0 100644 --- a/fs/copy_linux.go +++ b/fs/copy_linux.go @@ -37,7 +37,7 @@ func copyFileContent(dst, src *os.File) error { return errors.Wrap(err, "unable to stat source") } - n, err := sysx.CopyFileRange(src.Fd(), nil, dst.Fd(), nil, int(st.Size()), 0) + n, err := unix.CopyFileRange(int(src.Fd()), nil, int(dst.Fd()), nil, int(st.Size()), 0) if err != nil { if err != unix.ENOSYS && err != unix.EXDEV { return errors.Wrap(err, "copy file range failed")