Skip to content

Commit

Permalink
Move libcontainer to x/sys/unix
Browse files Browse the repository at this point in the history
Since syscall is outdated and broken for some architectures,
use x/sys/unix instead.

There are still some dependencies on the syscall package that will
remain in syscall for the forseeable future:

Errno
Signal
SysProcAttr

Additionally, os still uses syscall, so it needs to be kept for anything
returning *os.ProcessState, such as process.Wait.

Signed-off-by: Christy Perez <[email protected]>
  • Loading branch information
clnperez committed May 11, 2017
1 parent 2daa115 commit 852f375
Show file tree
Hide file tree
Showing 34 changed files with 301 additions and 308 deletions.
6 changes: 4 additions & 2 deletions libcontainer/cgroups/fs/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import (
"path/filepath"
"strconv"
"strings"
"syscall"
"syscall" // only for Errno

"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"

"golang.org/x/sys/unix"
)

const (
Expand Down Expand Up @@ -93,7 +95,7 @@ func setKernelMemory(path string, kernelMemoryLimit uint64) error {
// once tasks have been attached to the cgroup
if pathErr, ok := err.(*os.PathError); ok {
if errNo, ok := pathErr.Err.(syscall.Errno); ok {
if errNo == syscall.EBUSY {
if errNo == unix.EBUSY {
return fmt.Errorf("failed to set %s, because either tasks have already joined this cgroup or it has children", cgroupKernelMemoryLimit)
}
}
Expand Down
14 changes: 7 additions & 7 deletions libcontainer/configs/namespaces_syscall.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@

package configs

import "syscall"
import "golang.org/x/sys/unix"

func (n *Namespace) Syscall() int {
return namespaceInfo[n.Type]
}

var namespaceInfo = map[NamespaceType]int{
NEWNET: syscall.CLONE_NEWNET,
NEWNS: syscall.CLONE_NEWNS,
NEWUSER: syscall.CLONE_NEWUSER,
NEWIPC: syscall.CLONE_NEWIPC,
NEWUTS: syscall.CLONE_NEWUTS,
NEWPID: syscall.CLONE_NEWPID,
NEWNET: unix.CLONE_NEWNET,
NEWNS: unix.CLONE_NEWNS,
NEWUSER: unix.CLONE_NEWUSER,
NEWIPC: unix.CLONE_NEWIPC,
NEWUTS: unix.CLONE_NEWUTS,
NEWPID: unix.CLONE_NEWPID,
}

// CloneFlags parses the container's Namespaces options to set the correct
Expand Down
24 changes: 13 additions & 11 deletions libcontainer/container_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"reflect"
"strings"
"sync"
"syscall"
"syscall" // only for SysProcAttr and Signal
"time"

"github.com/Sirupsen/logrus"
Expand All @@ -26,6 +26,8 @@ import (
"github.com/opencontainers/runc/libcontainer/utils"
"github.com/syndtr/gocapability/capability"
"github.com/vishvananda/netlink/nl"

"golang.org/x/sys/unix"
)

const stdioFdCount = 3
Expand Down Expand Up @@ -321,12 +323,12 @@ func (c *linuxContainer) createExecFifo() error {
if _, err := os.Stat(fifoName); err == nil {
return fmt.Errorf("exec fifo %s already exists", fifoName)
}
oldMask := syscall.Umask(0000)
if err := syscall.Mkfifo(fifoName, 0622); err != nil {
syscall.Umask(oldMask)
oldMask := unix.Umask(0000)
if err := unix.Mkfifo(fifoName, 0622); err != nil {
unix.Umask(oldMask)
return err
}
syscall.Umask(oldMask)
unix.Umask(oldMask)
if err := os.Chown(fifoName, rootuid, rootgid); err != nil {
return err
}
Expand Down Expand Up @@ -914,11 +916,11 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
if err != nil {
return err
}
err = syscall.Mount(c.config.Rootfs, root, "", syscall.MS_BIND|syscall.MS_REC, "")
err = unix.Mount(c.config.Rootfs, root, "", unix.MS_BIND|unix.MS_REC, "")
if err != nil {
return err
}
defer syscall.Unmount(root, syscall.MNT_DETACH)
defer unix.Unmount(root, unix.MNT_DETACH)
t := criurpc.CriuReqType_RESTORE
req := &criurpc.CriuReq{
Type: &t,
Expand Down Expand Up @@ -967,7 +969,7 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
c.addCriuRestoreMount(req, m)
}

if criuOpts.EmptyNs&syscall.CLONE_NEWNET == 0 {
if criuOpts.EmptyNs&unix.CLONE_NEWNET == 0 {
c.restoreNetwork(req, criuOpts)
}

Expand Down Expand Up @@ -1030,7 +1032,7 @@ func (c *linuxContainer) criuApplyCgroups(pid int, req *criurpc.CriuReq) error {
}

func (c *linuxContainer) criuSwrk(process *Process, req *criurpc.CriuReq, opts *CriuOpts, applyCgroups bool) error {
fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_SEQPACKET|syscall.SOCK_CLOEXEC, 0)
fds, err := unix.Socketpair(unix.AF_LOCAL, unix.SOCK_SEQPACKET|unix.SOCK_CLOEXEC, 0)
if err != nil {
return err
}
Expand Down Expand Up @@ -1360,8 +1362,8 @@ func (c *linuxContainer) runType() (Status, error) {
}
pid := c.initProcess.pid()
// return Running if the init process is alive
if err := syscall.Kill(pid, 0); err != nil {
if err == syscall.ESRCH {
if err := unix.Kill(pid, 0); err != nil {
if err == unix.ESRCH {
// It means the process does not exist anymore, could happen when the
// process exited just when we call the function, we should not return
// error in this case.
Expand Down
9 changes: 5 additions & 4 deletions libcontainer/devices/devices_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import (
"io/ioutil"
"os"
"path/filepath"
"syscall"

"github.com/opencontainers/runc/libcontainer/configs"

"golang.org/x/sys/unix"
)

var (
Expand Down Expand Up @@ -38,13 +39,13 @@ func DeviceFromPath(path, permissions string) (*configs.Device, error) {
case mode&os.ModeDevice == 0:
return nil, ErrNotADevice
case mode&os.ModeCharDevice != 0:
fileModePermissionBits |= syscall.S_IFCHR
fileModePermissionBits |= unix.S_IFCHR
devType = 'c'
default:
fileModePermissionBits |= syscall.S_IFBLK
fileModePermissionBits |= unix.S_IFBLK
devType = 'b'
}
stat_t, ok := fileInfo.Sys().(*syscall.Stat_t)
stat_t, ok := fileInfo.Sys().(*unix.Stat_t)
if !ok {
return nil, fmt.Errorf("cannot determine the device number for device %s", path)
}
Expand Down
7 changes: 4 additions & 3 deletions libcontainer/factory_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"regexp"
"runtime/debug"
"strconv"
"syscall"

"github.com/docker/docker/pkg/mount"
"github.com/opencontainers/runc/libcontainer/cgroups"
Expand All @@ -20,6 +19,8 @@ import (
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/configs/validate"
"github.com/opencontainers/runc/libcontainer/utils"

"golang.org/x/sys/unix"
)

const (
Expand Down Expand Up @@ -92,7 +93,7 @@ func TmpfsRoot(l *LinuxFactory) error {
return err
}
if !mounted {
if err := syscall.Mount("tmpfs", l.Root, "tmpfs", 0, ""); err != nil {
if err := unix.Mount("tmpfs", l.Root, "tmpfs", 0, ""); err != nil {
return err
}
}
Expand Down Expand Up @@ -303,7 +304,7 @@ func (l *LinuxFactory) StartInitialization() (err error) {
return err
}

// If Init succeeds, syscall.Exec will not return, hence none of the defers will be called.
// If Init succeeds, unix.Exec will not return, hence none of the defers will be called.
return i.Init()
}

Expand Down
5 changes: 3 additions & 2 deletions libcontainer/factory_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ import (
"os"
"path/filepath"
"reflect"
"syscall"
"testing"

"github.com/docker/docker/pkg/mount"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/utils"

"golang.org/x/sys/unix"
)

func newTestRoot() (string, error) {
Expand Down Expand Up @@ -99,7 +100,7 @@ func TestFactoryNewTmpfs(t *testing.T) {
if !found {
t.Fatalf("Factory Root is not listed in mounts list")
}
defer syscall.Unmount(root, syscall.MNT_DETACH)
defer unix.Unmount(root, unix.MNT_DETACH)
}

func TestFactoryLoadNotExists(t *testing.T) {
Expand Down
32 changes: 17 additions & 15 deletions libcontainer/init_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"net"
"os"
"strings"
"syscall"
"syscall" // only for Errno
"unsafe"

"github.com/Sirupsen/logrus"
Expand All @@ -19,6 +19,8 @@ import (
"github.com/opencontainers/runc/libcontainer/user"
"github.com/opencontainers/runc/libcontainer/utils"
"github.com/vishvananda/netlink"

sysunix "golang.org/x/sys/unix"
)

type initType string
Expand Down Expand Up @@ -84,7 +86,7 @@ func newContainerInit(t initType, pipe *os.File, consoleSocket *os.File, stateDi
return &linuxStandardInit{
pipe: pipe,
consoleSocket: consoleSocket,
parentPid: syscall.Getppid(),
parentPid: sysunix.Getppid(),
config: config,
stateDirFD: stateDirFD,
}, nil
Expand Down Expand Up @@ -146,7 +148,7 @@ func finalizeNamespace(config *initConfig) error {
return err
}
if config.Cwd != "" {
if err := syscall.Chdir(config.Cwd); err != nil {
if err := sysunix.Chdir(config.Cwd); err != nil {
return fmt.Errorf("chdir to cwd (%q) set in config.json failed: %v", config.Cwd, err)
}
}
Expand Down Expand Up @@ -287,7 +289,7 @@ func setupUser(config *initConfig) error {
// set the group).
if !config.Rootless {
suppGroups := append(execUser.Sgids, addGroups...)
if err := syscall.Setgroups(suppGroups); err != nil {
if err := sysunix.Setgroups(suppGroups); err != nil {
return err
}
}
Expand All @@ -313,17 +315,17 @@ func setupUser(config *initConfig) error {
// The ownership needs to match because it is created outside of the container and needs to be
// localized.
func fixStdioPermissions(config *initConfig, u *user.ExecUser) error {
var null syscall.Stat_t
if err := syscall.Stat("/dev/null", &null); err != nil {
var null sysunix.Stat_t
if err := sysunix.Stat("/dev/null", &null); err != nil {
return err
}
for _, fd := range []uintptr{
os.Stdin.Fd(),
os.Stderr.Fd(),
os.Stdout.Fd(),
} {
var s syscall.Stat_t
if err := syscall.Fstat(int(fd), &s); err != nil {
var s sysunix.Stat_t
if err := sysunix.Fstat(int(fd), &s); err != nil {
return err
}

Expand All @@ -346,7 +348,7 @@ func fixStdioPermissions(config *initConfig, u *user.ExecUser) error {
// that users expect to be able to actually use their console. Without
// this code, you couldn't effectively run as a non-root user inside a
// container and also have a console set up.
if err := syscall.Fchown(int(fd), u.Uid, int(s.Gid)); err != nil {
if err := sysunix.Fchown(int(fd), u.Uid, int(s.Gid)); err != nil {
return err
}
}
Expand Down Expand Up @@ -401,7 +403,7 @@ func setupRoute(config *configs.Config) error {

func setupRlimits(limits []configs.Rlimit, pid int) error {
for _, rlimit := range limits {
if err := system.Prlimit(pid, rlimit.Type, syscall.Rlimit{Max: rlimit.Hard, Cur: rlimit.Soft}); err != nil {
if err := system.Prlimit(pid, rlimit.Type, sysunix.Rlimit{Max: rlimit.Hard, Cur: rlimit.Soft}); err != nil {
return fmt.Errorf("error setting rlimit type %v: %v", rlimit.Type, err)
}
}
Expand All @@ -424,23 +426,23 @@ type siginfo struct {
// Its based off blockUntilWaitable in src/os/wait_waitid.go
func isWaitable(pid int) (bool, error) {
si := &siginfo{}
_, _, e := syscall.Syscall6(syscall.SYS_WAITID, _P_PID, uintptr(pid), uintptr(unsafe.Pointer(si)), syscall.WEXITED|syscall.WNOWAIT|syscall.WNOHANG, 0, 0)
_, _, e := sysunix.Syscall6(sysunix.SYS_WAITID, _P_PID, uintptr(pid), uintptr(unsafe.Pointer(si)), sysunix.WEXITED|sysunix.WNOWAIT|sysunix.WNOHANG, 0, 0)
if e != 0 {
return false, os.NewSyscallError("waitid", e)
}

return si.si_pid != 0, nil
}

// isNoChildren returns true if err represents a syscall.ECHILD false otherwise
// isNoChildren returns true if err represents a unix.ECHILD (formerly syscall.ECHILD) false otherwise
func isNoChildren(err error) bool {
switch err := err.(type) {
case syscall.Errno:
if err == syscall.ECHILD {
if err == sysunix.ECHILD {
return true
}
case *os.SyscallError:
if err.Err == syscall.ECHILD {
if err.Err == sysunix.ECHILD {
return true
}
}
Expand Down Expand Up @@ -478,7 +480,7 @@ func signalAllProcesses(m cgroups.Manager, s os.Signal) error {
}

for _, p := range procs {
if s != syscall.SIGKILL {
if s != sysunix.SIGKILL {
if ok, err := isWaitable(p.Pid); err != nil {
if !isNoChildren(err) {
logrus.Warn("signalAllProcesses: ", p.Pid, err)
Expand Down
5 changes: 3 additions & 2 deletions libcontainer/integration/checkpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import (
"os"
"path/filepath"
"strings"
"syscall"
"testing"

"github.com/opencontainers/runc/libcontainer"
"github.com/opencontainers/runc/libcontainer/configs"

"golang.org/x/sys/unix"
)

func showFile(t *testing.T, fname string) error {
Expand Down Expand Up @@ -59,7 +60,7 @@ func TestCheckpoint(t *testing.T) {
config.Mounts = append(config.Mounts, &configs.Mount{
Destination: "/sys/fs/cgroup",
Device: "cgroup",
Flags: defaultMountFlags | syscall.MS_RDONLY,
Flags: defaultMountFlags | unix.MS_RDONLY,
})

factory, err := libcontainer.New(root, libcontainer.Cgroupfs)
Expand Down
Loading

0 comments on commit 852f375

Please sign in to comment.