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:
parent
639454475c
commit
3d7cb4293c
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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),
|
||||||
},
|
},
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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())
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
18
signals.go
18
signals.go
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue