зеркало из https://github.com/microsoft/docker.git
Merge pull request #11333 from crosbymichael/upldate-libcontainer-mar-11
Update libcontainer to aa10040b570386c1ae311c6245b
This commit is contained in:
Коммит
586f75d61c
|
@ -68,7 +68,7 @@ if [ "$1" = '--go' ]; then
|
|||
mv tmp-tar src/code.google.com/p/go/src/pkg/archive/tar
|
||||
fi
|
||||
|
||||
clone git github.com/docker/libcontainer dd3cb8822352fd4acc0b8b426bd86e47e98f6853
|
||||
clone git github.com/docker/libcontainer aa10040b570386c1ae311c6245b9e21295b2b83a
|
||||
# see src/github.com/docker/libcontainer/update-vendor.sh which is the "source of truth" for libcontainer deps (just like this file)
|
||||
rm -rf src/github.com/docker/libcontainer/vendor
|
||||
eval "$(grep '^clone ' src/github.com/docker/libcontainer/update-vendor.sh | grep -v 'github.com/codegangsta/cli')"
|
||||
|
|
|
@ -54,12 +54,10 @@ func getCgroupRoot() (string, error) {
|
|||
return cgroupRoot, nil
|
||||
}
|
||||
|
||||
// we can pick any subsystem to find the root
|
||||
cpuRoot, err := cgroups.FindCgroupMountpoint("cpu")
|
||||
root, err := cgroups.FindCgroupMountpointDir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
root := filepath.Dir(cpuRoot)
|
||||
|
||||
if _, err := os.Stat(root); err != nil {
|
||||
return "", err
|
||||
|
@ -231,6 +229,12 @@ func (raw *data) parent(subsystem string) (string, error) {
|
|||
}
|
||||
|
||||
func (raw *data) path(subsystem string) (string, error) {
|
||||
_, err := cgroups.FindCgroupMountpoint(subsystem)
|
||||
// If we didn't mount the subsystem, there is no point we make the path.
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// If the cgroup name/path is absolute do not look relative to the cgroup of the init process.
|
||||
if filepath.IsAbs(raw.cgroup) {
|
||||
path := filepath.Join(raw.root, subsystem, raw.cgroup)
|
||||
|
|
|
@ -17,8 +17,12 @@ type BlkioGroup struct {
|
|||
|
||||
func (s *BlkioGroup) Apply(d *data) error {
|
||||
dir, err := d.join("blkio")
|
||||
if err != nil && !cgroups.IsNotFound(err) {
|
||||
return err
|
||||
if err != nil {
|
||||
if cgroups.IsNotFound(err) {
|
||||
return nil
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.Set(dir, d.c); err != nil {
|
||||
|
|
|
@ -18,7 +18,11 @@ func (s *CpuGroup) Apply(d *data) error {
|
|||
// on a container basis
|
||||
dir, err := d.join("cpu")
|
||||
if err != nil {
|
||||
return err
|
||||
if cgroups.IsNotFound(err) {
|
||||
return nil
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.Set(dir, d.c); err != nil {
|
||||
|
|
|
@ -17,7 +17,11 @@ type CpusetGroup struct {
|
|||
func (s *CpusetGroup) Apply(d *data) error {
|
||||
dir, err := d.path("cpuset")
|
||||
if err != nil {
|
||||
return err
|
||||
if cgroups.IsNotFound(err) {
|
||||
return nil
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return s.ApplyDir(dir, d.c, d.pid)
|
||||
}
|
||||
|
|
|
@ -11,7 +11,11 @@ type DevicesGroup struct {
|
|||
func (s *DevicesGroup) Apply(d *data) error {
|
||||
dir, err := d.join("devices")
|
||||
if err != nil {
|
||||
return err
|
||||
if cgroups.IsNotFound(err) {
|
||||
return nil
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.Set(dir, d.c); err != nil {
|
||||
|
|
|
@ -25,7 +25,7 @@ func TestDevicesSetAllow(t *testing.T) {
|
|||
defer helper.cleanup()
|
||||
|
||||
helper.writeFileContents(map[string]string{
|
||||
"device.deny": "a",
|
||||
"devices.deny": "a",
|
||||
})
|
||||
|
||||
helper.CgroupData.c.AllowAllDevices = false
|
||||
|
@ -35,8 +35,6 @@ func TestDevicesSetAllow(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// FIXME: this doesn't make sence, the file devices.allow under real cgroupfs
|
||||
// is not allowed to read. Our test path don't have cgroupfs mounted.
|
||||
value, err := getCgroupParamString(helper.CgroupPath, "devices.allow")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse devices.allow - %s", err)
|
||||
|
|
|
@ -13,8 +13,12 @@ type FreezerGroup struct {
|
|||
|
||||
func (s *FreezerGroup) Apply(d *data) error {
|
||||
dir, err := d.join("freezer")
|
||||
if err != nil && !cgroups.IsNotFound(err) {
|
||||
return err
|
||||
if err != nil {
|
||||
if cgroups.IsNotFound(err) {
|
||||
return nil
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.Set(dir, d.c); err != nil {
|
||||
|
|
|
@ -16,9 +16,12 @@ type MemoryGroup struct {
|
|||
|
||||
func (s *MemoryGroup) Apply(d *data) error {
|
||||
dir, err := d.join("memory")
|
||||
// only return an error for memory if it was specified
|
||||
if err != nil && (d.c.Memory != 0 || d.c.MemoryReservation != 0 || d.c.MemorySwap != 0) {
|
||||
return err
|
||||
if err != nil {
|
||||
if cgroups.IsNotFound(err) {
|
||||
return nil
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
|
|
|
@ -55,6 +55,63 @@ func TestMemorySetMemory(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestMemorySetMemoryswap(t *testing.T) {
|
||||
helper := NewCgroupTestUtil("memory", t)
|
||||
defer helper.cleanup()
|
||||
|
||||
const (
|
||||
memoryswapBefore = 314572800 // 300M
|
||||
memoryswapAfter = 524288000 // 500M
|
||||
)
|
||||
|
||||
helper.writeFileContents(map[string]string{
|
||||
"memory.memsw.limit_in_bytes": strconv.Itoa(memoryswapBefore),
|
||||
})
|
||||
|
||||
helper.CgroupData.c.MemorySwap = memoryswapAfter
|
||||
memory := &MemoryGroup{}
|
||||
if err := memory.Set(helper.CgroupPath, helper.CgroupData.c); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
value, err := getCgroupParamUint(helper.CgroupPath, "memory.memsw.limit_in_bytes")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse memory.memsw.limit_in_bytes - %s", err)
|
||||
}
|
||||
if value != memoryswapAfter {
|
||||
t.Fatal("Got the wrong value, set memory.memsw.limit_in_bytes failed.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMemorySetMemoryswapDefault(t *testing.T) {
|
||||
helper := NewCgroupTestUtil("memory", t)
|
||||
defer helper.cleanup()
|
||||
|
||||
const (
|
||||
memoryBefore = 209715200 // 200M
|
||||
memoryAfter = 314572800 // 300M
|
||||
memoryswapAfter = 629145600 // 300M*2
|
||||
)
|
||||
|
||||
helper.writeFileContents(map[string]string{
|
||||
"memory.limit_in_bytes": strconv.Itoa(memoryBefore),
|
||||
})
|
||||
|
||||
helper.CgroupData.c.Memory = memoryAfter
|
||||
memory := &MemoryGroup{}
|
||||
if err := memory.Set(helper.CgroupPath, helper.CgroupData.c); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
value, err := getCgroupParamUint(helper.CgroupPath, "memory.memsw.limit_in_bytes")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse memory.memsw.limit_in_bytes - %s", err)
|
||||
}
|
||||
if value != memoryswapAfter {
|
||||
t.Fatal("Got the wrong value, set memory.memsw.limit_in_bytes failed.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMemoryStats(t *testing.T) {
|
||||
helper := NewCgroupTestUtil("memory", t)
|
||||
defer helper.cleanup()
|
||||
|
|
|
@ -6,9 +6,9 @@ Creates a mock of the cgroup filesystem for the duration of the test.
|
|||
package fs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/libcontainer/configs"
|
||||
|
@ -31,12 +31,12 @@ func NewCgroupTestUtil(subsystem string, t *testing.T) *cgroupTestUtil {
|
|||
d := &data{
|
||||
c: &configs.Cgroup{},
|
||||
}
|
||||
tempDir, err := ioutil.TempDir("", fmt.Sprintf("%s_cgroup_test", subsystem))
|
||||
tempDir, err := ioutil.TempDir("", "cgroup_test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
d.root = tempDir
|
||||
testCgroupPath, err := d.path(subsystem)
|
||||
testCgroupPath := filepath.Join(d.root, subsystem)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -34,6 +34,21 @@ func FindCgroupMountpoint(subsystem string) (string, error) {
|
|||
return "", NewNotFoundError(subsystem)
|
||||
}
|
||||
|
||||
func FindCgroupMountpointDir() (string, error) {
|
||||
mounts, err := mount.GetMounts()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, mount := range mounts {
|
||||
if mount.Fstype == "cgroup" {
|
||||
return filepath.Dir(mount.Mountpoint), nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", NewNotFoundError("cgroup")
|
||||
}
|
||||
|
||||
type Mount struct {
|
||||
Mountpoint string
|
||||
Subsystems []string
|
||||
|
|
|
@ -1,25 +1,12 @@
|
|||
// +build linux
|
||||
// +build linux,!gccgo
|
||||
|
||||
package nsenter
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -Wall
|
||||
extern void nsexec();
|
||||
void __attribute__((constructor)) init() {
|
||||
void __attribute__((constructor)) init(void) {
|
||||
nsexec();
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
// AlwaysFalse is here to stay false
|
||||
// (and be exported so the compiler doesn't optimize out its reference)
|
||||
var AlwaysFalse bool
|
||||
|
||||
func init() {
|
||||
if AlwaysFalse {
|
||||
// by referencing this C init() in a noop test, it will ensure the compiler
|
||||
// links in the C function.
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65134
|
||||
C.init()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
// +build linux,gccgo
|
||||
|
||||
package nsenter
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -Wall
|
||||
extern void nsexec();
|
||||
void __attribute__((constructor)) init(void) {
|
||||
nsexec();
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
// AlwaysFalse is here to stay false
|
||||
// (and be exported so the compiler doesn't optimize out its reference)
|
||||
var AlwaysFalse bool
|
||||
|
||||
func init() {
|
||||
if AlwaysFalse {
|
||||
// by referencing this C init() in a noop test, it will ensure the compiler
|
||||
// links in the C function.
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65134
|
||||
C.init()
|
||||
}
|
||||
}
|
|
@ -104,6 +104,10 @@ func mount(m *configs.Mount, rootfs, mountLabel string) error {
|
|||
if err := os.MkdirAll(dest, 0755); err != nil && !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
if m.Device == "mqueue" {
|
||||
// mqueue should not be labeled, otherwise the mount will fail
|
||||
data = ""
|
||||
}
|
||||
return syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags), data)
|
||||
case "bind":
|
||||
stat, err := os.Stat(m.Source)
|
||||
|
|
|
@ -37,8 +37,8 @@ var (
|
|||
spaceRegex = regexp.MustCompile(`^([^=]+) (.*)$`)
|
||||
mcsList = make(map[string]bool)
|
||||
selinuxfs = "unknown"
|
||||
selinuxEnabled = false
|
||||
selinuxEnabledChecked = false
|
||||
selinuxEnabled = false // Stores whether selinux is currently enabled
|
||||
selinuxEnabledChecked = false // Stores whether selinux enablement has been checked or established yet
|
||||
)
|
||||
|
||||
type SELinuxContext map[string]string
|
||||
|
@ -48,6 +48,11 @@ func SetDisabled() {
|
|||
selinuxEnabled, selinuxEnabledChecked = false, true
|
||||
}
|
||||
|
||||
// getSelinuxMountPoint returns the path to the mountpoint of an selinuxfs
|
||||
// filesystem or an empty string if no mountpoint is found. Selinuxfs is
|
||||
// a proc-like pseudo-filesystem that exposes the selinux policy API to
|
||||
// processes. The existence of an selinuxfs mount is used to determine
|
||||
// whether selinux is currently enabled or not.
|
||||
func getSelinuxMountPoint() string {
|
||||
if selinuxfs != "unknown" {
|
||||
return selinuxfs
|
||||
|
@ -74,6 +79,7 @@ func getSelinuxMountPoint() string {
|
|||
return selinuxfs
|
||||
}
|
||||
|
||||
// SelinuxEnabled returns whether selinux is currently enabled.
|
||||
func SelinuxEnabled() bool {
|
||||
if selinuxEnabledChecked {
|
||||
return selinuxEnabled
|
||||
|
@ -145,11 +151,12 @@ func readCon(name string) (string, error) {
|
|||
return val, err
|
||||
}
|
||||
|
||||
// Setfilecon sets the SELinux label for this path or returns an error.
|
||||
func Setfilecon(path string, scon string) error {
|
||||
return system.Lsetxattr(path, xattrNameSelinux, []byte(scon), 0)
|
||||
}
|
||||
|
||||
// Return the SELinux label for this path
|
||||
// Getfilecon returns the SELinux label for this path or returns an error.
|
||||
func Getfilecon(path string) (string, error) {
|
||||
con, err := system.Lgetxattr(path, xattrNameSelinux)
|
||||
return string(con), err
|
||||
|
@ -163,11 +170,12 @@ func Getfscreatecon() (string, error) {
|
|||
return readCon(fmt.Sprintf("/proc/self/task/%d/attr/fscreate", syscall.Gettid()))
|
||||
}
|
||||
|
||||
// Return the SELinux label of the current process thread.
|
||||
// Getcon returns the SELinux label of the current process thread, or an error.
|
||||
func Getcon() (string, error) {
|
||||
return readCon(fmt.Sprintf("/proc/self/task/%d/attr/current", syscall.Gettid()))
|
||||
}
|
||||
|
||||
// Getpidcon returns the SELinux label of the given pid, or an error.
|
||||
func Getpidcon(pid int) (string, error) {
|
||||
return readCon(fmt.Sprintf("/proc/%d/attr/current", pid))
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче