execdriver: Make GetPidsForContainer() a driver call

The current implementation is lxc specific.

Docker-DCO-1.1-Signed-off-by: Alexander Larsson <alexl@redhat.com> (github: alexlarsson)
This commit is contained in:
Alexander Larsson 2014-01-28 16:17:51 +01:00
parent ffdc2d2657
commit 335bc39c9a
5 changed files with 51 additions and 49 deletions

View file

@ -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")
}

View file

@ -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

View file

@ -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 {

View file

@ -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
}

View file

@ -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