Skip to content

Commit

Permalink
Merge pull request moby#8293 from crosbymichael/update-libcontainer-sep8
Browse files Browse the repository at this point in the history
Update libcontainer to c744f6470e37be5ce1f1ae09b842c15c1bee120d
  • Loading branch information
tianon committed Sep 30, 2014
2 parents 595b5bf + 532c29e commit 07179a7
Show file tree
Hide file tree
Showing 16 changed files with 750 additions and 296 deletions.
1 change: 1 addition & 0 deletions daemon/execdriver/native/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func (d *driver) createContainer(c *execdriver.Command) (*libcontainer.Config, e
container.Cgroups.Name = c.ID
container.Cgroups.AllowedDevices = c.AllowedDevices
container.MountConfig.DeviceNodes = c.AutoCreatedDevices
container.RootFs = c.Rootfs

// check to see if we are running in ramdisk to disable pivot root
container.MountConfig.NoPivotRoot = os.Getenv("DOCKER_RAMDISK") != ""
Expand Down
4 changes: 2 additions & 2 deletions daemon/execdriver/native/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba
return -1, err
}

return namespaces.Exec(container, c.ProcessConfig.Stdin, c.ProcessConfig.Stdout, c.ProcessConfig.Stderr, c.ProcessConfig.Console, c.Rootfs, dataPath, args, func(container *libcontainer.Config, console, rootfs, dataPath, init string, child *os.File, args []string) *exec.Cmd {
return namespaces.Exec(container, c.ProcessConfig.Stdin, c.ProcessConfig.Stdout, c.ProcessConfig.Stderr, c.ProcessConfig.Console, dataPath, args, func(container *libcontainer.Config, console, dataPath, init string, child *os.File, args []string) *exec.Cmd {
c.ProcessConfig.Path = d.initPath
c.ProcessConfig.Args = append([]string{
DriverName,
Expand All @@ -117,7 +117,7 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba
c.ProcessConfig.ExtraFiles = []*os.File{child}

c.ProcessConfig.Env = container.Env
c.ProcessConfig.Dir = c.Rootfs
c.ProcessConfig.Dir = container.RootFs

return &c.ProcessConfig.Cmd
}, func() {
Expand Down
2 changes: 1 addition & 1 deletion hack/vendor.sh
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,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 185328a42654f6dc9a41814e57882f69d65f6ab7
clone git github.com/docker/libcontainer c744f6470e37be5ce1f1ae09b842c15c1bee120d
# 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')"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (s *CpuacctGroup) GetStats(path string, stats *cgroups.Stats) error {
return err
}

totalUsage, err := getCgroupParamInt(path, "cpuacct.usage")
totalUsage, err := getCgroupParamUint(path, "cpuacct.usage")
if err != nil {
return err
}
Expand Down
15 changes: 8 additions & 7 deletions vendor/src/github.com/docker/libcontainer/cgroups/fs/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package fs

import (
"bufio"
"fmt"
"os"
"path/filepath"
"strconv"
Expand Down Expand Up @@ -66,25 +67,25 @@ func (s *MemoryGroup) GetStats(path string, stats *cgroups.Stats) error {
for sc.Scan() {
t, v, err := getCgroupParamKeyValue(sc.Text())
if err != nil {
return err
return fmt.Errorf("failed to parse memory.stat (%q) - %v", sc.Text(), err)
}
stats.MemoryStats.Stats[t] = v
}

// Set memory usage and max historical usage.
value, err := getCgroupParamInt(path, "memory.usage_in_bytes")
value, err := getCgroupParamUint(path, "memory.usage_in_bytes")
if err != nil {
return err
return fmt.Errorf("failed to parse memory.usage_in_bytes - %v", err)
}
stats.MemoryStats.Usage = value
value, err = getCgroupParamInt(path, "memory.max_usage_in_bytes")
value, err = getCgroupParamUint(path, "memory.max_usage_in_bytes")
if err != nil {
return err
return fmt.Errorf("failed to parse memory.max_usage_in_bytes - %v", err)
}
stats.MemoryStats.MaxUsage = value
value, err = getCgroupParamInt(path, "memory.failcnt")
value, err = getCgroupParamUint(path, "memory.failcnt")
if err != nil {
return err
return fmt.Errorf("failed to parse memory.failcnt - %v", err)
}
stats.MemoryStats.Failcnt = value

Expand Down
32 changes: 27 additions & 5 deletions vendor/src/github.com/docker/libcontainer/cgroups/fs/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,49 @@ var (
ErrNotValidFormat = errors.New("line is not a valid key value format")
)

// Saturates negative values at zero and returns a uint64.
// Due to kernel bugs, some of the memory cgroup stats can be negative.
func parseUint(s string, base, bitSize int) (uint64, error) {
value, err := strconv.ParseUint(s, base, bitSize)
if err != nil {
intValue, intErr := strconv.ParseInt(s, base, bitSize)
// 1. Handle negative values greater than MinInt64 (and)
// 2. Handle negative values lesser than MinInt64
if intErr == nil && intValue < 0 {
return 0, nil
} else if intErr != nil && intErr.(*strconv.NumError).Err == strconv.ErrRange && intValue < 0 {
return 0, nil
}

return value, err
}

return value, nil
}

// Parses a cgroup param and returns as name, value
// i.e. "io_service_bytes 1234" will return as io_service_bytes, 1234
func getCgroupParamKeyValue(t string) (string, uint64, error) {
parts := strings.Fields(t)
switch len(parts) {
case 2:
value, err := strconv.ParseUint(parts[1], 10, 64)
value, err := parseUint(parts[1], 10, 64)
if err != nil {
return "", 0, fmt.Errorf("Unable to convert param value to uint64: %s", err)
return "", 0, fmt.Errorf("Unable to convert param value (%q) to uint64: %v", parts[1], err)
}

return parts[0], value, nil
default:
return "", 0, ErrNotValidFormat
}
}

// Gets a single int64 value from the specified cgroup file.
func getCgroupParamInt(cgroupPath, cgroupFile string) (uint64, error) {
// Gets a single uint64 value from the specified cgroup file.
func getCgroupParamUint(cgroupPath, cgroupFile string) (uint64, error) {
contents, err := ioutil.ReadFile(filepath.Join(cgroupPath, cgroupFile))
if err != nil {
return 0, err
}
return strconv.ParseUint(strings.TrimSpace(string(contents)), 10, 64)

return parseUint(strings.TrimSpace(string(contents)), 10, 64)
}
35 changes: 31 additions & 4 deletions vendor/src/github.com/docker/libcontainer/cgroups/fs/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package fs

import (
"io/ioutil"
"math"
"os"
"path/filepath"
"strconv"
"testing"
)

Expand All @@ -27,7 +29,7 @@ func TestGetCgroupParamsInt(t *testing.T) {
if err != nil {
t.Fatal(err)
}
value, err := getCgroupParamInt(tempDir, cgroupFile)
value, err := getCgroupParamUint(tempDir, cgroupFile)
if err != nil {
t.Fatal(err)
} else if value != floatValue {
Expand All @@ -39,19 +41,44 @@ func TestGetCgroupParamsInt(t *testing.T) {
if err != nil {
t.Fatal(err)
}
value, err = getCgroupParamInt(tempDir, cgroupFile)
value, err = getCgroupParamUint(tempDir, cgroupFile)
if err != nil {
t.Fatal(err)
} else if value != floatValue {
t.Fatalf("Expected %d to equal %f", value, floatValue)
}

// Success with negative values
err = ioutil.WriteFile(tempFile, []byte("-12345"), 0755)
if err != nil {
t.Fatal(err)
}
value, err = getCgroupParamUint(tempDir, cgroupFile)
if err != nil {
t.Fatal(err)
} else if value != 0 {
t.Fatalf("Expected %d to equal %f", value, 0)
}

// Success with negative values lesser than min int64
s := strconv.FormatFloat(math.MinInt64, 'f', -1, 64)
err = ioutil.WriteFile(tempFile, []byte(s), 0755)
if err != nil {
t.Fatal(err)
}
value, err = getCgroupParamUint(tempDir, cgroupFile)
if err != nil {
t.Fatal(err)
} else if value != 0 {
t.Fatalf("Expected %d to equal %f", value, 0)
}

// Not a float.
err = ioutil.WriteFile(tempFile, []byte("not-a-float"), 0755)
if err != nil {
t.Fatal(err)
}
_, err = getCgroupParamInt(tempDir, cgroupFile)
_, err = getCgroupParamUint(tempDir, cgroupFile)
if err == nil {
t.Fatal("Expecting error, got none")
}
Expand All @@ -61,7 +88,7 @@ func TestGetCgroupParamsInt(t *testing.T) {
if err != nil {
t.Fatal(err)
}
_, err = getCgroupParamInt(tempDir, cgroupFile)
_, err = getCgroupParamUint(tempDir, cgroupFile)
if err == nil {
t.Fatal("Expecting error, got none")
}
Expand Down
3 changes: 3 additions & 0 deletions vendor/src/github.com/docker/libcontainer/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ type Config struct {
// Mount specific options.
MountConfig *MountConfig `json:"mount_config,omitempty"`

// Pathname to container's root filesystem
RootFs string `json:"root_fs,omitempty"`

// Hostname optionally sets the container's hostname if provided
Hostname string `json:"hostname,omitempty"`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ import (
"github.com/docker/libcontainer"
)

type CreateCommand func(container *libcontainer.Config, console, rootfs, dataPath, init string, childPipe *os.File, args []string) *exec.Cmd
type CreateCommand func(container *libcontainer.Config, console, dataPath, init string, childPipe *os.File, args []string) *exec.Cmd
8 changes: 4 additions & 4 deletions vendor/src/github.com/docker/libcontainer/namespaces/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
// Move this to libcontainer package.
// Exec performs setup outside of a namespace so that a container can be
// executed. Exec is a high level function for working with container namespaces.
func Exec(container *libcontainer.Config, stdin io.Reader, stdout, stderr io.Writer, console string, rootfs, dataPath string, args []string, createCommand CreateCommand, startCallback func()) (int, error) {
func Exec(container *libcontainer.Config, stdin io.Reader, stdout, stderr io.Writer, console, dataPath string, args []string, createCommand CreateCommand, startCallback func()) (int, error) {
var (
err error
)
Expand All @@ -34,7 +34,7 @@ func Exec(container *libcontainer.Config, stdin io.Reader, stdout, stderr io.Wri
}
defer syncPipe.Close()

command := createCommand(container, console, rootfs, dataPath, os.Args[0], syncPipe.Child(), args)
command := createCommand(container, console, dataPath, os.Args[0], syncPipe.Child(), args)
// Note: these are only used in non-tty mode
// if there is a tty for the container it will be opened within the namespace and the
// fds will be duped to stdin, stdiout, and stderr
Expand Down Expand Up @@ -121,7 +121,7 @@ func Exec(container *libcontainer.Config, stdin io.Reader, stdout, stderr io.Wri
// root: the path to the container json file and information
// pipe: sync pipe to synchronize the parent and child processes
// args: the arguments to pass to the container to run as the user's program
func DefaultCreateCommand(container *libcontainer.Config, console, rootfs, dataPath, init string, pipe *os.File, args []string) *exec.Cmd {
func DefaultCreateCommand(container *libcontainer.Config, console, dataPath, init string, pipe *os.File, args []string) *exec.Cmd {
// get our binary name from arg0 so we can always reexec ourself
env := []string{
"console=" + console,
Expand All @@ -141,7 +141,7 @@ func DefaultCreateCommand(container *libcontainer.Config, console, rootfs, dataP

command := exec.Command(init, append([]string{"init", "--"}, args...)...)
// make sure the process is executed inside the context of the rootfs
command.Dir = rootfs
command.Dir = container.RootFs
command.Env = append(os.Environ(), env...)

if command.SysProcAttr == nil {
Expand Down
Loading

0 comments on commit 07179a7

Please sign in to comment.