Move libcontainer to x/sys/unix

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 <christy@linux.vnet.ibm.com>
This commit is contained in:
Christy Perez 2017-05-09 17:38:27 -04:00
parent 639454475c
commit 3d7cb4293c
33 changed files with 292 additions and 300 deletions

View File

@ -10,10 +10,12 @@ import (
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings" "strings"
"syscall" "syscall" // only for Errno
"github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
"golang.org/x/sys/unix"
) )
const ( const (
@ -93,7 +95,7 @@ func setKernelMemory(path string, kernelMemoryLimit uint64) error {
// once tasks have been attached to the cgroup // once tasks have been attached to the cgroup
if pathErr, ok := err.(*os.PathError); ok { if pathErr, ok := err.(*os.PathError); ok {
if errNo, ok := pathErr.Err.(syscall.Errno); 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) return fmt.Errorf("failed to set %s, because either tasks have already joined this cgroup or it has children", cgroupKernelMemoryLimit)
} }
} }

View File

@ -2,19 +2,19 @@
package configs package configs
import "syscall" import "golang.org/x/sys/unix"
func (n *Namespace) Syscall() int { func (n *Namespace) Syscall() int {
return namespaceInfo[n.Type] return namespaceInfo[n.Type]
} }
var namespaceInfo = map[NamespaceType]int{ var namespaceInfo = map[NamespaceType]int{
NEWNET: syscall.CLONE_NEWNET, NEWNET: unix.CLONE_NEWNET,
NEWNS: syscall.CLONE_NEWNS, NEWNS: unix.CLONE_NEWNS,
NEWUSER: syscall.CLONE_NEWUSER, NEWUSER: unix.CLONE_NEWUSER,
NEWIPC: syscall.CLONE_NEWIPC, NEWIPC: unix.CLONE_NEWIPC,
NEWUTS: syscall.CLONE_NEWUTS, NEWUTS: unix.CLONE_NEWUTS,
NEWPID: syscall.CLONE_NEWPID, NEWPID: unix.CLONE_NEWPID,
} }
// CloneFlags parses the container's Namespaces options to set the correct // CloneFlags parses the container's Namespaces options to set the correct

View File

@ -15,7 +15,7 @@ import (
"reflect" "reflect"
"strings" "strings"
"sync" "sync"
"syscall" "syscall" // only for SysProcAttr and Signal
"time" "time"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
@ -324,12 +324,12 @@ func (c *linuxContainer) createExecFifo() error {
if _, err := os.Stat(fifoName); err == nil { if _, err := os.Stat(fifoName); err == nil {
return fmt.Errorf("exec fifo %s already exists", fifoName) return fmt.Errorf("exec fifo %s already exists", fifoName)
} }
oldMask := syscall.Umask(0000) oldMask := unix.Umask(0000)
if err := syscall.Mkfifo(fifoName, 0622); err != nil { if err := unix.Mkfifo(fifoName, 0622); err != nil {
syscall.Umask(oldMask) unix.Umask(oldMask)
return err return err
} }
syscall.Umask(oldMask) unix.Umask(oldMask)
if err := os.Chown(fifoName, rootuid, rootgid); err != nil { if err := os.Chown(fifoName, rootuid, rootgid); err != nil {
return err return err
} }
@ -923,11 +923,11 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
if err != nil { if err != nil {
return err 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 { if err != nil {
return err return err
} }
defer syscall.Unmount(root, syscall.MNT_DETACH) defer unix.Unmount(root, unix.MNT_DETACH)
t := criurpc.CriuReqType_RESTORE t := criurpc.CriuReqType_RESTORE
req := &criurpc.CriuReq{ req := &criurpc.CriuReq{
Type: &t, Type: &t,
@ -977,7 +977,7 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
c.addCriuRestoreMount(req, m) c.addCriuRestoreMount(req, m)
} }
if criuOpts.EmptyNs&syscall.CLONE_NEWNET == 0 { if criuOpts.EmptyNs&unix.CLONE_NEWNET == 0 {
c.restoreNetwork(req, criuOpts) c.restoreNetwork(req, criuOpts)
} }
@ -1040,7 +1040,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 { func (c *linuxContainer) criuSwrk(process *Process, req *criurpc.CriuReq, opts *CriuOpts, applyCgroups bool) error {
fds, err := unix.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 { if err != nil {
return err return err
} }
@ -1386,8 +1386,8 @@ func (c *linuxContainer) runType() (Status, error) {
} }
pid := c.initProcess.pid() pid := c.initProcess.pid()
// return Running if the init process is alive // return Running if the init process is alive
if err := syscall.Kill(pid, 0); err != nil { if err := unix.Kill(pid, 0); err != nil {
if err == syscall.ESRCH { if err == unix.ESRCH {
// It means the process does not exist anymore, could happen when the // It means the process does not exist anymore, could happen when the
// process exited just when we call the function, we should not return // process exited just when we call the function, we should not return
// error in this case. // error in this case.

View File

@ -6,9 +6,11 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"syscall" "syscall" //only for Stat_t
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
"golang.org/x/sys/unix"
) )
var ( var (
@ -36,10 +38,10 @@ func DeviceFromPath(path, permissions string) (*configs.Device, error) {
case mode&os.ModeDevice == 0: case mode&os.ModeDevice == 0:
return nil, ErrNotADevice return nil, ErrNotADevice
case mode&os.ModeCharDevice != 0: case mode&os.ModeCharDevice != 0:
fileModePermissionBits |= syscall.S_IFCHR fileModePermissionBits |= unix.S_IFCHR
devType = 'c' devType = 'c'
default: default:
fileModePermissionBits |= syscall.S_IFBLK fileModePermissionBits |= unix.S_IFBLK
devType = 'b' devType = 'b'
} }
stat_t, ok := fileInfo.Sys().(*syscall.Stat_t) stat_t, ok := fileInfo.Sys().(*syscall.Stat_t)

View File

@ -10,7 +10,6 @@ import (
"regexp" "regexp"
"runtime/debug" "runtime/debug"
"strconv" "strconv"
"syscall"
"github.com/docker/docker/pkg/mount" "github.com/docker/docker/pkg/mount"
"github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups"
@ -20,6 +19,8 @@ import (
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/configs/validate" "github.com/opencontainers/runc/libcontainer/configs/validate"
"github.com/opencontainers/runc/libcontainer/utils" "github.com/opencontainers/runc/libcontainer/utils"
"golang.org/x/sys/unix"
) )
const ( const (
@ -92,7 +93,7 @@ func TmpfsRoot(l *LinuxFactory) error {
return err return err
} }
if !mounted { 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 return err
} }
} }

View File

@ -7,12 +7,13 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"reflect" "reflect"
"syscall"
"testing" "testing"
"github.com/docker/docker/pkg/mount" "github.com/docker/docker/pkg/mount"
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/utils" "github.com/opencontainers/runc/libcontainer/utils"
"golang.org/x/sys/unix"
) )
func newTestRoot() (string, error) { func newTestRoot() (string, error) {
@ -99,7 +100,7 @@ func TestFactoryNewTmpfs(t *testing.T) {
if !found { if !found {
t.Fatalf("Factory Root is not listed in mounts list") 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) { func TestFactoryLoadNotExists(t *testing.T) {

View File

@ -9,7 +9,7 @@ import (
"net" "net"
"os" "os"
"strings" "strings"
"syscall" "syscall" // only for Errno
"unsafe" "unsafe"
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
@ -19,6 +19,8 @@ import (
"github.com/opencontainers/runc/libcontainer/user" "github.com/opencontainers/runc/libcontainer/user"
"github.com/opencontainers/runc/libcontainer/utils" "github.com/opencontainers/runc/libcontainer/utils"
"github.com/vishvananda/netlink" "github.com/vishvananda/netlink"
"golang.org/x/sys/unix"
) )
type initType string type initType string
@ -84,7 +86,7 @@ func newContainerInit(t initType, pipe *os.File, consoleSocket *os.File, stateDi
return &linuxStandardInit{ return &linuxStandardInit{
pipe: pipe, pipe: pipe,
consoleSocket: consoleSocket, consoleSocket: consoleSocket,
parentPid: syscall.Getppid(), parentPid: unix.Getppid(),
config: config, config: config,
stateDirFD: stateDirFD, stateDirFD: stateDirFD,
}, nil }, nil
@ -146,7 +148,7 @@ func finalizeNamespace(config *initConfig) error {
return err return err
} }
if config.Cwd != "" { if config.Cwd != "" {
if err := syscall.Chdir(config.Cwd); err != nil { if err := unix.Chdir(config.Cwd); err != nil {
return fmt.Errorf("chdir to cwd (%q) set in config.json failed: %v", config.Cwd, err) return fmt.Errorf("chdir to cwd (%q) set in config.json failed: %v", config.Cwd, err)
} }
} }
@ -287,7 +289,7 @@ func setupUser(config *initConfig) error {
// set the group). // set the group).
if !config.Rootless { if !config.Rootless {
suppGroups := append(execUser.Sgids, addGroups...) suppGroups := append(execUser.Sgids, addGroups...)
if err := syscall.Setgroups(suppGroups); err != nil { if err := unix.Setgroups(suppGroups); err != nil {
return err return err
} }
} }
@ -313,8 +315,8 @@ func setupUser(config *initConfig) error {
// The ownership needs to match because it is created outside of the container and needs to be // The ownership needs to match because it is created outside of the container and needs to be
// localized. // localized.
func fixStdioPermissions(config *initConfig, u *user.ExecUser) error { func fixStdioPermissions(config *initConfig, u *user.ExecUser) error {
var null syscall.Stat_t var null unix.Stat_t
if err := syscall.Stat("/dev/null", &null); err != nil { if err := unix.Stat("/dev/null", &null); err != nil {
return err return err
} }
for _, fd := range []uintptr{ for _, fd := range []uintptr{
@ -322,8 +324,8 @@ func fixStdioPermissions(config *initConfig, u *user.ExecUser) error {
os.Stderr.Fd(), os.Stderr.Fd(),
os.Stdout.Fd(), os.Stdout.Fd(),
} { } {
var s syscall.Stat_t var s unix.Stat_t
if err := syscall.Fstat(int(fd), &s); err != nil { if err := unix.Fstat(int(fd), &s); err != nil {
return err return err
} }
@ -346,7 +348,7 @@ func fixStdioPermissions(config *initConfig, u *user.ExecUser) error {
// that users expect to be able to actually use their console. Without // 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 // this code, you couldn't effectively run as a non-root user inside a
// container and also have a console set up. // container and also have a console set up.
if err := syscall.Fchown(int(fd), u.Uid, int(s.Gid)); err != nil { if err := unix.Fchown(int(fd), u.Uid, int(s.Gid)); err != nil {
return err return err
} }
} }
@ -401,7 +403,7 @@ func setupRoute(config *configs.Config) error {
func setupRlimits(limits []configs.Rlimit, pid int) error { func setupRlimits(limits []configs.Rlimit, pid int) error {
for _, rlimit := range limits { 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, unix.Rlimit{Max: rlimit.Hard, Cur: rlimit.Soft}); err != nil {
return fmt.Errorf("error setting rlimit type %v: %v", rlimit.Type, err) return fmt.Errorf("error setting rlimit type %v: %v", rlimit.Type, err)
} }
} }
@ -424,7 +426,7 @@ type siginfo struct {
// Its based off blockUntilWaitable in src/os/wait_waitid.go // Its based off blockUntilWaitable in src/os/wait_waitid.go
func isWaitable(pid int) (bool, error) { func isWaitable(pid int) (bool, error) {
si := &siginfo{} 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 := unix.Syscall6(unix.SYS_WAITID, _P_PID, uintptr(pid), uintptr(unsafe.Pointer(si)), unix.WEXITED|unix.WNOWAIT|unix.WNOHANG, 0, 0)
if e != 0 { if e != 0 {
return false, os.NewSyscallError("waitid", e) return false, os.NewSyscallError("waitid", e)
} }
@ -432,15 +434,15 @@ func isWaitable(pid int) (bool, error) {
return si.si_pid != 0, nil 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 { func isNoChildren(err error) bool {
switch err := err.(type) { switch err := err.(type) {
case syscall.Errno: case syscall.Errno:
if err == syscall.ECHILD { if err == unix.ECHILD {
return true return true
} }
case *os.SyscallError: case *os.SyscallError:
if err.Err == syscall.ECHILD { if err.Err == unix.ECHILD {
return true return true
} }
} }
@ -478,7 +480,7 @@ func signalAllProcesses(m cgroups.Manager, s os.Signal) error {
} }
for _, p := range procs { for _, p := range procs {
if s != syscall.SIGKILL { if s != unix.SIGKILL {
if ok, err := isWaitable(p.Pid); err != nil { if ok, err := isWaitable(p.Pid); err != nil {
if !isNoChildren(err) { if !isNoChildren(err) {
logrus.Warn("signalAllProcesses: ", p.Pid, err) logrus.Warn("signalAllProcesses: ", p.Pid, err)

View File

@ -8,11 +8,12 @@ import (
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"strings" "strings"
"syscall"
"testing" "testing"
"github.com/opencontainers/runc/libcontainer" "github.com/opencontainers/runc/libcontainer"
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
"golang.org/x/sys/unix"
) )
func showFile(t *testing.T, fname string) error { func showFile(t *testing.T, fname string) error {
@ -75,7 +76,7 @@ func testCheckpoint(t *testing.T, userns bool) {
config.Mounts = append(config.Mounts, &configs.Mount{ config.Mounts = append(config.Mounts, &configs.Mount{
Destination: "/sys/fs/cgroup", Destination: "/sys/fs/cgroup",
Device: "cgroup", Device: "cgroup",
Flags: defaultMountFlags | syscall.MS_RDONLY, Flags: defaultMountFlags | unix.MS_RDONLY,
}) })
if userns { if userns {

View File

@ -11,12 +11,13 @@ import (
"reflect" "reflect"
"strconv" "strconv"
"strings" "strings"
"syscall"
"testing" "testing"
"github.com/opencontainers/runc/libcontainer" "github.com/opencontainers/runc/libcontainer"
"github.com/opencontainers/runc/libcontainer/cgroups/systemd" "github.com/opencontainers/runc/libcontainer/cgroups/systemd"
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
"golang.org/x/sys/unix"
) )
func TestExecPS(t *testing.T) { func TestExecPS(t *testing.T) {
@ -188,7 +189,7 @@ func testRlimit(t *testing.T, userns bool) {
// ensure limit is lower than what the config requests to test that in a user namespace // ensure limit is lower than what the config requests to test that in a user namespace
// the Setrlimit call happens early enough that we still have permissions to raise the limit. // the Setrlimit call happens early enough that we still have permissions to raise the limit.
ok(t, syscall.Setrlimit(syscall.RLIMIT_NOFILE, &syscall.Rlimit{ ok(t, unix.Setrlimit(unix.RLIMIT_NOFILE, &unix.Rlimit{
Max: 1024, Max: 1024,
Cur: 1024, Cur: 1024,
})) }))
@ -874,7 +875,7 @@ func TestMountCmds(t *testing.T) {
Source: tmpDir, Source: tmpDir,
Destination: "/tmp", Destination: "/tmp",
Device: "bind", Device: "bind",
Flags: syscall.MS_BIND | syscall.MS_REC, Flags: unix.MS_BIND | unix.MS_REC,
PremountCmds: []configs.Command{ PremountCmds: []configs.Command{
{Path: "touch", Args: []string{filepath.Join(tmpDir, "hello")}}, {Path: "touch", Args: []string{filepath.Join(tmpDir, "hello")}},
{Path: "touch", Args: []string{filepath.Join(tmpDir, "world")}}, {Path: "touch", Args: []string{filepath.Join(tmpDir, "world")}},
@ -969,7 +970,7 @@ func TestMountCgroupRO(t *testing.T) {
config.Mounts = append(config.Mounts, &configs.Mount{ config.Mounts = append(config.Mounts, &configs.Mount{
Destination: "/sys/fs/cgroup", Destination: "/sys/fs/cgroup",
Device: "cgroup", Device: "cgroup",
Flags: defaultMountFlags | syscall.MS_RDONLY, Flags: defaultMountFlags | unix.MS_RDONLY,
}) })
buffers, exitCode, err := runContainer(config, "", "mount") buffers, exitCode, err := runContainer(config, "", "mount")
@ -1244,7 +1245,7 @@ func TestSTDIOPermissions(t *testing.T) {
} }
func unmountOp(path string) error { func unmountOp(path string) error {
if err := syscall.Unmount(path, syscall.MNT_DETACH); err != nil { if err := unix.Unmount(path, unix.MNT_DETACH); err != nil {
return err return err
} }
return nil return nil
@ -1269,7 +1270,7 @@ func TestRootfsPropagationSlaveMount(t *testing.T) {
defer remove(rootfs) defer remove(rootfs)
config := newTemplateConfig(rootfs) config := newTemplateConfig(rootfs)
config.RootPropagation = syscall.MS_SLAVE | syscall.MS_REC config.RootPropagation = unix.MS_SLAVE | unix.MS_REC
// Bind mount a volume // Bind mount a volume
dir1host, err := ioutil.TempDir("", "mnt1host") dir1host, err := ioutil.TempDir("", "mnt1host")
@ -1278,9 +1279,9 @@ func TestRootfsPropagationSlaveMount(t *testing.T) {
// Make this dir a "shared" mount point. This will make sure a // Make this dir a "shared" mount point. This will make sure a
// slave relationship can be established in container. // slave relationship can be established in container.
err = syscall.Mount(dir1host, dir1host, "bind", syscall.MS_BIND|syscall.MS_REC, "") err = unix.Mount(dir1host, dir1host, "bind", unix.MS_BIND|unix.MS_REC, "")
ok(t, err) ok(t, err)
err = syscall.Mount("", dir1host, "", syscall.MS_SHARED|syscall.MS_REC, "") err = unix.Mount("", dir1host, "", unix.MS_SHARED|unix.MS_REC, "")
ok(t, err) ok(t, err)
defer unmountOp(dir1host) defer unmountOp(dir1host)
@ -1288,7 +1289,7 @@ func TestRootfsPropagationSlaveMount(t *testing.T) {
Source: dir1host, Source: dir1host,
Destination: dir1cont, Destination: dir1cont,
Device: "bind", Device: "bind",
Flags: syscall.MS_BIND | syscall.MS_REC}) Flags: unix.MS_BIND | unix.MS_REC})
// TODO: systemd specific processing // TODO: systemd specific processing
f := factory f := factory
@ -1318,7 +1319,7 @@ func TestRootfsPropagationSlaveMount(t *testing.T) {
ok(t, err) ok(t, err)
defer os.RemoveAll(dir2host) defer os.RemoveAll(dir2host)
err = syscall.Mount(dir2host, dir2host, "bind", syscall.MS_BIND, "") err = unix.Mount(dir2host, dir2host, "bind", unix.MS_BIND, "")
defer unmountOp(dir2host) defer unmountOp(dir2host)
ok(t, err) ok(t, err)
@ -1386,7 +1387,7 @@ func TestRootfsPropagationSharedMount(t *testing.T) {
ok(t, err) ok(t, err)
defer remove(rootfs) defer remove(rootfs)
config := newTemplateConfig(rootfs) config := newTemplateConfig(rootfs)
config.RootPropagation = syscall.MS_PRIVATE config.RootPropagation = unix.MS_PRIVATE
// Bind mount a volume // Bind mount a volume
dir1host, err := ioutil.TempDir("", "mnt1host") dir1host, err := ioutil.TempDir("", "mnt1host")
@ -1395,9 +1396,9 @@ func TestRootfsPropagationSharedMount(t *testing.T) {
// Make this dir a "shared" mount point. This will make sure a // Make this dir a "shared" mount point. This will make sure a
// shared relationship can be established in container. // shared relationship can be established in container.
err = syscall.Mount(dir1host, dir1host, "bind", syscall.MS_BIND|syscall.MS_REC, "") err = unix.Mount(dir1host, dir1host, "bind", unix.MS_BIND|unix.MS_REC, "")
ok(t, err) ok(t, err)
err = syscall.Mount("", dir1host, "", syscall.MS_SHARED|syscall.MS_REC, "") err = unix.Mount("", dir1host, "", unix.MS_SHARED|unix.MS_REC, "")
ok(t, err) ok(t, err)
defer unmountOp(dir1host) defer unmountOp(dir1host)
@ -1405,7 +1406,7 @@ func TestRootfsPropagationSharedMount(t *testing.T) {
Source: dir1host, Source: dir1host,
Destination: dir1cont, Destination: dir1cont,
Device: "bind", Device: "bind",
Flags: syscall.MS_BIND | syscall.MS_REC}) Flags: unix.MS_BIND | unix.MS_REC})
// TODO: systemd specific processing // TODO: systemd specific processing
f := factory f := factory

View File

@ -7,13 +7,14 @@ import (
"os" "os"
"strconv" "strconv"
"strings" "strings"
"syscall"
"testing" "testing"
"time" "time"
"github.com/opencontainers/runc/libcontainer" "github.com/opencontainers/runc/libcontainer"
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/utils" "github.com/opencontainers/runc/libcontainer/utils"
"golang.org/x/sys/unix"
) )
func TestExecIn(t *testing.T) { func TestExecIn(t *testing.T) {
@ -122,7 +123,7 @@ func testExecInRlimit(t *testing.T, userns bool) {
Stderr: buffers.Stderr, Stderr: buffers.Stderr,
Rlimits: []configs.Rlimit{ Rlimits: []configs.Rlimit{
// increase process rlimit higher than container rlimit to test per-process limit // increase process rlimit higher than container rlimit to test per-process limit
{Type: syscall.RLIMIT_NOFILE, Hard: 1026, Soft: 1026}, {Type: unix.RLIMIT_NOFILE, Hard: 1026, Soft: 1026},
}, },
} }
err = container.Run(ps) err = container.Run(ps)

View File

@ -1,9 +1,9 @@
package integration package integration
import ( import (
"syscall"
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
"golang.org/x/sys/unix"
) )
var standardEnvironment = []string{ var standardEnvironment = []string{
@ -13,7 +13,7 @@ var standardEnvironment = []string{
"TERM=xterm", "TERM=xterm",
} }
const defaultMountFlags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV const defaultMountFlags = unix.MS_NOEXEC | unix.MS_NOSUID | unix.MS_NODEV
// newTemplateConfig returns a base template for running a container // newTemplateConfig returns a base template for running a container
// //
@ -140,14 +140,14 @@ func newTemplateConfig(rootfs string) *configs.Config {
Source: "tmpfs", Source: "tmpfs",
Destination: "/dev", Destination: "/dev",
Device: "tmpfs", Device: "tmpfs",
Flags: syscall.MS_NOSUID | syscall.MS_STRICTATIME, Flags: unix.MS_NOSUID | unix.MS_STRICTATIME,
Data: "mode=755", Data: "mode=755",
}, },
{ {
Source: "devpts", Source: "devpts",
Destination: "/dev/pts", Destination: "/dev/pts",
Device: "devpts", Device: "devpts",
Flags: syscall.MS_NOSUID | syscall.MS_NOEXEC, Flags: unix.MS_NOSUID | unix.MS_NOEXEC,
Data: "newinstance,ptmxmode=0666,mode=0620,gid=5", Data: "newinstance,ptmxmode=0666,mode=0620,gid=5",
}, },
{ {
@ -170,7 +170,7 @@ func newTemplateConfig(rootfs string) *configs.Config {
Source: "sysfs", Source: "sysfs",
Destination: "/sys", Destination: "/sys",
Device: "sysfs", Device: "sysfs",
Flags: defaultMountFlags | syscall.MS_RDONLY, Flags: defaultMountFlags | unix.MS_RDONLY,
}, },
}, },
Networks: []*configs.Network{ Networks: []*configs.Network{
@ -182,7 +182,7 @@ func newTemplateConfig(rootfs string) *configs.Config {
}, },
Rlimits: []configs.Rlimit{ Rlimits: []configs.Rlimit{
{ {
Type: syscall.RLIMIT_NOFILE, Type: unix.RLIMIT_NOFILE,
Hard: uint64(1025), Hard: uint64(1025),
Soft: uint64(1025), Soft: uint64(1025),
}, },

View File

@ -6,8 +6,9 @@ import (
"fmt" "fmt"
"strconv" "strconv"
"strings" "strings"
"syscall"
"unsafe" "unsafe"
"golang.org/x/sys/unix"
) )
const KEYCTL_JOIN_SESSION_KEYRING = 1 const KEYCTL_JOIN_SESSION_KEYRING = 1
@ -21,13 +22,13 @@ func JoinSessionKeyring(name string) (KeySerial, error) {
var err error var err error
if len(name) > 0 { if len(name) > 0 {
_name, err = syscall.BytePtrFromString(name) _name, err = unix.BytePtrFromString(name)
if err != nil { if err != nil {
return KeySerial(0), err return KeySerial(0), err
} }
} }
sessKeyId, _, errn := syscall.Syscall(syscall.SYS_KEYCTL, KEYCTL_JOIN_SESSION_KEYRING, uintptr(unsafe.Pointer(_name)), 0) sessKeyId, _, errn := unix.Syscall(unix.SYS_KEYCTL, KEYCTL_JOIN_SESSION_KEYRING, uintptr(unsafe.Pointer(_name)), 0)
if errn != 0 { if errn != 0 {
return 0, fmt.Errorf("could not create session key: %v", errn) return 0, fmt.Errorf("could not create session key: %v", errn)
} }
@ -41,7 +42,7 @@ func ModKeyringPerm(ringId KeySerial, mask, setbits uint32) error {
dest := make([]byte, 1024) dest := make([]byte, 1024)
destBytes := unsafe.Pointer(&dest[0]) destBytes := unsafe.Pointer(&dest[0])
if _, _, err := syscall.Syscall6(syscall.SYS_KEYCTL, uintptr(KEYCTL_DESCRIBE), uintptr(ringId), uintptr(destBytes), uintptr(len(dest)), 0, 0); err != 0 { if _, _, err := unix.Syscall6(unix.SYS_KEYCTL, uintptr(KEYCTL_DESCRIBE), uintptr(ringId), uintptr(destBytes), uintptr(len(dest)), 0, 0); err != 0 {
return err return err
} }
@ -58,7 +59,7 @@ func ModKeyringPerm(ringId KeySerial, mask, setbits uint32) error {
perm := (uint32(perm64) & mask) | setbits perm := (uint32(perm64) & mask) | setbits
if _, _, err := syscall.Syscall(syscall.SYS_KEYCTL, uintptr(KEYCTL_SETPERM), uintptr(ringId), uintptr(perm)); err != 0 { if _, _, err := unix.Syscall(unix.SYS_KEYCTL, uintptr(KEYCTL_SETPERM), uintptr(ringId), uintptr(perm)); err != 0 {
return err return err
} }

View File

@ -7,7 +7,8 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"syscall"
"golang.org/x/sys/unix"
) )
const oomCgroupName = "memory" const oomCgroupName = "memory"
@ -25,7 +26,7 @@ func registerMemoryEvent(cgDir string, evName string, arg string) (<-chan struct
if err != nil { if err != nil {
return nil, err return nil, err
} }
fd, _, syserr := syscall.RawSyscall(syscall.SYS_EVENTFD2, 0, syscall.FD_CLOEXEC, 0) fd, _, syserr := unix.RawSyscall(unix.SYS_EVENTFD2, 0, unix.FD_CLOEXEC, 0)
if syserr != 0 { if syserr != 0 {
evFile.Close() evFile.Close()
return nil, syserr return nil, syserr

View File

@ -8,9 +8,10 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"syscall"
"testing" "testing"
"time" "time"
"golang.org/x/sys/unix"
) )
type notifyFunc func(paths map[string]string) (<-chan struct{}, error) type notifyFunc func(paths map[string]string) (<-chan struct{}, error)
@ -53,11 +54,11 @@ func testMemoryNotification(t *testing.T, evName string, notify notifyFunc, targ
} }
// re-open the eventfd // re-open the eventfd
efd, err := syscall.Dup(eventFd) efd, err := unix.Dup(eventFd)
if err != nil { if err != nil {
t.Fatal("unable to reopen eventfd:", err) t.Fatal("unable to reopen eventfd:", err)
} }
defer syscall.Close(efd) defer unix.Close(efd)
if err != nil { if err != nil {
t.Fatal("unable to dup event fd:", err) t.Fatal("unable to dup event fd:", err)
@ -66,7 +67,7 @@ func testMemoryNotification(t *testing.T, evName string, notify notifyFunc, targ
buf := make([]byte, 8) buf := make([]byte, 8)
binary.LittleEndian.PutUint64(buf, 1) binary.LittleEndian.PutUint64(buf, 1)
if _, err := syscall.Write(efd, buf); err != nil { if _, err := unix.Write(efd, buf); err != nil {
t.Fatal("unable to write to eventfd:", err) t.Fatal("unable to write to eventfd:", err)
} }
@ -81,7 +82,7 @@ func testMemoryNotification(t *testing.T, evName string, notify notifyFunc, targ
if err := os.RemoveAll(memoryPath); err != nil { if err := os.RemoveAll(memoryPath); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if _, err := syscall.Write(efd, buf); err != nil { if _, err := unix.Write(efd, buf); err != nil {
t.Fatal("unable to write to eventfd:", err) t.Fatal("unable to write to eventfd:", err)
} }
@ -94,12 +95,12 @@ func testMemoryNotification(t *testing.T, evName string, notify notifyFunc, targ
case <-time.After(100 * time.Millisecond): case <-time.After(100 * time.Millisecond):
} }
if _, _, err := syscall.Syscall(syscall.SYS_FCNTL, uintptr(evFd), syscall.F_GETFD, 0); err != syscall.EBADF { if _, _, err := unix.Syscall(unix.SYS_FCNTL, uintptr(evFd), unix.F_GETFD, 0); err != unix.EBADF {
t.Error("expected event control to be closed") t.Errorf("expected event control to be closed, but received error %s", err.Error())
} }
if _, _, err := syscall.Syscall(syscall.SYS_FCNTL, uintptr(eventFd), syscall.F_GETFD, 0); err != syscall.EBADF { if _, _, err := unix.Syscall(unix.SYS_FCNTL, uintptr(eventFd), unix.F_GETFD, 0); err != unix.EBADF {
t.Error("expected event fd to be closed") t.Errorf("expected event fd to be closed, but received error %s", err.Error())
} }
} }

View File

@ -9,11 +9,12 @@ import (
"os" "os"
"os/exec" "os/exec"
"strings" "strings"
"syscall"
"testing" "testing"
"github.com/opencontainers/runc/libcontainer" "github.com/opencontainers/runc/libcontainer"
"github.com/vishvananda/netlink/nl" "github.com/vishvananda/netlink/nl"
"golang.org/x/sys/unix"
) )
type pid struct { type pid struct {
@ -47,7 +48,7 @@ func TestNsenterValidPaths(t *testing.T) {
r := nl.NewNetlinkRequest(int(libcontainer.InitMsg), 0) r := nl.NewNetlinkRequest(int(libcontainer.InitMsg), 0)
r.AddData(&libcontainer.Int32msg{ r.AddData(&libcontainer.Int32msg{
Type: libcontainer.CloneFlagsAttr, Type: libcontainer.CloneFlagsAttr,
Value: uint32(syscall.CLONE_NEWNET), Value: uint32(unix.CLONE_NEWNET),
}) })
r.AddData(&libcontainer.Bytemsg{ r.AddData(&libcontainer.Bytemsg{
Type: libcontainer.NsPathsAttr, Type: libcontainer.NsPathsAttr,
@ -103,7 +104,7 @@ func TestNsenterInvalidPaths(t *testing.T) {
r := nl.NewNetlinkRequest(int(libcontainer.InitMsg), 0) r := nl.NewNetlinkRequest(int(libcontainer.InitMsg), 0)
r.AddData(&libcontainer.Int32msg{ r.AddData(&libcontainer.Int32msg{
Type: libcontainer.CloneFlagsAttr, Type: libcontainer.CloneFlagsAttr,
Value: uint32(syscall.CLONE_NEWNET), Value: uint32(unix.CLONE_NEWNET),
}) })
r.AddData(&libcontainer.Bytemsg{ r.AddData(&libcontainer.Bytemsg{
Type: libcontainer.NsPathsAttr, Type: libcontainer.NsPathsAttr,
@ -143,7 +144,7 @@ func TestNsenterIncorrectPathType(t *testing.T) {
r := nl.NewNetlinkRequest(int(libcontainer.InitMsg), 0) r := nl.NewNetlinkRequest(int(libcontainer.InitMsg), 0)
r.AddData(&libcontainer.Int32msg{ r.AddData(&libcontainer.Int32msg{
Type: libcontainer.CloneFlagsAttr, Type: libcontainer.CloneFlagsAttr,
Value: uint32(syscall.CLONE_NEWNET), Value: uint32(unix.CLONE_NEWNET),
}) })
r.AddData(&libcontainer.Bytemsg{ r.AddData(&libcontainer.Bytemsg{
Type: libcontainer.NsPathsAttr, Type: libcontainer.NsPathsAttr,
@ -166,7 +167,7 @@ func init() {
} }
func newPipe() (parent *os.File, child *os.File, err error) { func newPipe() (parent *os.File, child *os.File, err error) {
fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM|syscall.SOCK_CLOEXEC, 0) fds, err := unix.Socketpair(unix.AF_LOCAL, unix.SOCK_STREAM|unix.SOCK_CLOEXEC, 0)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }

View File

@ -11,12 +11,14 @@ import (
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"strconv" "strconv"
"syscall" "syscall" // only for Signal
"github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/system" "github.com/opencontainers/runc/libcontainer/system"
"github.com/opencontainers/runc/libcontainer/utils" "github.com/opencontainers/runc/libcontainer/utils"
"golang.org/x/sys/unix"
) )
type parentProcess interface { type parentProcess interface {
@ -62,7 +64,7 @@ func (p *setnsProcess) signal(sig os.Signal) error {
if !ok { if !ok {
return errors.New("os: unsupported signal type") return errors.New("os: unsupported signal type")
} }
return syscall.Kill(p.pid(), s) return unix.Kill(p.pid(), s)
} }
func (p *setnsProcess) start() (err error) { func (p *setnsProcess) start() (err error) {
@ -108,7 +110,7 @@ func (p *setnsProcess) start() (err error) {
} }
}) })
if err := syscall.Shutdown(int(p.parentPipe.Fd()), syscall.SHUT_WR); err != nil { if err := unix.Shutdown(int(p.parentPipe.Fd()), unix.SHUT_WR); err != nil {
return newSystemErrorWithCause(err, "calling shutdown on init pipe") return newSystemErrorWithCause(err, "calling shutdown on init pipe")
} }
// Must be done after Shutdown so the child will exit and we can wait for it. // Must be done after Shutdown so the child will exit and we can wait for it.
@ -341,7 +343,7 @@ func (p *initProcess) start() error {
if p.config.Config.Namespaces.Contains(configs.NEWNS) && !sentResume { if p.config.Config.Namespaces.Contains(configs.NEWNS) && !sentResume {
return newSystemError(fmt.Errorf("could not synchronise after executing prestart hooks with container process")) return newSystemError(fmt.Errorf("could not synchronise after executing prestart hooks with container process"))
} }
if err := syscall.Shutdown(int(p.parentPipe.Fd()), syscall.SHUT_WR); err != nil { if err := unix.Shutdown(int(p.parentPipe.Fd()), unix.SHUT_WR); err != nil {
return newSystemErrorWithCause(err, "shutting down init pipe") return newSystemErrorWithCause(err, "shutting down init pipe")
} }
@ -360,7 +362,7 @@ func (p *initProcess) wait() (*os.ProcessState, error) {
} }
// we should kill all processes in cgroup when init is died if we use host PID namespace // we should kill all processes in cgroup when init is died if we use host PID namespace
if p.sharePidns { if p.sharePidns {
signalAllProcesses(p.manager, syscall.SIGKILL) signalAllProcesses(p.manager, unix.SIGKILL)
} }
return p.cmd.ProcessState, nil return p.cmd.ProcessState, nil
} }
@ -409,7 +411,7 @@ func (p *initProcess) signal(sig os.Signal) error {
if !ok { if !ok {
return errors.New("os: unsupported signal type") return errors.New("os: unsupported signal type")
} }
return syscall.Kill(p.pid(), s) return unix.Kill(p.pid(), s)
} }
func (p *initProcess) setExternalDescriptors(newFds []string) { func (p *initProcess) setExternalDescriptors(newFds []string) {
@ -450,7 +452,7 @@ func (p *Process) InitializeIO(rootuid, rootgid int) (i *IO, err error) {
defer func() { defer func() {
if err != nil { if err != nil {
for _, fd := range fds { for _, fd := range fds {
syscall.Close(int(fd)) unix.Close(int(fd))
} }
} }
}() }()
@ -475,7 +477,7 @@ func (p *Process) InitializeIO(rootuid, rootgid int) (i *IO, err error) {
p.Stderr, i.Stderr = w, r p.Stderr, i.Stderr = w, r
// change ownership of the pipes incase we are in a user namespace // change ownership of the pipes incase we are in a user namespace
for _, fd := range fds { for _, fd := range fds {
if err := syscall.Fchown(int(fd), rootuid, rootgid); err != nil { if err := unix.Fchown(int(fd), rootuid, rootgid); err != nil {
return nil, err return nil, err
} }
} }

View File

@ -11,7 +11,6 @@ import (
"path" "path"
"path/filepath" "path/filepath"
"strings" "strings"
"syscall"
"time" "time"
"github.com/docker/docker/pkg/mount" "github.com/docker/docker/pkg/mount"
@ -22,9 +21,11 @@ import (
"github.com/opencontainers/runc/libcontainer/system" "github.com/opencontainers/runc/libcontainer/system"
libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils" libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils"
"github.com/opencontainers/selinux/go-selinux/label" "github.com/opencontainers/selinux/go-selinux/label"
"golang.org/x/sys/unix"
) )
const defaultMountFlags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV const defaultMountFlags = unix.MS_NOEXEC | unix.MS_NOSUID | unix.MS_NODEV
// needsSetupDev returns true if /dev needs to be set up. // needsSetupDev returns true if /dev needs to be set up.
func needsSetupDev(config *configs.Config) bool { func needsSetupDev(config *configs.Config) bool {
@ -91,7 +92,7 @@ func prepareRootfs(pipe io.ReadWriter, config *configs.Config) (err error) {
// container. It's just cleaner to do this here (at the expense of the // container. It's just cleaner to do this here (at the expense of the
// operation not being perfectly split). // operation not being perfectly split).
if err := syscall.Chdir(config.Rootfs); err != nil { if err := unix.Chdir(config.Rootfs); err != nil {
return newSystemErrorWithCausef(err, "changing dir to %q", config.Rootfs) return newSystemErrorWithCausef(err, "changing dir to %q", config.Rootfs)
} }
@ -119,7 +120,7 @@ func finalizeRootfs(config *configs.Config) (err error) {
// remount dev as ro if specified // remount dev as ro if specified
for _, m := range config.Mounts { for _, m := range config.Mounts {
if libcontainerUtils.CleanPath(m.Destination) == "/dev" { if libcontainerUtils.CleanPath(m.Destination) == "/dev" {
if m.Flags&syscall.MS_RDONLY == syscall.MS_RDONLY { if m.Flags&unix.MS_RDONLY == unix.MS_RDONLY {
if err := remountReadonly(m); err != nil { if err := remountReadonly(m); err != nil {
return newSystemErrorWithCausef(err, "remounting %q as readonly", m.Destination) return newSystemErrorWithCausef(err, "remounting %q as readonly", m.Destination)
} }
@ -135,7 +136,7 @@ func finalizeRootfs(config *configs.Config) (err error) {
} }
} }
syscall.Umask(0022) unix.Umask(0022)
return nil return nil
} }
@ -199,14 +200,14 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
if copyUp { if copyUp {
if err := fileutils.CopyDirectory(dest, tmpDir); err != nil { if err := fileutils.CopyDirectory(dest, tmpDir); err != nil {
errMsg := fmt.Errorf("tmpcopyup: failed to copy %s to %s: %v", dest, tmpDir, err) errMsg := fmt.Errorf("tmpcopyup: failed to copy %s to %s: %v", dest, tmpDir, err)
if err1 := syscall.Unmount(tmpDir, syscall.MNT_DETACH); err1 != nil { if err1 := unix.Unmount(tmpDir, unix.MNT_DETACH); err1 != nil {
return newSystemErrorWithCausef(err1, "tmpcopyup: %v: failed to unmount", errMsg) return newSystemErrorWithCausef(err1, "tmpcopyup: %v: failed to unmount", errMsg)
} }
return errMsg return errMsg
} }
if err := syscall.Mount(tmpDir, dest, "", syscall.MS_MOVE, ""); err != nil { if err := unix.Mount(tmpDir, dest, "", unix.MS_MOVE, ""); err != nil {
errMsg := fmt.Errorf("tmpcopyup: failed to move mount %s to %s: %v", tmpDir, dest, err) errMsg := fmt.Errorf("tmpcopyup: failed to move mount %s to %s: %v", tmpDir, dest, err)
if err1 := syscall.Unmount(tmpDir, syscall.MNT_DETACH); err1 != nil { if err1 := unix.Unmount(tmpDir, unix.MNT_DETACH); err1 != nil {
return newSystemErrorWithCausef(err1, "tmpcopyup: %v: failed to unmount", errMsg) return newSystemErrorWithCausef(err1, "tmpcopyup: %v: failed to unmount", errMsg)
} }
return errMsg return errMsg
@ -245,7 +246,7 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
} }
// bind mount won't change mount options, we need remount to make mount options effective. // bind mount won't change mount options, we need remount to make mount options effective.
// first check that we have non-default options required before attempting a remount // first check that we have non-default options required before attempting a remount
if m.Flags&^(syscall.MS_REC|syscall.MS_REMOUNT|syscall.MS_BIND) != 0 { if m.Flags&^(unix.MS_REC|unix.MS_REMOUNT|unix.MS_BIND) != 0 {
// only remount if unique mount options are set // only remount if unique mount options are set
if err := remount(m, rootfs); err != nil { if err := remount(m, rootfs); err != nil {
return err return err
@ -299,13 +300,13 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
} }
} }
} }
if m.Flags&syscall.MS_RDONLY != 0 { if m.Flags&unix.MS_RDONLY != 0 {
// remount cgroup root as readonly // remount cgroup root as readonly
mcgrouproot := &configs.Mount{ mcgrouproot := &configs.Mount{
Source: m.Destination, Source: m.Destination,
Device: "bind", Device: "bind",
Destination: m.Destination, Destination: m.Destination,
Flags: defaultMountFlags | syscall.MS_RDONLY | syscall.MS_BIND, Flags: defaultMountFlags | unix.MS_RDONLY | unix.MS_BIND,
} }
if err := remount(mcgrouproot, rootfs); err != nil { if err := remount(mcgrouproot, rootfs); err != nil {
return err return err
@ -359,7 +360,7 @@ func getCgroupMounts(m *configs.Mount) ([]*configs.Mount, error) {
Device: "bind", Device: "bind",
Source: filepath.Join(mm.Mountpoint, relDir), Source: filepath.Join(mm.Mountpoint, relDir),
Destination: filepath.Join(m.Destination, filepath.Base(mm.Mountpoint)), Destination: filepath.Join(m.Destination, filepath.Base(mm.Mountpoint)),
Flags: syscall.MS_BIND | syscall.MS_REC | m.Flags, Flags: unix.MS_BIND | unix.MS_REC | m.Flags,
PropagationFlags: m.PropagationFlags, PropagationFlags: m.PropagationFlags,
}) })
} }
@ -435,22 +436,22 @@ func setupDevSymlinks(rootfs string) error {
// needs to be called after we chroot/pivot into the container's rootfs so that any // needs to be called after we chroot/pivot into the container's rootfs so that any
// symlinks are resolved locally. // symlinks are resolved locally.
func reOpenDevNull() error { func reOpenDevNull() error {
var stat, devNullStat syscall.Stat_t var stat, devNullStat unix.Stat_t
file, err := os.OpenFile("/dev/null", os.O_RDWR, 0) file, err := os.OpenFile("/dev/null", os.O_RDWR, 0)
if err != nil { if err != nil {
return fmt.Errorf("Failed to open /dev/null - %s", err) return fmt.Errorf("Failed to open /dev/null - %s", err)
} }
defer file.Close() defer file.Close()
if err := syscall.Fstat(int(file.Fd()), &devNullStat); err != nil { if err := unix.Fstat(int(file.Fd()), &devNullStat); err != nil {
return err return err
} }
for fd := 0; fd < 3; fd++ { for fd := 0; fd < 3; fd++ {
if err := syscall.Fstat(fd, &stat); err != nil { if err := unix.Fstat(fd, &stat); err != nil {
return err return err
} }
if stat.Rdev == devNullStat.Rdev { if stat.Rdev == devNullStat.Rdev {
// Close and re-open the fd. // Close and re-open the fd.
if err := syscall.Dup3(int(file.Fd()), fd, 0); err != nil { if err := unix.Dup3(int(file.Fd()), fd, 0); err != nil {
return err return err
} }
} }
@ -461,16 +462,16 @@ func reOpenDevNull() error {
// Create the device nodes in the container. // Create the device nodes in the container.
func createDevices(config *configs.Config) error { func createDevices(config *configs.Config) error {
useBindMount := system.RunningInUserNS() || config.Namespaces.Contains(configs.NEWUSER) useBindMount := system.RunningInUserNS() || config.Namespaces.Contains(configs.NEWUSER)
oldMask := syscall.Umask(0000) oldMask := unix.Umask(0000)
for _, node := range config.Devices { for _, node := range config.Devices {
// containers running in a user namespace are not allowed to mknod // containers running in a user namespace are not allowed to mknod
// devices so we can just bind mount it from the host. // devices so we can just bind mount it from the host.
if err := createDeviceNode(config.Rootfs, node, useBindMount); err != nil { if err := createDeviceNode(config.Rootfs, node, useBindMount); err != nil {
syscall.Umask(oldMask) unix.Umask(oldMask)
return err return err
} }
} }
syscall.Umask(oldMask) unix.Umask(oldMask)
return nil return nil
} }
@ -482,7 +483,7 @@ func bindMountDeviceNode(dest string, node *configs.Device) error {
if f != nil { if f != nil {
f.Close() f.Close()
} }
return syscall.Mount(node.Path, dest, "bind", syscall.MS_BIND, "") return unix.Mount(node.Path, dest, "bind", unix.MS_BIND, "")
} }
// Creates the device node in the rootfs of the container. // Creates the device node in the rootfs of the container.
@ -510,18 +511,18 @@ func mknodDevice(dest string, node *configs.Device) error {
fileMode := node.FileMode fileMode := node.FileMode
switch node.Type { switch node.Type {
case 'c', 'u': case 'c', 'u':
fileMode |= syscall.S_IFCHR fileMode |= unix.S_IFCHR
case 'b': case 'b':
fileMode |= syscall.S_IFBLK fileMode |= unix.S_IFBLK
case 'p': case 'p':
fileMode |= syscall.S_IFIFO fileMode |= unix.S_IFIFO
default: default:
return fmt.Errorf("%c is not a valid device type for device %s", node.Type, node.Path) return fmt.Errorf("%c is not a valid device type for device %s", node.Type, node.Path)
} }
if err := syscall.Mknod(dest, uint32(fileMode), node.Mkdev()); err != nil { if err := unix.Mknod(dest, uint32(fileMode), node.Mkdev()); err != nil {
return err return err
} }
return syscall.Chown(dest, int(node.Uid), int(node.Gid)) return unix.Chown(dest, int(node.Uid), int(node.Gid))
} }
func getMountInfo(mountinfo []*mount.Info, dir string) *mount.Info { func getMountInfo(mountinfo []*mount.Info, dir string) *mount.Info {
@ -588,18 +589,18 @@ func rootfsParentMountPrivate(rootfs string) error {
// shared. Secondly when we bind mount rootfs it will propagate to // shared. Secondly when we bind mount rootfs it will propagate to
// parent namespace and we don't want that to happen. // parent namespace and we don't want that to happen.
if sharedMount { if sharedMount {
return syscall.Mount("", parentMount, "", syscall.MS_PRIVATE, "") return unix.Mount("", parentMount, "", unix.MS_PRIVATE, "")
} }
return nil return nil
} }
func prepareRoot(config *configs.Config) error { func prepareRoot(config *configs.Config) error {
flag := syscall.MS_SLAVE | syscall.MS_REC flag := unix.MS_SLAVE | unix.MS_REC
if config.RootPropagation != 0 { if config.RootPropagation != 0 {
flag = config.RootPropagation flag = config.RootPropagation
} }
if err := syscall.Mount("", "/", "", uintptr(flag), ""); err != nil { if err := unix.Mount("", "/", "", uintptr(flag), ""); err != nil {
return err return err
} }
@ -610,11 +611,11 @@ func prepareRoot(config *configs.Config) error {
return err return err
} }
return syscall.Mount(config.Rootfs, config.Rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, "") return unix.Mount(config.Rootfs, config.Rootfs, "bind", unix.MS_BIND|unix.MS_REC, "")
} }
func setReadonly() error { func setReadonly() error {
return syscall.Mount("/", "/", "bind", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC, "") return unix.Mount("/", "/", "bind", unix.MS_BIND|unix.MS_REMOUNT|unix.MS_RDONLY|unix.MS_REC, "")
} }
func setupPtmx(config *configs.Config) error { func setupPtmx(config *configs.Config) error {
@ -637,24 +638,24 @@ func pivotRoot(rootfs string) error {
// with pivot_root this allows us to pivot without creating directories in // with pivot_root this allows us to pivot without creating directories in
// the rootfs. Shout-outs to the LXC developers for giving us this idea. // the rootfs. Shout-outs to the LXC developers for giving us this idea.
oldroot, err := syscall.Open("/", syscall.O_DIRECTORY|syscall.O_RDONLY, 0) oldroot, err := unix.Open("/", unix.O_DIRECTORY|unix.O_RDONLY, 0)
if err != nil { if err != nil {
return err return err
} }
defer syscall.Close(oldroot) defer unix.Close(oldroot)
newroot, err := syscall.Open(rootfs, syscall.O_DIRECTORY|syscall.O_RDONLY, 0) newroot, err := unix.Open(rootfs, unix.O_DIRECTORY|unix.O_RDONLY, 0)
if err != nil { if err != nil {
return err return err
} }
defer syscall.Close(newroot) defer unix.Close(newroot)
// Change to the new root so that the pivot_root actually acts on it. // Change to the new root so that the pivot_root actually acts on it.
if err := syscall.Fchdir(newroot); err != nil { if err := unix.Fchdir(newroot); err != nil {
return err return err
} }
if err := syscall.PivotRoot(".", "."); err != nil { if err := unix.PivotRoot(".", "."); err != nil {
return fmt.Errorf("pivot_root %s", err) return fmt.Errorf("pivot_root %s", err)
} }
@ -663,35 +664,35 @@ func pivotRoot(rootfs string) error {
// really any guarantee from the kernel what /proc/self/cwd will be after a // really any guarantee from the kernel what /proc/self/cwd will be after a
// pivot_root(2). // pivot_root(2).
if err := syscall.Fchdir(oldroot); err != nil { if err := unix.Fchdir(oldroot); err != nil {
return err return err
} }
// Make oldroot rprivate to make sure our unmounts don't propagate to the // Make oldroot rprivate to make sure our unmounts don't propagate to the
// host (and thus bork the machine). // host (and thus bork the machine).
if err := syscall.Mount("", ".", "", syscall.MS_PRIVATE|syscall.MS_REC, ""); err != nil { if err := unix.Mount("", ".", "", unix.MS_PRIVATE|unix.MS_REC, ""); err != nil {
return err return err
} }
// Preform the unmount. MNT_DETACH allows us to unmount /proc/self/cwd. // Preform the unmount. MNT_DETACH allows us to unmount /proc/self/cwd.
if err := syscall.Unmount(".", syscall.MNT_DETACH); err != nil { if err := unix.Unmount(".", unix.MNT_DETACH); err != nil {
return err return err
} }
// Switch back to our shiny new root. // Switch back to our shiny new root.
if err := syscall.Chdir("/"); err != nil { if err := unix.Chdir("/"); err != nil {
return fmt.Errorf("chdir / %s", err) return fmt.Errorf("chdir / %s", err)
} }
return nil return nil
} }
func msMoveRoot(rootfs string) error { func msMoveRoot(rootfs string) error {
if err := syscall.Mount(rootfs, "/", "", syscall.MS_MOVE, ""); err != nil { if err := unix.Mount(rootfs, "/", "", unix.MS_MOVE, ""); err != nil {
return err return err
} }
if err := syscall.Chroot("."); err != nil { if err := unix.Chroot("."); err != nil {
return err return err
} }
return syscall.Chdir("/") return unix.Chdir("/")
} }
// createIfNotExists creates a file or a directory only if it does not already exist. // createIfNotExists creates a file or a directory only if it does not already exist.
@ -716,13 +717,13 @@ func createIfNotExists(path string, isDir bool) error {
// readonlyPath will make a path read only. // readonlyPath will make a path read only.
func readonlyPath(path string) error { func readonlyPath(path string) error {
if err := syscall.Mount(path, path, "", syscall.MS_BIND|syscall.MS_REC, ""); err != nil { if err := unix.Mount(path, path, "", unix.MS_BIND|unix.MS_REC, ""); err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return nil return nil
} }
return err return err
} }
return syscall.Mount(path, path, "", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC, "") return unix.Mount(path, path, "", unix.MS_BIND|unix.MS_REMOUNT|unix.MS_RDONLY|unix.MS_REC, "")
} }
// remountReadonly will remount an existing mount point and ensure that it is read-only. // remountReadonly will remount an existing mount point and ensure that it is read-only.
@ -732,9 +733,9 @@ func remountReadonly(m *configs.Mount) error {
flags = m.Flags flags = m.Flags
) )
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
if err := syscall.Mount("", dest, "", uintptr(flags|syscall.MS_REMOUNT|syscall.MS_RDONLY), ""); err != nil { if err := unix.Mount("", dest, "", uintptr(flags|unix.MS_REMOUNT|unix.MS_RDONLY), ""); err != nil {
switch err { switch err {
case syscall.EBUSY: case unix.EBUSY:
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
continue continue
default: default:
@ -752,9 +753,9 @@ func remountReadonly(m *configs.Mount) error {
// For files, maskPath bind mounts /dev/null over the top of the specified path. // For files, maskPath bind mounts /dev/null over the top of the specified path.
// For directories, maskPath mounts read-only tmpfs over the top of the specified path. // For directories, maskPath mounts read-only tmpfs over the top of the specified path.
func maskPath(path string) error { func maskPath(path string) error {
if err := syscall.Mount("/dev/null", path, "", syscall.MS_BIND, ""); err != nil && !os.IsNotExist(err) { if err := unix.Mount("/dev/null", path, "", unix.MS_BIND, ""); err != nil && !os.IsNotExist(err) {
if err == syscall.ENOTDIR { if err == unix.ENOTDIR {
return syscall.Mount("tmpfs", path, "tmpfs", syscall.MS_RDONLY, "") return unix.Mount("tmpfs", path, "tmpfs", unix.MS_RDONLY, "")
} }
return err return err
} }
@ -775,7 +776,7 @@ func remount(m *configs.Mount, rootfs string) error {
if !strings.HasPrefix(dest, rootfs) { if !strings.HasPrefix(dest, rootfs) {
dest = filepath.Join(rootfs, dest) dest = filepath.Join(rootfs, dest)
} }
if err := syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags|syscall.MS_REMOUNT), ""); err != nil { if err := unix.Mount(m.Source, dest, m.Device, uintptr(m.Flags|unix.MS_REMOUNT), ""); err != nil {
return err return err
} }
return nil return nil
@ -790,7 +791,7 @@ func mountPropagate(m *configs.Mount, rootfs string, mountLabel string) error {
flags = m.Flags flags = m.Flags
) )
if libcontainerUtils.CleanPath(dest) == "/dev" { if libcontainerUtils.CleanPath(dest) == "/dev" {
flags &= ^syscall.MS_RDONLY flags &= ^unix.MS_RDONLY
} }
copyUp := m.Extensions&configs.EXT_COPYUP == configs.EXT_COPYUP copyUp := m.Extensions&configs.EXT_COPYUP == configs.EXT_COPYUP
@ -798,12 +799,12 @@ func mountPropagate(m *configs.Mount, rootfs string, mountLabel string) error {
dest = filepath.Join(rootfs, dest) dest = filepath.Join(rootfs, dest)
} }
if err := syscall.Mount(m.Source, dest, m.Device, uintptr(flags), data); err != nil { if err := unix.Mount(m.Source, dest, m.Device, uintptr(flags), data); err != nil {
return err return err
} }
for _, pflag := range m.PropagationFlags { for _, pflag := range m.PropagationFlags {
if err := syscall.Mount("", dest, "", uintptr(pflag), ""); err != nil { if err := unix.Mount("", dest, "", uintptr(pflag), ""); err != nil {
return err return err
} }
} }

View File

@ -7,18 +7,19 @@ import (
"fmt" "fmt"
"os" "os"
"strings" "strings"
"syscall"
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
libseccomp "github.com/seccomp/libseccomp-golang" libseccomp "github.com/seccomp/libseccomp-golang"
"golang.org/x/sys/unix"
) )
var ( var (
actAllow = libseccomp.ActAllow actAllow = libseccomp.ActAllow
actTrap = libseccomp.ActTrap actTrap = libseccomp.ActTrap
actKill = libseccomp.ActKill actKill = libseccomp.ActKill
actTrace = libseccomp.ActTrace.SetReturnCode(int16(syscall.EPERM)) actTrace = libseccomp.ActTrace.SetReturnCode(int16(unix.EPERM))
actErrno = libseccomp.ActErrno.SetReturnCode(int16(syscall.EPERM)) actErrno = libseccomp.ActErrno.SetReturnCode(int16(unix.EPERM))
// SeccompModeFilter refers to the syscall argument SECCOMP_MODE_FILTER. // SeccompModeFilter refers to the syscall argument SECCOMP_MODE_FILTER.
SeccompModeFilter = uintptr(2) SeccompModeFilter = uintptr(2)
@ -84,9 +85,9 @@ func IsEnabled() bool {
s, err := parseStatusFile("/proc/self/status") s, err := parseStatusFile("/proc/self/status")
if err != nil { if err != nil {
// Check if Seccomp is supported, via CONFIG_SECCOMP. // Check if Seccomp is supported, via CONFIG_SECCOMP.
if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_GET_SECCOMP, 0, 0); err != syscall.EINVAL { if _, _, err := unix.RawSyscall(unix.SYS_PRCTL, unix.PR_GET_SECCOMP, 0, 0); err != unix.EINVAL {
// Make sure the kernel has CONFIG_SECCOMP_FILTER. // Make sure the kernel has CONFIG_SECCOMP_FILTER.
if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_SECCOMP, SeccompModeFilter, 0); err != syscall.EINVAL { if _, _, err := unix.RawSyscall(unix.SYS_PRCTL, unix.PR_SET_SECCOMP, SeccompModeFilter, 0); err != unix.EINVAL {
return true return true
} }
} }

View File

@ -9,13 +9,14 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"syscall"
"time" "time"
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/seccomp" "github.com/opencontainers/runc/libcontainer/seccomp"
libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils" libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils"
"github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-spec/specs-go"
"golang.org/x/sys/unix"
) )
const wildcard = -1 const wildcard = -1
@ -30,13 +31,13 @@ var namespaceMapping = map[specs.LinuxNamespaceType]configs.NamespaceType{
} }
var mountPropagationMapping = map[string]int{ var mountPropagationMapping = map[string]int{
"rprivate": syscall.MS_PRIVATE | syscall.MS_REC, "rprivate": unix.MS_PRIVATE | unix.MS_REC,
"private": syscall.MS_PRIVATE, "private": unix.MS_PRIVATE,
"rslave": syscall.MS_SLAVE | syscall.MS_REC, "rslave": unix.MS_SLAVE | unix.MS_REC,
"slave": syscall.MS_SLAVE, "slave": unix.MS_SLAVE,
"rshared": syscall.MS_SHARED | syscall.MS_REC, "rshared": unix.MS_SHARED | unix.MS_REC,
"shared": syscall.MS_SHARED, "shared": unix.MS_SHARED,
"": syscall.MS_PRIVATE | syscall.MS_REC, "": unix.MS_PRIVATE | unix.MS_REC,
} }
var allowedDevices = []*configs.Device{ var allowedDevices = []*configs.Device{
@ -638,41 +639,41 @@ func parseMountOptions(options []string) (int, []int, string, int) {
clear bool clear bool
flag int flag int
}{ }{
"async": {true, syscall.MS_SYNCHRONOUS}, "async": {true, unix.MS_SYNCHRONOUS},
"atime": {true, syscall.MS_NOATIME}, "atime": {true, unix.MS_NOATIME},
"bind": {false, syscall.MS_BIND}, "bind": {false, unix.MS_BIND},
"defaults": {false, 0}, "defaults": {false, 0},
"dev": {true, syscall.MS_NODEV}, "dev": {true, unix.MS_NODEV},
"diratime": {true, syscall.MS_NODIRATIME}, "diratime": {true, unix.MS_NODIRATIME},
"dirsync": {false, syscall.MS_DIRSYNC}, "dirsync": {false, unix.MS_DIRSYNC},
"exec": {true, syscall.MS_NOEXEC}, "exec": {true, unix.MS_NOEXEC},
"mand": {false, syscall.MS_MANDLOCK}, "mand": {false, unix.MS_MANDLOCK},
"noatime": {false, syscall.MS_NOATIME}, "noatime": {false, unix.MS_NOATIME},
"nodev": {false, syscall.MS_NODEV}, "nodev": {false, unix.MS_NODEV},
"nodiratime": {false, syscall.MS_NODIRATIME}, "nodiratime": {false, unix.MS_NODIRATIME},
"noexec": {false, syscall.MS_NOEXEC}, "noexec": {false, unix.MS_NOEXEC},
"nomand": {true, syscall.MS_MANDLOCK}, "nomand": {true, unix.MS_MANDLOCK},
"norelatime": {true, syscall.MS_RELATIME}, "norelatime": {true, unix.MS_RELATIME},
"nostrictatime": {true, syscall.MS_STRICTATIME}, "nostrictatime": {true, unix.MS_STRICTATIME},
"nosuid": {false, syscall.MS_NOSUID}, "nosuid": {false, unix.MS_NOSUID},
"rbind": {false, syscall.MS_BIND | syscall.MS_REC}, "rbind": {false, unix.MS_BIND | unix.MS_REC},
"relatime": {false, syscall.MS_RELATIME}, "relatime": {false, unix.MS_RELATIME},
"remount": {false, syscall.MS_REMOUNT}, "remount": {false, unix.MS_REMOUNT},
"ro": {false, syscall.MS_RDONLY}, "ro": {false, unix.MS_RDONLY},
"rw": {true, syscall.MS_RDONLY}, "rw": {true, unix.MS_RDONLY},
"strictatime": {false, syscall.MS_STRICTATIME}, "strictatime": {false, unix.MS_STRICTATIME},
"suid": {true, syscall.MS_NOSUID}, "suid": {true, unix.MS_NOSUID},
"sync": {false, syscall.MS_SYNCHRONOUS}, "sync": {false, unix.MS_SYNCHRONOUS},
} }
propagationFlags := map[string]int{ propagationFlags := map[string]int{
"private": syscall.MS_PRIVATE, "private": unix.MS_PRIVATE,
"shared": syscall.MS_SHARED, "shared": unix.MS_SHARED,
"slave": syscall.MS_SLAVE, "slave": unix.MS_SLAVE,
"unbindable": syscall.MS_UNBINDABLE, "unbindable": unix.MS_UNBINDABLE,
"rprivate": syscall.MS_PRIVATE | syscall.MS_REC, "rprivate": unix.MS_PRIVATE | unix.MS_REC,
"rshared": syscall.MS_SHARED | syscall.MS_REC, "rshared": unix.MS_SHARED | unix.MS_REC,
"rslave": syscall.MS_SLAVE | syscall.MS_REC, "rslave": unix.MS_SLAVE | unix.MS_REC,
"runbindable": syscall.MS_UNBINDABLE | syscall.MS_REC, "runbindable": unix.MS_UNBINDABLE | unix.MS_REC,
} }
extensionFlags := map[string]struct { extensionFlags := map[string]struct {
clear bool clear bool

View File

@ -6,7 +6,7 @@ import (
"fmt" "fmt"
"os" "os"
"os/exec" "os/exec"
"syscall" "syscall" //only for Exec
"github.com/opencontainers/runc/libcontainer/apparmor" "github.com/opencontainers/runc/libcontainer/apparmor"
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
@ -14,6 +14,8 @@ import (
"github.com/opencontainers/runc/libcontainer/seccomp" "github.com/opencontainers/runc/libcontainer/seccomp"
"github.com/opencontainers/runc/libcontainer/system" "github.com/opencontainers/runc/libcontainer/system"
"github.com/opencontainers/selinux/go-selinux/label" "github.com/opencontainers/selinux/go-selinux/label"
"golang.org/x/sys/unix"
) )
type linuxStandardInit struct { type linuxStandardInit struct {
@ -95,7 +97,7 @@ func (l *linuxStandardInit) Init() error {
} }
if hostname := l.config.Config.Hostname; hostname != "" { if hostname := l.config.Config.Hostname; hostname != "" {
if err := syscall.Sethostname([]byte(hostname)); err != nil { if err := unix.Sethostname([]byte(hostname)); err != nil {
return err return err
} }
} }
@ -155,8 +157,8 @@ func (l *linuxStandardInit) Init() error {
// compare the parent from the initial start of the init process and make sure that it did not change. // compare the parent from the initial start of the init process and make sure that it did not change.
// if the parent changes that means it died and we were reparented to something else so we should // if the parent changes that means it died and we were reparented to something else so we should
// just kill ourself and not cause problems for someone else. // just kill ourself and not cause problems for someone else.
if syscall.Getppid() != l.parentPid { if unix.Getppid() != l.parentPid {
return syscall.Kill(syscall.Getpid(), syscall.SIGKILL) return unix.Kill(unix.Getpid(), unix.SIGKILL)
} }
// check for the arg before waiting to make sure it exists and it is returned // check for the arg before waiting to make sure it exists and it is returned
// as a create time error. // as a create time error.
@ -168,11 +170,11 @@ func (l *linuxStandardInit) Init() error {
l.pipe.Close() l.pipe.Close()
// wait for the fifo to be opened on the other side before // wait for the fifo to be opened on the other side before
// exec'ing the users process. // exec'ing the users process.
fd, err := syscall.Openat(l.stateDirFD, execFifoFilename, os.O_WRONLY|syscall.O_CLOEXEC, 0) fd, err := unix.Openat(l.stateDirFD, execFifoFilename, os.O_WRONLY|unix.O_CLOEXEC, 0)
if err != nil { if err != nil {
return newSystemErrorWithCause(err, "openat exec fifo") return newSystemErrorWithCause(err, "openat exec fifo")
} }
if _, err := syscall.Write(fd, []byte("0")); err != nil { if _, err := unix.Write(fd, []byte("0")); err != nil {
return newSystemErrorWithCause(err, "write 0 exec fifo") return newSystemErrorWithCause(err, "write 0 exec fifo")
} }
if l.config.Config.Seccomp != nil && l.config.NoNewPrivileges { if l.config.Config.Seccomp != nil && l.config.NoNewPrivileges {
@ -182,7 +184,7 @@ func (l *linuxStandardInit) Init() error {
} }
// close the statedir fd before exec because the kernel resets dumpable in the wrong order // close the statedir fd before exec because the kernel resets dumpable in the wrong order
// https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318 // https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318
syscall.Close(l.stateDirFD) unix.Close(l.stateDirFD)
if err := syscall.Exec(name, l.config.Args[0:], os.Environ()); err != nil { if err := syscall.Exec(name, l.config.Args[0:], os.Environ()); err != nil {
return newSystemErrorWithCause(err, "exec user process") return newSystemErrorWithCause(err, "exec user process")
} }

View File

@ -6,11 +6,12 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"syscall"
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/utils" "github.com/opencontainers/runc/libcontainer/utils"
"golang.org/x/sys/unix"
) )
func newStateTransitionError(from, to containerState) error { func newStateTransitionError(from, to containerState) error {
@ -39,7 +40,7 @@ type containerState interface {
func destroy(c *linuxContainer) error { func destroy(c *linuxContainer) error {
if !c.config.Namespaces.Contains(configs.NEWPID) { if !c.config.Namespaces.Contains(configs.NEWPID) {
if err := signalAllProcesses(c.cgroupManager, syscall.SIGKILL); err != nil { if err := signalAllProcesses(c.cgroupManager, unix.SIGKILL); err != nil {
logrus.Warn(err) logrus.Warn(err)
} }
} }
@ -156,7 +157,7 @@ func (i *createdState) transition(s containerState) error {
} }
func (i *createdState) destroy() error { func (i *createdState) destroy() error {
i.c.initProcess.signal(syscall.SIGKILL) i.c.initProcess.signal(unix.SIGKILL)
return destroy(i.c) return destroy(i.c)
} }

View File

@ -7,8 +7,10 @@ import (
"fmt" "fmt"
"os" "os"
"os/exec" "os/exec"
"syscall" "syscall" // only for exec
"unsafe" "unsafe"
"golang.org/x/sys/unix"
) )
// If arg2 is nonzero, set the "child subreaper" attribute of the // If arg2 is nonzero, set the "child subreaper" attribute of the
@ -53,8 +55,8 @@ func Execv(cmd string, args []string, env []string) error {
return syscall.Exec(name, args, env) return syscall.Exec(name, args, env)
} }
func Prlimit(pid, resource int, limit syscall.Rlimit) error { func Prlimit(pid, resource int, limit unix.Rlimit) error {
_, _, err := syscall.RawSyscall6(syscall.SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(&limit)), uintptr(unsafe.Pointer(&limit)), 0, 0) _, _, err := unix.RawSyscall6(unix.SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(&limit)), uintptr(unsafe.Pointer(&limit)), 0, 0)
if err != 0 { if err != 0 {
return err return err
} }
@ -62,7 +64,7 @@ func Prlimit(pid, resource int, limit syscall.Rlimit) error {
} }
func SetParentDeathSignal(sig uintptr) error { func SetParentDeathSignal(sig uintptr) error {
if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_PDEATHSIG, sig, 0); err != 0 { if _, _, err := unix.RawSyscall(unix.SYS_PRCTL, unix.PR_SET_PDEATHSIG, sig, 0); err != 0 {
return err return err
} }
return nil return nil
@ -70,7 +72,7 @@ func SetParentDeathSignal(sig uintptr) error {
func GetParentDeathSignal() (ParentDeathSignal, error) { func GetParentDeathSignal() (ParentDeathSignal, error) {
var sig int var sig int
_, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_GET_PDEATHSIG, uintptr(unsafe.Pointer(&sig)), 0) _, _, err := unix.RawSyscall(unix.SYS_PRCTL, unix.PR_GET_PDEATHSIG, uintptr(unsafe.Pointer(&sig)), 0)
if err != 0 { if err != 0 {
return -1, err return -1, err
} }
@ -78,7 +80,7 @@ func GetParentDeathSignal() (ParentDeathSignal, error) {
} }
func SetKeepCaps() error { func SetKeepCaps() error {
if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_KEEPCAPS, 1, 0); err != 0 { if _, _, err := unix.RawSyscall(unix.SYS_PRCTL, unix.PR_SET_KEEPCAPS, 1, 0); err != 0 {
return err return err
} }
@ -86,7 +88,7 @@ func SetKeepCaps() error {
} }
func ClearKeepCaps() error { func ClearKeepCaps() error {
if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_KEEPCAPS, 0, 0); err != 0 { if _, _, err := unix.RawSyscall(unix.SYS_PRCTL, unix.PR_SET_KEEPCAPS, 0, 0); err != 0 {
return err return err
} }
@ -94,7 +96,7 @@ func ClearKeepCaps() error {
} }
func Setctty() error { func Setctty() error {
if _, _, err := syscall.RawSyscall(syscall.SYS_IOCTL, 0, uintptr(syscall.TIOCSCTTY), 0); err != 0 { if _, _, err := unix.RawSyscall(unix.SYS_IOCTL, 0, uintptr(unix.TIOCSCTTY), 0); err != 0 {
return err return err
} }
return nil return nil
@ -135,7 +137,7 @@ func SetSubreaper(i int) error {
} }
func Prctl(option int, arg2, arg3, arg4, arg5 uintptr) (err error) { func Prctl(option int, arg2, arg3, arg4, arg5 uintptr) (err error) {
_, _, e1 := syscall.Syscall6(syscall.SYS_PRCTL, uintptr(option), arg2, arg3, arg4, arg5, 0) _, _, e1 := unix.Syscall6(unix.SYS_PRCTL, uintptr(option), arg2, arg3, arg4, arg5, 0)
if e1 != 0 { if e1 != 0 {
err = e1 err = e1
} }

View File

@ -1,40 +0,0 @@
package system
import (
"fmt"
"runtime"
"syscall"
)
// Via http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=7b21fddd087678a70ad64afc0f632e0f1071b092
//
// We need different setns values for the different platforms and arch
// We are declaring the macro here because the SETNS syscall does not exist in th stdlib
var setNsMap = map[string]uintptr{
"linux/386": 346,
"linux/arm64": 268,
"linux/amd64": 308,
"linux/arm": 375,
"linux/ppc": 350,
"linux/ppc64": 350,
"linux/ppc64le": 350,
"linux/s390x": 339,
}
var sysSetns = setNsMap[fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)]
func SysSetns() uint32 {
return uint32(sysSetns)
}
func Setns(fd uintptr, flags uintptr) error {
ns, exists := setNsMap[fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)]
if !exists {
return fmt.Errorf("unsupported platform %s/%s", runtime.GOOS, runtime.GOARCH)
}
_, _, err := syscall.RawSyscall(ns, fd, flags, 0)
if err != 0 {
return err
}
return nil
}

View File

@ -3,12 +3,12 @@
package system package system
import ( import (
"syscall" "golang.org/x/sys/unix"
) )
// Setuid sets the uid of the calling thread to the specified uid. // Setuid sets the uid of the calling thread to the specified uid.
func Setuid(uid int) (err error) { func Setuid(uid int) (err error) {
_, _, e1 := syscall.RawSyscall(syscall.SYS_SETUID32, uintptr(uid), 0, 0) _, _, e1 := unix.RawSyscall(unix.SYS_SETUID32, uintptr(uid), 0, 0)
if e1 != 0 { if e1 != 0 {
err = e1 err = e1
} }
@ -17,7 +17,7 @@ func Setuid(uid int) (err error) {
// Setgid sets the gid of the calling thread to the specified gid. // Setgid sets the gid of the calling thread to the specified gid.
func Setgid(gid int) (err error) { func Setgid(gid int) (err error) {
_, _, e1 := syscall.RawSyscall(syscall.SYS_SETGID32, uintptr(gid), 0, 0) _, _, e1 := unix.RawSyscall(unix.SYS_SETGID32, uintptr(gid), 0, 0)
if e1 != 0 { if e1 != 0 {
err = e1 err = e1
} }

View File

@ -3,12 +3,12 @@
package system package system
import ( import (
"syscall" "golang.org/x/sys/unix"
) )
// Setuid sets the uid of the calling thread to the specified uid. // Setuid sets the uid of the calling thread to the specified uid.
func Setuid(uid int) (err error) { func Setuid(uid int) (err error) {
_, _, e1 := syscall.RawSyscall(syscall.SYS_SETUID, uintptr(uid), 0, 0) _, _, e1 := unix.RawSyscall(unix.SYS_SETUID, uintptr(uid), 0, 0)
if e1 != 0 { if e1 != 0 {
err = e1 err = e1
} }
@ -17,7 +17,7 @@ func Setuid(uid int) (err error) {
// Setgid sets the gid of the calling thread to the specified gid. // Setgid sets the gid of the calling thread to the specified gid.
func Setgid(gid int) (err error) { func Setgid(gid int) (err error) {
_, _, e1 := syscall.RawSyscall(syscall.SYS_SETGID, uintptr(gid), 0, 0) _, _, e1 := unix.RawSyscall(unix.SYS_SETGID, uintptr(gid), 0, 0)
if e1 != 0 { if e1 != 0 {
err = e1 err = e1
} }

View File

@ -3,12 +3,12 @@
package system package system
import ( import (
"syscall" "golang.org/x/sys/unix"
) )
// Setuid sets the uid of the calling thread to the specified uid. // Setuid sets the uid of the calling thread to the specified uid.
func Setuid(uid int) (err error) { func Setuid(uid int) (err error) {
_, _, e1 := syscall.RawSyscall(syscall.SYS_SETUID32, uintptr(uid), 0, 0) _, _, e1 := unix.RawSyscall(unix.SYS_SETUID32, uintptr(uid), 0, 0)
if e1 != 0 { if e1 != 0 {
err = e1 err = e1
} }
@ -17,7 +17,7 @@ func Setuid(uid int) (err error) {
// Setgid sets the gid of the calling thread to the specified gid. // Setgid sets the gid of the calling thread to the specified gid.
func Setgid(gid int) (err error) { func Setgid(gid int) (err error) {
_, _, e1 := syscall.RawSyscall(syscall.SYS_SETGID32, uintptr(gid), 0, 0) _, _, e1 := unix.RawSyscall(unix.SYS_SETGID32, uintptr(gid), 0, 0)
if e1 != 0 { if e1 != 0 {
err = e1 err = e1
} }

View File

@ -1,8 +1,9 @@
package system package system
import ( import (
"syscall"
"unsafe" "unsafe"
"golang.org/x/sys/unix"
) )
var _zero uintptr var _zero uintptr
@ -10,7 +11,7 @@ var _zero uintptr
// Returns the size of xattrs and nil error // Returns the size of xattrs and nil error
// Requires path, takes allocated []byte or nil as last argument // Requires path, takes allocated []byte or nil as last argument
func Llistxattr(path string, dest []byte) (size int, err error) { func Llistxattr(path string, dest []byte) (size int, err error) {
pathBytes, err := syscall.BytePtrFromString(path) pathBytes, err := unix.BytePtrFromString(path)
if err != nil { if err != nil {
return -1, err return -1, err
} }
@ -21,7 +22,7 @@ func Llistxattr(path string, dest []byte) (size int, err error) {
newpathBytes = unsafe.Pointer(&_zero) newpathBytes = unsafe.Pointer(&_zero)
} }
_size, _, errno := syscall.Syscall6(syscall.SYS_LLISTXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(newpathBytes), uintptr(len(dest)), 0, 0, 0) _size, _, errno := unix.Syscall6(unix.SYS_LLISTXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(newpathBytes), uintptr(len(dest)), 0, 0, 0)
size = int(_size) size = int(_size)
if errno != 0 { if errno != 0 {
return -1, errno return -1, errno
@ -34,11 +35,11 @@ func Llistxattr(path string, dest []byte) (size int, err error) {
// Requires path and its attribute as arguments // Requires path and its attribute as arguments
func Lgetxattr(path string, attr string) ([]byte, error) { func Lgetxattr(path string, attr string) ([]byte, error) {
var sz int var sz int
pathBytes, err := syscall.BytePtrFromString(path) pathBytes, err := unix.BytePtrFromString(path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
attrBytes, err := syscall.BytePtrFromString(attr) attrBytes, err := unix.BytePtrFromString(attr)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -47,25 +48,25 @@ func Lgetxattr(path string, attr string) ([]byte, error) {
sz = 128 sz = 128
dest := make([]byte, sz) dest := make([]byte, sz)
destBytes := unsafe.Pointer(&dest[0]) destBytes := unsafe.Pointer(&dest[0])
_sz, _, errno := syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0) _sz, _, errno := unix.Syscall6(unix.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0)
switch { switch {
case errno == syscall.ENODATA: case errno == unix.ENODATA:
return nil, errno return nil, errno
case errno == syscall.ENOTSUP: case errno == unix.ENOTSUP:
return nil, errno return nil, errno
case errno == syscall.ERANGE: case errno == unix.ERANGE:
// 128 byte array might just not be good enough, // 128 byte array might just not be good enough,
// A dummy buffer is used ``uintptr(0)`` to get real size // A dummy buffer is used ``uintptr(0)`` to get real size
// of the xattrs on disk // of the xattrs on disk
_sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(unsafe.Pointer(nil)), uintptr(0), 0, 0) _sz, _, errno = unix.Syscall6(unix.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(unsafe.Pointer(nil)), uintptr(0), 0, 0)
sz = int(_sz) sz = int(_sz)
if sz < 0 { if sz < 0 {
return nil, errno return nil, errno
} }
dest = make([]byte, sz) dest = make([]byte, sz)
destBytes := unsafe.Pointer(&dest[0]) destBytes := unsafe.Pointer(&dest[0])
_sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0) _sz, _, errno = unix.Syscall6(unix.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0)
if errno != 0 { if errno != 0 {
return nil, errno return nil, errno
} }
@ -77,11 +78,11 @@ func Lgetxattr(path string, attr string) ([]byte, error) {
} }
func Lsetxattr(path string, attr string, data []byte, flags int) error { func Lsetxattr(path string, attr string, data []byte, flags int) error {
pathBytes, err := syscall.BytePtrFromString(path) pathBytes, err := unix.BytePtrFromString(path)
if err != nil { if err != nil {
return err return err
} }
attrBytes, err := syscall.BytePtrFromString(attr) attrBytes, err := unix.BytePtrFromString(attr)
if err != nil { if err != nil {
return err return err
} }
@ -91,7 +92,7 @@ func Lsetxattr(path string, attr string, data []byte, flags int) error {
} else { } else {
dataBytes = unsafe.Pointer(&_zero) dataBytes = unsafe.Pointer(&_zero)
} }
_, _, errno := syscall.Syscall6(syscall.SYS_LSETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(dataBytes), uintptr(len(data)), uintptr(flags), 0) _, _, errno := unix.Syscall6(unix.SYS_LSETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(dataBytes), uintptr(len(data)), uintptr(flags), 0)
if errno != 0 { if errno != 0 {
return errno return errno
} }

View File

@ -2,7 +2,8 @@ package user
import ( import (
"errors" "errors"
"syscall"
"golang.org/x/sys/unix"
) )
var ( var (
@ -40,7 +41,7 @@ func lookupUser(filter func(u User) bool) (User, error) {
// user cannot be found (or there is no /etc/passwd file on the filesystem), // user cannot be found (or there is no /etc/passwd file on the filesystem),
// then CurrentUser returns an error. // then CurrentUser returns an error.
func CurrentUser() (User, error) { func CurrentUser() (User, error) {
return LookupUid(syscall.Getuid()) return LookupUid(unix.Getuid())
} }
// LookupUser looks up a user by their username in /etc/passwd. If the user // LookupUser looks up a user by their username in /etc/passwd. If the user
@ -88,7 +89,7 @@ func lookupGroup(filter func(g Group) bool) (Group, error) {
// entry in /etc/passwd. If the group cannot be found (or there is no // entry in /etc/passwd. If the group cannot be found (or there is no
// /etc/group file on the filesystem), then CurrentGroup returns an error. // /etc/group file on the filesystem), then CurrentGroup returns an error.
func CurrentGroup() (Group, error) { func CurrentGroup() (Group, error) {
return LookupGid(syscall.Getgid()) return LookupGid(unix.Getgid())
} }
// LookupGroup looks up a group by its name in /etc/group. If the group cannot // LookupGroup looks up a group by its name in /etc/group. If the group cannot

View File

@ -8,8 +8,9 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"syscall"
"unsafe" "unsafe"
"golang.org/x/sys/unix"
) )
const ( const (
@ -41,7 +42,7 @@ func ResolveRootfs(uncleanRootfs string) (string, error) {
// ExitStatus returns the correct exit status for a process based on if it // ExitStatus returns the correct exit status for a process based on if it
// was signaled or exited cleanly // was signaled or exited cleanly
func ExitStatus(status syscall.WaitStatus) int { func ExitStatus(status unix.WaitStatus) int {
if status.Signaled() { if status.Signaled() {
return exitSignalOffset + int(status.Signal()) return exitSignalOffset + int(status.Signal())
} }

View File

@ -5,8 +5,9 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"syscall"
"testing" "testing"
"golang.org/x/sys/unix"
) )
func TestGenerateName(t *testing.T) { func TestGenerateName(t *testing.T) {
@ -94,7 +95,7 @@ func TestResolveRootfsWithNonExistingDir(t *testing.T) {
} }
func TestExitStatus(t *testing.T) { func TestExitStatus(t *testing.T) {
status := syscall.WaitStatus(0) status := unix.WaitStatus(0)
ex := ExitStatus(status) ex := ExitStatus(status)
if ex != 0 { if ex != 0 {
t.Errorf("expected exit status to equal 0 and received %d", ex) t.Errorf("expected exit status to equal 0 and received %d", ex)
@ -102,7 +103,7 @@ func TestExitStatus(t *testing.T) {
} }
func TestExitStatusSignaled(t *testing.T) { func TestExitStatusSignaled(t *testing.T) {
status := syscall.WaitStatus(2) status := unix.WaitStatus(2)
ex := ExitStatus(status) ex := ExitStatus(status)
if ex != 130 { if ex != 130 {
t.Errorf("expected exit status to equal 130 and received %d", ex) t.Errorf("expected exit status to equal 130 and received %d", ex)

View File

@ -6,7 +6,8 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"strconv" "strconv"
"syscall"
"golang.org/x/sys/unix"
) )
func CloseExecFrom(minFd int) error { func CloseExecFrom(minFd int) error {
@ -26,8 +27,8 @@ func CloseExecFrom(minFd int) error {
continue continue
} }
// intentionally ignore errors from syscall.CloseOnExec // intentionally ignore errors from unix.CloseOnExec
syscall.CloseOnExec(fd) unix.CloseOnExec(fd)
// the cases where this might fail are basically file descriptors that have already been closed (including and especially the one that was created when ioutil.ReadDir did the "opendir" syscall) // the cases where this might fail are basically file descriptors that have already been closed (including and especially the one that was created when ioutil.ReadDir did the "opendir" syscall)
} }
return nil return nil
@ -35,7 +36,7 @@ func CloseExecFrom(minFd int) error {
// NewSockPair returns a new unix socket pair // NewSockPair returns a new unix socket pair
func NewSockPair(name string) (parent *os.File, child *os.File, err error) { func NewSockPair(name string) (parent *os.File, child *os.File, err error) {
fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM|syscall.SOCK_CLOEXEC, 0) fds, err := unix.Socketpair(unix.AF_LOCAL, unix.SOCK_STREAM|unix.SOCK_CLOEXEC, 0)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }

View File

@ -3,13 +3,13 @@
package xattr package xattr
import ( import (
"syscall"
"github.com/opencontainers/runc/libcontainer/system" "github.com/opencontainers/runc/libcontainer/system"
"golang.org/x/sys/unix"
) )
func XattrEnabled(path string) bool { func XattrEnabled(path string) bool {
if Setxattr(path, "user.test", "") == syscall.ENOTSUP { if Setxattr(path, "user.test", "") == unix.ENOTSUP {
return false return false
} }
return true return true

View File

@ -5,12 +5,14 @@ package main
import ( import (
"os" "os"
"os/signal" "os/signal"
"syscall" "syscall" // only for Signal
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/opencontainers/runc/libcontainer" "github.com/opencontainers/runc/libcontainer"
"github.com/opencontainers/runc/libcontainer/system" "github.com/opencontainers/runc/libcontainer/system"
"github.com/opencontainers/runc/libcontainer/utils" "github.com/opencontainers/runc/libcontainer/utils"
"golang.org/x/sys/unix"
) )
const signalBufferSize = 2048 const signalBufferSize = 2048
@ -76,9 +78,9 @@ func (h *signalHandler) forward(process *libcontainer.Process, tty *tty, detach
tty.resize() tty.resize()
for s := range h.signals { for s := range h.signals {
switch s { switch s {
case syscall.SIGWINCH: case unix.SIGWINCH:
tty.resize() tty.resize()
case syscall.SIGCHLD: case unix.SIGCHLD:
exits, err := h.reap() exits, err := h.reap()
if err != nil { if err != nil {
logrus.Error(err) logrus.Error(err)
@ -101,7 +103,7 @@ func (h *signalHandler) forward(process *libcontainer.Process, tty *tty, detach
} }
default: default:
logrus.Debugf("sending signal to process %s", s) logrus.Debugf("sending signal to process %s", s)
if err := syscall.Kill(pid1, s.(syscall.Signal)); err != nil { if err := unix.Kill(pid1, s.(syscall.Signal)); err != nil {
logrus.Error(err) logrus.Error(err)
} }
} }
@ -113,13 +115,13 @@ func (h *signalHandler) forward(process *libcontainer.Process, tty *tty, detach
// then returns all exits to the main event loop for further processing. // then returns all exits to the main event loop for further processing.
func (h *signalHandler) reap() (exits []exit, err error) { func (h *signalHandler) reap() (exits []exit, err error) {
var ( var (
ws syscall.WaitStatus ws unix.WaitStatus
rus syscall.Rusage rus unix.Rusage
) )
for { for {
pid, err := syscall.Wait4(-1, &ws, syscall.WNOHANG, &rus) pid, err := unix.Wait4(-1, &ws, unix.WNOHANG, &rus)
if err != nil { if err != nil {
if err == syscall.ECHILD { if err == unix.ECHILD {
return exits, nil return exits, nil
} }
return nil, err return nil, err