From 5ab2f45fc645e49265b5f0b1686fe42e8ae8b059 Mon Sep 17 00:00:00 2001 From: Vishnu kannan Date: Fri, 29 Jan 2016 16:36:43 -0800 Subject: [PATCH] Use storage dir from docker info for filesystem usage tracking. Signed-off-by: Vishnu kannan --- container/docker/factory.go | 60 +++++++++++++++++++++++++++++++++---- container/docker/handler.go | 15 ++++------ 2 files changed, 60 insertions(+), 15 deletions(-) diff --git a/container/docker/factory.go b/container/docker/factory.go index de73365d..34ed4b70 100644 --- a/container/docker/factory.go +++ b/container/docker/factory.go @@ -15,6 +15,7 @@ package docker import ( + "encoding/json" "flag" "fmt" "path" @@ -40,6 +41,7 @@ var ArgDockerEndpoint = flag.String("docker", "unix:///var/run/docker.sock", "do var DockerNamespace = "docker" // Basepath to all container specific information that libcontainer stores. +// TODO: Deprecate this flag var dockerRootDir = flag.String("docker_root", "/var/lib/docker", "Absolute path to the Docker state root directory (default: /var/lib/docker)") var dockerRunDir = flag.String("docker_run", "/var/run/docker", "Absolute path to the Docker run directory (default: /var/run/docker)") @@ -61,6 +63,10 @@ func DockerStateDir() string { var useSystemd = false var check = sync.Once{} +const ( + dockerRootDirKey = "Root Dir" +) + func UseSystemd() bool { check.Do(func() { if *noSystemd { @@ -100,7 +106,8 @@ const ( type dockerFactory struct { machineInfoFactory info.MachineInfoFactory - storageDriver storageDriver + storageDriver storageDriver + storageDriverDir string client *docker.Client @@ -129,6 +136,7 @@ func (self *dockerFactory) NewContainerHandler(name string, inHostNamespace bool self.machineInfoFactory, self.fsInfo, self.storageDriver, + self.storageDriverDir, &self.cgroupSubsystems, inHostNamespace, metadataEnvs, @@ -204,6 +212,37 @@ func parseDockerVersion(full_version_string string) ([]int, error) { return version_array, nil } +func getStorageDir(dockerInfo *docker.Env) (string, error) { + storageDriverInfo := dockerInfo.GetList("DriverStatus") + if len(storageDriverInfo) == 0 { + return "", fmt.Errorf("failed to find docker storage driver options") + } + + var storageDir string + for _, data := range storageDriverInfo { + if data == "" { + continue + } + var parts [][]string + if err := json.Unmarshal([]byte(data), &parts); err != nil { + return "", fmt.Errorf("failed to parse docker storage driver options - %+v", data) + } + for _, part := range parts { + if len(part) != 2 { + return "", fmt.Errorf("failed to parse docker storage driver options - %+v", part) + } + if part[0] == dockerRootDirKey { + storageDir = part[1] + break + } + } + } + if storageDir == "" { + return "", fmt.Errorf("failed to find docker storage directory from docker info. Expected key %q in storage driver info %v", dockerRootDirKey, storageDriverInfo) + } + return storageDir, nil +} + // Register root container before running this function! func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo) error { if UseSystemd() { @@ -232,18 +271,26 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo) error { } } - // Check that the libcontainer execdriver is used. - information, err := DockerInfo() + information, err := client.Info() if err != nil { return fmt.Errorf("failed to detect Docker info: %v", err) } - execDriver, ok := information["ExecutionDriver"] - if !ok || !strings.HasPrefix(execDriver, "native") { + + // Check that the libcontainer execdriver is used. + execDriver := information.Get("ExecutionDriver") + if !strings.HasPrefix(execDriver, "native") { return fmt.Errorf("docker found, but not using native exec driver") } - sd, _ := information["Driver"] + sd := information.Get("Driver") + if sd == "" { + return fmt.Errorf("failed to find docker storage driver") + } + storageDir, err := getStorageDir(information) + if err != nil { + return err + } cgroupSubsystems, err := libcontainer.GetCgroupSubsystems() if err != nil { return fmt.Errorf("failed to get cgroup subsystems: %v", err) @@ -254,6 +301,7 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo) error { machineInfoFactory: factory, client: client, storageDriver: storageDriver(sd), + storageDriverDir: storageDir, cgroupSubsystems: cgroupSubsystems, fsInfo: fsInfo, } diff --git a/container/docker/handler.go b/container/docker/handler.go index 2d8af6ce..61f2a571 100644 --- a/container/docker/handler.go +++ b/container/docker/handler.go @@ -35,14 +35,10 @@ import ( ) const ( - // Path to aufs dir where all the files exist. - // aufs/layers is ignored here since it does not hold a lot of data. - // aufs/mnt contains the mount points used to compose the rootfs. Hence it is also ignored. - pathToAufsDir = "aufs/diff" + // The read write layers exist here. + aufsRWLayer = "diff" // Path to the directory where docker stores log files if the json logging driver is enabled. pathToContainersDir = "containers" - // Path to the overlayfs storage driver directory. - pathToOverlayDir = "overlay" ) type dockerContainerHandler struct { @@ -92,6 +88,7 @@ func newDockerContainerHandler( machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, storageDriver storageDriver, + storageDriverDir string, cgroupSubsystems *containerlibcontainer.CgroupSubsystems, inHostNamespace bool, metadataEnvs []string, @@ -118,13 +115,13 @@ func newDockerContainerHandler( id := ContainerNameToDockerId(name) // Add the Containers dir where the log files are stored. - otherStorageDir := path.Join(*dockerRootDir, pathToContainersDir, id) + otherStorageDir := path.Join(path.Dir(storageDriverDir), pathToContainersDir, id) var rootfsStorageDir string switch storageDriver { case aufsStorageDriver: - rootfsStorageDir = path.Join(*dockerRootDir, pathToAufsDir, id) + rootfsStorageDir = path.Join(storageDriverDir, aufsRWLayer, id) case overlayStorageDriver: - rootfsStorageDir = path.Join(*dockerRootDir, pathToOverlayDir, id) + rootfsStorageDir = path.Join(storageDriverDir, id) } handler := &dockerContainerHandler{