diff --git a/hack/vendor.sh b/hack/vendor.sh index 652126769a..7af22ea64e 100755 --- a/hack/vendor.sh +++ b/hack/vendor.sh @@ -59,7 +59,7 @@ rm -rf src/code.google.com/p/go mkdir -p src/code.google.com/p/go/src/pkg/archive mv tmp-tar src/code.google.com/p/go/src/pkg/archive/tar -clone git github.com/docker/libcontainer 29363e2d2d7b8f62a5f353be333758f83df540a9 +clone git github.com/docker/libcontainer db65c35051d05f3fb218a0e84a11267e0894fe0a # 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')" diff --git a/vendor/src/github.com/docker/libcontainer/cgroups/cgroups.go b/vendor/src/github.com/docker/libcontainer/cgroups/cgroups.go index 598454862b..567e9a6c16 100644 --- a/vendor/src/github.com/docker/libcontainer/cgroups/cgroups.go +++ b/vendor/src/github.com/docker/libcontainer/cgroups/cgroups.go @@ -1,15 +1,11 @@ package cgroups import ( - "errors" + "fmt" "github.com/docker/libcontainer/devices" ) -var ( - ErrNotFound = errors.New("mountpoint not found") -) - type FreezerState string const ( @@ -18,6 +14,29 @@ const ( Thawed FreezerState = "THAWED" ) +type NotFoundError struct { + Subsystem string +} + +func (e *NotFoundError) Error() string { + return fmt.Sprintf("mountpoint for %s not found", e.Subsystem) +} + +func NewNotFoundError(sub string) error { + return &NotFoundError{ + Subsystem: sub, + } +} + +func IsNotFound(err error) bool { + if err == nil { + return false + } + + _, ok := err.(*NotFoundError) + return ok +} + type Cgroup struct { Name string `json:"name,omitempty"` Parent string `json:"parent,omitempty"` // name of parent cgroup or slice diff --git a/vendor/src/github.com/docker/libcontainer/cgroups/fs/apply_raw.go b/vendor/src/github.com/docker/libcontainer/cgroups/fs/apply_raw.go index e20cdbb926..443dbb698b 100644 --- a/vendor/src/github.com/docker/libcontainer/cgroups/fs/apply_raw.go +++ b/vendor/src/github.com/docker/libcontainer/cgroups/fs/apply_raw.go @@ -76,7 +76,7 @@ func GetStats(c *cgroups.Cgroup) (*cgroups.Stats, error) { path, err := d.path(sysname) if err != nil { // Don't fail if a cgroup hierarchy was not found, just skip this subsystem - if err == cgroups.ErrNotFound { + if cgroups.IsNotFound(err) { continue } @@ -155,25 +155,45 @@ func (raw *data) parent(subsystem string) (string, error) { func (raw *data) Paths() (map[string]string, error) { paths := make(map[string]string) + for sysname := range subsystems { path, err := raw.path(sysname) if err != nil { + // Don't fail if a cgroup hierarchy was not found, just skip this subsystem + if cgroups.IsNotFound(err) { + continue + } + return nil, err } + paths[sysname] = path } + return paths, nil } func (raw *data) path(subsystem string) (string, error) { // If the cgroup name/path is absolute do not look relative to the cgroup of the init process. if filepath.IsAbs(raw.cgroup) { - return filepath.Join(raw.root, subsystem, raw.cgroup), nil + path := filepath.Join(raw.root, subsystem, raw.cgroup) + + if _, err := os.Stat(path); err != nil { + if os.IsNotExist(err) { + return "", cgroups.NewNotFoundError(subsystem) + } + + return "", err + } + + return path, nil } + parent, err := raw.parent(subsystem) if err != nil { return "", err } + return filepath.Join(parent, raw.cgroup), nil } diff --git a/vendor/src/github.com/docker/libcontainer/cgroups/fs/blkio.go b/vendor/src/github.com/docker/libcontainer/cgroups/fs/blkio.go index 38b8757727..f784d01151 100644 --- a/vendor/src/github.com/docker/libcontainer/cgroups/fs/blkio.go +++ b/vendor/src/github.com/docker/libcontainer/cgroups/fs/blkio.go @@ -16,9 +16,10 @@ type BlkioGroup struct { func (s *BlkioGroup) Set(d *data) error { // we just want to join this group even though we don't set anything - if _, err := d.join("blkio"); err != nil && err != cgroups.ErrNotFound { + if _, err := d.join("blkio"); err != nil && !cgroups.IsNotFound(err) { return err } + return nil } diff --git a/vendor/src/github.com/docker/libcontainer/cgroups/fs/cpuacct.go b/vendor/src/github.com/docker/libcontainer/cgroups/fs/cpuacct.go index 7761d4c283..853ab6bffd 100644 --- a/vendor/src/github.com/docker/libcontainer/cgroups/fs/cpuacct.go +++ b/vendor/src/github.com/docker/libcontainer/cgroups/fs/cpuacct.go @@ -27,9 +27,10 @@ type CpuacctGroup struct { func (s *CpuacctGroup) Set(d *data) error { // we just want to join this group even though we don't set anything - if _, err := d.join("cpuacct"); err != nil && err != cgroups.ErrNotFound { + if _, err := d.join("cpuacct"); err != nil && !cgroups.IsNotFound(err) { return err } + return nil } diff --git a/vendor/src/github.com/docker/libcontainer/cgroups/fs/freezer.go b/vendor/src/github.com/docker/libcontainer/cgroups/fs/freezer.go index db2a41ca34..c6b677fa95 100644 --- a/vendor/src/github.com/docker/libcontainer/cgroups/fs/freezer.go +++ b/vendor/src/github.com/docker/libcontainer/cgroups/fs/freezer.go @@ -33,7 +33,7 @@ func (s *FreezerGroup) Set(d *data) error { time.Sleep(1 * time.Millisecond) } default: - if _, err := d.join("freezer"); err != nil && err != cgroups.ErrNotFound { + if _, err := d.join("freezer"); err != nil && !cgroups.IsNotFound(err) { return err } } diff --git a/vendor/src/github.com/docker/libcontainer/cgroups/fs/perf_event.go b/vendor/src/github.com/docker/libcontainer/cgroups/fs/perf_event.go index 5f45678ff3..813274d8cb 100644 --- a/vendor/src/github.com/docker/libcontainer/cgroups/fs/perf_event.go +++ b/vendor/src/github.com/docker/libcontainer/cgroups/fs/perf_event.go @@ -9,7 +9,7 @@ type PerfEventGroup struct { func (s *PerfEventGroup) Set(d *data) error { // we just want to join this group even though we don't set anything - if _, err := d.join("perf_event"); err != nil && err != cgroups.ErrNotFound { + if _, err := d.join("perf_event"); err != nil && !cgroups.IsNotFound(err) { return err } return nil diff --git a/vendor/src/github.com/docker/libcontainer/cgroups/fs/utils_test.go b/vendor/src/github.com/docker/libcontainer/cgroups/fs/utils_test.go index 6ea59bc506..63d743f06e 100644 --- a/vendor/src/github.com/docker/libcontainer/cgroups/fs/utils_test.go +++ b/vendor/src/github.com/docker/libcontainer/cgroups/fs/utils_test.go @@ -5,8 +5,6 @@ import ( "os" "path/filepath" "testing" - - "github.com/docker/libcontainer/cgroups" ) const ( @@ -68,20 +66,3 @@ func TestGetCgroupParamsInt(t *testing.T) { t.Fatal("Expecting error, got none") } } - -func TestAbsolutePathHandling(t *testing.T) { - testCgroup := cgroups.Cgroup{ - Name: "bar", - Parent: "/foo", - } - cgroupData := data{ - root: "/sys/fs/cgroup", - cgroup: "/foo/bar", - c: &testCgroup, - pid: 1, - } - expectedPath := filepath.Join(cgroupData.root, "cpu", testCgroup.Parent, testCgroup.Name) - if path, err := cgroupData.path("cpu"); path != expectedPath || err != nil { - t.Fatalf("expected path %s but got %s %s", expectedPath, path, err) - } -} diff --git a/vendor/src/github.com/docker/libcontainer/cgroups/systemd/apply_systemd.go b/vendor/src/github.com/docker/libcontainer/cgroups/systemd/apply_systemd.go index 7fcd99bceb..7af4818e23 100644 --- a/vendor/src/github.com/docker/libcontainer/cgroups/systemd/apply_systemd.go +++ b/vendor/src/github.com/docker/libcontainer/cgroups/systemd/apply_systemd.go @@ -13,8 +13,7 @@ import ( "sync" "time" - systemd1 "github.com/coreos/go-systemd/dbus" - "github.com/docker/docker/pkg/systemd" + systemd "github.com/coreos/go-systemd/dbus" "github.com/docker/libcontainer/cgroups" "github.com/docker/libcontainer/cgroups/fs" "github.com/godbus/dbus" @@ -30,7 +29,7 @@ type subsystem interface { var ( connLock sync.Mutex - theConn *systemd1.Conn + theConn *systemd.Conn hasStartTransientUnit bool subsystems = map[string]subsystem{ "devices": &fs.DevicesGroup{}, @@ -45,7 +44,8 @@ var ( ) func UseSystemd() bool { - if !systemd.SdBooted() { + s, err := os.Stat("/run/systemd/system") + if err != nil || !s.IsDir() { return false } @@ -54,7 +54,7 @@ func UseSystemd() bool { if theConn == nil { var err error - theConn, err = systemd1.New() + theConn, err = systemd.New() if err != nil { return false } @@ -88,7 +88,7 @@ func Apply(c *cgroups.Cgroup, pid int) (cgroups.ActiveCgroup, error) { var ( unitName = getUnitName(c) slice = "system.slice" - properties []systemd1.Property + properties []systemd.Property res = &systemdCgroup{} ) @@ -99,27 +99,27 @@ func Apply(c *cgroups.Cgroup, pid int) (cgroups.ActiveCgroup, error) { } properties = append(properties, - systemd1.Property{"Slice", dbus.MakeVariant(slice)}, - systemd1.Property{"Description", dbus.MakeVariant("docker container " + c.Name)}, - systemd1.Property{"PIDs", dbus.MakeVariant([]uint32{uint32(pid)})}, + systemd.Property{"Slice", dbus.MakeVariant(slice)}, + systemd.Property{"Description", dbus.MakeVariant("docker container " + c.Name)}, + systemd.Property{"PIDs", dbus.MakeVariant([]uint32{uint32(pid)})}, ) // Always enable accounting, this gets us the same behaviour as the fs implementation, // plus the kernel has some problems with joining the memory cgroup at a later time. properties = append(properties, - systemd1.Property{"MemoryAccounting", dbus.MakeVariant(true)}, - systemd1.Property{"CPUAccounting", dbus.MakeVariant(true)}, - systemd1.Property{"BlockIOAccounting", dbus.MakeVariant(true)}) + systemd.Property{"MemoryAccounting", dbus.MakeVariant(true)}, + systemd.Property{"CPUAccounting", dbus.MakeVariant(true)}, + systemd.Property{"BlockIOAccounting", dbus.MakeVariant(true)}) if c.Memory != 0 { properties = append(properties, - systemd1.Property{"MemoryLimit", dbus.MakeVariant(uint64(c.Memory))}) + systemd.Property{"MemoryLimit", dbus.MakeVariant(uint64(c.Memory))}) } // TODO: MemoryReservation and MemorySwap not available in systemd if c.CpuShares != 0 { properties = append(properties, - systemd1.Property{"CPUShares", dbus.MakeVariant(uint64(c.CpuShares))}) + systemd.Property{"CPUShares", dbus.MakeVariant(uint64(c.CpuShares))}) } if _, err := theConn.StartTransientUnit(unitName, "replace", properties...); err != nil { @@ -166,7 +166,7 @@ func (c *systemdCgroup) Paths() (map[string]string, error) { subsystemPath, err := getSubsystemPath(c.cgroup, sysname) if err != nil { // Don't fail if a cgroup hierarchy was not found, just skip this subsystem - if err == cgroups.ErrNotFound { + if cgroups.IsNotFound(err) { continue } @@ -274,7 +274,7 @@ func GetStats(c *cgroups.Cgroup) (*cgroups.Stats, error) { subsystemPath, err := getSubsystemPath(c, sysname) if err != nil { // Don't fail if a cgroup hierarchy was not found, just skip this subsystem - if err == cgroups.ErrNotFound { + if cgroups.IsNotFound(err) { continue } diff --git a/vendor/src/github.com/docker/libcontainer/cgroups/utils.go b/vendor/src/github.com/docker/libcontainer/cgroups/utils.go index 6688ff71e4..5516c5a222 100644 --- a/vendor/src/github.com/docker/libcontainer/cgroups/utils.go +++ b/vendor/src/github.com/docker/libcontainer/cgroups/utils.go @@ -29,7 +29,8 @@ func FindCgroupMountpoint(subsystem string) (string, error) { } } } - return "", ErrNotFound + + return "", NewNotFoundError(subsystem) } type Mount struct { @@ -153,19 +154,23 @@ func ReadProcsFile(dir string) ([]int, error) { func parseCgroupFile(subsystem string, r io.Reader) (string, error) { s := bufio.NewScanner(r) + for s.Scan() { if err := s.Err(); err != nil { return "", err } + text := s.Text() parts := strings.Split(text, ":") + for _, subs := range strings.Split(parts[1], ",") { if subs == subsystem { return parts[2], nil } } } - return "", ErrNotFound + + return "", NewNotFoundError(subsystem) } func pathExists(path string) bool {