Unverified Commit f330633a authored by Kubernetes Prow Robot's avatar Kubernetes Prow Robot Committed by GitHub

Merge pull request #74675 from dashpole/cadvisor_godep_v0.33.0

update cadvisor godeps to v0.33.0
parents 2b63efcd 4e063fe0
......@@ -2002,188 +2002,188 @@
},
{
"ImportPath": "github.com/google/cadvisor/accelerators",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/cache/memory",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/client/v2",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/collector",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/container",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/container/common",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/container/containerd",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/container/crio",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/container/docker",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/container/libcontainer",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/container/mesos",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/container/raw",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/container/rkt",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/container/systemd",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/devicemapper",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/events",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/fs",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/info/v1",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/info/v2",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/machine",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/manager",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/manager/watcher",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/manager/watcher/raw",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/manager/watcher/rkt",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/metrics",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/storage",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/summary",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/utils",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/utils/cloudinfo",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/utils/cpuload",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/utils/cpuload/netlink",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/utils/docker",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/utils/oomparser",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/utils/sysfs",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/utils/sysinfo",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/version",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/cadvisor/zfs",
"Comment": "v0.32.0",
"Rev": "8949c822ea91fa6b4996614a5ad6ade840be24ee"
"Comment": "v0.33.0",
"Rev": "511ec9ef821b334c3825cebb728208578c2300e8"
},
{
"ImportPath": "github.com/google/certificate-transparency-go",
......
......@@ -51,7 +51,6 @@ type realFsHandler struct {
}
const (
timeout = 2 * time.Minute
maxBackoffFactor = 20
)
......@@ -74,17 +73,16 @@ func NewFsHandler(period time.Duration, rootfs, extraDir string, fsInfo fs.FsInf
func (fh *realFsHandler) update() error {
var (
baseUsage, extraDirUsage, inodeUsage uint64
rootDiskErr, rootInodeErr, extraDiskErr error
rootUsage, extraUsage fs.UsageInfo
rootErr, extraErr error
)
// TODO(vishh): Add support for external mounts.
if fh.rootfs != "" {
baseUsage, rootDiskErr = fh.fsInfo.GetDirDiskUsage(fh.rootfs, timeout)
inodeUsage, rootInodeErr = fh.fsInfo.GetDirInodeUsage(fh.rootfs, timeout)
rootUsage, rootErr = fh.fsInfo.GetDirUsage(fh.rootfs)
}
if fh.extraDir != "" {
extraDirUsage, extraDiskErr = fh.fsInfo.GetDirDiskUsage(fh.extraDir, timeout)
extraUsage, extraErr = fh.fsInfo.GetDirUsage(fh.extraDir)
}
// Wait to handle errors until after all operartions are run.
......@@ -92,18 +90,17 @@ func (fh *realFsHandler) update() error {
fh.Lock()
defer fh.Unlock()
fh.lastUpdate = time.Now()
if rootInodeErr == nil && fh.rootfs != "" {
fh.usage.InodeUsage = inodeUsage
if fh.rootfs != "" && rootErr == nil {
fh.usage.InodeUsage = rootUsage.Inodes
fh.usage.TotalUsageBytes = rootUsage.Bytes + extraUsage.Bytes
}
if rootDiskErr == nil && fh.rootfs != "" {
fh.usage.TotalUsageBytes = baseUsage + extraDirUsage
}
if extraDiskErr == nil && fh.extraDir != "" {
fh.usage.BaseUsageBytes = baseUsage
if fh.extraDir != "" && extraErr == nil {
fh.usage.BaseUsageBytes = rootUsage.Bytes
}
// Combine errors into a single error to return
if rootDiskErr != nil || rootInodeErr != nil || extraDiskErr != nil {
return fmt.Errorf("rootDiskErr: %v, rootInodeErr: %v, extraDiskErr: %v", rootDiskErr, rootInodeErr, extraDiskErr)
if rootErr != nil || extraErr != nil {
return fmt.Errorf("rootDiskErr: %v, extraDiskErr: %v", rootErr, extraErr)
}
return nil
}
......@@ -132,7 +129,7 @@ func (fh *realFsHandler) trackUsage() {
// if the long duration is persistent either because of slow
// disk or lots of containers.
longOp = longOp + time.Second
klog.V(2).Infof("du and find on following dirs took %v: %v; will not log again for this container unless duration exceeds %v", duration, []string{fh.rootfs, fh.extraDir}, longOp)
klog.V(2).Infof("fs: disk usage and inodes count on following dirs took %v: %v; will not log again for this container unless duration exceeds %v", duration, []string{fh.rootfs, fh.extraDir}, longOp)
}
}
}
......
......@@ -134,7 +134,7 @@ func readString(dirpath string, file string) string {
if err != nil {
// Ignore non-existent files
if !os.IsNotExist(err) {
klog.Errorf("readString: Failed to read %q: %s", cgroupFile, err)
klog.Warningf("readString: Failed to read %q: %s", cgroupFile, err)
}
return ""
}
......
......@@ -128,7 +128,7 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics
return fmt.Errorf("failed to fetch containerd client version: %v", err)
}
cgroupSubsystems, err := libcontainer.GetCgroupSubsystems()
cgroupSubsystems, err := libcontainer.GetCgroupSubsystems(includedMetrics)
if err != nil {
return fmt.Errorf("failed to get cgroup subsystems: %v", err)
}
......
......@@ -18,7 +18,6 @@ package containerd
import (
"encoding/json"
"fmt"
"path"
"strings"
"time"
......@@ -67,10 +66,7 @@ func newContainerdContainerHandler(
includedMetrics container.MetricSet,
) (container.ContainerHandler, error) {
// Create the cgroup paths.
cgroupPaths := make(map[string]string, len(cgroupSubsystems.MountPoints))
for key, val := range cgroupSubsystems.MountPoints {
cgroupPaths[key] = path.Join(val, name)
}
cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems.MountPoints, name)
// Generate the equivalent cgroup manager for this container.
cgroupManager := &cgroupfs.Manager{
......
......@@ -149,7 +149,7 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics
// TODO determine crio version so we can work differently w/ future versions if needed
cgroupSubsystems, err := libcontainer.GetCgroupSubsystems()
cgroupSubsystems, err := libcontainer.GetCgroupSubsystems(includedMetrics)
if err != nil {
return fmt.Errorf("failed to get cgroup subsystems: %v", err)
}
......
......@@ -86,10 +86,7 @@ func newCrioContainerHandler(
includedMetrics container.MetricSet,
) (container.ContainerHandler, error) {
// Create the cgroup paths.
cgroupPaths := make(map[string]string, len(cgroupSubsystems.MountPoints))
for key, val := range cgroupSubsystems.MountPoints {
cgroupPaths[key] = path.Join(val, name)
}
cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems.MountPoints, name)
// Generate the equivalent cgroup manager for this container.
cgroupManager := &cgroupfs.Manager{
......
......@@ -325,7 +325,7 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics
dockerAPIVersion, _ := APIVersion()
cgroupSubsystems, err := libcontainer.GetCgroupSubsystems()
cgroupSubsystems, err := libcontainer.GetCgroupSubsystems(includedMetrics)
if err != nil {
return fmt.Errorf("failed to get cgroup subsystems: %v", err)
}
......
......@@ -134,10 +134,7 @@ func newDockerContainerHandler(
zfsWatcher *zfs.ZfsWatcher,
) (container.ContainerHandler, error) {
// Create the cgroup paths.
cgroupPaths := make(map[string]string, len(cgroupSubsystems.MountPoints))
for key, val := range cgroupSubsystems.MountPoints {
cgroupPaths[key] = path.Join(val, name)
}
cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems.MountPoints, name)
// Generate the equivalent cgroup manager for this container.
cgroupManager := &cgroupfs.Manager{
......
......@@ -66,8 +66,7 @@ func (h *Handler) GetStats() (*info.ContainerStats, error) {
libcontainerStats := &libcontainer.Stats{
CgroupStats: cgroupStats,
}
withPerCPU := h.includedMetrics.Has(container.PerCpuUsageMetrics)
stats := newContainerStats(libcontainerStats, withPerCPU)
stats := newContainerStats(libcontainerStats, h.includedMetrics)
if h.includedMetrics.Has(container.ProcessSchedulerMetrics) {
pids, err := h.cgroupManager.GetAllPids()
......@@ -599,14 +598,16 @@ func setNetworkStats(libcontainerStats *libcontainer.Stats, ret *info.ContainerS
}
}
func newContainerStats(libcontainerStats *libcontainer.Stats, withPerCPU bool) *info.ContainerStats {
func newContainerStats(libcontainerStats *libcontainer.Stats, includedMetrics container.MetricSet) *info.ContainerStats {
ret := &info.ContainerStats{
Timestamp: time.Now(),
}
if s := libcontainerStats.CgroupStats; s != nil {
setCpuStats(s, ret, withPerCPU)
setDiskIoStats(s, ret)
setCpuStats(s, ret, includedMetrics.Has(container.PerCpuUsageMetrics))
if includedMetrics.Has(container.DiskIOMetrics) {
setDiskIoStats(s, ret)
}
setMemoryStats(s, ret)
}
if len(libcontainerStats.Interfaces) > 0 {
......
......@@ -19,6 +19,7 @@ import (
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/container"
"github.com/opencontainers/runc/libcontainer/cgroups"
"k8s.io/klog"
)
......@@ -33,18 +34,36 @@ type CgroupSubsystems struct {
MountPoints map[string]string
}
// Get information about the cgroup subsystems.
func GetCgroupSubsystems() (CgroupSubsystems, error) {
// Get information about the cgroup subsystems those we want
func GetCgroupSubsystems(includedMetrics container.MetricSet) (CgroupSubsystems, error) {
// Get all cgroup mounts.
allCgroups, err := cgroups.GetCgroupMounts(true)
if err != nil {
return CgroupSubsystems{}, err
}
return getCgroupSubsystemsHelper(allCgroups)
disableCgroups := map[string]struct{}{}
//currently we only support disable blkio subsystem
if !includedMetrics.Has(container.DiskIOMetrics) {
disableCgroups["blkio"] = struct{}{}
}
return getCgroupSubsystemsHelper(allCgroups, disableCgroups)
}
// Get information about all the cgroup subsystems.
func GetAllCgroupSubsystems() (CgroupSubsystems, error) {
// Get all cgroup mounts.
allCgroups, err := cgroups.GetCgroupMounts(true)
if err != nil {
return CgroupSubsystems{}, err
}
emptyDisableCgroups := map[string]struct{}{}
return getCgroupSubsystemsHelper(allCgroups, emptyDisableCgroups)
}
func getCgroupSubsystemsHelper(allCgroups []cgroups.Mount) (CgroupSubsystems, error) {
func getCgroupSubsystemsHelper(allCgroups []cgroups.Mount, disableCgroups map[string]struct{}) (CgroupSubsystems, error) {
if len(allCgroups) == 0 {
return CgroupSubsystems{}, fmt.Errorf("failed to find cgroup mounts")
}
......@@ -55,6 +74,9 @@ func getCgroupSubsystemsHelper(allCgroups []cgroups.Mount) (CgroupSubsystems, er
mountPoints := make(map[string]string, len(allCgroups))
for _, mount := range allCgroups {
for _, subsystem := range mount.Subsystems {
if _, exists := disableCgroups[subsystem]; exists {
continue
}
if _, ok := supportedSubsystems[subsystem]; !ok {
// Unsupported subsystem
continue
......
......@@ -130,7 +130,7 @@ func Register(
return fmt.Errorf("unable to create mesos agent client: %v", err)
}
cgroupSubsystems, err := libcontainer.GetCgroupSubsystems()
cgroupSubsystems, err := libcontainer.GetCgroupSubsystems(includedMetrics)
if err != nil {
return fmt.Errorf("failed to get cgroup subsystems: %v", err)
}
......
......@@ -17,7 +17,6 @@ package mesos
import (
"fmt"
"path"
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/container/common"
......@@ -68,9 +67,6 @@ func newMesosContainerHandler(
client mesosAgentClient,
) (container.ContainerHandler, error) {
cgroupPaths := common.MakeCgroupPaths(cgroupSubsystems.MountPoints, name)
for key, val := range cgroupSubsystems.MountPoints {
cgroupPaths[key] = path.Join(val, name)
}
// Generate the equivalent cgroup manager for this container.
cgroupManager := &cgroupfs.Manager{
......
......@@ -113,8 +113,10 @@ func (s *state) fetchLabelsFromTask(exID string, labels map[string]string) error
}
}
for _, l := range t.Labels.Labels {
labels[l.Key] = *l.Value
if t.Labels != nil {
for _, l := range t.Labels.Labels {
labels[l.Key] = *l.Value
}
}
return nil
......
......@@ -63,17 +63,20 @@ func (self *rawFactory) NewContainerHandler(name string, inHostNamespace bool) (
return newRawContainerHandler(name, self.cgroupSubsystems, self.machineInfoFactory, self.fsInfo, self.watcher, rootFs, self.includedMetrics)
}
// The raw factory can handle any container. If --docker_only is set to false, non-docker containers are ignored.
// The raw factory can handle any container. If --docker_only is set to true, non-docker containers are ignored except for "/" and those whitelisted by raw_cgroup_prefix_whitelist flag.
func (self *rawFactory) CanHandleAndAccept(name string) (bool, bool, error) {
accept := name == "/" || !*dockerOnly
if name == "/" {
return true, true, nil
}
if *dockerOnly && self.rawPrefixWhiteList[0] == "" {
return true, false, nil
}
for _, prefix := range self.rawPrefixWhiteList {
if strings.HasPrefix(name, prefix) {
accept = true
break
return true, true, nil
}
}
return true, accept, nil
return true, false, nil
}
func (self *rawFactory) DebugInfo() map[string][]string {
......@@ -81,7 +84,7 @@ func (self *rawFactory) DebugInfo() map[string][]string {
}
func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics map[container.MetricKind]struct{}, rawPrefixWhiteList []string) error {
cgroupSubsystems, err := libcontainer.GetCgroupSubsystems()
cgroupSubsystems, err := libcontainer.GetCgroupSubsystems(includedMetrics)
if err != nil {
return fmt.Errorf("failed to get cgroup subsystems: %v", err)
}
......
......@@ -39,8 +39,9 @@ type rawContainerHandler struct {
// (e.g.: "cpu" -> "/sys/fs/cgroup/cpu/test")
cgroupPaths map[string]string
fsInfo fs.FsInfo
externalMounts []common.Mount
fsInfo fs.FsInfo
externalMounts []common.Mount
includedMetrics container.MetricSet
libcontainerHandler *libcontainer.Handler
}
......@@ -86,6 +87,7 @@ func newRawContainerHandler(name string, cgroupSubsystems *libcontainer.CgroupSu
cgroupPaths: cgroupPaths,
fsInfo: fsInfo,
externalMounts: externalMounts,
includedMetrics: includedMetrics,
libcontainerHandler: handler,
}, nil
}
......@@ -185,36 +187,40 @@ func fsToFsStats(fs *fs.Fs) info.FsStats {
}
func (self *rawContainerHandler) getFsStats(stats *info.ContainerStats) error {
var allFs []fs.Fs
// Get Filesystem information only for the root cgroup.
if isRootCgroup(self.name) {
filesystems, err := self.fsInfo.GetGlobalFsInfo()
if err != nil {
return err
}
for i := range filesystems {
fs := filesystems[i]
stats.Filesystem = append(stats.Filesystem, fsToFsStats(&fs))
}
allFs = filesystems
} else if len(self.externalMounts) > 0 {
var mountSet map[string]struct{}
mountSet = make(map[string]struct{})
for _, mount := range self.externalMounts {
mountSet[mount.HostDir] = struct{}{}
}
filesystems, err := self.fsInfo.GetFsInfoForPath(mountSet)
if err != nil {
return err
var filesystems []fs.Fs
if self.includedMetrics.Has(container.DiskUsageMetrics) || self.includedMetrics.Has(container.DiskIOMetrics) {
var err error
// Get Filesystem information only for the root cgroup.
if isRootCgroup(self.name) {
filesystems, err = self.fsInfo.GetGlobalFsInfo()
if err != nil {
return err
}
} else if len(self.externalMounts) > 0 {
var mountSet map[string]struct{}
mountSet = make(map[string]struct{})
for _, mount := range self.externalMounts {
mountSet[mount.HostDir] = struct{}{}
}
filesystems, err = self.fsInfo.GetFsInfoForPath(mountSet)
if err != nil {
return err
}
}
}
if self.includedMetrics.Has(container.DiskUsageMetrics) {
for i := range filesystems {
fs := filesystems[i]
stats.Filesystem = append(stats.Filesystem, fsToFsStats(&fs))
}
allFs = filesystems
}
common.AssignDeviceNamesToDiskStats(&fsNamer{fs: allFs, factory: self.machineInfoFactory}, &stats.DiskIo)
if self.includedMetrics.Has(container.DiskIOMetrics) {
common.AssignDeviceNamesToDiskStats(&fsNamer{fs: filesystems, factory: self.machineInfoFactory}, &stats.DiskIo)
}
return nil
}
......
......@@ -78,7 +78,7 @@ func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, incl
return fmt.Errorf("unable to get the RktPath variable %v", err)
}
cgroupSubsystems, err := libcontainer.GetCgroupSubsystems()
cgroupSubsystems, err := libcontainer.GetCgroupSubsystems(includedMetrics)
if err != nil {
return fmt.Errorf("failed to get cgroup subsystems: %v", err)
}
......
......@@ -19,7 +19,6 @@ package fs
import (
"bufio"
"bytes"
"fmt"
"io/ioutil"
"os"
......@@ -30,7 +29,6 @@ import (
"strconv"
"strings"
"syscall"
"time"
"github.com/docker/docker/pkg/mount"
"github.com/google/cadvisor/devicemapper"
......@@ -47,8 +45,12 @@ const (
LabelCrioImages = "crio-images"
)
// The maximum number of `du` and `find` tasks that can be running at once.
const maxConcurrentOps = 20
const (
// The block size in bytes.
statBlockSize uint64 = 512
// The maximum number of `disk usage` tasks that can be running at once.
maxConcurrentOps = 20
)
// A pool for restricting the number of consecutive `du` and `find` tasks running.
var pool = make(chan struct{}, maxConcurrentOps)
......@@ -559,78 +561,73 @@ func (self *RealFsInfo) GetDirFsDevice(dir string) (*DeviceInfo, error) {
return nil, fmt.Errorf("could not find device with major: %d, minor: %d in cached partitions map", major, minor)
}
func (self *RealFsInfo) GetDirDiskUsage(dir string, timeout time.Duration) (uint64, error) {
claimToken()
defer releaseToken()
return GetDirDiskUsage(dir, timeout)
}
func GetDirUsage(dir string) (UsageInfo, error) {
var usage UsageInfo
func GetDirDiskUsage(dir string, timeout time.Duration) (uint64, error) {
if dir == "" {
return 0, fmt.Errorf("invalid directory")
return usage, fmt.Errorf("invalid directory")
}
cmd := exec.Command("ionice", "-c3", "nice", "-n", "19", "du", "-s", dir)
stdoutp, err := cmd.StdoutPipe()
if err != nil {
return 0, fmt.Errorf("failed to setup stdout for cmd %v - %v", cmd.Args, err)
}
stderrp, err := cmd.StderrPipe()
rootInfo, err := os.Stat(dir)
if err != nil {
return 0, fmt.Errorf("failed to setup stderr for cmd %v - %v", cmd.Args, err)
return usage, fmt.Errorf("could not stat %q to get inode usage: %v", dir, err)
}
if err := cmd.Start(); err != nil {
return 0, fmt.Errorf("failed to exec du - %v", err)
rootStat, ok := rootInfo.Sys().(*syscall.Stat_t)
if !ok {
return usage, fmt.Errorf("unsuported fileinfo for getting inode usage of %q", dir)
}
timer := time.AfterFunc(timeout, func() {
klog.Warningf("Killing cmd %v due to timeout(%s)", cmd.Args, timeout.String())
cmd.Process.Kill()
rootDevId := rootStat.Dev
// dedupedInode stores inodes that could be duplicates (nlink > 1)
dedupedInodes := make(map[uint64]struct{})
err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if os.IsNotExist(err) {
// expected if files appear/vanish
return nil
}
if err != nil {
return fmt.Errorf("unable to count inodes for part of dir %s: %s", dir, err)
}
// according to the docs, Sys can be nil
if info.Sys() == nil {
return fmt.Errorf("fileinfo Sys is nil")
}
s, ok := info.Sys().(*syscall.Stat_t)
if !ok {
return fmt.Errorf("unsupported fileinfo; could not convert to stat_t")
}
if s.Dev != rootDevId {
// don't descend into directories on other devices
return filepath.SkipDir
}
if s.Nlink > 1 {
if _, ok := dedupedInodes[s.Ino]; !ok {
// Dedupe things that could be hardlinks
dedupedInodes[s.Ino] = struct{}{}
usage.Bytes += uint64(s.Blocks) * statBlockSize
usage.Inodes++
}
} else {
usage.Bytes += uint64(s.Blocks) * statBlockSize
usage.Inodes++
}
return nil
})
stdoutb, souterr := ioutil.ReadAll(stdoutp)
if souterr != nil {
klog.Errorf("Failed to read from stdout for cmd %v - %v", cmd.Args, souterr)
}
stderrb, _ := ioutil.ReadAll(stderrp)
err = cmd.Wait()
timer.Stop()
if err != nil {
return 0, fmt.Errorf("du command failed on %s with output stdout: %s, stderr: %s - %v", dir, string(stdoutb), string(stderrb), err)
}
stdout := string(stdoutb)
usageInKb, err := strconv.ParseUint(strings.Fields(stdout)[0], 10, 64)
if err != nil {
return 0, fmt.Errorf("cannot parse 'du' output %s - %s", stdout, err)
}
return usageInKb * 1024, nil
return usage, nil
}
func (self *RealFsInfo) GetDirInodeUsage(dir string, timeout time.Duration) (uint64, error) {
func (self *RealFsInfo) GetDirUsage(dir string) (UsageInfo, error) {
claimToken()
defer releaseToken()
return GetDirInodeUsage(dir, timeout)
}
func GetDirInodeUsage(dir string, timeout time.Duration) (uint64, error) {
if dir == "" {
return 0, fmt.Errorf("invalid directory")
}
var counter byteCounter
var stderr bytes.Buffer
findCmd := exec.Command("ionice", "-c3", "nice", "-n", "19", "find", dir, "-xdev", "-printf", ".")
findCmd.Stdout, findCmd.Stderr = &counter, &stderr
if err := findCmd.Start(); err != nil {
return 0, fmt.Errorf("failed to exec cmd %v - %v; stderr: %v", findCmd.Args, err, stderr.String())
}
timer := time.AfterFunc(timeout, func() {
klog.Warningf("Killing cmd %v due to timeout(%s)", findCmd.Args, timeout.String())
findCmd.Process.Kill()
})
err := findCmd.Wait()
timer.Stop()
if err != nil {
return 0, fmt.Errorf("cmd %v failed. stderr: %s; err: %v", findCmd.Args, stderr.String(), err)
}
return counter.bytesWritten, nil
return GetDirUsage(dir)
}
func getVfsStats(path string) (total uint64, free uint64, avail uint64, inodes uint64, inodesFree uint64, err error) {
......
......@@ -16,7 +16,6 @@ package fs
import (
"errors"
"time"
)
type DeviceInfo struct {
......@@ -62,6 +61,11 @@ type DiskStats struct {
WeightedIoTime uint64
}
type UsageInfo struct {
Bytes uint64
Inodes uint64
}
// ErrNoSuchDevice is the error indicating the requested device does not exist.
var ErrNoSuchDevice = errors.New("cadvisor: no such device")
......@@ -72,11 +76,8 @@ type FsInfo interface {
// Returns capacity and free space, in bytes, of the set of mounts passed.
GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, error)
// Returns number of bytes occupied by 'dir'.
GetDirDiskUsage(dir string, timeout time.Duration) (uint64, error)
// Returns number of inodes used by 'dir'.
GetDirInodeUsage(dir string, timeout time.Duration) (uint64, error)
// GetDirUsage returns a usage information for 'dir'.
GetDirUsage(dir string) (UsageInfo, error)
// GetDeviceInfoByFsUUID returns the information of the device with the
// specified filesystem uuid. If no such device exists, this function will
......
......@@ -16,12 +16,13 @@
package machine
import (
"bytes"
"fmt"
"io/ioutil"
"path/filepath"
"regexp"
"strconv"
"strings"
// s390/s390x changes
"runtime"
......@@ -36,9 +37,10 @@ import (
)
var (
cpuRegExp = regexp.MustCompile(`^processor\s*:\s*([0-9]+)$`)
coreRegExp = regexp.MustCompile(`^core id\s*:\s*([0-9]+)$`)
nodeRegExp = regexp.MustCompile(`^physical id\s*:\s*([0-9]+)$`)
cpuRegExp = regexp.MustCompile(`^processor\s*:\s*([0-9]+)$`)
coreRegExp = regexp.MustCompile(`^core id\s*:\s*([0-9]+)$`)
nodeRegExp = regexp.MustCompile(`^physical id\s*:\s*([0-9]+)$`)
nodeBusRegExp = regexp.MustCompile(`^node([0-9]+)$`)
// Power systems have a different format so cater for both
cpuClockSpeedMHz = regexp.MustCompile(`(?:cpu MHz|clock)\s*:\s*([0-9]+\.[0-9]+)(?:MHz)?`)
memoryCapacityRegexp = regexp.MustCompile(`MemTotal:\s*([0-9]+) kB`)
......@@ -46,6 +48,7 @@ var (
)
const maxFreqFile = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq"
const cpuBusPath = "/sys/bus/cpu/devices/"
// GetClockSpeed returns the CPU clock speed, given a []byte formatted as the /proc/cpuinfo file.
func GetClockSpeed(procInfo []byte) (uint64, error) {
......@@ -127,6 +130,67 @@ func parseCapacity(b []byte, r *regexp.Regexp) (uint64, error) {
return m * 1024, err
}
/* Look for sysfs cpu path containing core_id */
/* Such as: sys/bus/cpu/devices/cpu0/topology/core_id */
func getCoreIdFromCpuBus(cpuBusPath string, threadId int) (int, error) {
path := filepath.Join(cpuBusPath, fmt.Sprintf("cpu%d/topology", threadId))
file := filepath.Join(path, "core_id")
num, err := ioutil.ReadFile(file)
if err != nil {
return threadId, err
}
coreId, err := strconv.ParseInt(string(bytes.TrimSpace(num)), 10, 32)
if err != nil {
return threadId, err
}
if coreId < 0 {
// report threadId if found coreId < 0
coreId = int64(threadId)
}
return int(coreId), nil
}
/* Look for sysfs cpu path containing node id */
/* Such as: /sys/bus/cpu/devices/cpu0/node%d */
func getNodeIdFromCpuBus(cpuBusPath string, threadId int) (int, error) {
path := filepath.Join(cpuBusPath, fmt.Sprintf("cpu%d", threadId))
files, err := ioutil.ReadDir(path)
if err != nil {
return 0, err
}
nodeId := 0
for _, file := range files {
filename := file.Name()
isNode, error := regexp.MatchString("^node([0-9]+)$", filename)
if error != nil {
continue
}
if !isNode {
continue
}
ok, val, _ := extractValue(filename, nodeBusRegExp)
if err != nil {
continue
}
if ok {
if val < 0 {
continue
}
nodeId = val
}
}
return nodeId, nil
}
func GetTopology(sysFs sysfs.SysFs, cpuinfo string) ([]info.Node, int, error) {
nodes := []info.Node{}
......@@ -161,8 +225,36 @@ func GetTopology(sysFs sysfs.SysFs, cpuinfo string) ([]info.Node, int, error) {
lastNode = -1
}
lastThread = thread
/* On Arm platform, no 'core id' and 'physical id' in '/proc/cpuinfo'. */
/* So we search sysfs cpu path directly. */
/* This method can also be used on other platforms, such as x86, ppc64le... */
/* /sys/bus/cpu/devices/cpu%d contains the information of 'core_id' & 'node_id'. */
/* Such as: /sys/bus/cpu/devices/cpu0/topology/core_id */
/* Such as: /sys/bus/cpu/devices/cpu0/node0 */
if isAArch64() {
val, err = getCoreIdFromCpuBus(cpuBusPath, lastThread)
if err != nil {
// Report thread id if no NUMA
val = lastThread
}
lastCore = val
val, err = getNodeIdFromCpuBus(cpuBusPath, lastThread)
if err != nil {
// Report node 0 if no NUMA
val = 0
}
lastNode = val
}
continue
}
if isAArch64() {
/* On Arm platform, no 'core id' and 'physical id' in '/proc/cpuinfo'. */
continue
}
ok, val, err = extractValue(line, coreRegExp)
if err != nil {
return nil, -1, fmt.Errorf("could not parse core info from %q: %v", line, err)
......@@ -171,6 +263,7 @@ func GetTopology(sysFs sysfs.SysFs, cpuinfo string) ([]info.Node, int, error) {
lastCore = val
continue
}
ok, val, err = extractValue(line, nodeRegExp)
if err != nil {
return nil, -1, fmt.Errorf("could not parse node info from %q: %v", line, err)
......@@ -180,6 +273,7 @@ func GetTopology(sysFs sysfs.SysFs, cpuinfo string) ([]info.Node, int, error) {
continue
}
}
nodeIdx, err := addNode(&nodes, lastNode)
if err != nil {
return nil, -1, fmt.Errorf("failed to add node %d: %v", lastNode, err)
......
......@@ -56,6 +56,7 @@ import (
)
var globalHousekeepingInterval = flag.Duration("global_housekeeping_interval", 1*time.Minute, "Interval between global housekeepings")
var updateMachineInfoInterval = flag.Duration("update_machine_info_interval", 5*time.Minute, "Interval between machine info updates.")
var logCadvisorUsage = flag.Bool("log_cadvisor_usage", false, "Whether to log the usage of the cAdvisor container")
var eventStorageAgeLimit = flag.String("event_storage_age_limit", "default=24h", "Max length of time for which to store events (per type). Value is a comma separated list of key values, where the keys are event types (e.g.: creation, oom) or \"default\" and the value is a duration. Default is applied to all non-specified event types")
var eventStorageEventLimit = flag.String("event_storage_event_limit", "default=100000", "Max number of events to store (per type). Value is a comma separated list of key values, where the keys are event types (e.g.: creation, oom) or \"default\" and the value is an integer. Default is applied to all non-specified event types")
......@@ -208,6 +209,7 @@ func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, maxHousekeepingIn
quitChannels: make([]chan error, 0, 2),
memoryCache: memoryCache,
fsInfo: fsInfo,
sysFs: sysfs,
cadvisorContainer: selfContainer,
inHostNamespace: inHostNamespace,
startupTime: time.Now(),
......@@ -277,6 +279,8 @@ type manager struct {
containersLock sync.RWMutex
memoryCache *memory.InMemoryCache
fsInfo fs.FsInfo
sysFs sysfs.SysFs
machineMu sync.RWMutex // protects machineInfo
machineInfo info.MachineInfo
quitChannels []chan error
cadvisorContainer string
......@@ -382,6 +386,10 @@ func (self *manager) Start() error {
self.quitChannels = append(self.quitChannels, quitGlobalHousekeeping)
go self.globalHousekeeping(quitGlobalHousekeeping)
quitUpdateMachineInfo := make(chan error)
self.quitChannels = append(self.quitChannels, quitUpdateMachineInfo)
go self.updateMachineInfo(quitUpdateMachineInfo)
return nil
}
......@@ -402,6 +410,28 @@ func (self *manager) Stop() error {
return nil
}
func (self *manager) updateMachineInfo(quit chan error) {
ticker := time.NewTicker(*updateMachineInfoInterval)
for {
select {
case <-ticker.C:
info, err := machine.Info(self.sysFs, self.fsInfo, self.inHostNamespace)
if err != nil {
klog.Errorf("Could not get machine info: %v", err)
break
}
self.machineMu.Lock()
self.machineInfo = *info
self.machineMu.Unlock()
klog.V(5).Infof("Update machine info: %+v", *info)
case <-quit:
ticker.Stop()
quit <- nil
return
}
}
}
func (self *manager) globalHousekeeping(quit chan error) {
// Long housekeeping is either 100ms or half of the housekeeping interval.
longHousekeeping := 100 * time.Millisecond
......@@ -501,7 +531,9 @@ func (self *manager) getAdjustedSpec(cinfo *containerInfo) info.ContainerSpec {
if spec.HasMemory {
// Memory.Limit is 0 means there's no limit
if spec.Memory.Limit == 0 {
self.machineMu.RLock()
spec.Memory.Limit = uint64(self.machineInfo.MemoryCapacity)
self.machineMu.RUnlock()
}
}
return spec
......@@ -834,6 +866,8 @@ func (self *manager) GetFsInfo(label string) ([]v2.FsInfo, error) {
}
func (m *manager) GetMachineInfo() (*info.MachineInfo, error) {
m.machineMu.RLock()
defer m.machineMu.RUnlock()
// Copy and return the MachineInfo.
return &m.machineInfo, nil
}
......
......@@ -45,7 +45,7 @@ type rawContainerWatcher struct {
}
func NewRawContainerWatcher() (watcher.ContainerWatcher, error) {
cgroupSubsystems, err := libcontainer.GetCgroupSubsystems()
cgroupSubsystems, err := libcontainer.GetAllCgroupSubsystems()
if err != nil {
return nil, fmt.Errorf("failed to get cgroup subsystems: %v", err)
}
......
......@@ -19,6 +19,7 @@ import (
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
"io/ioutil"
"os"
"strings"
info "github.com/google/cadvisor/info/v1"
......@@ -26,15 +27,28 @@ import (
const (
ProductVerFileName = "/sys/class/dmi/id/product_version"
BiosVerFileName = "/sys/class/dmi/id/bios_vendor"
Amazon = "amazon"
)
func onAWS() bool {
data, err := ioutil.ReadFile(ProductVerFileName)
if err != nil {
return false
var dataProduct []byte
var dataBios []byte
if _, err := os.Stat(ProductVerFileName); err == nil {
dataProduct, err = ioutil.ReadFile(ProductVerFileName)
if err != nil {
return false
}
}
if _, err := os.Stat(BiosVerFileName); err == nil {
dataBios, err = ioutil.ReadFile(BiosVerFileName)
if err != nil {
return false
}
}
return strings.Contains(string(data), Amazon)
return strings.Contains(string(dataProduct), Amazon) || strings.Contains(strings.ToLower(string(dataBios)), Amazon)
}
func getAwsMetadata(name string) string {
......
......@@ -101,8 +101,9 @@ func (self *OomParser) StreamOoms(outStream chan<- *OomInstance) {
in_oom_kernel_log := checkIfStartOfOomMessages(msg.Message)
if in_oom_kernel_log {
oomCurrentInstance := &OomInstance{
ContainerName: "/",
TimeOfDeath: msg.Timestamp,
ContainerName: "/",
VictimContainerName: "/",
TimeOfDeath: msg.Timestamp,
}
for msg := range kmsgEntries {
err := getContainerName(msg.Message, oomCurrentInstance)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment