mirror of
https://github.com/weaveworks/scope.git
synced 2026-02-14 10:00:13 +00:00
performance: network namespace ID is a 32-bit quantity
This shrinks some data-structures slightly. Citation: https://github.com/torvalds/linux/blob/6f0d349d922b/include/linux/ns_common.h#L10
This commit is contained in:
@@ -190,7 +190,7 @@ func (t *connectionTracker) performEbpfTrack(rpt *report.Report, hostNodeID stri
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *connectionTracker) addConnection(rpt *report.Report, incoming bool, ft fourTuple, namespaceID uint64, extraFromNode, extraToNode map[string]string) {
|
||||
func (t *connectionTracker) addConnection(rpt *report.Report, incoming bool, ft fourTuple, namespaceID uint32, extraFromNode, extraToNode map[string]string) {
|
||||
if incoming {
|
||||
ft = reverse(ft)
|
||||
extraFromNode, extraToNode = extraToNode, extraFromNode
|
||||
@@ -207,7 +207,7 @@ func (t *connectionTracker) addConnection(rpt *report.Report, incoming bool, ft
|
||||
t.addDNS(rpt, toAddr.String())
|
||||
}
|
||||
|
||||
func (t *connectionTracker) makeEndpointNode(namespaceID uint64, addr net.IP, port uint16, extra map[string]string) report.Node {
|
||||
func (t *connectionTracker) makeEndpointNode(namespaceID uint32, addr net.IP, port uint16, extra map[string]string) report.Node {
|
||||
node := report.MakeNodeWith(report.MakeEndpointNodeIDB(t.conf.HostID, namespaceID, addr, port), nil)
|
||||
if extra != nil {
|
||||
node = node.WithLatests(extra)
|
||||
@@ -240,7 +240,7 @@ func (t *connectionTracker) Stop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func connectionTuple(conn *procspy.Connection, seenTuples map[string]fourTuple) (fourTuple, uint64, bool) {
|
||||
func connectionTuple(conn *procspy.Connection, seenTuples map[string]fourTuple) (fourTuple, uint32, bool) {
|
||||
tuple := makeFourTuple(conn.LocalAddress, conn.RemoteAddress, conn.LocalPort, conn.RemotePort)
|
||||
|
||||
// If we've already seen this connection, we should know the direction
|
||||
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
// An ebpfConnection represents a TCP connection
|
||||
type ebpfConnection struct {
|
||||
tuple fourTuple
|
||||
networkNamespace uint64
|
||||
networkNamespace uint32
|
||||
incoming bool
|
||||
pid int
|
||||
}
|
||||
@@ -173,7 +173,7 @@ func (t *EbpfTracker) TCPEventV4(e tracer.TcpV4) {
|
||||
t.handleFdInstall(e.Type, int(e.Pid), int(e.Fd))
|
||||
} else {
|
||||
tuple := makeFourTuple(e.SAddr, e.DAddr, e.SPort, e.DPort)
|
||||
t.handleConnection(e.Type, tuple, int(e.Pid), uint64(e.NetNS))
|
||||
t.handleConnection(e.Type, tuple, int(e.Pid), e.NetNS)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ func (t *EbpfTracker) LostV6(count uint64) {
|
||||
// TODO: IPv6 not supported in Scope
|
||||
}
|
||||
|
||||
func tupleFromPidFd(pid int, fd int) (tuple fourTuple, netns uint64, ok bool) {
|
||||
func tupleFromPidFd(pid int, fd int) (tuple fourTuple, netns uint32, ok bool) {
|
||||
// read /proc/$pid/ns/net
|
||||
//
|
||||
// probe/endpoint/procspy/proc_linux.go supports Linux < 3.8 but we
|
||||
@@ -268,7 +268,7 @@ func (t *EbpfTracker) handleFdInstall(ev tracer.EventType, pid int, fd int) {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *EbpfTracker) handleConnection(ev tracer.EventType, tuple fourTuple, pid int, networkNamespace uint64) {
|
||||
func (t *EbpfTracker) handleConnection(ev tracer.EventType, tuple fourTuple, pid int, networkNamespace uint32) {
|
||||
t.Lock()
|
||||
defer t.Unlock()
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ func TestHandleConnection(t *testing.T) {
|
||||
fromPort: ClientPort,
|
||||
toPort: ServerPort,
|
||||
},
|
||||
networkNamespace: uint64(NetNS),
|
||||
networkNamespace: NetNS,
|
||||
incoming: false,
|
||||
pid: int(ClientPid),
|
||||
}
|
||||
@@ -89,7 +89,7 @@ func TestHandleConnection(t *testing.T) {
|
||||
fromPort: ServerPort,
|
||||
toPort: ClientPort,
|
||||
},
|
||||
networkNamespace: uint64(NetNS),
|
||||
networkNamespace: NetNS,
|
||||
incoming: true,
|
||||
pid: int(ServerPid),
|
||||
}
|
||||
@@ -110,14 +110,14 @@ func TestHandleConnection(t *testing.T) {
|
||||
mockEbpfTracker := newMockEbpfTracker()
|
||||
|
||||
tuple := fourTuple{ClientAddr, ServerAddr, uint16(IPv4ConnectEvent.SPort), uint16(IPv4ConnectEvent.DPort)}
|
||||
mockEbpfTracker.handleConnection(IPv4ConnectEvent.Type, tuple, int(IPv4ConnectEvent.Pid), uint64(NetNS))
|
||||
mockEbpfTracker.handleConnection(IPv4ConnectEvent.Type, tuple, int(IPv4ConnectEvent.Pid), NetNS)
|
||||
if !reflect.DeepEqual(mockEbpfTracker.openConnections[tuple], IPv4ConnectEbpfConnection) {
|
||||
t.Errorf("Connection mismatch connect event\nTarget connection:%v\nParsed connection:%v",
|
||||
IPv4ConnectEbpfConnection, mockEbpfTracker.openConnections[tuple])
|
||||
}
|
||||
|
||||
tuple = fourTuple{ClientAddr, ServerAddr, uint16(IPv4ConnectCloseEvent.SPort), uint16(IPv4ConnectCloseEvent.DPort)}
|
||||
mockEbpfTracker.handleConnection(IPv4ConnectCloseEvent.Type, tuple, int(IPv4ConnectCloseEvent.Pid), uint64(NetNS))
|
||||
mockEbpfTracker.handleConnection(IPv4ConnectCloseEvent.Type, tuple, int(IPv4ConnectCloseEvent.Pid), NetNS)
|
||||
if len(mockEbpfTracker.openConnections) != 0 {
|
||||
t.Errorf("Connection mismatch close event\nConnection to close:%v",
|
||||
mockEbpfTracker.openConnections[tuple])
|
||||
@@ -126,14 +126,14 @@ func TestHandleConnection(t *testing.T) {
|
||||
mockEbpfTracker = newMockEbpfTracker()
|
||||
|
||||
tuple = fourTuple{ServerAddr, ClientAddr, uint16(IPv4AcceptEvent.SPort), uint16(IPv4AcceptEvent.DPort)}
|
||||
mockEbpfTracker.handleConnection(IPv4AcceptEvent.Type, tuple, int(IPv4AcceptEvent.Pid), uint64(NetNS))
|
||||
mockEbpfTracker.handleConnection(IPv4AcceptEvent.Type, tuple, int(IPv4AcceptEvent.Pid), NetNS)
|
||||
if !reflect.DeepEqual(mockEbpfTracker.openConnections[tuple], IPv4AcceptEbpfConnection) {
|
||||
t.Errorf("Connection mismatch connect event\nTarget connection:%v\nParsed connection:%v",
|
||||
IPv4AcceptEbpfConnection, mockEbpfTracker.openConnections[tuple])
|
||||
}
|
||||
|
||||
tuple = fourTuple{ServerAddr, ClientAddr, uint16(IPv4AcceptCloseEvent.SPort), uint16(IPv4AcceptCloseEvent.DPort)}
|
||||
mockEbpfTracker.handleConnection(IPv4AcceptCloseEvent.Type, tuple, int(IPv4AcceptCloseEvent.Pid), uint64(NetNS))
|
||||
mockEbpfTracker.handleConnection(IPv4AcceptCloseEvent.Type, tuple, int(IPv4AcceptCloseEvent.Pid), NetNS)
|
||||
|
||||
if len(mockEbpfTracker.openConnections) != 0 {
|
||||
t.Errorf("Connection mismatch close event\nConnection to close:%v",
|
||||
|
||||
@@ -146,7 +146,7 @@ func readProcessConnections(buf *bytes.Buffer, namespaceProcs []*process.Process
|
||||
}
|
||||
|
||||
// walkNamespace does the work of walk for a single namespace
|
||||
func (w pidWalker) walkNamespace(namespaceID uint64, buf *bytes.Buffer, sockets map[uint64]*Proc, namespaceProcs []*process.Process) error {
|
||||
func (w pidWalker) walkNamespace(namespaceID uint32, buf *bytes.Buffer, sockets map[uint64]*Proc, namespaceProcs []*process.Process) error {
|
||||
|
||||
if found, err := readProcessConnections(buf, namespaceProcs); err != nil || !found {
|
||||
return err
|
||||
@@ -216,7 +216,7 @@ func (w pidWalker) walkNamespace(namespaceID uint64, buf *bytes.Buffer, sockets
|
||||
}
|
||||
|
||||
// ReadNetnsFromPID gets the netns inode of the specified pid
|
||||
func ReadNetnsFromPID(pid int) (uint64, error) {
|
||||
func ReadNetnsFromPID(pid int) (uint32, error) {
|
||||
var statT syscall.Stat_t
|
||||
|
||||
dirName := strconv.Itoa(pid)
|
||||
@@ -225,7 +225,9 @@ func ReadNetnsFromPID(pid int) (uint64, error) {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return statT.Ino, nil
|
||||
// Although Inode is a 64-bit field, namespaces have 32-bit IDs
|
||||
// see https://github.com/torvalds/linux/blob/6f0d349d922b/include/linux/ns_common.h#L10
|
||||
return uint32(statT.Ino), nil
|
||||
}
|
||||
|
||||
// walk walks over all numerical (PID) /proc entries. It reads
|
||||
@@ -235,7 +237,7 @@ func ReadNetnsFromPID(pid int) (uint64, error) {
|
||||
func (w pidWalker) walk(buf *bytes.Buffer) (map[uint64]*Proc, error) {
|
||||
var (
|
||||
sockets = map[uint64]*Proc{} // map socket inode -> process
|
||||
namespaces = map[uint64][]*process.Process{} // map network namespace id -> processes
|
||||
namespaces = map[uint32][]*process.Process{} // map network namespace id -> processes
|
||||
)
|
||||
|
||||
// We do two process traversals: One to group processes by namespace and
|
||||
|
||||
@@ -30,7 +30,7 @@ type Connection struct {
|
||||
type Proc struct {
|
||||
PID uint
|
||||
Name string
|
||||
NetNamespaceID uint64
|
||||
NetNamespaceID uint32
|
||||
}
|
||||
|
||||
// ConnIter is returned by Connections().
|
||||
|
||||
@@ -35,10 +35,10 @@ func MakeEndpointNodeID(hostID, namespaceID, address, port string) string {
|
||||
}
|
||||
|
||||
// MakeEndpointNodeIDB produces an endpoint node ID from its composite parts in binary, not strings.
|
||||
func MakeEndpointNodeIDB(hostID string, namespaceID uint64, addressIP net.IP, port uint16) string {
|
||||
func MakeEndpointNodeIDB(hostID string, namespaceID uint32, addressIP net.IP, port uint16) string {
|
||||
namespace := ""
|
||||
if namespaceID > 0 {
|
||||
namespace = strconv.FormatUint(namespaceID, 10)
|
||||
namespace = strconv.FormatUint(uint64(namespaceID), 10)
|
||||
}
|
||||
return makeAddressID(hostID, namespace, addressIP.String(), addressIP) + ScopeDelim + strconv.Itoa(int(port))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user