Merge pull request #1476 from derekwaynecarr/update-godeps

Fix running cAdvisor in container on RHEL systems
This commit is contained in:
Derek Carr 2016-09-22 16:26:42 -04:00 committed by GitHub
commit 22695f92ea
27 changed files with 274 additions and 270 deletions

64
Godeps/Godeps.json generated
View File

@ -337,83 +337,83 @@
}, },
{ {
"ImportPath": "github.com/opencontainers/runc/libcontainer", "ImportPath": "github.com/opencontainers/runc/libcontainer",
"Comment": "v1.0.0-rc1-71-g4dedd09", "Comment": "v1.0.0-rc1-224-g5653ced",
"Rev": "4dedd0939638fc27a609de1cb37e0666b3cf2079" "Rev": "5653ced544b1fa9d9623f12aaf9601bf1aefc013"
}, },
{ {
"ImportPath": "github.com/opencontainers/runc/libcontainer/apparmor", "ImportPath": "github.com/opencontainers/runc/libcontainer/apparmor",
"Comment": "v1.0.0-rc1-71-g4dedd09", "Comment": "v1.0.0-rc1-224-g5653ced",
"Rev": "4dedd0939638fc27a609de1cb37e0666b3cf2079" "Rev": "5653ced544b1fa9d9623f12aaf9601bf1aefc013"
}, },
{ {
"ImportPath": "github.com/opencontainers/runc/libcontainer/cgroups", "ImportPath": "github.com/opencontainers/runc/libcontainer/cgroups",
"Comment": "v1.0.0-rc1-71-g4dedd09", "Comment": "v1.0.0-rc1-224-g5653ced",
"Rev": "4dedd0939638fc27a609de1cb37e0666b3cf2079" "Rev": "5653ced544b1fa9d9623f12aaf9601bf1aefc013"
}, },
{ {
"ImportPath": "github.com/opencontainers/runc/libcontainer/cgroups/fs", "ImportPath": "github.com/opencontainers/runc/libcontainer/cgroups/fs",
"Comment": "v1.0.0-rc1-71-g4dedd09", "Comment": "v1.0.0-rc1-224-g5653ced",
"Rev": "4dedd0939638fc27a609de1cb37e0666b3cf2079" "Rev": "5653ced544b1fa9d9623f12aaf9601bf1aefc013"
}, },
{ {
"ImportPath": "github.com/opencontainers/runc/libcontainer/cgroups/systemd", "ImportPath": "github.com/opencontainers/runc/libcontainer/cgroups/systemd",
"Comment": "v1.0.0-rc1-71-g4dedd09", "Comment": "v1.0.0-rc1-224-g5653ced",
"Rev": "4dedd0939638fc27a609de1cb37e0666b3cf2079" "Rev": "5653ced544b1fa9d9623f12aaf9601bf1aefc013"
}, },
{ {
"ImportPath": "github.com/opencontainers/runc/libcontainer/configs", "ImportPath": "github.com/opencontainers/runc/libcontainer/configs",
"Comment": "v1.0.0-rc1-71-g4dedd09", "Comment": "v1.0.0-rc1-224-g5653ced",
"Rev": "4dedd0939638fc27a609de1cb37e0666b3cf2079" "Rev": "5653ced544b1fa9d9623f12aaf9601bf1aefc013"
}, },
{ {
"ImportPath": "github.com/opencontainers/runc/libcontainer/configs/validate", "ImportPath": "github.com/opencontainers/runc/libcontainer/configs/validate",
"Comment": "v1.0.0-rc1-71-g4dedd09", "Comment": "v1.0.0-rc1-224-g5653ced",
"Rev": "4dedd0939638fc27a609de1cb37e0666b3cf2079" "Rev": "5653ced544b1fa9d9623f12aaf9601bf1aefc013"
}, },
{ {
"ImportPath": "github.com/opencontainers/runc/libcontainer/criurpc", "ImportPath": "github.com/opencontainers/runc/libcontainer/criurpc",
"Comment": "v1.0.0-rc1-71-g4dedd09", "Comment": "v1.0.0-rc1-224-g5653ced",
"Rev": "4dedd0939638fc27a609de1cb37e0666b3cf2079" "Rev": "5653ced544b1fa9d9623f12aaf9601bf1aefc013"
}, },
{ {
"ImportPath": "github.com/opencontainers/runc/libcontainer/keys", "ImportPath": "github.com/opencontainers/runc/libcontainer/keys",
"Comment": "v1.0.0-rc1-71-g4dedd09", "Comment": "v1.0.0-rc1-224-g5653ced",
"Rev": "4dedd0939638fc27a609de1cb37e0666b3cf2079" "Rev": "5653ced544b1fa9d9623f12aaf9601bf1aefc013"
}, },
{ {
"ImportPath": "github.com/opencontainers/runc/libcontainer/label", "ImportPath": "github.com/opencontainers/runc/libcontainer/label",
"Comment": "v1.0.0-rc1-71-g4dedd09", "Comment": "v1.0.0-rc1-224-g5653ced",
"Rev": "4dedd0939638fc27a609de1cb37e0666b3cf2079" "Rev": "5653ced544b1fa9d9623f12aaf9601bf1aefc013"
}, },
{ {
"ImportPath": "github.com/opencontainers/runc/libcontainer/seccomp", "ImportPath": "github.com/opencontainers/runc/libcontainer/seccomp",
"Comment": "v1.0.0-rc1-71-g4dedd09", "Comment": "v1.0.0-rc1-224-g5653ced",
"Rev": "4dedd0939638fc27a609de1cb37e0666b3cf2079" "Rev": "5653ced544b1fa9d9623f12aaf9601bf1aefc013"
}, },
{ {
"ImportPath": "github.com/opencontainers/runc/libcontainer/selinux", "ImportPath": "github.com/opencontainers/runc/libcontainer/selinux",
"Comment": "v1.0.0-rc1-71-g4dedd09", "Comment": "v1.0.0-rc1-224-g5653ced",
"Rev": "4dedd0939638fc27a609de1cb37e0666b3cf2079" "Rev": "5653ced544b1fa9d9623f12aaf9601bf1aefc013"
}, },
{ {
"ImportPath": "github.com/opencontainers/runc/libcontainer/stacktrace", "ImportPath": "github.com/opencontainers/runc/libcontainer/stacktrace",
"Comment": "v1.0.0-rc1-71-g4dedd09", "Comment": "v1.0.0-rc1-224-g5653ced",
"Rev": "4dedd0939638fc27a609de1cb37e0666b3cf2079" "Rev": "5653ced544b1fa9d9623f12aaf9601bf1aefc013"
}, },
{ {
"ImportPath": "github.com/opencontainers/runc/libcontainer/system", "ImportPath": "github.com/opencontainers/runc/libcontainer/system",
"Comment": "v1.0.0-rc1-71-g4dedd09", "Comment": "v1.0.0-rc1-224-g5653ced",
"Rev": "4dedd0939638fc27a609de1cb37e0666b3cf2079" "Rev": "5653ced544b1fa9d9623f12aaf9601bf1aefc013"
}, },
{ {
"ImportPath": "github.com/opencontainers/runc/libcontainer/user", "ImportPath": "github.com/opencontainers/runc/libcontainer/user",
"Comment": "v1.0.0-rc1-71-g4dedd09", "Comment": "v1.0.0-rc1-224-g5653ced",
"Rev": "4dedd0939638fc27a609de1cb37e0666b3cf2079" "Rev": "5653ced544b1fa9d9623f12aaf9601bf1aefc013"
}, },
{ {
"ImportPath": "github.com/opencontainers/runc/libcontainer/utils", "ImportPath": "github.com/opencontainers/runc/libcontainer/utils",
"Comment": "v1.0.0-rc1-71-g4dedd09", "Comment": "v1.0.0-rc1-224-g5653ced",
"Rev": "4dedd0939638fc27a609de1cb37e0666b3cf2079" "Rev": "5653ced544b1fa9d9623f12aaf9601bf1aefc013"
}, },
{ {
"ImportPath": "github.com/pborman/uuid", "ImportPath": "github.com/pborman/uuid",

View File

@ -45,7 +45,7 @@ type CgroupSubsystems struct {
// Get information about the cgroup subsystems. // Get information about the cgroup subsystems.
func GetCgroupSubsystems() (CgroupSubsystems, error) { func GetCgroupSubsystems() (CgroupSubsystems, error) {
// Get all cgroup mounts. // Get all cgroup mounts.
allCgroups, err := cgroups.GetCgroupMounts() allCgroups, err := cgroups.GetCgroupMounts(true)
if err != nil { if err != nil {
return CgroupSubsystems{}, err return CgroupSubsystems{}, err
} }

View File

@ -77,7 +77,7 @@ config := &configs.Config{
Parent: "system", Parent: "system",
Resources: &configs.Resources{ Resources: &configs.Resources{
MemorySwappiness: nil, MemorySwappiness: nil,
AllowAllDevices: false, AllowAllDevices: nil,
AllowedDevices: configs.DefaultAllowedDevices, AllowedDevices: configs.DefaultAllowedDevices,
}, },
}, },

View File

@ -71,7 +71,6 @@ that are required for executing a container's process.
| /dev/tty | 0666 | rwm | | /dev/tty | 0666 | rwm |
| /dev/random | 0666 | rwm | | /dev/random | 0666 | rwm |
| /dev/urandom | 0666 | rwm | | /dev/urandom | 0666 | rwm |
| /dev/fuse | 0666 | rwm |
**ptmx** **ptmx**

View File

@ -37,7 +37,7 @@ type Manager interface {
// restore the object later. // restore the object later.
GetPaths() map[string]string GetPaths() map[string]string
// Set the cgroup as configured. // Sets the cgroup as configured.
Set(container *configs.Config) error Set(container *configs.Config) error
} }

View File

@ -9,7 +9,6 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strconv"
"sync" "sync"
"github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups"
@ -33,7 +32,6 @@ var (
&FreezerGroup{}, &FreezerGroup{},
&NameGroup{GroupName: "name=systemd", Join: true}, &NameGroup{GroupName: "name=systemd", Join: true},
} }
CgroupProcesses = "cgroup.procs"
HugePageSizes, _ = cgroups.GetHugePageSize() HugePageSizes, _ = cgroups.GetHugePageSize()
) )
@ -106,6 +104,8 @@ func (m *Manager) Apply(pid int) (err error) {
if m.Cgroups == nil { if m.Cgroups == nil {
return nil return nil
} }
m.mu.Lock()
defer m.mu.Unlock()
var c = m.Cgroups var c = m.Cgroups
@ -130,8 +130,6 @@ func (m *Manager) Apply(pid int) (err error) {
return cgroups.EnterPid(m.Paths, pid) return cgroups.EnterPid(m.Paths, pid)
} }
m.mu.Lock()
defer m.mu.Unlock()
paths := make(map[string]string) paths := make(map[string]string)
for _, sys := range subsystems { for _, sys := range subsystems {
if err := sys.Apply(d); err != nil { if err := sys.Apply(d); err != nil {
@ -192,18 +190,15 @@ func (m *Manager) GetStats() (*cgroups.Stats, error) {
} }
func (m *Manager) Set(container *configs.Config) error { func (m *Manager) Set(container *configs.Config) error {
for _, sys := range subsystems { // If Paths are set, then we are just joining cgroups paths
// Generate fake cgroup data. // and there is no need to set any values.
d, err := getCgroupData(container.Cgroups, -1) if m.Cgroups.Paths != nil {
if err != nil { return nil
return err }
}
// Get the path, but don't error out if the cgroup wasn't found.
path, err := d.path(sys.Name())
if err != nil && !cgroups.IsNotFound(err) {
return err
}
paths := m.GetPaths()
for _, sys := range subsystems {
path := paths[sys.Name()]
if err := sys.Set(path, container.Cgroups); err != nil { if err := sys.Set(path, container.Cgroups); err != nil {
return err return err
} }
@ -220,14 +215,8 @@ func (m *Manager) Set(container *configs.Config) error {
// Freeze toggles the container's freezer cgroup depending on the state // Freeze toggles the container's freezer cgroup depending on the state
// provided // provided
func (m *Manager) Freeze(state configs.FreezerState) error { func (m *Manager) Freeze(state configs.FreezerState) error {
d, err := getCgroupData(m.Cgroups, 0) paths := m.GetPaths()
if err != nil { dir := paths["freezer"]
return err
}
dir, err := d.path("freezer")
if err != nil {
return err
}
prevState := m.Cgroups.Resources.Freezer prevState := m.Cgroups.Resources.Freezer
m.Cgroups.Resources.Freezer = state m.Cgroups.Resources.Freezer = state
freezer, err := subsystems.Get("freezer") freezer, err := subsystems.Get("freezer")
@ -243,28 +232,13 @@ func (m *Manager) Freeze(state configs.FreezerState) error {
} }
func (m *Manager) GetPids() ([]int, error) { func (m *Manager) GetPids() ([]int, error) {
dir, err := getCgroupPath(m.Cgroups) paths := m.GetPaths()
if err != nil { return cgroups.GetPids(paths["devices"])
return nil, err
}
return cgroups.GetPids(dir)
} }
func (m *Manager) GetAllPids() ([]int, error) { func (m *Manager) GetAllPids() ([]int, error) {
dir, err := getCgroupPath(m.Cgroups) paths := m.GetPaths()
if err != nil { return cgroups.GetAllPids(paths["devices"])
return nil, err
}
return cgroups.GetAllPids(dir)
}
func getCgroupPath(c *configs.Cgroup) (string, error) {
d, err := getCgroupData(c, 0)
if err != nil {
return "", err
}
return d.path("devices")
} }
func getCgroupData(c *configs.Cgroup, pid int) (*cgroupData, error) { func getCgroupData(c *configs.Cgroup, pid int) (*cgroupData, error) {
@ -341,7 +315,7 @@ func (raw *cgroupData) join(subsystem string) (string, error) {
if err := os.MkdirAll(path, 0755); err != nil { if err := os.MkdirAll(path, 0755); err != nil {
return "", err return "", err
} }
if err := writeFile(path, CgroupProcesses, strconv.Itoa(raw.pid)); err != nil { if err := cgroups.WriteCgroupProc(path, raw.pid); err != nil {
return "", err return "", err
} }
return path, nil return path, nil

View File

@ -22,10 +22,48 @@ func (s *CpuGroup) Name() string {
func (s *CpuGroup) Apply(d *cgroupData) error { func (s *CpuGroup) Apply(d *cgroupData) error {
// We always want to join the cpu group, to allow fair cpu scheduling // We always want to join the cpu group, to allow fair cpu scheduling
// on a container basis // on a container basis
_, err := d.join("cpu") path, err := d.path("cpu")
if err != nil && !cgroups.IsNotFound(err) { if err != nil && !cgroups.IsNotFound(err) {
return err return err
} }
return s.ApplyDir(path, d.config, d.pid)
}
func (s *CpuGroup) ApplyDir(path string, cgroup *configs.Cgroup, pid int) error {
// This might happen if we have no cpu cgroup mounted.
// Just do nothing and don't fail.
if path == "" {
return nil
}
if err := os.MkdirAll(path, 0755); err != nil {
return err
}
// We should set the real-Time group scheduling settings before moving
// in the process because if the process is already in SCHED_RR mode
// and no RT bandwidth is set, adding it will fail.
if err := s.SetRtSched(path, cgroup); err != nil {
return err
}
// because we are not using d.join we need to place the pid into the procs file
// unlike the other subsystems
if err := cgroups.WriteCgroupProc(path, pid); err != nil {
return err
}
return nil
}
func (s *CpuGroup) SetRtSched(path string, cgroup *configs.Cgroup) error {
if cgroup.Resources.CpuRtPeriod != 0 {
if err := writeFile(path, "cpu.rt_period_us", strconv.FormatInt(cgroup.Resources.CpuRtPeriod, 10)); err != nil {
return err
}
}
if cgroup.Resources.CpuRtRuntime != 0 {
if err := writeFile(path, "cpu.rt_runtime_us", strconv.FormatInt(cgroup.Resources.CpuRtRuntime, 10)); err != nil {
return err
}
}
return nil return nil
} }
@ -45,15 +83,8 @@ func (s *CpuGroup) Set(path string, cgroup *configs.Cgroup) error {
return err return err
} }
} }
if cgroup.Resources.CpuRtPeriod != 0 { if err := s.SetRtSched(path, cgroup); err != nil {
if err := writeFile(path, "cpu.rt_period_us", strconv.FormatInt(cgroup.Resources.CpuRtPeriod, 10)); err != nil { return err
return err
}
}
if cgroup.Resources.CpuRtRuntime != 0 {
if err := writeFile(path, "cpu.rt_runtime_us", strconv.FormatInt(cgroup.Resources.CpuRtRuntime, 10)); err != nil {
return err
}
} }
return nil return nil

View File

@ -8,7 +8,6 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strconv"
"github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
@ -67,7 +66,7 @@ func (s *CpusetGroup) ApplyDir(dir string, cgroup *configs.Cgroup, pid int) erro
} }
// because we are not using d.join we need to place the pid into the procs file // because we are not using d.join we need to place the pid into the procs file
// unlike the other subsystems // unlike the other subsystems
if err := writeFile(dir, "cgroup.procs", strconv.Itoa(pid)); err != nil { if err := cgroups.WriteCgroupProc(dir, pid); err != nil {
return err return err
} }

View File

@ -43,21 +43,23 @@ func (s *DevicesGroup) Set(path string, cgroup *configs.Cgroup) error {
} }
return nil return nil
} }
if !cgroup.Resources.AllowAllDevices { if cgroup.Resources.AllowAllDevices != nil {
if err := writeFile(path, "devices.deny", "a"); err != nil { if *cgroup.Resources.AllowAllDevices == false {
return err if err := writeFile(path, "devices.deny", "a"); err != nil {
}
for _, dev := range cgroup.Resources.AllowedDevices {
if err := writeFile(path, "devices.allow", dev.CgroupString()); err != nil {
return err return err
} }
}
return nil
}
if err := writeFile(path, "devices.allow", "a"); err != nil { for _, dev := range cgroup.Resources.AllowedDevices {
return err if err := writeFile(path, "devices.allow", dev.CgroupString()); err != nil {
return err
}
}
return nil
}
if err := writeFile(path, "devices.allow", "a"); err != nil {
return err
}
} }
for _, dev := range cgroup.Resources.DeniedDevices { for _, dev := range cgroup.Resources.DeniedDevices {

View File

@ -5,16 +5,21 @@ package fs
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings" "strings"
"time" "syscall"
"github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/configs"
) )
const (
cgroupKernelMemoryLimit = "memory.kmem.limit_in_bytes"
)
type MemoryGroup struct { type MemoryGroup struct {
} }
@ -27,78 +32,68 @@ func (s *MemoryGroup) Apply(d *cgroupData) (err error) {
if err != nil && !cgroups.IsNotFound(err) { if err != nil && !cgroups.IsNotFound(err) {
return err return err
} }
// reset error. if memoryAssigned(d.config) {
err = nil if path != "" {
if path == "" { if err := os.MkdirAll(path, 0755); err != nil {
// Invalid input. return err
return fmt.Errorf("invalid path for memory cgroups: %+v", d) }
}
if err := EnableKernelMemoryAccounting(path); err != nil {
return err
}
} }
defer func() { defer func() {
if err != nil { if err != nil {
os.RemoveAll(path) os.RemoveAll(path)
} }
}() }()
if !cgroups.PathExists(path) {
if err = os.MkdirAll(path, 0755); err != nil {
return err
}
}
if memoryAssigned(d.config) {
// We have to set kernel memory here, as we can't change it once
// processes have been attached to the cgroup.
if err = s.SetKernelMemory(path, d.config); err != nil {
return err
}
}
// We need to join memory cgroup after set memory limits, because // We need to join memory cgroup after set memory limits, because
// kmem.limit_in_bytes can only be set when the cgroup is empty. // kmem.limit_in_bytes can only be set when the cgroup is empty.
if _, jerr := d.join("memory"); jerr != nil && !cgroups.IsNotFound(jerr) { _, err = d.join("memory")
err = jerr if err != nil && !cgroups.IsNotFound(err) {
return err return err
} }
return nil return nil
} }
func getModifyTime(path string) (time.Time, error) { func EnableKernelMemoryAccounting(path string) error {
stat, err := os.Stat(path) // Check if kernel memory is enabled
if err != nil { // We have to limit the kernel memory here as it won't be accounted at all
return time.Time{}, fmt.Errorf("failed to get memory cgroups creation time: %v", err) // until a limit is set on the cgroup and limit cannot be set once the
// cgroup has children, or if there are already tasks in the cgroup.
kernelMemoryLimit := int64(1)
if err := setKernelMemory(path, kernelMemoryLimit); err != nil {
return err
} }
return stat.ModTime(), nil kernelMemoryLimit = int64(-1)
if err := setKernelMemory(path, kernelMemoryLimit); err != nil {
return err
}
return nil
} }
func (s *MemoryGroup) SetKernelMemory(path string, cgroup *configs.Cgroup) error { func setKernelMemory(path string, kernelMemoryLimit int64) error {
// This has to be done separately because it has special if path == "" {
// constraints (it can only be initialized before setting up a return fmt.Errorf("no such directory for %s", cgroupKernelMemoryLimit)
// hierarchy or adding a task to the cgroups. However, if }
// sucessfully initialized, it can be updated anytime afterwards) if !cgroups.PathExists(filepath.Join(path, cgroupKernelMemoryLimit)) {
if cgroup.Resources.KernelMemory != 0 { // kernel memory is not enabled on the system so we should do nothing
// Is kmem.limit_in_bytes already set? return nil
// memory.kmem.max_usage_in_bytes is a read-only file. Use it to get cgroups creation time. }
kmemCreationTime, err := getModifyTime(filepath.Join(path, "memory.kmem.max_usage_in_bytes")) if err := ioutil.WriteFile(filepath.Join(path, cgroupKernelMemoryLimit), []byte(strconv.FormatInt(kernelMemoryLimit, 10)), 0700); err != nil {
if err != nil { // Check if the error number returned by the syscall is "EBUSY"
return err // The EBUSY signal is returned on attempts to write to the
} // memory.kmem.limit_in_bytes file if the cgroup has children or
kmemLimitsUpdateTime, err := getModifyTime(filepath.Join(path, "memory.kmem.limit_in_bytes")) // once tasks have been attached to the cgroup
if err != nil { if pathErr, ok := err.(*os.PathError); ok {
return err if errNo, ok := pathErr.Err.(syscall.Errno); ok {
} if errNo == syscall.EBUSY {
// kmem.limit_in_bytes has already been set if its update time is after that of creation time. return fmt.Errorf("failed to set %s, because either tasks have already joined this cgroup or it has children", cgroupKernelMemoryLimit)
// We use `!=` op instead of `>` because updates are losing precision compared to creation. }
kmemInitialized := !kmemLimitsUpdateTime.Equal(kmemCreationTime)
if !kmemInitialized {
// If there's already tasks in the cgroup, we can't change the limit either
tasks, err := getCgroupParamString(path, "tasks")
if err != nil {
return err
}
if tasks != "" {
return fmt.Errorf("cannot set kmem.limit_in_bytes after task have joined this cgroup")
} }
} }
if err := writeFile(path, "memory.kmem.limit_in_bytes", strconv.FormatInt(cgroup.Resources.KernelMemory, 10)); err != nil { return fmt.Errorf("failed to write %v to %v: %v", kernelMemoryLimit, cgroupKernelMemoryLimit, err)
return err
}
} }
return nil return nil
} }
@ -151,8 +146,10 @@ func (s *MemoryGroup) Set(path string, cgroup *configs.Cgroup) error {
return err return err
} }
if err := s.SetKernelMemory(path, cgroup); err != nil { if cgroup.Resources.KernelMemory != 0 {
return err if err := setKernelMemory(path, cgroup.Resources.KernelMemory); err != nil {
return err
}
} }
if cgroup.Resources.MemoryReservation != 0 { if cgroup.Resources.MemoryReservation != 0 {
@ -160,6 +157,7 @@ func (s *MemoryGroup) Set(path string, cgroup *configs.Cgroup) error {
return err return err
} }
} }
if cgroup.Resources.KernelMemoryTCP != 0 { if cgroup.Resources.KernelMemoryTCP != 0 {
if err := writeFile(path, "memory.kmem.tcp.limit_in_bytes", strconv.FormatInt(cgroup.Resources.KernelMemoryTCP, 10)); err != nil { if err := writeFile(path, "memory.kmem.tcp.limit_in_bytes", strconv.FormatInt(cgroup.Resources.KernelMemoryTCP, 10)); err != nil {
return err return err

View File

@ -388,6 +388,8 @@ func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) {
if err != nil { if err != nil {
return "", err return "", err
} }
// if pid 1 is systemd 226 or later, it will be in init.scope, not the root
initPath = strings.TrimSuffix(filepath.Clean(initPath), "init.scope")
slice := "system.slice" slice := "system.slice"
if c.Parent != "" { if c.Parent != "" {
@ -455,6 +457,11 @@ func (m *Manager) GetStats() (*cgroups.Stats, error) {
} }
func (m *Manager) Set(container *configs.Config) error { func (m *Manager) Set(container *configs.Config) error {
// If Paths are set, then we are just joining cgroups paths
// and there is no need to set any values.
if m.Cgroups.Paths != nil {
return nil
}
for _, sys := range subsystems { for _, sys := range subsystems {
// Get the subsystem path, but don't error out for not found cgroups. // Get the subsystem path, but don't error out for not found cgroups.
path, err := getSubsystemPath(container.Cgroups, sys.Name()) path, err := getSubsystemPath(container.Cgroups, sys.Name())
@ -485,5 +492,8 @@ func setKernelMemory(c *configs.Cgroup) error {
return err return err
} }
return os.MkdirAll(path, 0755) if err := os.MkdirAll(path, 0755); err != nil {
return err
}
return fs.EnableKernelMemoryAccounting(path)
} }

View File

@ -16,7 +16,10 @@ import (
"github.com/docker/go-units" "github.com/docker/go-units"
) )
const cgroupNamePrefix = "name=" const (
cgroupNamePrefix = "name="
CgroupProcesses = "cgroup.procs"
)
// https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt // https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt
func FindCgroupMountpoint(subsystem string) (string, error) { func FindCgroupMountpoint(subsystem string) (string, error) {
@ -136,7 +139,7 @@ func (m Mount) GetThisCgroupDir(cgroups map[string]string) (string, error) {
return getControllerPath(m.Subsystems[0], cgroups) return getControllerPath(m.Subsystems[0], cgroups)
} }
func getCgroupMountsHelper(ss map[string]bool, mi io.Reader) ([]Mount, error) { func getCgroupMountsHelper(ss map[string]bool, mi io.Reader, all bool) ([]Mount, error) {
res := make([]Mount, 0, len(ss)) res := make([]Mount, 0, len(ss))
scanner := bufio.NewScanner(mi) scanner := bufio.NewScanner(mi)
numFound := 0 numFound := 0
@ -163,7 +166,9 @@ func getCgroupMountsHelper(ss map[string]bool, mi io.Reader) ([]Mount, error) {
} else { } else {
m.Subsystems = append(m.Subsystems, opt) m.Subsystems = append(m.Subsystems, opt)
} }
numFound++ if !all {
numFound++
}
} }
res = append(res, m) res = append(res, m)
} }
@ -173,23 +178,25 @@ func getCgroupMountsHelper(ss map[string]bool, mi io.Reader) ([]Mount, error) {
return res, nil return res, nil
} }
func GetCgroupMounts() ([]Mount, error) { // GetCgroupMounts returns the mounts for the cgroup subsystems.
// all indicates whether to return just the first instance or all the mounts.
func GetCgroupMounts(all bool) ([]Mount, error) {
f, err := os.Open("/proc/self/mountinfo") f, err := os.Open("/proc/self/mountinfo")
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer f.Close() defer f.Close()
all, err := ParseCgroupFile("/proc/self/cgroup") allSubsystems, err := ParseCgroupFile("/proc/self/cgroup")
if err != nil { if err != nil {
return nil, err return nil, err
} }
allMap := make(map[string]bool) allMap := make(map[string]bool)
for s := range all { for s := range allSubsystems {
allMap[s] = true allMap[s] = true
} }
return getCgroupMountsHelper(allMap, f) return getCgroupMountsHelper(allMap, f, all)
} }
// GetAllSubsystems returns all the cgroup subsystems supported by the kernel // GetAllSubsystems returns all the cgroup subsystems supported by the kernel
@ -239,7 +246,7 @@ func GetInitCgroupDir(subsystem string) (string, error) {
} }
func readProcsFile(dir string) ([]int, error) { func readProcsFile(dir string) ([]int, error) {
f, err := os.Open(filepath.Join(dir, "cgroup.procs")) f, err := os.Open(filepath.Join(dir, CgroupProcesses))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -326,8 +333,7 @@ func PathExists(path string) bool {
func EnterPid(cgroupPaths map[string]string, pid int) error { func EnterPid(cgroupPaths map[string]string, pid int) error {
for _, path := range cgroupPaths { for _, path := range cgroupPaths {
if PathExists(path) { if PathExists(path) {
if err := ioutil.WriteFile(filepath.Join(path, "cgroup.procs"), if err := WriteCgroupProc(path, pid); err != nil {
[]byte(strconv.Itoa(pid)), 0700); err != nil {
return err return err
} }
} }
@ -396,7 +402,7 @@ func GetAllPids(path string) ([]int, error) {
// collect pids from all sub-cgroups // collect pids from all sub-cgroups
err := filepath.Walk(path, func(p string, info os.FileInfo, iErr error) error { err := filepath.Walk(path, func(p string, info os.FileInfo, iErr error) error {
dir, file := filepath.Split(p) dir, file := filepath.Split(p)
if file != "cgroup.procs" { if file != CgroupProcesses {
return nil return nil
} }
if iErr != nil { if iErr != nil {
@ -411,3 +417,20 @@ func GetAllPids(path string) ([]int, error) {
}) })
return pids, err return pids, err
} }
// WriteCgroupProc writes the specified pid into the cgroup's cgroup.procs file
func WriteCgroupProc(dir string, pid int) error {
// Normally dir should not be empty, one case is that cgroup subsystem
// is not mounted, we will get empty dir, and we want it fail here.
if dir == "" {
return fmt.Errorf("no such directory for %s", CgroupProcesses)
}
// Dont attach any pid to the cgroup if -1 is specified as a pid
if pid != -1 {
if err := ioutil.WriteFile(filepath.Join(dir, CgroupProcesses), []byte(strconv.Itoa(pid)), 0700); err != nil {
return fmt.Errorf("failed to write %v to %v: %v", pid, CgroupProcesses, err)
}
}
return nil
}

View File

@ -36,7 +36,7 @@ type Cgroup struct {
type Resources struct { type Resources struct {
// If this is true allow access to any kind of device within the container. If false, allow access only to devices explicitly listed in the allowed_devices list. // If this is true allow access to any kind of device within the container. If false, allow access only to devices explicitly listed in the allowed_devices list.
// Deprecated // Deprecated
AllowAllDevices bool `json:"allow_all_devices,omitempty"` AllowAllDevices *bool `json:"allow_all_devices,omitempty"`
// Deprecated // Deprecated
AllowedDevices []*Device `json:"allowed_devices,omitempty"` AllowedDevices []*Device `json:"allowed_devices,omitempty"`
// Deprecated // Deprecated
@ -120,5 +120,5 @@ type Resources struct {
NetPrioIfpriomap []*IfPrioMap `json:"net_prio_ifpriomap"` NetPrioIfpriomap []*IfPrioMap `json:"net_prio_ifpriomap"`
// Set class identifier for container's network packets // Set class identifier for container's network packets
NetClsClassid uint32 `json:"net_cls_classid"` NetClsClassid uint32 `json:"net_cls_classid_u"`
} }

View File

@ -300,29 +300,38 @@ func (c Command) Run(s HookState) error {
if err != nil { if err != nil {
return err return err
} }
var stdout, stderr bytes.Buffer
cmd := exec.Cmd{ cmd := exec.Cmd{
Path: c.Path, Path: c.Path,
Args: c.Args, Args: c.Args,
Env: c.Env, Env: c.Env,
Stdin: bytes.NewReader(b), Stdin: bytes.NewReader(b),
Stdout: &stdout,
Stderr: &stderr,
}
if err := cmd.Start(); err != nil {
return err
} }
errC := make(chan error, 1) errC := make(chan error, 1)
go func() { go func() {
out, err := cmd.CombinedOutput() err := cmd.Wait()
if err != nil { if err != nil {
err = fmt.Errorf("%s: %s", err, out) err = fmt.Errorf("error running hook: %v, stdout: %s, stderr: %s", err, stdout.String(), stderr.String())
} }
errC <- err errC <- err
}() }()
var timerCh <-chan time.Time
if c.Timeout != nil { if c.Timeout != nil {
select { timer := time.NewTimer(*c.Timeout)
case err := <-errC: defer timer.Stop()
return err timerCh = timer.C
case <-time.After(*c.Timeout): }
cmd.Process.Kill() select {
cmd.Wait() case err := <-errC:
return fmt.Errorf("hook ran past specified timeout of %.1fs", c.Timeout.Seconds()) return err
} case <-timerCh:
cmd.Process.Kill()
cmd.Wait()
return fmt.Errorf("hook ran past specified timeout of %.1fs", c.Timeout.Seconds())
} }
return <-errC
} }

View File

@ -107,19 +107,5 @@ var (
Permissions: "rwm", Permissions: "rwm",
}, },
}, DefaultSimpleDevices...) }, DefaultSimpleDevices...)
DefaultAutoCreatedDevices = append([]*Device{ DefaultAutoCreatedDevices = append([]*Device{}, DefaultSimpleDevices...)
{
// /dev/fuse is created but not allowed.
// This is to allow java to work. Because java
// Insists on there being a /dev/fuse
// https://github.com/docker/docker/issues/514
// https://github.com/docker/docker/issues/2393
//
Path: "/dev/fuse",
Type: 'c',
Major: 10,
Minor: 229,
Permissions: "rwm",
},
}, DefaultSimpleDevices...)
) )

View File

@ -75,8 +75,8 @@ type BaseContainer interface {
// Returns the current status of the container. // Returns the current status of the container.
// //
// errors: // errors:
// ContainerDestroyed - Container no longer exists, // ContainerNotExists - Container no longer exists,
// SystemError - System error. // Systemerror - System error.
Status() (Status, error) Status() (Status, error)
// State returns the current container's state information. // State returns the current container's state information.
@ -91,8 +91,8 @@ type BaseContainer interface {
// Returns the PIDs inside this container. The PIDs are in the namespace of the calling process. // Returns the PIDs inside this container. The PIDs are in the namespace of the calling process.
// //
// errors: // errors:
// ContainerDestroyed - Container no longer exists, // ContainerNotExists - Container no longer exists,
// SystemError - System error. // Systemerror - System error.
// //
// Some of the returned PIDs may no longer refer to processes in the Container, unless // Some of the returned PIDs may no longer refer to processes in the Container, unless
// the Container state is PAUSED in which case every PID in the slice is valid. // the Container state is PAUSED in which case every PID in the slice is valid.
@ -101,8 +101,8 @@ type BaseContainer interface {
// Returns statistics for the container. // Returns statistics for the container.
// //
// errors: // errors:
// ContainerDestroyed - Container no longer exists, // ContainerNotExists - Container no longer exists,
// SystemError - System error. // Systemerror - System error.
Stats() (*Stats, error) Stats() (*Stats, error)
// Set resources of container as configured // Set resources of container as configured
@ -117,7 +117,7 @@ type BaseContainer interface {
// start. You can track process lifecycle with passed Process structure. // start. You can track process lifecycle with passed Process structure.
// //
// errors: // errors:
// ContainerDestroyed - Container no longer exists, // ContainerNotExists - Container no longer exists,
// ConfigInvalid - config is invalid, // ConfigInvalid - config is invalid,
// ContainerPaused - Container is paused, // ContainerPaused - Container is paused,
// SystemError - System error. // SystemError - System error.
@ -128,7 +128,7 @@ type BaseContainer interface {
// opens the fifo after start returns. // opens the fifo after start returns.
// //
// errors: // errors:
// ContainerDestroyed - Container no longer exists, // ContainerNotExists - Container no longer exists,
// ConfigInvalid - config is invalid, // ConfigInvalid - config is invalid,
// ContainerPaused - Container is paused, // ContainerPaused - Container is paused,
// SystemError - System error. // SystemError - System error.

View File

@ -35,7 +35,6 @@ type linuxContainer struct {
root string root string
config *configs.Config config *configs.Config
cgroupManager cgroups.Manager cgroupManager cgroups.Manager
initPath string
initArgs []string initArgs []string
initProcess parentProcess initProcess parentProcess
initProcessStartTime string initProcessStartTime string
@ -86,13 +85,14 @@ type Container interface {
// Systemerror - System error. // Systemerror - System error.
Restore(process *Process, criuOpts *CriuOpts) error Restore(process *Process, criuOpts *CriuOpts) error
// If the Container state is RUNNING, sets the Container state to PAUSING and pauses // If the Container state is RUNNING or CREATED, sets the Container state to PAUSING and pauses
// the execution of any user processes. Asynchronously, when the container finished being paused the // the execution of any user processes. Asynchronously, when the container finished being paused the
// state is changed to PAUSED. // state is changed to PAUSED.
// If the Container state is PAUSED, do nothing. // If the Container state is PAUSED, do nothing.
// //
// errors: // errors:
// ContainerDestroyed - Container no longer exists, // ContainerNotExists - Container no longer exists,
// ContainerNotRunning - Container not running or created,
// Systemerror - System error. // Systemerror - System error.
Pause() error Pause() error
@ -101,7 +101,8 @@ type Container interface {
// If the Container state is RUNNING, do nothing. // If the Container state is RUNNING, do nothing.
// //
// errors: // errors:
// ContainerDestroyed - Container no longer exists, // ContainerNotExists - Container no longer exists,
// ContainerNotPaused - Container is not paused,
// Systemerror - System error. // Systemerror - System error.
Resume() error Resume() error
@ -308,10 +309,7 @@ func (c *linuxContainer) newParentProcess(p *Process, doInit bool) (parentProces
} }
func (c *linuxContainer) commandTemplate(p *Process, childPipe, rootDir *os.File) (*exec.Cmd, error) { func (c *linuxContainer) commandTemplate(p *Process, childPipe, rootDir *os.File) (*exec.Cmd, error) {
cmd := &exec.Cmd{ cmd := exec.Command(c.initArgs[0], c.initArgs[1:]...)
Path: c.initPath,
Args: c.initArgs,
}
cmd.Stdin = p.Stdin cmd.Stdin = p.Stdin
cmd.Stdout = p.Stdout cmd.Stdout = p.Stdout
cmd.Stderr = p.Stderr cmd.Stderr = p.Stderr
@ -447,7 +445,7 @@ func (c *linuxContainer) Pause() error {
c: c, c: c,
}) })
} }
return newGenericError(fmt.Errorf("container not running: %s", status), ContainerNotRunning) return newGenericError(fmt.Errorf("container not running or created: %s", status), ContainerNotRunning)
} }
func (c *linuxContainer) Resume() error { func (c *linuxContainer) Resume() error {
@ -1049,6 +1047,8 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc
}); err != nil { }); err != nil {
return err return err
} }
// create a timestamp indicating when the restored checkpoint was started
c.created = time.Now().UTC()
if _, err := c.updateState(r); err != nil { if _, err := c.updateState(r); err != nil {
return err return err
} }

View File

@ -6,7 +6,6 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"os" "os"
"os/exec"
"path/filepath" "path/filepath"
"regexp" "regexp"
"runtime/debug" "runtime/debug"
@ -33,32 +32,9 @@ var (
) )
// InitArgs returns an options func to configure a LinuxFactory with the // InitArgs returns an options func to configure a LinuxFactory with the
// provided init arguments. // provided init binary path and arguments.
func InitArgs(args ...string) func(*LinuxFactory) error { func InitArgs(args ...string) func(*LinuxFactory) error {
return func(l *LinuxFactory) error { return func(l *LinuxFactory) error {
name := args[0]
if filepath.Base(name) == name {
if lp, err := exec.LookPath(name); err == nil {
name = lp
}
} else {
abs, err := filepath.Abs(name)
if err != nil {
return err
}
name = abs
}
l.InitPath = "/proc/self/exe"
l.InitArgs = append([]string{name}, args[1:]...)
return nil
}
}
// InitPath returns an options func to configure a LinuxFactory with the
// provided absolute path to the init binary and arguements.
func InitPath(path string, args ...string) func(*LinuxFactory) error {
return func(l *LinuxFactory) error {
l.InitPath = path
l.InitArgs = args l.InitArgs = args
return nil return nil
} }
@ -122,10 +98,10 @@ func New(root string, options ...func(*LinuxFactory) error) (Factory, error) {
} }
l := &LinuxFactory{ l := &LinuxFactory{
Root: root, Root: root,
InitArgs: []string{"/proc/self/exe", "init"},
Validator: validate.New(), Validator: validate.New(),
CriuPath: "criu", CriuPath: "criu",
} }
InitArgs(os.Args[0], "init")(l)
Cgroupfs(l) Cgroupfs(l)
for _, opt := range options { for _, opt := range options {
if err := opt(l); err != nil { if err := opt(l); err != nil {
@ -140,9 +116,6 @@ type LinuxFactory struct {
// Root directory for the factory to store state. // Root directory for the factory to store state.
Root string Root string
// InitPath is the absolute path to the init binary.
InitPath string
// InitArgs are arguments for calling the init responsibilities for spawning // InitArgs are arguments for calling the init responsibilities for spawning
// a container. // a container.
InitArgs []string InitArgs []string
@ -202,7 +175,6 @@ func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, err
id: id, id: id,
root: containerRoot, root: containerRoot,
config: config, config: config,
initPath: l.InitPath,
initArgs: l.InitArgs, initArgs: l.InitArgs,
criuPath: l.CriuPath, criuPath: l.CriuPath,
cgroupManager: l.NewCgroupsManager(config.Cgroups, nil), cgroupManager: l.NewCgroupsManager(config.Cgroups, nil),
@ -216,7 +188,7 @@ func (l *LinuxFactory) Load(id string) (Container, error) {
return nil, newGenericError(fmt.Errorf("invalid root"), ConfigInvalid) return nil, newGenericError(fmt.Errorf("invalid root"), ConfigInvalid)
} }
containerRoot := filepath.Join(l.Root, id) containerRoot := filepath.Join(l.Root, id)
state, err := l.loadState(containerRoot) state, err := l.loadState(containerRoot, id)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -230,7 +202,6 @@ func (l *LinuxFactory) Load(id string) (Container, error) {
initProcessStartTime: state.InitProcessStartTime, initProcessStartTime: state.InitProcessStartTime,
id: id, id: id,
config: &state.Config, config: &state.Config,
initPath: l.InitPath,
initArgs: l.InitArgs, initArgs: l.InitArgs,
criuPath: l.CriuPath, criuPath: l.CriuPath,
cgroupManager: l.NewCgroupsManager(state.Config.Cgroups, state.CgroupPaths), cgroupManager: l.NewCgroupsManager(state.Config.Cgroups, state.CgroupPaths),
@ -302,11 +273,11 @@ func (l *LinuxFactory) StartInitialization() (err error) {
return i.Init() return i.Init()
} }
func (l *LinuxFactory) loadState(root string) (*State, error) { func (l *LinuxFactory) loadState(root, id string) (*State, error) {
f, err := os.Open(filepath.Join(root, stateFilename)) f, err := os.Open(filepath.Join(root, stateFilename))
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return nil, newGenericError(err, ContainerNotExists) return nil, newGenericError(fmt.Errorf("container %q does not exists", id), ContainerNotExists)
} }
return nil, newGenericError(err, SystemError) return nil, newGenericError(err, SystemError)
} }

View File

@ -67,9 +67,6 @@ func newSystemErrorWithCause(err error, cause string) Error {
// stack frames skipped. This is only to be called by the other functions for // stack frames skipped. This is only to be called by the other functions for
// formatting the error. // formatting the error.
func createSystemError(err error, cause string) Error { func createSystemError(err error, cause string) Error {
if le, ok := err.(Error); ok {
return le
}
gerr := &genericError{ gerr := &genericError{
Timestamp: time.Now(), Timestamp: time.Now(),
Err: err, Err: err,

View File

@ -144,7 +144,7 @@ func finalizeNamespace(config *initConfig) error {
} }
if config.Cwd != "" { if config.Cwd != "" {
if err := syscall.Chdir(config.Cwd); err != nil { if err := syscall.Chdir(config.Cwd); err != nil {
return err return fmt.Errorf("chdir to cwd (%q) set in config.json failed: %v", config.Cwd, err)
} }
} }
return nil return nil

View File

@ -1,6 +1,6 @@
// +build linux // +build linux
package keyctl package keys
import ( import (
"fmt" "fmt"

View File

@ -129,7 +129,7 @@ func Relabel(path string, fileLabel string, shared bool) error {
exclude_paths := map[string]bool{"/": true, "/usr": true, "/etc": true} exclude_paths := map[string]bool{"/": true, "/usr": true, "/etc": true}
if exclude_paths[path] { if exclude_paths[path] {
return fmt.Errorf("Relabeling of %s is not allowed", path) return fmt.Errorf("SELinux relabeling of %s is not allowed", path)
} }
if shared { if shared {
@ -137,7 +137,10 @@ func Relabel(path string, fileLabel string, shared bool) error {
c["level"] = "s0" c["level"] = "s0"
fileLabel = c.Get() fileLabel = c.Get()
} }
return selinux.Chcon(path, fileLabel, true) if err := selinux.Chcon(path, fileLabel, true); err != nil {
return fmt.Errorf("SELinux relabeling of %s is not allowed: %q", path, err)
}
return nil
} }
// GetPidLabel will return the label of the process running with the specified pid // GetPidLabel will return the label of the process running with the specified pid

View File

@ -32,7 +32,7 @@ type parentProcess interface {
// wait waits on the process returning the process state. // wait waits on the process returning the process state.
wait() (*os.ProcessState, error) wait() (*os.ProcessState, error)
// startTime return's the process start time. // startTime returns the process start time.
startTime() (string, error) startTime() (string, error)
signal(os.Signal) error signal(os.Signal) error
@ -356,7 +356,7 @@ loop:
} }
} }
if !sentRun { if !sentRun {
return newSystemErrorWithCause(ierr, "container init failed") return newSystemErrorWithCause(ierr, "container init")
} }
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"))

View File

@ -50,7 +50,7 @@ func setupRootfs(config *configs.Config, console *linuxConsole, pipe io.ReadWrit
} }
} }
if err := mountToRootfs(m, config.Rootfs, config.MountLabel); err != nil { if err := mountToRootfs(m, config.Rootfs, config.MountLabel); err != nil {
return newSystemErrorWithCausef(err, "mounting %q to rootfs %q", m.Destination, config.Rootfs) return newSystemErrorWithCausef(err, "mounting %q to rootfs %q at %q", m.Source, config.Rootfs, m.Destination)
} }
for _, postcmd := range m.PostmountCmds { for _, postcmd := range m.PostmountCmds {
@ -270,7 +270,7 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
} }
func getCgroupMounts(m *configs.Mount) ([]*configs.Mount, error) { func getCgroupMounts(m *configs.Mount) ([]*configs.Mount, error) {
mounts, err := cgroups.GetCgroupMounts() mounts, err := cgroups.GetCgroupMounts(false)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -320,6 +320,8 @@ func checkMountDestination(rootfs, dest string) error {
"/proc/diskstats", "/proc/diskstats",
"/proc/meminfo", "/proc/meminfo",
"/proc/stat", "/proc/stat",
"/proc/swaps",
"/proc/uptime",
"/proc/net/dev", "/proc/net/dev",
} }
for _, valid := range validDestinations { for _, valid := range validDestinations {

View File

@ -26,7 +26,7 @@ func (l *linuxSetnsInit) getSessionRingName() string {
func (l *linuxSetnsInit) Init() error { func (l *linuxSetnsInit) Init() error {
if !l.config.Config.NoNewKeyring { if !l.config.Config.NoNewKeyring {
// do not inherit the parent's session keyring // do not inherit the parent's session keyring
if _, err := keyctl.JoinSessionKeyring(l.getSessionRingName()); err != nil { if _, err := keys.JoinSessionKeyring(l.getSessionRingName()); err != nil {
return err return err
} }
} }

View File

@ -49,12 +49,12 @@ func (l *linuxStandardInit) Init() error {
ringname, keepperms, newperms := l.getSessionRingParams() ringname, keepperms, newperms := l.getSessionRingParams()
// do not inherit the parent's session keyring // do not inherit the parent's session keyring
sessKeyId, err := keyctl.JoinSessionKeyring(ringname) sessKeyId, err := keys.JoinSessionKeyring(ringname)
if err != nil { if err != nil {
return err return err
} }
// make session keyring searcheable // make session keyring searcheable
if err := keyctl.ModKeyringPerm(sessKeyId, keepperms, newperms); err != nil { if err := keys.ModKeyringPerm(sessKeyId, keepperms, newperms); err != nil {
return err return err
} }
} }

View File

@ -8,7 +8,7 @@ import (
// 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 := syscall.RawSyscall(syscall.SYS_SETUID32, uintptr(uid), 0, 0)
if e1 != 0 { if e1 != 0 {
err = e1 err = e1
} }