mirror of
https://github.com/weaveworks/scope.git
synced 2026-05-06 01:08:03 +00:00
vendoring: update gobpf and tcptracer-bpf
This commit is contained in:
38
vendor/github.com/iovisor/gobpf/elf/elf.go
generated
vendored
38
vendor/github.com/iovisor/gobpf/elf/elf.go
generated
vendored
@@ -348,7 +348,14 @@ func (b *Module) relocate(data []byte, rdata []byte) error {
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Module) Load() error {
|
||||
type SectionParams struct {
|
||||
PerfRingBufferPageCount int
|
||||
SkipPerfMapInitialization bool
|
||||
}
|
||||
|
||||
// Load loads the BPF programs and BPF maps in the module. Each ELF section
|
||||
// can optionally have parameters that changes how it is configured.
|
||||
func (b *Module) Load(parameters map[string]SectionParams) error {
|
||||
if b.fileName != "" {
|
||||
fileReader, err := os.Open(b.fileName)
|
||||
if err != nil {
|
||||
@@ -541,10 +548,10 @@ func (b *Module) Load() error {
|
||||
}
|
||||
}
|
||||
|
||||
return b.initializePerfMaps()
|
||||
return b.initializePerfMaps(parameters)
|
||||
}
|
||||
|
||||
func (b *Module) initializePerfMaps() error {
|
||||
func (b *Module) initializePerfMaps(parameters map[string]SectionParams) error {
|
||||
for name, m := range b.maps {
|
||||
var cpu C.int = 0
|
||||
|
||||
@@ -552,6 +559,22 @@ func (b *Module) initializePerfMaps() error {
|
||||
continue
|
||||
}
|
||||
|
||||
pageSize := os.Getpagesize()
|
||||
b.maps[name].pageCount = 8 // reasonable default
|
||||
|
||||
sectionName := "maps/" + name
|
||||
if params, ok := parameters[sectionName]; ok {
|
||||
if params.SkipPerfMapInitialization {
|
||||
continue
|
||||
}
|
||||
if params.PerfRingBufferPageCount > 0 {
|
||||
if params.PerfRingBufferPageCount <= 0 || (params.PerfRingBufferPageCount&(params.PerfRingBufferPageCount-1)) != 0 {
|
||||
return fmt.Errorf("number of pages (%d) must be stricly positive and a power of 2", params.PerfRingBufferPageCount)
|
||||
}
|
||||
b.maps[name].pageCount = params.PerfRingBufferPageCount
|
||||
}
|
||||
}
|
||||
|
||||
for {
|
||||
pmuFD, err := C.perf_event_open_map(-1 /* pid */, cpu /* cpu */, -1 /* group_fd */, C.PERF_FLAG_FD_CLOEXEC)
|
||||
if pmuFD < 0 {
|
||||
@@ -562,9 +585,7 @@ func (b *Module) initializePerfMaps() error {
|
||||
}
|
||||
|
||||
// mmap
|
||||
pageSize := os.Getpagesize()
|
||||
pageCount := 8
|
||||
mmapSize := pageSize * (pageCount + 1)
|
||||
mmapSize := pageSize * (b.maps[name].pageCount + 1)
|
||||
|
||||
base, err := syscall.Mmap(int(pmuFD), 0, mmapSize, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED)
|
||||
if err != nil {
|
||||
@@ -602,8 +623,9 @@ type Map struct {
|
||||
m *C.bpf_map
|
||||
|
||||
// only for perf maps
|
||||
pmuFDs []C.int
|
||||
headers []*C.struct_perf_event_mmap_page
|
||||
pmuFDs []C.int
|
||||
headers []*C.struct_perf_event_mmap_page
|
||||
pageCount int
|
||||
}
|
||||
|
||||
func (b *Module) IterMaps() <-chan *Map {
|
||||
|
||||
11
vendor/github.com/iovisor/gobpf/elf/elf_unsupported.go
generated
vendored
11
vendor/github.com/iovisor/gobpf/elf/elf_unsupported.go
generated
vendored
@@ -6,12 +6,13 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func (b *Module) Load() error {
|
||||
return fmt.Errorf("not supported")
|
||||
}
|
||||
|
||||
// not supported; dummy struct
|
||||
type BPFKProbePerf struct{}
|
||||
type SectionParams struct{}
|
||||
|
||||
func (b *Module) Load(parameters map[string]SectionParams) error {
|
||||
return fmt.Errorf("not supported")
|
||||
}
|
||||
|
||||
func NewBpfPerfEvent(fileName string) *BPFKProbePerf {
|
||||
// not supported
|
||||
@@ -22,7 +23,7 @@ func (b *BPFKProbePerf) Load() error {
|
||||
return fmt.Errorf("not supported")
|
||||
}
|
||||
|
||||
func (b *BPFKProbePerf) PollStart(mapName string, receiverChan chan []byte) {
|
||||
func (b *BPFKProbePerf) PollStart(mapName string, receiverChan chan []byte, lostChan chan uint64) {
|
||||
// not supported
|
||||
return
|
||||
}
|
||||
|
||||
35
vendor/github.com/iovisor/gobpf/elf/perf.go
generated
vendored
35
vendor/github.com/iovisor/gobpf/elf/perf.go
generated
vendored
@@ -106,7 +106,9 @@ import "C"
|
||||
type PerfMap struct {
|
||||
name string
|
||||
program *Module
|
||||
pageCount int
|
||||
receiverChan chan []byte
|
||||
lostChan chan uint64
|
||||
pollStop chan bool
|
||||
timestamp func(*[]byte) uint64
|
||||
}
|
||||
@@ -118,8 +120,8 @@ type PerfEventSample struct {
|
||||
data byte // Size bytes of data
|
||||
}
|
||||
|
||||
func InitPerfMap(b *Module, mapName string, receiverChan chan []byte) (*PerfMap, error) {
|
||||
_, ok := b.maps[mapName]
|
||||
func InitPerfMap(b *Module, mapName string, receiverChan chan []byte, lostChan chan uint64) (*PerfMap, error) {
|
||||
m, ok := b.maps[mapName]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("no map with name %s", mapName)
|
||||
}
|
||||
@@ -127,7 +129,9 @@ func InitPerfMap(b *Module, mapName string, receiverChan chan []byte) (*PerfMap,
|
||||
return &PerfMap{
|
||||
name: mapName,
|
||||
program: b,
|
||||
pageCount: m.pageCount,
|
||||
receiverChan: receiverChan,
|
||||
lostChan: lostChan,
|
||||
pollStop: make(chan bool),
|
||||
}, nil
|
||||
}
|
||||
@@ -157,7 +161,6 @@ func (pm *PerfMap) PollStart() {
|
||||
go func() {
|
||||
cpuCount := len(m.pmuFDs)
|
||||
pageSize := os.Getpagesize()
|
||||
pageCount := 8
|
||||
state := C.struct_read_state{}
|
||||
|
||||
for {
|
||||
@@ -168,59 +171,61 @@ func (pm *PerfMap) PollStart() {
|
||||
perfEventPoll(m.pmuFDs)
|
||||
}
|
||||
|
||||
harvestLoop:
|
||||
for {
|
||||
var harvestCount C.int
|
||||
beforeHarvest := nowNanoseconds()
|
||||
for cpu := 0; cpu < cpuCount; cpu++ {
|
||||
ringBufferLoop:
|
||||
for {
|
||||
var sample *PerfEventSample
|
||||
var lost *PerfEventLost
|
||||
|
||||
ok := C.perf_event_read(C.int(pageCount), C.int(pageSize),
|
||||
ok := C.perf_event_read(C.int(pm.pageCount), C.int(pageSize),
|
||||
unsafe.Pointer(&state), unsafe.Pointer(m.headers[cpu]),
|
||||
unsafe.Pointer(&sample), unsafe.Pointer(&lost))
|
||||
|
||||
switch ok {
|
||||
case 0:
|
||||
break // nothing to read
|
||||
break ringBufferLoop // nothing to read
|
||||
case C.PERF_RECORD_SAMPLE:
|
||||
size := sample.Size - 4
|
||||
b := C.GoBytes(unsafe.Pointer(&sample.data), C.int(size))
|
||||
incoming.bytesArray = append(incoming.bytesArray, b)
|
||||
harvestCount++
|
||||
if pm.timestamp == nil {
|
||||
continue
|
||||
continue ringBufferLoop
|
||||
}
|
||||
if incoming.timestamp(&b) > beforeHarvest {
|
||||
// see comment below
|
||||
break
|
||||
} else {
|
||||
continue
|
||||
break ringBufferLoop
|
||||
}
|
||||
case C.PERF_RECORD_LOST:
|
||||
if pm.lostChan != nil {
|
||||
pm.lostChan <- lost.Lost
|
||||
}
|
||||
default:
|
||||
// TODO: handle lost/unknown events?
|
||||
// ignore unknown events
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if incoming.timestamp != nil {
|
||||
sort.Sort(incoming)
|
||||
}
|
||||
for i := 0; i < incoming.Len(); i++ {
|
||||
for incoming.Len() > 0 {
|
||||
if incoming.timestamp != nil && incoming.timestamp(&incoming.bytesArray[0]) > beforeHarvest {
|
||||
// This record has been sent after the beginning of the harvest. Stop
|
||||
// processing here to keep the order. "incoming" is sorted, so the next
|
||||
// elements also must not be processed now.
|
||||
break
|
||||
break harvestLoop
|
||||
}
|
||||
pm.receiverChan <- incoming.bytesArray[0]
|
||||
// remove first element
|
||||
incoming.bytesArray = incoming.bytesArray[1:]
|
||||
}
|
||||
if harvestCount == 0 && len(incoming.bytesArray) == 0 {
|
||||
break
|
||||
break harvestLoop
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -265,7 +270,7 @@ func (a OrderedBytesArray) Swap(i, j int) {
|
||||
}
|
||||
|
||||
func (a OrderedBytesArray) Less(i, j int) bool {
|
||||
return *(*C.uint64_t)(unsafe.Pointer(&a.bytesArray[i][0])) < *(*C.uint64_t)(unsafe.Pointer(&a.bytesArray[j][0]))
|
||||
return a.timestamp(&a.bytesArray[i]) < a.timestamp(&a.bytesArray[j])
|
||||
}
|
||||
|
||||
// Matching 'struct perf_event_header in <linux/perf_event.h>
|
||||
|
||||
25
vendor/github.com/iovisor/gobpf/elf/table.go
generated
vendored
25
vendor/github.com/iovisor/gobpf/elf/table.go
generated
vendored
@@ -106,3 +106,28 @@ func (b *Module) LookupElement(mp *Map, key, value unsafe.Pointer) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteElement deletes the given key in the the map stored in mp.
|
||||
// The key is stored in the key unsafe.Pointer.
|
||||
func (b *Module) DeleteElement(mp *Map, key unsafe.Pointer) error {
|
||||
uba := C.union_bpf_attr{}
|
||||
value := unsafe.Pointer(nil)
|
||||
C.create_bpf_lookup_elem(
|
||||
C.int(mp.m.fd),
|
||||
key,
|
||||
value,
|
||||
unsafe.Pointer(&uba),
|
||||
)
|
||||
ret, _, err := syscall.Syscall(
|
||||
C.__NR_bpf,
|
||||
C.BPF_MAP_DELETE_ELEM,
|
||||
uintptr(unsafe.Pointer(&uba)),
|
||||
unsafe.Sizeof(uba),
|
||||
)
|
||||
|
||||
if ret != 0 || err != 0 {
|
||||
return fmt.Errorf("unable to delete element: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
28
vendor/github.com/weaveworks/tcptracer-bpf/pkg/tracer/tracer.go
generated
vendored
28
vendor/github.com/weaveworks/tcptracer-bpf/pkg/tracer/tracer.go
generated
vendored
@@ -30,7 +30,7 @@ func TracerAsset() ([]byte, error) {
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func NewTracer(tcpEventCbV4 func(TcpV4), tcpEventCbV6 func(TcpV6)) (*Tracer, error) {
|
||||
func NewTracer(tcpEventCbV4 func(TcpV4), tcpEventCbV6 func(TcpV6), lostCb func(lost uint64)) (*Tracer, error) {
|
||||
buf, err := Asset("tcptracer-ebpf.o")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't find asset: %s", err)
|
||||
@@ -42,7 +42,9 @@ func NewTracer(tcpEventCbV4 func(TcpV4), tcpEventCbV6 func(TcpV6)) (*Tracer, err
|
||||
return nil, fmt.Errorf("BPF not supported")
|
||||
}
|
||||
|
||||
err = m.Load()
|
||||
sectionParams := make(map[string]bpflib.SectionParams)
|
||||
sectionParams["maps/tcp_event_ipv4"] = bpflib.SectionParams{PerfRingBufferPageCount: 256}
|
||||
err = m.Load(sectionParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -54,13 +56,15 @@ func NewTracer(tcpEventCbV4 func(TcpV4), tcpEventCbV6 func(TcpV6)) (*Tracer, err
|
||||
|
||||
channelV4 := make(chan []byte)
|
||||
channelV6 := make(chan []byte)
|
||||
lostChanV4 := make(chan uint64)
|
||||
lostChanV6 := make(chan uint64)
|
||||
|
||||
perfMapIPV4, err := initializeIPv4(m, channelV4)
|
||||
perfMapIPV4, err := initializeIPv4(m, channelV4, lostChanV4)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to init perf map for IPv4 events: %s", err)
|
||||
}
|
||||
|
||||
perfMapIPV6, err := initializeIPv6(m, channelV6)
|
||||
perfMapIPV6, err := initializeIPv6(m, channelV6, lostChanV6)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to init perf map for IPv6 events: %s", err)
|
||||
}
|
||||
@@ -77,6 +81,8 @@ func NewTracer(tcpEventCbV4 func(TcpV4), tcpEventCbV6 func(TcpV6)) (*Tracer, err
|
||||
return
|
||||
case data := <-channelV4:
|
||||
tcpEventCbV4(tcpV4ToGo(&data))
|
||||
case lost := <-lostChanV4:
|
||||
lostCb(lost)
|
||||
}
|
||||
}
|
||||
}()
|
||||
@@ -88,6 +94,8 @@ func NewTracer(tcpEventCbV4 func(TcpV4), tcpEventCbV6 func(TcpV6)) (*Tracer, err
|
||||
return
|
||||
case data := <-channelV6:
|
||||
tcpEventCbV6(tcpV6ToGo(&data))
|
||||
case lost := <-lostChanV6:
|
||||
lostCb(lost)
|
||||
}
|
||||
}
|
||||
}()
|
||||
@@ -109,12 +117,12 @@ func (t *Tracer) Stop() {
|
||||
t.perfMapIPV6.PollStop()
|
||||
}
|
||||
|
||||
func initialize(module *bpflib.Module, eventMapName string, eventChan chan []byte) (*bpflib.PerfMap, error) {
|
||||
func initialize(module *bpflib.Module, eventMapName string, eventChan chan []byte, lostChan chan uint64) (*bpflib.PerfMap, error) {
|
||||
if err := guess(module); err != nil {
|
||||
return nil, fmt.Errorf("error guessing offsets: %v", err)
|
||||
}
|
||||
|
||||
pm, err := bpflib.InitPerfMap(module, eventMapName, eventChan)
|
||||
pm, err := bpflib.InitPerfMap(module, eventMapName, eventChan, lostChan)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error initializing perf map for %q: %v", eventMapName, err)
|
||||
}
|
||||
@@ -123,10 +131,10 @@ func initialize(module *bpflib.Module, eventMapName string, eventChan chan []byt
|
||||
|
||||
}
|
||||
|
||||
func initializeIPv4(module *bpflib.Module, eventChan chan []byte) (*bpflib.PerfMap, error) {
|
||||
return initialize(module, "tcp_event_ipv4", eventChan)
|
||||
func initializeIPv4(module *bpflib.Module, eventChan chan []byte, lostChan chan uint64) (*bpflib.PerfMap, error) {
|
||||
return initialize(module, "tcp_event_ipv4", eventChan, lostChan)
|
||||
}
|
||||
|
||||
func initializeIPv6(module *bpflib.Module, eventChan chan []byte) (*bpflib.PerfMap, error) {
|
||||
return initialize(module, "tcp_event_ipv6", eventChan)
|
||||
func initializeIPv6(module *bpflib.Module, eventChan chan []byte, lostChan chan uint64) (*bpflib.PerfMap, error) {
|
||||
return initialize(module, "tcp_event_ipv6", eventChan, lostChan)
|
||||
}
|
||||
|
||||
2
vendor/github.com/weaveworks/tcptracer-bpf/pkg/tracer/tracer_unsupported.go
generated
vendored
2
vendor/github.com/weaveworks/tcptracer-bpf/pkg/tracer/tracer_unsupported.go
generated
vendored
@@ -12,7 +12,7 @@ func TracerAsset() ([]byte, error) {
|
||||
return nil, fmt.Errorf("not supported on non-Linux systems")
|
||||
}
|
||||
|
||||
func NewTracer(tcpEventCbV4 func(TcpV4), tcpEventCbV6 func(TcpV6)) (*Tracer, error) {
|
||||
func NewTracer(tcpEventCbV4 func(TcpV4), tcpEventCbV6 func(TcpV6), lostCb func(lost uint64)) (*Tracer, error) {
|
||||
return nil, fmt.Errorf("not supported on non-Linux systems")
|
||||
}
|
||||
|
||||
|
||||
7
vendor/github.com/weaveworks/tcptracer-bpf/tests/tracer.go
generated
vendored
7
vendor/github.com/weaveworks/tcptracer-bpf/tests/tracer.go
generated
vendored
@@ -35,13 +35,18 @@ func tcpEventCbV6(e tracer.TcpV6) {
|
||||
lastTimestampV6 = e.Timestamp
|
||||
}
|
||||
|
||||
func lostCb(count uint64) {
|
||||
fmt.Printf("ERROR: lost %d events!\n", count)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 1 {
|
||||
fmt.Fprintf(os.Stderr, "Usage: %s\n", os.Args[0])
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
t, err := tracer.NewTracer(tcpEventCbV4, tcpEventCbV6)
|
||||
t, err := tracer.NewTracer(tcpEventCbV4, tcpEventCbV6, lostCb)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||
os.Exit(1)
|
||||
|
||||
4
vendor/manifest
vendored
4
vendor/manifest
vendored
@@ -1020,7 +1020,7 @@
|
||||
"importpath": "github.com/iovisor/gobpf/elf",
|
||||
"repository": "https://github.com/iovisor/gobpf",
|
||||
"vcs": "git",
|
||||
"revision": "65e4048660d6c4339ebae113ac55b1af6f01305d",
|
||||
"revision": "23f7ee81c1cc244d16ddc8110c2ec8b8a09d0448",
|
||||
"branch": "master",
|
||||
"path": "/elf",
|
||||
"notests": true
|
||||
@@ -1462,7 +1462,7 @@
|
||||
"importpath": "github.com/weaveworks/tcptracer-bpf",
|
||||
"repository": "https://github.com/weaveworks/tcptracer-bpf",
|
||||
"vcs": "git",
|
||||
"revision": "b715a3b635b8d9c4a096bbd6009826b57fe64c38",
|
||||
"revision": "a82fffdbfee2ffe2c469279dbfeb3734cf7de1f2",
|
||||
"branch": "master",
|
||||
"notests": true
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user