diff --git a/README.md b/README.md index 1d865fae..a19f1a21 100644 --- a/README.md +++ b/README.md @@ -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 \ diff --git a/container/raw/handler.go b/container/raw/handler.go index cc1e7002..6d6fd7a9 100644 --- a/container/raw/handler.go +++ b/container/raw/handler.go @@ -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) { @@ -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 } @@ -144,6 +144,10 @@ func (self *rawContainerHandler) GetSpec() (info.ContainerSpec, error) { } } + // Fs. + if self.name == "/" { + spec.HasFs = true + } return spec, nil } @@ -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 } diff --git a/deploy/Dockerfile b/deploy/Dockerfile index 1c1b2d28..5702ab63 100644 --- a/deploy/Dockerfile +++ b/deploy/Dockerfile @@ -3,6 +3,7 @@ MAINTAINER dengnan@google.com vmarmol@google.com vishnuk@google.com # Grab cadvisor from the staging directory. ADD cadvisor /usr/bin/cadvisor +RUN mkdir /rootfs EXPOSE 8080 ENTRYPOINT ["/usr/bin/cadvisor"] diff --git a/fs/fs.go b/fs/fs.go index b99bd75c..a5bd2331 100644 --- a/fs/fs.go +++ b/fs/fs.go @@ -10,6 +10,7 @@ package fs import "C" import ( + "strings" "syscall" "unsafe" @@ -17,33 +18,41 @@ import ( "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 diff --git a/fs/types.go b/fs/types.go index e527993e..78294b85 100644 --- a/fs/types.go +++ b/fs/types.go @@ -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) } diff --git a/info/container.go b/info/container.go index dbfb698f..83197b39 100644 --- a/info/container.go +++ b/info/container.go @@ -17,7 +17,7 @@ package info import ( "reflect" "time" - + "github.com/google/cadvisor/fs" ) @@ -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 @@ -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