From 531f9507d2035f4f0b067b38d80cfefb91891a7a Mon Sep 17 00:00:00 2001 From: Alexander Blagoev Date: Mon, 1 May 2017 20:59:02 +0300 Subject: [PATCH] Read /proc/net files with a single read syscall. The /proc/net files are not guaranteed to be consistent, they are only consitent on the row level. This is probably one of the reasons why consequent read calls might return duplicate entries - the kernel is changing the file as it is being read. In certain situations this might lead to loop like situations - the same net entry is being returned when reading the file as new connections are added to the kernel tcp table, i.e there can be a lot of duplications. This commit is trying to reduce the duplications, by fetching the contents of the net files with a single read syscall. --- net/net_linux.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/net/net_linux.go b/net/net_linux.go index 174ecf7..28078eb 100644 --- a/net/net_linux.go +++ b/net/net_linux.go @@ -3,6 +3,7 @@ package net import ( + "bytes" "encoding/hex" "errors" "fmt" @@ -613,14 +614,18 @@ func processInet(file string, kind netConnectionKindType, inodes map[string][]in // IPv6 not supported, return empty. return []connTmp{}, nil } - lines, err := common.ReadLines(file) + + contents, err := ioutil.ReadFile(file) if err != nil { return nil, err } + + lines := bytes.Split(contents, []byte("\n")) + var ret []connTmp // skip first line for _, line := range lines[1:] { - l := strings.Fields(line) + l := strings.Fields(string(line)) if len(l) < 10 { continue } @@ -667,15 +672,17 @@ func processInet(file string, kind netConnectionKindType, inodes map[string][]in } func processUnix(file string, kind netConnectionKindType, inodes map[string][]inodeMap, filterPid int32) ([]connTmp, error) { - lines, err := common.ReadLines(file) + contents, err := ioutil.ReadFile(file) if err != nil { return nil, err } + lines := bytes.Split(contents, []byte("\n")) + var ret []connTmp // skip first line for _, line := range lines[1:] { - tokens := strings.Fields(line) + tokens := strings.Fields(string(line)) if len(tokens) < 6 { continue }