浏览代码

Cgroups allow devices for privileged containers
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)

Michael Crosby 11 年之前
父节点
当前提交
a76407ac61
共有 3 个文件被更改,包括 40 次插入11 次删除
  1. 37 1
      execdriver/namespaces/driver.go
  2. 2 2
      integration/container_test.go
  3. 1 8
      pkg/libcontainer/nsinit/init.go

+ 37 - 1
execdriver/namespaces/driver.go

@@ -6,6 +6,7 @@ import (
 	"fmt"
 	"github.com/dotcloud/docker/execdriver"
 	"github.com/dotcloud/docker/execdriver/lxc"
+	"github.com/dotcloud/docker/pkg/cgroups"
 	"github.com/dotcloud/docker/pkg/libcontainer"
 	"github.com/dotcloud/docker/pkg/libcontainer/nsinit"
 	"io"
@@ -13,6 +14,7 @@ import (
 	"os"
 	"os/exec"
 	"path/filepath"
+	"strconv"
 	"strings"
 	"syscall"
 )
@@ -125,7 +127,40 @@ func (d *driver) Name() string {
 }
 
 func (d *driver) GetPidsForContainer(id string) ([]int, error) {
-	return nil, ErrNotSupported
+	pids := []int{}
+
+	subsystem := "cpu"
+	cgroupRoot, err := cgroups.FindCgroupMountpoint(subsystem)
+	if err != nil {
+		return pids, err
+	}
+	cgroupRoot = filepath.Dir(cgroupRoot)
+
+	cgroupDir, err := cgroups.GetThisCgroupDir(subsystem)
+	if err != nil {
+		return pids, err
+	}
+
+	filename := filepath.Join(cgroupRoot, cgroupDir, id, "tasks")
+	if _, err := os.Stat(filename); os.IsNotExist(err) {
+		filename = filepath.Join(cgroupRoot, cgroupDir, "docker", id, "tasks")
+	}
+
+	output, err := ioutil.ReadFile(filename)
+	if err != nil {
+		return pids, err
+	}
+	for _, p := range strings.Split(string(output), "\n") {
+		if len(p) == 0 {
+			continue
+		}
+		pid, err := strconv.Atoi(p)
+		if err != nil {
+			return pids, fmt.Errorf("Invalid pid '%s': %s", p, err)
+		}
+		pids = append(pids, pid)
+	}
+	return pids, nil
 }
 
 func writeContainerFile(container *libcontainer.Container, rootfs string) error {
@@ -219,6 +254,7 @@ func createContainer(c *execdriver.Command) *libcontainer.Container {
 	}
 	if c.Privileged {
 		container.Capabilities = nil
+		container.Cgroups.DeviceAccess = true
 	}
 	if c.Resources != nil {
 		container.Cgroups.CpuShares = c.Resources.CpuShares

+ 2 - 2
integration/container_test.go

@@ -1581,8 +1581,8 @@ func TestPrivilegedCanMknod(t *testing.T) {
 	eng := NewTestEngine(t)
 	runtime := mkRuntimeFromEngine(eng, t)
 	defer runtime.Nuke()
-	if output, _ := runContainer(eng, runtime, []string{"-privileged", "_", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok"}, t); output != "ok\n" {
-		t.Fatal("Could not mknod into privileged container")
+	if output, err := runContainer(eng, runtime, []string{"-privileged", "_", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok"}, t); output != "ok\n" {
+		t.Fatalf("Could not mknod into privileged container %s %v", output, err)
 	}
 }
 

+ 1 - 8
pkg/libcontainer/nsinit/init.go

@@ -9,7 +9,6 @@ import (
 	"github.com/dotcloud/docker/pkg/libcontainer/network"
 	"github.com/dotcloud/docker/pkg/system"
 	"github.com/dotcloud/docker/pkg/user"
-	"log"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -23,7 +22,6 @@ func Init(container *libcontainer.Container, uncleanRootfs, console string, sync
 	if err != nil {
 		return err
 	}
-	log.Printf("initializing namespace at %s", rootfs)
 
 	// We always read this as it is a way to sync with the parent as well
 	context, err := syncPipe.ReadFromParent()
@@ -32,10 +30,8 @@ func Init(container *libcontainer.Container, uncleanRootfs, console string, sync
 		return err
 	}
 	syncPipe.Close()
-	log.Printf("received context from parent %v", context)
 
 	if console != "" {
-		log.Printf("setting up console for %s", console)
 		// close pipes so that we can replace it with the pty
 		closeStdPipes()
 		slave, err := openTerminal(console, syscall.O_RDWR)
@@ -66,11 +62,9 @@ func Init(container *libcontainer.Container, uncleanRootfs, console string, sync
 	if err := system.Sethostname(container.Hostname); err != nil {
 		return fmt.Errorf("sethostname %s", err)
 	}
-	log.Printf("dropping capabilities")
 	if err := capabilities.DropCapabilities(container); err != nil {
 		return fmt.Errorf("drop capabilities %s", err)
 	}
-	log.Printf("setting user in namespace")
 	if err := setupUser(container); err != nil {
 		return fmt.Errorf("setup user %s", err)
 	}
@@ -87,7 +81,6 @@ func execArgs(args []string, env []string) error {
 	if err != nil {
 		return err
 	}
-	log.Printf("execing %s goodbye", name)
 	if err := system.Exec(name, args[0:], env); err != nil {
 		return fmt.Errorf("exec %s", err)
 	}
@@ -111,7 +104,7 @@ func resolveRootfs(uncleanRootfs string) (string, error) {
 }
 
 func setupUser(container *libcontainer.Container) error {
-	if container.User != "" {
+	if container.User != "" && container.User != "root" {
 		uid, gid, suppGids, err := user.GetUserGroupSupplementary(container.User, syscall.Getuid(), syscall.Getgid())
 		if err != nil {
 			return err