From ee8701aa974a36de2f392922391d800dc77dc315 Mon Sep 17 00:00:00 2001 From: Thomas Orozco Date: Tue, 5 Apr 2016 14:23:57 +0200 Subject: [PATCH] Netlink: aggressively close cgroup fds Not closing the FDs manually means we have to rely on garbage collection to run before cgroup FDs are closed. If the system is running a lot of load probes at a high-frequency (i.e. dynamic housekeeping isn't backing off because of load variations), we can end up hitting our FD limit due to keeping around lots of (useless) FDs. --- utils/cpuload/netlink/netlink.go | 7 ++++--- utils/cpuload/netlink/reader.go | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/utils/cpuload/netlink/netlink.go b/utils/cpuload/netlink/netlink.go index 7ca05f36..e32b3fd9 100644 --- a/utils/cpuload/netlink/netlink.go +++ b/utils/cpuload/netlink/netlink.go @@ -18,6 +18,7 @@ import ( "bytes" "encoding/binary" "fmt" + "os" "syscall" info "github.com/google/cadvisor/info/v1" @@ -219,10 +220,10 @@ func verifyHeader(msg syscall.NetlinkMessage) error { // Get load stats for a task group. // id: family id for taskstats. -// fd: fd to path to the cgroup directory under cpu hierarchy. +// cfd: open file to path to the cgroup directory under cpu hierarchy. // conn: open netlink connection used to communicate with kernel. -func getLoadStats(id uint16, fd uintptr, conn *Connection) (info.LoadStats, error) { - msg := prepareCmdMessage(id, fd) +func getLoadStats(id uint16, cfd *os.File, conn *Connection) (info.LoadStats, error) { + msg := prepareCmdMessage(id, cfd.Fd()) err := conn.WriteMessage(msg.toRawMsg()) if err != nil { return info.LoadStats{}, err diff --git a/utils/cpuload/netlink/reader.go b/utils/cpuload/netlink/reader.go index 4e3aa681..1f43d755 100644 --- a/utils/cpuload/netlink/reader.go +++ b/utils/cpuload/netlink/reader.go @@ -66,11 +66,12 @@ func (self *NetlinkReader) GetCpuLoad(name string, path string) (info.LoadStats, } cfd, err := os.Open(path) + defer cfd.Close() if err != nil { return info.LoadStats{}, fmt.Errorf("failed to open cgroup path %s: %q", path, err) } - stats, err := getLoadStats(self.familyId, cfd.Fd(), self.conn) + stats, err := getLoadStats(self.familyId, cfd, self.conn) if err != nil { return info.LoadStats{}, err }