diff --git a/execdriver/chroot/driver.go b/execdriver/chroot/driver.go index 4b2e02904e..1fe8a5418f 100644 --- a/execdriver/chroot/driver.go +++ b/execdriver/chroot/driver.go @@ -85,3 +85,7 @@ func (d *driver) Info(id string) execdriver.Info { func (d *driver) Name() string { return fmt.Sprintf("%s-%s", DriverName, Version) } + +func (d *driver) GetPidsForContainer(id string) ([]int, error) { + return nil, fmt.Errorf("Not supported") +} diff --git a/execdriver/driver.go b/execdriver/driver.go index 511e9e80c6..fd6e0e1c31 100644 --- a/execdriver/driver.go +++ b/execdriver/driver.go @@ -61,9 +61,10 @@ type Info interface { type Driver interface { Run(c *Command, startCallback StartCallback) (int, error) // Run executes the process and blocks until the process exits and returns the exit code Kill(c *Command, sig int) error - Restore(c *Command) error // Wait and try to re-attach on an out of process command - Name() string // Driver name - Info(id string) Info // "temporary" hack (until we move state from core to plugins) + Restore(c *Command) error // Wait and try to re-attach on an out of process command + Name() string // Driver name + Info(id string) Info // "temporary" hack (until we move state from core to plugins) + GetPidsForContainer(id string) ([]int, error) // Returns a list of pids for the given container. } // Network settings of the container diff --git a/execdriver/lxc/driver.go b/execdriver/lxc/driver.go index 0e64dfd968..d35c72dbe9 100644 --- a/execdriver/lxc/driver.go +++ b/execdriver/lxc/driver.go @@ -3,12 +3,14 @@ package lxc import ( "fmt" "github.com/dotcloud/docker/execdriver" + "github.com/dotcloud/docker/pkg/cgroups" "github.com/dotcloud/docker/utils" "io/ioutil" "log" "os" "os/exec" "path" + "path/filepath" "strconv" "strings" "syscall" @@ -272,6 +274,45 @@ func (d *driver) Info(id string) execdriver.Info { } } +func (d *driver) GetPidsForContainer(id string) ([]int, error) { + pids := []int{} + + // memory is chosen randomly, any cgroup used by docker works + subsystem := "memory" + + cgroupRoot, err := cgroups.FindCgroupMountpoint(subsystem) + if err != nil { + return pids, err + } + + 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) { + // With more recent lxc versions use, cgroup will be in lxc/ + filename = filepath.Join(cgroupRoot, cgroupDir, "lxc", 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 linkLxcStart(root string) error { sourcePath, err := exec.LookPath("lxc-start") if err != nil { diff --git a/pkg/cgroups/cgroups.go b/pkg/cgroups/cgroups.go index de7b079dc2..91ac3842ac 100644 --- a/pkg/cgroups/cgroups.go +++ b/pkg/cgroups/cgroups.go @@ -5,10 +5,7 @@ import ( "fmt" "github.com/dotcloud/docker/pkg/mount" "io" - "io/ioutil" "os" - "path/filepath" - "strconv" "strings" ) @@ -33,7 +30,7 @@ func FindCgroupMountpoint(subsystem string) (string, error) { } // Returns the relative path to the cgroup docker is running in. -func getThisCgroupDir(subsystem string) (string, error) { +func GetThisCgroupDir(subsystem string) (string, error) { f, err := os.Open("/proc/self/cgroup") if err != nil { return "", err @@ -58,43 +55,3 @@ func parseCgroupFile(subsystem string, r io.Reader) (string, error) { } return "", fmt.Errorf("cgroup '%s' not found in /proc/self/cgroup", subsystem) } - -// Returns a list of pids for the given container. -func GetPidsForContainer(id string) ([]int, error) { - pids := []int{} - - // memory is chosen randomly, any cgroup used by docker works - subsystem := "memory" - - cgroupRoot, err := FindCgroupMountpoint(subsystem) - if err != nil { - return pids, err - } - - cgroupDir, err := getThisCgroupDir(subsystem) - if err != nil { - return pids, err - } - - filename := filepath.Join(cgroupRoot, cgroupDir, id, "tasks") - if _, err := os.Stat(filename); os.IsNotExist(err) { - // With more recent lxc versions use, cgroup will be in lxc/ - filename = filepath.Join(cgroupRoot, cgroupDir, "lxc", 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 -} diff --git a/server.go b/server.go index 5fbde5865d..ebccf4c850 100644 --- a/server.go +++ b/server.go @@ -7,7 +7,6 @@ import ( "github.com/dotcloud/docker/archive" "github.com/dotcloud/docker/auth" "github.com/dotcloud/docker/engine" - "github.com/dotcloud/docker/pkg/cgroups" "github.com/dotcloud/docker/pkg/graphdb" "github.com/dotcloud/docker/registry" "github.com/dotcloud/docker/utils" @@ -980,7 +979,7 @@ func (srv *Server) ContainerTop(job *engine.Job) engine.Status { job.Errorf("Container %s is not running", name) return engine.StatusErr } - pids, err := cgroups.GetPidsForContainer(container.ID) + pids, err := srv.runtime.execDriver.GetPidsForContainer(container.ID) if err != nil { job.Error(err) return engine.StatusErr