Browse code

Merge pull request #13196 from crosbymichael/update-libocntainer-may13

Update libcontainer to a37b2a4f152e2a1c9de596f54c0

Alexander Morozov authored on 2015/05/15 02:49:25
Showing 11 changed files
... ...
@@ -65,7 +65,7 @@ mv tmp-digest src/github.com/docker/distribution/digest
65 65
 mkdir -p src/github.com/docker/distribution/registry
66 66
 mv tmp-api src/github.com/docker/distribution/registry/api
67 67
 
68
-clone git github.com/docker/libcontainer 90f8aa670f1f424041059060c7c63fe4dee2e441
68
+clone git github.com/docker/libcontainer a37b2a4f152e2a1c9de596f54c051cb889de0691
69 69
 # libcontainer deps (see src/github.com/docker/libcontainer/update-vendor.sh)
70 70
 clone git github.com/coreos/go-systemd v2
71 71
 clone git github.com/godbus/dbus v2
... ...
@@ -3245,8 +3245,8 @@ func (s *DockerSuite) TestMountIntoProc(c *check.C) {
3245 3245
 func (s *DockerSuite) TestMountIntoSys(c *check.C) {
3246 3246
 	testRequires(c, NativeExecDriver)
3247 3247
 	defer deleteAllContainers()
3248
-	code, err := runCommand(exec.Command(dockerBinary, "run", "-v", "/sys/", "busybox", "true"))
3249
-	if err == nil || code == 0 {
3250
-		c.Fatal("container should not be able to mount into /sys")
3248
+	_, err := runCommand(exec.Command(dockerBinary, "run", "-v", "/sys/fs/cgroup", "busybox", "true"))
3249
+	if err != nil {
3250
+		c.Fatal("container should be able to mount into /sys/fs/cgroup")
3251 3251
 	}
3252 3252
 }
... ...
@@ -262,6 +262,11 @@ func (raw *data) join(subsystem string) (string, error) {
262 262
 }
263 263
 
264 264
 func writeFile(dir, file, data string) error {
265
+	// Normally dir should not be empty, one case is that cgroup subsystem
266
+	// is not mounted, we will get empty dir, and we want it fail here.
267
+	if dir == "" {
268
+		return fmt.Errorf("no such directory for %s.", file)
269
+	}
265 270
 	return ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700)
266 271
 }
267 272
 
... ...
@@ -17,7 +17,7 @@ func (s *CpuGroup) Apply(d *data) error {
17 17
 	// We always want to join the cpu group, to allow fair cpu scheduling
18 18
 	// on a container basis
19 19
 	dir, err := d.join("cpu")
20
-	if err != nil {
20
+	if err != nil && !cgroups.IsNotFound(err) {
21 21
 		return err
22 22
 	}
23 23
 
... ...
@@ -16,7 +16,7 @@ type CpusetGroup struct {
16 16
 
17 17
 func (s *CpusetGroup) Apply(d *data) error {
18 18
 	dir, err := d.path("cpuset")
19
-	if err != nil {
19
+	if err != nil && !cgroups.IsNotFound(err) {
20 20
 		return err
21 21
 	}
22 22
 
... ...
@@ -48,6 +48,11 @@ func (s *CpusetGroup) GetStats(path string, stats *cgroups.Stats) error {
48 48
 }
49 49
 
50 50
 func (s *CpusetGroup) ApplyDir(dir string, cgroup *configs.Cgroup, pid int) error {
51
+	// This might happen if we have no cpuset cgroup mounted.
52
+	// Just do nothing and don't fail.
53
+	if dir == "" {
54
+		return nil
55
+	}
51 56
 	if err := s.ensureParent(dir); err != nil {
52 57
 		return err
53 58
 	}
... ...
@@ -11,6 +11,8 @@ type DevicesGroup struct {
11 11
 func (s *DevicesGroup) Apply(d *data) error {
12 12
 	dir, err := d.join("devices")
13 13
 	if err != nil {
14
+		// We will return error even it's `not found` error, devices
15
+		// cgroup is hard requirement for container's security.
14 16
 		return err
15 17
 	}
16 18
 
... ...
@@ -16,8 +16,7 @@ type MemoryGroup struct {
16 16
 
17 17
 func (s *MemoryGroup) Apply(d *data) error {
18 18
 	dir, err := d.join("memory")
19
-	// only return an error for memory if it was specified
20
-	if err != nil && (d.c.Memory != 0 || d.c.MemoryReservation != 0 || d.c.MemorySwap != 0) {
19
+	if err != nil && !cgroups.IsNotFound(err) {
21 20
 		return err
22 21
 	}
23 22
 	defer func() {
... ...
@@ -256,6 +256,11 @@ func (m *Manager) GetPaths() map[string]string {
256 256
 }
257 257
 
258 258
 func writeFile(dir, file, data string) error {
259
+	// Normally dir should not be empty, one case is that cgroup subsystem
260
+	// is not mounted, we will get empty dir, and we want it fail here.
261
+	if dir == "" {
262
+		return fmt.Errorf("no such directory for %s.", file)
263
+	}
259 264
 	return ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700)
260 265
 }
261 266
 
... ...
@@ -276,16 +281,16 @@ func join(c *configs.Cgroup, subsystem string, pid int) (string, error) {
276 276
 
277 277
 func joinCpu(c *configs.Cgroup, pid int) error {
278 278
 	path, err := getSubsystemPath(c, "cpu")
279
-	if err != nil {
279
+	if err != nil && !cgroups.IsNotFound(err) {
280 280
 		return err
281 281
 	}
282 282
 	if c.CpuQuota != 0 {
283
-		if err = ioutil.WriteFile(filepath.Join(path, "cpu.cfs_quota_us"), []byte(strconv.FormatInt(c.CpuQuota, 10)), 0700); err != nil {
283
+		if err = writeFile(path, "cpu.cfs_quota_us", strconv.FormatInt(c.CpuQuota, 10)); err != nil {
284 284
 			return err
285 285
 		}
286 286
 	}
287 287
 	if c.CpuPeriod != 0 {
288
-		if err = ioutil.WriteFile(filepath.Join(path, "cpu.cfs_period_us"), []byte(strconv.FormatInt(c.CpuPeriod, 10)), 0700); err != nil {
288
+		if err = writeFile(path, "cpu.cfs_period_us", strconv.FormatInt(c.CpuPeriod, 10)); err != nil {
289 289
 			return err
290 290
 		}
291 291
 	}
... ...
@@ -293,7 +298,7 @@ func joinCpu(c *configs.Cgroup, pid int) error {
293 293
 }
294 294
 
295 295
 func joinFreezer(c *configs.Cgroup, pid int) error {
296
-	if _, err := join(c, "freezer", pid); err != nil {
296
+	if _, err := join(c, "freezer", pid); err != nil && !cgroups.IsNotFound(err) {
297 297
 		return err
298 298
 	}
299 299
 
... ...
@@ -393,6 +398,8 @@ func getUnitName(c *configs.Cgroup) string {
393 393
 // This happens at least for v208 when any sibling unit is started.
394 394
 func joinDevices(c *configs.Cgroup, pid int) error {
395 395
 	path, err := join(c, "devices", pid)
396
+	// Even if it's `not found` error, we'll return err because devices cgroup
397
+	// is hard requirement for container security.
396 398
 	if err != nil {
397 399
 		return err
398 400
 	}
... ...
@@ -410,11 +417,11 @@ func joinMemory(c *configs.Cgroup, pid int) error {
410 410
 	}
411 411
 
412 412
 	path, err := getSubsystemPath(c, "memory")
413
-	if err != nil {
413
+	if err != nil && !cgroups.IsNotFound(err) {
414 414
 		return err
415 415
 	}
416 416
 
417
-	return ioutil.WriteFile(filepath.Join(path, "memory.memsw.limit_in_bytes"), []byte(strconv.FormatInt(memorySwap, 10)), 0700)
417
+	return writeFile(path, "memory.memsw.limit_in_bytes", strconv.FormatInt(memorySwap, 10))
418 418
 }
419 419
 
420 420
 // systemd does not atm set up the cpuset controller, so we must manually
... ...
@@ -422,7 +429,7 @@ func joinMemory(c *configs.Cgroup, pid int) error {
422 422
 // level must have a full setup as the default for a new directory is "no cpus"
423 423
 func joinCpuset(c *configs.Cgroup, pid int) error {
424 424
 	path, err := getSubsystemPath(c, "cpuset")
425
-	if err != nil {
425
+	if err != nil && !cgroups.IsNotFound(err) {
426 426
 		return err
427 427
 	}
428 428
 
... ...
@@ -215,7 +215,6 @@ func checkMountDestination(rootfs, dest string) error {
215 215
 	}
216 216
 	invalidDestinations := []string{
217 217
 		"/proc",
218
-		"/sys",
219 218
 	}
220 219
 	for _, invalid := range invalidDestinations {
221 220
 		path, err := filepath.Rel(filepath.Join(rootfs, invalid), dest)
... ...
@@ -15,8 +15,8 @@ func TestCheckMountDestOnProc(t *testing.T) {
15 15
 func TestCheckMountDestInSys(t *testing.T) {
16 16
 	dest := "/rootfs//sys/fs/cgroup"
17 17
 	err := checkMountDestination("/rootfs", dest)
18
-	if err == nil {
19
-		t.Fatal("destination inside proc should return an error")
18
+	if err != nil {
19
+		t.Fatal("destination inside /sys should not return an error")
20 20
 	}
21 21
 }
22 22
 
... ...
@@ -44,6 +44,6 @@ clone git github.com/codegangsta/cli 1.1.0
44 44
 clone git github.com/coreos/go-systemd v2
45 45
 clone git github.com/godbus/dbus v2
46 46
 clone git github.com/Sirupsen/logrus v0.7.3
47
-clone git github.com/syndtr/gocapability 8e4cdcb
47
+clone git github.com/syndtr/gocapability 66ef2aa
48 48
 
49 49
 # intentionally not vendoring Docker itself...  that'd be a circle :)