Skip to content

Commit

Permalink
Merge pull request #2557 from weaveworks/dont-read-all-of-proc
Browse files Browse the repository at this point in the history
don't read all of /proc when probe.proc.spy=false
  • Loading branch information
rade authored Jun 4, 2017
2 parents e4f5537 + 59f777a commit b29602f
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 32 deletions.
8 changes: 4 additions & 4 deletions probe/endpoint/connection_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func flowToTuple(f flow) (ft fourTuple) {
func (t *connectionTracker) useProcfs() {
t.ebpfTracker = nil
if t.conf.WalkProc && t.conf.Scanner == nil {
t.conf.Scanner = procspy.NewConnectionScanner(t.conf.ProcessCache)
t.conf.Scanner = procspy.NewConnectionScanner(t.conf.ProcessCache, t.conf.SpyProcs)
}
if t.flowWalker == nil {
t.flowWalker = newConntrackFlowWalker(t.conf.UseConntrack, t.conf.ProcRoot, t.conf.BufferSize)
Expand Down Expand Up @@ -112,7 +112,7 @@ func (t *connectionTracker) performFlowWalk(rpt *report.Report, seenTuples *map[
}

func (t *connectionTracker) performWalkProc(rpt *report.Report, hostNodeID string, seenTuples *map[string]fourTuple) error {
conns, err := t.conf.Scanner.Connections(t.conf.SpyProcs)
conns, err := t.conf.Scanner.Connections()
if err != nil {
return err
}
Expand Down Expand Up @@ -159,7 +159,7 @@ func (t *connectionTracker) getInitialState() {
processCache = process.NewCachingWalker(walker)
processCache.Tick()

scanner := procspy.NewSyncConnectionScanner(processCache)
scanner := procspy.NewSyncConnectionScanner(processCache, t.conf.SpyProcs)
seenTuples := map[string]fourTuple{}
// Consult the flowWalker to get the initial state
if err := IsConntrackSupported(t.conf.ProcRoot); t.conf.UseConntrack && err != nil {
Expand All @@ -173,7 +173,7 @@ func (t *connectionTracker) getInitialState() {
}
}

conns, err := scanner.Connections(t.conf.SpyProcs)
conns, err := scanner.Connections()
if err != nil {
log.Errorf("Error initializing ebpfTracker while scanning /proc, continuing without initial connections: %s", err)
}
Expand Down
2 changes: 1 addition & 1 deletion probe/endpoint/procspy/fixture.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func (f *fixedConnIter) Next() *Connection {
type FixedScanner []Connection

// Connections implements ConnectionsScanner.Connections
func (s FixedScanner) Connections(_ bool) (ConnIter, error) {
func (s FixedScanner) Connections() (ConnIter, error) {
iter := fixedConnIter(s)
return &iter, nil
}
Expand Down
8 changes: 2 additions & 6 deletions probe/endpoint/procspy/spy.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,8 @@ type ConnIter interface {

// ConnectionScanner scans the system for established (TCP) connections
type ConnectionScanner interface {
// Connections returns all established (TCP) connections. If processes is
// false we'll just list all TCP connections, and there is no need to be root.
// If processes is true it'll additionally try to lookup the process owning the
// connection, filling in the Proc field. You will need to run this as root to
// find all processes.
Connections(processes bool) (ConnIter, error)
// Connections returns all established (TCP) connections.
Connections() (ConnIter, error)
// Stops the scanning
Stop()
}
20 changes: 10 additions & 10 deletions probe/endpoint/procspy/spy_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,21 @@ const (
)

// NewConnectionScanner creates a new Darwin ConnectionScanner
func NewConnectionScanner(_ process.Walker) ConnectionScanner {
return &darwinScanner{}
func NewConnectionScanner(_ process.Walker, processes bool) ConnectionScanner {
return &darwinScanner{processes}
}

// NewSyncConnectionScanner creates a new synchronous Darwin ConnectionScanner
func NewSyncConnectionScanner(_ process.Walker) ConnectionScanner {
return &darwinScanner{}
func NewSyncConnectionScanner(_ process.Walker, processes bool) ConnectionScanner {
return &darwinScanner{processes}
}

type darwinScanner struct{}
type darwinScanner struct {
processes bool
}

// Connections returns all established (TCP) connections. No need to be root
// to run this. If processes is true it also tries to fill in the process
// fields of the connection. You need to be root to find all processes.
func (s *darwinScanner) Connections(processes bool) (ConnIter, error) {
// Connections returns all established (TCP) connections.
func (s *darwinScanner) Connections() (ConnIter, error) {
out, err := exec.Command(
netstatBinary,
"-n", // no number resolving
Expand All @@ -42,7 +42,7 @@ func (s *darwinScanner) Connections(processes bool) (ConnIter, error) {
}
connections := parseDarwinNetstat(string(out))

if processes {
if s.processes {
out, err := exec.Command(
lsofBinary,
"-i", // only Internet files
Expand Down
26 changes: 17 additions & 9 deletions probe/endpoint/procspy/spy_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,34 @@ func (c *pnConnIter) Next() *Connection {
}

// NewConnectionScanner creates a new Linux ConnectionScanner
func NewConnectionScanner(walker process.Walker) ConnectionScanner {
br := newBackgroundReader(walker)
return &linuxScanner{br}
func NewConnectionScanner(walker process.Walker, processes bool) ConnectionScanner {
scanner := &linuxScanner{}
if processes {
scanner.r = newBackgroundReader(walker)
}
return scanner
}

// NewSyncConnectionScanner creates a new synchronous Linux ConnectionScanner
func NewSyncConnectionScanner(walker process.Walker) ConnectionScanner {
fr := newForegroundReader(walker)
return &linuxScanner{fr}
func NewSyncConnectionScanner(walker process.Walker, processes bool) ConnectionScanner {
scanner := &linuxScanner{}
if processes {
scanner.r = newForegroundReader(walker)
}
return scanner
}

type linuxScanner struct {
r reader
}

func (s *linuxScanner) Connections(processes bool) (ConnIter, error) {
func (s *linuxScanner) Connections() (ConnIter, error) {
// buffer for contents of /proc/<pid>/net/tcp
buf := bufPool.Get().(*bytes.Buffer)
buf.Reset()

var procs map[uint64]*Proc
if processes {
if s.r != nil {
var err error
if procs, err = s.r.getWalkedProcPid(buf); err != nil {
return nil, err
Expand All @@ -74,5 +80,7 @@ func (s *linuxScanner) Connections(processes bool) (ConnIter, error) {
}

func (s *linuxScanner) Stop() {
s.r.stop()
if s.r != nil {
s.r.stop()
}
}
4 changes: 2 additions & 2 deletions probe/endpoint/procspy/spy_linux_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ import (
func TestLinuxConnections(t *testing.T) {
fs_hook.Mock(mockFS)
defer fs_hook.Restore()
scanner := NewConnectionScanner(process.NewWalker("/proc", false))
scanner := NewConnectionScanner(process.NewWalker("/proc", false), true)
defer scanner.Stop()

// let the background scanner finish its first pass
time.Sleep(1 * time.Second)

iter, err := scanner.Connections(true)
iter, err := scanner.Connections()
if err != nil {
t.Fatal(err)
}
Expand Down

0 comments on commit b29602f

Please sign in to comment.