Procházet zdrojové kódy

Merge pull request #8828 from crosbymichael/update-libcontainer-oct4

Update libcontainer to f60d7b9195f8dc0b5d343abbc3293d
Michael Crosby před 10 roky
rodič
revize
d176d1bfb4

+ 1 - 1
hack/vendor.sh

@@ -66,7 +66,7 @@ if [ "$1" = '--go' ]; then
 	mv tmp-tar src/code.google.com/p/go/src/pkg/archive/tar
 	mv tmp-tar src/code.google.com/p/go/src/pkg/archive/tar
 fi
 fi
 
 
-clone git github.com/docker/libcontainer aab3f6d17f2f56606f07f3a6eb6b693303f75812
+clone git github.com/docker/libcontainer f60d7b9195f8dc0b5d343abbc3293da7c17bb11c
 # see src/github.com/docker/libcontainer/update-vendor.sh which is the "source of truth" for libcontainer deps (just like this file)
 # 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
 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')"
 eval "$(grep '^clone ' src/github.com/docker/libcontainer/update-vendor.sh | grep -v 'github.com/codegangsta/cli')"

+ 2 - 2
vendor/src/github.com/docker/libcontainer/Makefile

@@ -12,10 +12,10 @@ sh:
 GO_PACKAGES = $(shell find . -not \( -wholename ./vendor -prune -o -wholename ./.git -prune \) -name '*.go' -print0 | xargs -0n1 dirname | sort -u)
 GO_PACKAGES = $(shell find . -not \( -wholename ./vendor -prune -o -wholename ./.git -prune \) -name '*.go' -print0 | xargs -0n1 dirname | sort -u)
 
 
 direct-test:
 direct-test:
-	go test -cover -v $(GO_PACKAGES)
+	go test $(TEST_TAGS) -cover -v $(GO_PACKAGES)
 
 
 direct-test-short:
 direct-test-short:
-	go test -cover -test.short -v $(GO_PACKAGES)
+	go test $(TEST_TAGS) -cover -test.short -v $(GO_PACKAGES)
 
 
 direct-build:
 direct-build:
 	go build -v $(GO_PACKAGES)
 	go build -v $(GO_PACKAGES)

+ 1 - 1
vendor/src/github.com/docker/libcontainer/README.md

@@ -56,7 +56,7 @@ Docs released under Creative commons.
 
 
 First of all, please familiarise yourself with the [libcontainer Principles](PRINCIPLES.md).
 First of all, please familiarise yourself with the [libcontainer Principles](PRINCIPLES.md).
 
 
-If you're a *contributor* or aspiring contributor, you should read the [Contributors' Guide](CONTRIBUTORS_GUIDE.md).
+If you're a *contributor* or aspiring contributor, you should read the [Contributors' Guide](CONTRIBUTING.md).
 
 
 If you're a *maintainer* or aspiring maintainer, you should read the [Maintainers' Guide](MAINTAINERS_GUIDE.md) and
 If you're a *maintainer* or aspiring maintainer, you should read the [Maintainers' Guide](MAINTAINERS_GUIDE.md) and
 "How can I become a maintainer?" in the Contributors' Guide.
 "How can I become a maintainer?" in the Contributors' Guide.

+ 20 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/blkio.go

@@ -146,6 +146,26 @@ func getCFQStats(path string, stats *cgroups.Stats) error {
 	}
 	}
 	stats.BlkioStats.IoQueuedRecursive = blkioStats
 	stats.BlkioStats.IoQueuedRecursive = blkioStats
 
 
+	if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_service_time_recursive")); err != nil {
+		return err
+	}
+	stats.BlkioStats.IoServiceTimeRecursive = blkioStats
+
+	if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_wait_time_recursive")); err != nil {
+		return err
+	}
+	stats.BlkioStats.IoWaitTimeRecursive = blkioStats
+
+	if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_merged_recursive")); err != nil {
+		return err
+	}
+	stats.BlkioStats.IoMergedRecursive = blkioStats
+
+	if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.time_recursive")); err != nil {
+		return err
+	}
+	stats.BlkioStats.IoTimeRecursive = blkioStats
+
 	return nil
 	return nil
 }
 }
 
 

+ 170 - 4
vendor/src/github.com/docker/libcontainer/cgroups/fs/blkio_test.go

@@ -26,7 +26,25 @@ Total 50`
 8:0 Async 3
 8:0 Async 3
 8:0 Total 5
 8:0 Total 5
 Total 5`
 Total 5`
-	throttleServiceBytes = `8:0 Read 11030528
+	serviceTimeRecursiveContents = `8:0 Read 173959
+8:0 Write 0
+8:0 Sync 0
+8:0 Async 173959
+8:0 Total 17395
+Total 17395`
+	waitTimeRecursiveContents = `8:0 Read 15571
+8:0 Write 0
+8:0 Sync 0
+8:0 Async 15571
+8:0 Total 15571`
+	mergedRecursiveContents = `8:0 Read 5
+8:0 Write 10
+8:0 Sync 0
+8:0 Async 0
+8:0 Total 15
+Total 15`
+	timeRecursiveContents = `8:0 8`
+	throttleServiceBytes  = `8:0 Read 11030528
 8:0 Write 23
 8:0 Write 23
 8:0 Sync 42
 8:0 Sync 42
 8:0 Async 11030528
 8:0 Async 11030528
@@ -61,6 +79,10 @@ func TestBlkioStats(t *testing.T) {
 		"blkio.io_service_bytes_recursive": serviceBytesRecursiveContents,
 		"blkio.io_service_bytes_recursive": serviceBytesRecursiveContents,
 		"blkio.io_serviced_recursive":      servicedRecursiveContents,
 		"blkio.io_serviced_recursive":      servicedRecursiveContents,
 		"blkio.io_queued_recursive":        queuedRecursiveContents,
 		"blkio.io_queued_recursive":        queuedRecursiveContents,
+		"blkio.io_service_time_recursive":  serviceTimeRecursiveContents,
+		"blkio.io_wait_time_recursive":     waitTimeRecursiveContents,
+		"blkio.io_merged_recursive":        mergedRecursiveContents,
+		"blkio.time_recursive":             timeRecursiveContents,
 		"blkio.sectors_recursive":          sectorsRecursiveContents,
 		"blkio.sectors_recursive":          sectorsRecursiveContents,
 	})
 	})
 
 
@@ -93,6 +115,26 @@ func TestBlkioStats(t *testing.T) {
 	appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 3, "Async")
 	appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 3, "Async")
 	appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 5, "Total")
 	appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 5, "Total")
 
 
+	appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 173959, "Read")
+	appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 0, "Write")
+	appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 0, "Sync")
+	appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 173959, "Async")
+	appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 17395, "Total")
+
+	appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 15571, "Read")
+	appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 0, "Write")
+	appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 0, "Sync")
+	appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 15571, "Async")
+	appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 15571, "Total")
+
+	appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 5, "Read")
+	appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 10, "Write")
+	appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 0, "Sync")
+	appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 0, "Async")
+	appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 15, "Total")
+
+	appendBlkioStatEntry(&expectedStats.IoTimeRecursive, 8, 0, 8, "")
+
 	expectBlkioStatsEquals(t, expectedStats, actualStats.BlkioStats)
 	expectBlkioStatsEquals(t, expectedStats, actualStats.BlkioStats)
 }
 }
 
 
@@ -103,6 +145,10 @@ func TestBlkioStatsNoSectorsFile(t *testing.T) {
 		"blkio.io_service_bytes_recursive": serviceBytesRecursiveContents,
 		"blkio.io_service_bytes_recursive": serviceBytesRecursiveContents,
 		"blkio.io_serviced_recursive":      servicedRecursiveContents,
 		"blkio.io_serviced_recursive":      servicedRecursiveContents,
 		"blkio.io_queued_recursive":        queuedRecursiveContents,
 		"blkio.io_queued_recursive":        queuedRecursiveContents,
+		"blkio.io_service_time_recursive":  serviceTimeRecursiveContents,
+		"blkio.io_wait_time_recursive":     waitTimeRecursiveContents,
+		"blkio.io_merged_recursive":        mergedRecursiveContents,
+		"blkio.time_recursive":             timeRecursiveContents,
 	})
 	})
 
 
 	blkio := &BlkioGroup{}
 	blkio := &BlkioGroup{}
@@ -117,9 +163,13 @@ func TestBlkioStatsNoServiceBytesFile(t *testing.T) {
 	helper := NewCgroupTestUtil("blkio", t)
 	helper := NewCgroupTestUtil("blkio", t)
 	defer helper.cleanup()
 	defer helper.cleanup()
 	helper.writeFileContents(map[string]string{
 	helper.writeFileContents(map[string]string{
-		"blkio.io_serviced_recursive": servicedRecursiveContents,
-		"blkio.io_queued_recursive":   queuedRecursiveContents,
-		"blkio.sectors_recursive":     sectorsRecursiveContents,
+		"blkio.io_serviced_recursive":     servicedRecursiveContents,
+		"blkio.io_queued_recursive":       queuedRecursiveContents,
+		"blkio.sectors_recursive":         sectorsRecursiveContents,
+		"blkio.io_service_time_recursive": serviceTimeRecursiveContents,
+		"blkio.io_wait_time_recursive":    waitTimeRecursiveContents,
+		"blkio.io_merged_recursive":       mergedRecursiveContents,
+		"blkio.time_recursive":            timeRecursiveContents,
 	})
 	})
 
 
 	blkio := &BlkioGroup{}
 	blkio := &BlkioGroup{}
@@ -137,6 +187,10 @@ func TestBlkioStatsNoServicedFile(t *testing.T) {
 		"blkio.io_service_bytes_recursive": serviceBytesRecursiveContents,
 		"blkio.io_service_bytes_recursive": serviceBytesRecursiveContents,
 		"blkio.io_queued_recursive":        queuedRecursiveContents,
 		"blkio.io_queued_recursive":        queuedRecursiveContents,
 		"blkio.sectors_recursive":          sectorsRecursiveContents,
 		"blkio.sectors_recursive":          sectorsRecursiveContents,
+		"blkio.io_service_time_recursive":  serviceTimeRecursiveContents,
+		"blkio.io_wait_time_recursive":     waitTimeRecursiveContents,
+		"blkio.io_merged_recursive":        mergedRecursiveContents,
+		"blkio.time_recursive":             timeRecursiveContents,
 	})
 	})
 
 
 	blkio := &BlkioGroup{}
 	blkio := &BlkioGroup{}
@@ -154,6 +208,106 @@ func TestBlkioStatsNoQueuedFile(t *testing.T) {
 		"blkio.io_service_bytes_recursive": serviceBytesRecursiveContents,
 		"blkio.io_service_bytes_recursive": serviceBytesRecursiveContents,
 		"blkio.io_serviced_recursive":      servicedRecursiveContents,
 		"blkio.io_serviced_recursive":      servicedRecursiveContents,
 		"blkio.sectors_recursive":          sectorsRecursiveContents,
 		"blkio.sectors_recursive":          sectorsRecursiveContents,
+		"blkio.io_service_time_recursive":  serviceTimeRecursiveContents,
+		"blkio.io_wait_time_recursive":     waitTimeRecursiveContents,
+		"blkio.io_merged_recursive":        mergedRecursiveContents,
+		"blkio.time_recursive":             timeRecursiveContents,
+	})
+
+	blkio := &BlkioGroup{}
+	actualStats := *cgroups.NewStats()
+	err := blkio.GetStats(helper.CgroupPath, &actualStats)
+	if err != nil {
+		t.Fatalf("Failed unexpectedly: %s", err)
+	}
+}
+
+func TestBlkioStatsNoServiceTimeFile(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping test in short mode.")
+	}
+	helper := NewCgroupTestUtil("blkio", t)
+	defer helper.cleanup()
+	helper.writeFileContents(map[string]string{
+		"blkio.io_service_bytes_recursive": serviceBytesRecursiveContents,
+		"blkio.io_serviced_recursive":      servicedRecursiveContents,
+		"blkio.io_queued_recursive":        queuedRecursiveContents,
+		"blkio.io_wait_time_recursive":     waitTimeRecursiveContents,
+		"blkio.io_merged_recursive":        mergedRecursiveContents,
+		"blkio.time_recursive":             timeRecursiveContents,
+		"blkio.sectors_recursive":          sectorsRecursiveContents,
+	})
+
+	blkio := &BlkioGroup{}
+	actualStats := *cgroups.NewStats()
+	err := blkio.GetStats(helper.CgroupPath, &actualStats)
+	if err != nil {
+		t.Fatalf("Failed unexpectedly: %s", err)
+	}
+}
+
+func TestBlkioStatsNoWaitTimeFile(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping test in short mode.")
+	}
+	helper := NewCgroupTestUtil("blkio", t)
+	defer helper.cleanup()
+	helper.writeFileContents(map[string]string{
+		"blkio.io_service_bytes_recursive": serviceBytesRecursiveContents,
+		"blkio.io_serviced_recursive":      servicedRecursiveContents,
+		"blkio.io_queued_recursive":        queuedRecursiveContents,
+		"blkio.io_service_time_recursive":  serviceTimeRecursiveContents,
+		"blkio.io_merged_recursive":        mergedRecursiveContents,
+		"blkio.time_recursive":             timeRecursiveContents,
+		"blkio.sectors_recursive":          sectorsRecursiveContents,
+	})
+
+	blkio := &BlkioGroup{}
+	actualStats := *cgroups.NewStats()
+	err := blkio.GetStats(helper.CgroupPath, &actualStats)
+	if err != nil {
+		t.Fatalf("Failed unexpectedly: %s", err)
+	}
+}
+
+func TestBlkioStatsNoMergedFile(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping test in short mode.")
+	}
+	helper := NewCgroupTestUtil("blkio", t)
+	defer helper.cleanup()
+	helper.writeFileContents(map[string]string{
+		"blkio.io_service_bytes_recursive": serviceBytesRecursiveContents,
+		"blkio.io_serviced_recursive":      servicedRecursiveContents,
+		"blkio.io_queued_recursive":        queuedRecursiveContents,
+		"blkio.io_service_time_recursive":  serviceTimeRecursiveContents,
+		"blkio.io_wait_time_recursive":     waitTimeRecursiveContents,
+		"blkio.time_recursive":             timeRecursiveContents,
+		"blkio.sectors_recursive":          sectorsRecursiveContents,
+	})
+
+	blkio := &BlkioGroup{}
+	actualStats := *cgroups.NewStats()
+	err := blkio.GetStats(helper.CgroupPath, &actualStats)
+	if err != nil {
+		t.Fatalf("Failed unexpectedly: %s", err)
+	}
+}
+
+func TestBlkioStatsNoTimeFile(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping test in short mode.")
+	}
+	helper := NewCgroupTestUtil("blkio", t)
+	defer helper.cleanup()
+	helper.writeFileContents(map[string]string{
+		"blkio.io_service_bytes_recursive": serviceBytesRecursiveContents,
+		"blkio.io_serviced_recursive":      servicedRecursiveContents,
+		"blkio.io_queued_recursive":        queuedRecursiveContents,
+		"blkio.io_service_time_recursive":  serviceTimeRecursiveContents,
+		"blkio.io_wait_time_recursive":     waitTimeRecursiveContents,
+		"blkio.io_merged_recursive":        mergedRecursiveContents,
+		"blkio.sectors_recursive":          sectorsRecursiveContents,
 	})
 	})
 
 
 	blkio := &BlkioGroup{}
 	blkio := &BlkioGroup{}
@@ -172,6 +326,10 @@ func TestBlkioStatsUnexpectedNumberOfFields(t *testing.T) {
 		"blkio.io_serviced_recursive":      servicedRecursiveContents,
 		"blkio.io_serviced_recursive":      servicedRecursiveContents,
 		"blkio.io_queued_recursive":        queuedRecursiveContents,
 		"blkio.io_queued_recursive":        queuedRecursiveContents,
 		"blkio.sectors_recursive":          sectorsRecursiveContents,
 		"blkio.sectors_recursive":          sectorsRecursiveContents,
+		"blkio.io_service_time_recursive":  serviceTimeRecursiveContents,
+		"blkio.io_wait_time_recursive":     waitTimeRecursiveContents,
+		"blkio.io_merged_recursive":        mergedRecursiveContents,
+		"blkio.time_recursive":             timeRecursiveContents,
 	})
 	})
 
 
 	blkio := &BlkioGroup{}
 	blkio := &BlkioGroup{}
@@ -190,6 +348,10 @@ func TestBlkioStatsUnexpectedFieldType(t *testing.T) {
 		"blkio.io_serviced_recursive":      servicedRecursiveContents,
 		"blkio.io_serviced_recursive":      servicedRecursiveContents,
 		"blkio.io_queued_recursive":        queuedRecursiveContents,
 		"blkio.io_queued_recursive":        queuedRecursiveContents,
 		"blkio.sectors_recursive":          sectorsRecursiveContents,
 		"blkio.sectors_recursive":          sectorsRecursiveContents,
+		"blkio.io_service_time_recursive":  serviceTimeRecursiveContents,
+		"blkio.io_wait_time_recursive":     waitTimeRecursiveContents,
+		"blkio.io_merged_recursive":        mergedRecursiveContents,
+		"blkio.time_recursive":             timeRecursiveContents,
 	})
 	})
 
 
 	blkio := &BlkioGroup{}
 	blkio := &BlkioGroup{}
@@ -208,6 +370,10 @@ func TestNonCFQBlkioStats(t *testing.T) {
 		"blkio.io_serviced_recursive":      "",
 		"blkio.io_serviced_recursive":      "",
 		"blkio.io_queued_recursive":        "",
 		"blkio.io_queued_recursive":        "",
 		"blkio.sectors_recursive":          "",
 		"blkio.sectors_recursive":          "",
+		"blkio.io_service_time_recursive":  "",
+		"blkio.io_wait_time_recursive":     "",
+		"blkio.io_merged_recursive":        "",
+		"blkio.time_recursive":             "",
 		"blkio.throttle.io_service_bytes":  throttleServiceBytes,
 		"blkio.throttle.io_service_bytes":  throttleServiceBytes,
 		"blkio.throttle.io_serviced":       throttleServiced,
 		"blkio.throttle.io_serviced":       throttleServiced,
 	})
 	})

+ 20 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/stats_util_test.go

@@ -41,6 +41,26 @@ func expectBlkioStatsEquals(t *testing.T, expected, actual cgroups.BlkioStats) {
 		log.Printf("blkio SectorsRecursive do not match - %s\n", err)
 		log.Printf("blkio SectorsRecursive do not match - %s\n", err)
 		t.Fail()
 		t.Fail()
 	}
 	}
+
+	if err := blkioStatEntryEquals(expected.IoServiceTimeRecursive, actual.IoServiceTimeRecursive); err != nil {
+		log.Printf("blkio IoServiceTimeRecursive do not match - %s\n", err)
+		t.Fail()
+	}
+
+	if err := blkioStatEntryEquals(expected.IoWaitTimeRecursive, actual.IoWaitTimeRecursive); err != nil {
+		log.Printf("blkio IoWaitTimeRecursive do not match - %s\n", err)
+		t.Fail()
+	}
+
+	if err := blkioStatEntryEquals(expected.IoMergedRecursive, actual.IoMergedRecursive); err != nil {
+		log.Printf("blkio IoMergedRecursive do not match - %s vs %s\n", expected.IoMergedRecursive, actual.IoMergedRecursive)
+		t.Fail()
+	}
+
+	if err := blkioStatEntryEquals(expected.IoTimeRecursive, actual.IoTimeRecursive); err != nil {
+		log.Printf("blkio IoTimeRecursive do not match - %s\n", err)
+		t.Fail()
+	}
 }
 }
 
 
 func expectThrottlingDataEquals(t *testing.T, expected, actual cgroups.ThrottlingData) {
 func expectThrottlingDataEquals(t *testing.T, expected, actual cgroups.ThrottlingData) {

+ 5 - 1
vendor/src/github.com/docker/libcontainer/cgroups/stats.go

@@ -52,8 +52,12 @@ type BlkioStatEntry struct {
 type BlkioStats struct {
 type BlkioStats struct {
 	// number of bytes tranferred to and from the block device
 	// number of bytes tranferred to and from the block device
 	IoServiceBytesRecursive []BlkioStatEntry `json:"io_service_bytes_recursive,omitempty"`
 	IoServiceBytesRecursive []BlkioStatEntry `json:"io_service_bytes_recursive,omitempty"`
-	IoServicedRecursive     []BlkioStatEntry `json:"io_serviced_recusrive,omitempty"`
+	IoServicedRecursive     []BlkioStatEntry `json:"io_serviced_recursive,omitempty"`
 	IoQueuedRecursive       []BlkioStatEntry `json:"io_queue_recursive,omitempty"`
 	IoQueuedRecursive       []BlkioStatEntry `json:"io_queue_recursive,omitempty"`
+	IoServiceTimeRecursive  []BlkioStatEntry `json:"io_service_time_recursive,omitempty"`
+	IoWaitTimeRecursive     []BlkioStatEntry `json:"io_wait_time_recursive,omitempty"`
+	IoMergedRecursive       []BlkioStatEntry `json:"io_merged_recursive,omitempty"`
+	IoTimeRecursive         []BlkioStatEntry `json:"io_time_recursive,omitempty"`
 	SectorsRecursive        []BlkioStatEntry `json:"sectors_recursive,omitempty"`
 	SectorsRecursive        []BlkioStatEntry `json:"sectors_recursive,omitempty"`
 }
 }
 
 

+ 3 - 0
vendor/src/github.com/docker/libcontainer/config.go

@@ -47,6 +47,9 @@ type Config struct {
 	// Networks specifies the container's network setup to be created
 	// Networks specifies the container's network setup to be created
 	Networks []*Network `json:"networks,omitempty"`
 	Networks []*Network `json:"networks,omitempty"`
 
 
+	// Ipc specifies the container's ipc setup to be created
+	IpcNsPath string `json:"ipc,omitempty"`
+
 	// Routes can be specified to create entries in the route table as the container is started
 	// Routes can be specified to create entries in the route table as the container is started
 	Routes []*Route `json:"routes,omitempty"`
 	Routes []*Route `json:"routes,omitempty"`
 
 

+ 4 - 1
vendor/src/github.com/docker/libcontainer/devices/devices.go

@@ -100,7 +100,8 @@ func getDeviceNodes(path string) ([]*Device, error) {
 
 
 	out := []*Device{}
 	out := []*Device{}
 	for _, f := range files {
 	for _, f := range files {
-		if f.IsDir() {
+		switch {
+		case f.IsDir():
 			switch f.Name() {
 			switch f.Name() {
 			case "pts", "shm", "fd":
 			case "pts", "shm", "fd":
 				continue
 				continue
@@ -113,6 +114,8 @@ func getDeviceNodes(path string) ([]*Device, error) {
 				out = append(out, sub...)
 				out = append(out, sub...)
 				continue
 				continue
 			}
 			}
+		case f.Name() == "console":
+			continue
 		}
 		}
 
 
 		device, err := GetDevice(filepath.Join(path, f.Name()), "rwm")
 		device, err := GetDevice(filepath.Join(path, f.Name()), "rwm")

+ 120 - 0
vendor/src/github.com/docker/libcontainer/integration/exec_test.go

@@ -1,6 +1,7 @@
 package integration
 package integration
 
 
 import (
 import (
+	"os"
 	"strings"
 	"strings"
 	"testing"
 	"testing"
 )
 )
@@ -36,3 +37,122 @@ func TestExecPS(t *testing.T) {
 		t.Fatalf("expected output %q but received %q", expected, actual)
 		t.Fatalf("expected output %q but received %q", expected, actual)
 	}
 	}
 }
 }
+
+func TestIPCPrivate(t *testing.T) {
+	if testing.Short() {
+		return
+	}
+
+	rootfs, err := newRootFs()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer remove(rootfs)
+
+	l, err := os.Readlink("/proc/1/ns/ipc")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	config := newTemplateConfig(rootfs)
+	config.Namespaces["NEWIPC"] = true
+	buffers, exitCode, err := runContainer(config, "", "readlink", "/proc/self/ns/ipc")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if exitCode != 0 {
+		t.Fatalf("exit code not 0. code %d stderr %q", exitCode, buffers.Stderr)
+	}
+
+	if actual := strings.Trim(buffers.Stdout.String(), "\n"); actual == l {
+		t.Fatalf("ipc link should be private to the conatiner but equals host %q %q", actual, l)
+	}
+}
+
+func TestIPCHost(t *testing.T) {
+	if testing.Short() {
+		return
+	}
+
+	rootfs, err := newRootFs()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer remove(rootfs)
+
+	l, err := os.Readlink("/proc/1/ns/ipc")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	config := newTemplateConfig(rootfs)
+	config.Namespaces["NEWIPC"] = false
+	buffers, exitCode, err := runContainer(config, "", "readlink", "/proc/self/ns/ipc")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if exitCode != 0 {
+		t.Fatalf("exit code not 0. code %d stderr %q", exitCode, buffers.Stderr)
+	}
+
+	if actual := strings.Trim(buffers.Stdout.String(), "\n"); actual != l {
+		t.Fatalf("ipc link not equal to host link %q %q", actual, l)
+	}
+}
+
+func TestIPCJoinPath(t *testing.T) {
+	if testing.Short() {
+		return
+	}
+
+	rootfs, err := newRootFs()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer remove(rootfs)
+
+	l, err := os.Readlink("/proc/1/ns/ipc")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	config := newTemplateConfig(rootfs)
+	config.Namespaces["NEWIPC"] = false
+	config.IpcNsPath = "/proc/1/ns/ipc"
+
+	buffers, exitCode, err := runContainer(config, "", "readlink", "/proc/self/ns/ipc")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if exitCode != 0 {
+		t.Fatalf("exit code not 0. code %d stderr %q", exitCode, buffers.Stderr)
+	}
+
+	if actual := strings.Trim(buffers.Stdout.String(), "\n"); actual != l {
+		t.Fatalf("ipc link not equal to host link %q %q", actual, l)
+	}
+}
+
+func TestIPCBadPath(t *testing.T) {
+	if testing.Short() {
+		return
+	}
+
+	rootfs, err := newRootFs()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer remove(rootfs)
+
+	config := newTemplateConfig(rootfs)
+	config.Namespaces["NEWIPC"] = false
+	config.IpcNsPath = "/proc/1/ns/ipcc"
+
+	_, _, err = runContainer(config, "", "true")
+	if err == nil {
+		t.Fatal("container succeded with bad ipc path")
+	}
+}

+ 29 - 0
vendor/src/github.com/docker/libcontainer/ipc/ipc.go

@@ -0,0 +1,29 @@
+package ipc
+
+import (
+	"fmt"
+	"os"
+	"syscall"
+
+	"github.com/docker/libcontainer/system"
+)
+
+// Join the IPC Namespace of specified ipc path if it exists.
+// If the path does not exist then you are not joining a container.
+func Initialize(nsPath string) error {
+	if nsPath == "" {
+		return nil
+	}
+	f, err := os.OpenFile(nsPath, os.O_RDONLY, 0)
+	if err != nil {
+		return fmt.Errorf("failed get IPC namespace fd: %v", err)
+	}
+
+	err = system.Setns(f.Fd(), syscall.CLONE_NEWIPC)
+	f.Close()
+
+	if err != nil {
+		return fmt.Errorf("failed to setns current IPC namespace: %v", err)
+	}
+	return nil
+}

+ 4 - 0
vendor/src/github.com/docker/libcontainer/namespaces/init.go

@@ -11,6 +11,7 @@ import (
 	"github.com/docker/libcontainer"
 	"github.com/docker/libcontainer"
 	"github.com/docker/libcontainer/apparmor"
 	"github.com/docker/libcontainer/apparmor"
 	"github.com/docker/libcontainer/console"
 	"github.com/docker/libcontainer/console"
+	"github.com/docker/libcontainer/ipc"
 	"github.com/docker/libcontainer/label"
 	"github.com/docker/libcontainer/label"
 	"github.com/docker/libcontainer/mount"
 	"github.com/docker/libcontainer/mount"
 	"github.com/docker/libcontainer/netlink"
 	"github.com/docker/libcontainer/netlink"
@@ -66,6 +67,9 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syn
 			return fmt.Errorf("setctty %s", err)
 			return fmt.Errorf("setctty %s", err)
 		}
 		}
 	}
 	}
+	if err := ipc.Initialize(container.IpcNsPath); err != nil {
+		return fmt.Errorf("setup IPC %s", err)
+	}
 	if err := setupNetwork(container, networkState); err != nil {
 	if err := setupNetwork(container, networkState); err != nil {
 		return fmt.Errorf("setup networking %s", err)
 		return fmt.Errorf("setup networking %s", err)
 	}
 	}

+ 41 - 36
vendor/src/github.com/docker/libcontainer/network/stats.go

@@ -2,7 +2,6 @@ package network
 
 
 import (
 import (
 	"io/ioutil"
 	"io/ioutil"
-	"os"
 	"path/filepath"
 	"path/filepath"
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
@@ -25,45 +24,51 @@ func GetStats(networkState *NetworkState) (*NetworkStats, error) {
 	if networkState.VethHost == "" {
 	if networkState.VethHost == "" {
 		return &NetworkStats{}, nil
 		return &NetworkStats{}, nil
 	}
 	}
-	data, err := readSysfsNetworkStats(networkState.VethHost)
-	if err != nil {
-		return nil, err
+
+	out := &NetworkStats{}
+
+	type netStatsPair struct {
+		// Where to write the output.
+		Out *uint64
+
+		// The network stats file to read.
+		File string
 	}
 	}
 
 
 	// Ingress for host veth is from the container. Hence tx_bytes stat on the host veth is actually number of bytes received by the container.
 	// Ingress for host veth is from the container. Hence tx_bytes stat on the host veth is actually number of bytes received by the container.
-	return &NetworkStats{
-		RxBytes:   data["tx_bytes"],
-		RxPackets: data["tx_packets"],
-		RxErrors:  data["tx_errors"],
-		RxDropped: data["tx_dropped"],
-		TxBytes:   data["rx_bytes"],
-		TxPackets: data["rx_packets"],
-		TxErrors:  data["rx_errors"],
-		TxDropped: data["rx_dropped"],
-	}, nil
-}
+	netStats := []netStatsPair{
+		{Out: &out.RxBytes, File: "tx_bytes"},
+		{Out: &out.RxPackets, File: "tx_packets"},
+		{Out: &out.RxErrors, File: "tx_errors"},
+		{Out: &out.RxDropped, File: "tx_dropped"},
 
 
-// Reads all the statistics available under /sys/class/net/<EthInterface>/statistics as a map with file name as key and data as integers.
-func readSysfsNetworkStats(ethInterface string) (map[string]uint64, error) {
-	out := make(map[string]uint64)
-
-	fullPath := filepath.Join("/sys/class/net", ethInterface, "statistics/")
-	err := filepath.Walk(fullPath, func(path string, _ os.FileInfo, _ error) error {
-		// skip fullPath.
-		if path == fullPath {
-			return nil
-		}
-		base := filepath.Base(path)
-		data, err := ioutil.ReadFile(path)
-		if err != nil {
-			return err
-		}
-		value, err := strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64)
+		{Out: &out.TxBytes, File: "rx_bytes"},
+		{Out: &out.TxPackets, File: "rx_packets"},
+		{Out: &out.TxErrors, File: "rx_errors"},
+		{Out: &out.TxDropped, File: "rx_dropped"},
+	}
+	for _, netStat := range netStats {
+		data, err := readSysfsNetworkStats(networkState.VethHost, netStat.File)
 		if err != nil {
 		if err != nil {
-			return err
+			return nil, err
 		}
 		}
-		out[base] = value
-		return nil
-	})
-	return out, err
+		*(netStat.Out) = data
+	}
+
+	return out, nil
+}
+
+// Reads the specified statistics available under /sys/class/net/<EthInterface>/statistics
+func readSysfsNetworkStats(ethInterface, statsFile string) (uint64, error) {
+	fullPath := filepath.Join("/sys/class/net", ethInterface, "statistics", statsFile)
+	data, err := ioutil.ReadFile(fullPath)
+	if err != nil {
+		return 0, err
+	}
+	value, err := strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64)
+	if err != nil {
+		return 0, err
+	}
+
+	return value, err
 }
 }

+ 8 - 0
vendor/src/github.com/docker/libcontainer/xattr/errors.go

@@ -0,0 +1,8 @@
+package xattr
+
+import (
+	"fmt"
+	"runtime"
+)
+
+var ErrNotSupportedPlatform = fmt.Errorf("platform and architecture is not supported %s %s", runtime.GOOS, runtime.GOARCH)