From 86238d0179d2eee09efd6d55205bd50de49071db Mon Sep 17 00:00:00 2001 From: Victor Marmol Date: Tue, 3 Feb 2015 15:26:31 -0800 Subject: [PATCH] Allow partial success of GetStats(). This should make us more robust in the face of failure (at the cost of making the failures less prominent). We allow GetStats() to return an error and a partial result. We will process the result and report the error. Fixes #306. --- container/docker/handler.go | 7 ++++--- container/raw/handler.go | 5 +++-- fs/fs.go | 3 ++- manager/container.go | 12 +++++++----- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/container/docker/handler.go b/container/docker/handler.go index f4de504d..05f0d0a3 100644 --- a/container/docker/handler.go +++ b/container/docker/handler.go @@ -82,6 +82,7 @@ func newDockerContainerHandler( usesAufsDriver bool, cgroupSubsystems *containerLibcontainer.CgroupSubsystems, ) (container.ContainerHandler, error) { + // TODO(vmarmol): Get from factory. fsInfo, err := fs.NewFsInfo() if err != nil { return nil, err @@ -299,16 +300,16 @@ func (self *dockerContainerHandler) getFsStats(stats *info.ContainerStats) error func (self *dockerContainerHandler) GetStats() (stats *info.ContainerStats, err error) { state, err := self.readLibcontainerState() if err != nil { - return + return nil, err } stats, err = containerLibcontainer.GetStats(self.cgroupPaths, state) if err != nil { - return + return stats, err } err = self.getFsStats(stats) if err != nil { - return + return stats, err } return stats, nil diff --git a/container/raw/handler.go b/container/raw/handler.go index 408c8de5..83a6c231 100644 --- a/container/raw/handler.go +++ b/container/raw/handler.go @@ -76,6 +76,7 @@ func newRawContainerHandler(name string, cgroupSubsystems *libcontainer.CgroupSu cgroupPaths[key] = path.Join(val, name) } + // TODO(vmarmol): Get from factory. fsInfo, err := fs.NewFsInfo() if err != nil { return nil, err @@ -303,12 +304,12 @@ func (self *rawContainerHandler) getFsStats(stats *info.ContainerStats) error { func (self *rawContainerHandler) GetStats() (*info.ContainerStats, error) { stats, err := libcontainer.GetStats(self.cgroupPaths, &self.libcontainerState) if err != nil { - return nil, err + return stats, err } err = self.getFsStats(stats) if err != nil { - return nil, err + return stats, err } // Fill in network stats for root. diff --git a/fs/fs.go b/fs/fs.go index 9ddb0522..7ebdafea 100644 --- a/fs/fs.go +++ b/fs/fs.go @@ -67,6 +67,7 @@ func NewFsInfo() (FsInfo, error) { } partitions[mount.Source] = partition{mount.Mountpoint, uint(mount.Major), uint(mount.Minor)} } + glog.Infof("Filesystem partitions: %+v", partitions) return &RealFsInfo{partitions}, nil } @@ -80,7 +81,7 @@ func (self *RealFsInfo) GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, er for device, partition := range self.partitions { _, hasMount := mountSet[partition.mountpoint] _, hasDevice := deviceSet[device] - if mountSet == nil || hasMount && !hasDevice { + if mountSet == nil || (hasMount && !hasDevice) { total, free, err := getVfsStats(partition.mountpoint) if err != nil { glog.Errorf("Statvfs failed. Error: %v", err) diff --git a/manager/container.go b/manager/container.go index a236cd2e..7a73f295 100644 --- a/manager/container.go +++ b/manager/container.go @@ -244,18 +244,20 @@ func (c *containerData) updateLoad(newLoad uint64) { } func (c *containerData) updateStats() error { - stats, err := c.handler.GetStats() - if err != nil { + stats, statsErr := c.handler.GetStats() + if statsErr != nil { // Ignore errors if the container is dead. if !c.handler.Exists() { return nil } - return err + + // Stats may be partially populated, push those before we return an error. } if stats == nil { - return nil + return statsErr } if c.loadReader != nil { + // TODO(vmarmol): Cache this path. path, err := c.handler.GetCgroupPath("cpu") if err == nil { loadStats, err := c.loadReader.GetCpuLoad(c.info.Name, path) @@ -280,7 +282,7 @@ func (c *containerData) updateStats() error { if err != nil { return err } - return nil + return statsErr } func (c *containerData) updateSubcontainers() error {