Skip to content

Commit

Permalink
Filesystem stats are now per container. As of now, fs stats are repor…
Browse files Browse the repository at this point in the history
…ted only for the

root cgroup.
To make cadvisor detect all the disks, the rootfs of host needs to mounted
inside cadvisor.
  • Loading branch information
vishh committed Sep 30, 2014
1 parent 946b18f commit b9e70f0
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 21 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ To quickly tryout cAdvisor on your machine with Docker (version 0.11 or above),

```
sudo docker run \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:rw \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
Expand Down
20 changes: 13 additions & 7 deletions container/raw/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type rawContainerHandler struct {
watcher *inotify.Watcher
stopWatcher chan error
watches map[string]struct{}
fsInfo fs.FsInfo
fsInfo fs.FsInfo
}

func newRawContainerHandler(name string, cgroupSubsystems *cgroupSubsystems, machineInfoFactory info.MachineInfoFactory) (container.ContainerHandler, error) {
Expand All @@ -55,7 +55,7 @@ func newRawContainerHandler(name string, cgroupSubsystems *cgroupSubsystems, mac
machineInfoFactory: machineInfoFactory,
stopWatcher: make(chan error),
watches: make(map[string]struct{}),
fsInfo: fs.NewFsInfo(),
fsInfo: fs.NewFsInfo(),
}, nil
}

Expand Down Expand Up @@ -144,6 +144,10 @@ func (self *rawContainerHandler) GetSpec() (info.ContainerSpec, error) {
}
}

// Fs.
if self.name == "/" {
spec.HasFs = true
}
return spec, nil
}

Expand All @@ -152,12 +156,14 @@ func (self *rawContainerHandler) GetStats() (*info.ContainerStats, error) {
if err != nil {
return nil, err
}
// Get Filesystem information
fsStats, err := self.fsInfo.GetFsStats(self.name)
if err != nil {
return nil, err
// Get Filesystem information only for the root cgroup.
if self.name == "/" {
stats.Fs, err = self.fsInfo.GetFsStats()
if err != nil {
return nil, err
}
}
stats.FsStats = fsStats

return stats, nil
}

Expand Down
1 change: 1 addition & 0 deletions deploy/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ MAINTAINER [email protected] [email protected] [email protected]

# Grab cadvisor from the staging directory.
ADD cadvisor /usr/bin/cadvisor
RUN mkdir /rootfs

EXPOSE 8080
ENTRYPOINT ["/usr/bin/cadvisor"]
27 changes: 18 additions & 9 deletions fs/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,49 @@ package fs
import "C"

import (
"strings"
"syscall"
"unsafe"

"github.com/docker/docker/pkg/mount"
"github.com/golang/glog"
)

const EXT_SUPER_MAGIC = 0xEF53

type FsInfoImpl struct{}

func NewFsInfo() FsInfo {
return &FsInfoImpl{}
}

func (*FsInfoImpl) GetFsStats(containerName string) ([]FsStat, error) {
func (*FsInfoImpl) GetFsStats() ([]FsStat, error) {
filesystems := make([]FsStat, 0)
if containerName != "/" {
return filesystems, nil
}
mounts, err := mount.GetMounts()
if err != nil {
return nil, err
}
processedPartitions := make(map[string]bool, 0)
for _, mount := range mounts {
if !strings.HasPrefix("ext", mount.FsType) || mount.Mountpoint != mount.Root {
if !strings.HasPrefix(mount.Fstype, "ext") {
continue
}
// Avoid bind mounts.
if _, ok := processedPartitions[mount.Source]; ok {
continue
}
total, free, err := getVfsStats(mount.Mountpoint)
if err != nil {
glog.Errorf("Statvfs failed. Error: %v", err)
} else {
glog.V(1).Infof("%s is an ext partition at %s. Total: %d, Free: %d", mount.Source, mount.Mountpoint, total, free)
filesystems = append(filesystems, FsStat{mount.Source, total, free})
glog.V(1).Infof("%s is an %s partition at %s. Total: %d, Free: %d", mount.Source, mount.Fstype, mount.Mountpoint, total, free)
fsStat := FsStat{
Device: mount.Source,
Major: uint(mount.Major),
Minor: uint(mount.Minor),
Capacity: total,
Free: free,
}
filesystems = append(filesystems, fsStat)
processedPartitions[mount.Source] = true
}
}
return filesystems, nil
Expand Down
8 changes: 5 additions & 3 deletions fs/types.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package fs

type FsStat struct {
Name string `json:"name"`
Device string `json:"device,omitempty"`
Major uint `json:"major"`
Minor uint `json:"minor"`
Capacity uint64 `json:"capacity"`
Free uint64 `json:"free"`
}

type FsInfo interface {
// Returns capacity and free space, in bytes, of all the ext2, ext3, ext4 filesystems used by container 'containerName'.
GetFsStats(containerName string) ([]FsStat, error)
// Returns capacity and free space, in bytes, of all the ext2, ext3, ext4 filesystems on the host.
GetFsStats() ([]FsStat, error)
}
6 changes: 4 additions & 2 deletions info/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ package info
import (
"reflect"
"time"

"github.com/google/cadvisor/fs"
)

Expand Down Expand Up @@ -49,6 +49,8 @@ type ContainerSpec struct {
Memory MemorySpec `json:"memory,omitempty"`

HasNetwork bool `json:"has_network"`

HasFs bool `json:"has_fs"`
}

// Container reference contains enough information to uniquely identify a container
Expand Down Expand Up @@ -239,7 +241,7 @@ type ContainerStats struct {
Memory *MemoryStats `json:"memory,omitempty"`
Network *NetworkStats `json:"network,omitempty"`
// Filesystem statistics
FsStats []fs.FsStat `json:"fs_stats,omitempty"`
Fs []fs.FsStat `json:"fs,omitempty"`
}

// Makes a deep copy of the ContainerStats and returns a pointer to the new
Expand Down

0 comments on commit b9e70f0

Please sign in to comment.