diff --git a/probe/endpoint/procspy/proc.go b/probe/endpoint/procspy/proc.go index bfbe3e1622..24a5e7527e 100644 --- a/probe/endpoint/procspy/proc.go +++ b/probe/endpoint/procspy/proc.go @@ -5,6 +5,7 @@ package procspy import ( "bytes" "log" + "os" "path/filepath" "strconv" "syscall" @@ -30,7 +31,7 @@ func walkProcPid(buf *bytes.Buffer, walker process.Walker, namespaceTicker <-cha var ( res = map[uint64]*Proc{} // map socket inode -> process namespaces = map[uint64][]*process.Process{} // map network namespace id -> processes - statT syscall.Stat_t + ) // Two process passes: One to group processes by namespace and another @@ -43,16 +44,23 @@ func walkProcPid(buf *bytes.Buffer, walker process.Walker, namespaceTicker <-cha walker.Walk(func(p, _ process.Process) { dirName := strconv.Itoa(p.PID) + linkBody, err := os.Readlink(filepath.Join(procRoot, dirName, "/ns/net")) + + // inode must contain a string with format 'net:[inode]' + if err != nil || len(linkBody) < 5 { + return + } - if err := fs.Lstat(filepath.Join(procRoot, dirName, "/ns/net"), &statT); err != nil { + nsInode, err := strconv.ParseUint(linkBody[5:len(linkBody)-1], 10, 64) + if err != nil { return } - procs, ok := namespaces[statT.Ino] + procs, ok := namespaces[nsInode] if ok { - namespaces[statT.Ino] = append(procs, &p) + namespaces[nsInode] = append(procs, &p) } else { - namespaces[statT.Ino] = []*process.Process{&p} + namespaces[nsInode] = []*process.Process{&p} } }) @@ -96,6 +104,7 @@ func walkProcPid(buf *bytes.Buffer, walker process.Walker, namespaceTicker <-cha } var proc *Proc for _, fd := range fds { + var statT syscall.Stat_t // Direct use of syscall.Stat() to save garbage. err = fs.Stat(filepath.Join(fdBase, fd), &statT) if err != nil {