btf_vmlinux.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package tracer
  2. import (
  3. "encoding/binary"
  4. "errors"
  5. "fmt"
  6. "github.com/cilium/ebpf"
  7. "github.com/cilium/ebpf/btf"
  8. . "github.com/coroot/coroot-node-agent/utils/modelse"
  9. "runtime"
  10. )
  11. func kernel_struct_field_offset(btfSpec *btf.Spec, member string, field string) int32 {
  12. typ, err := btfSpec.AnyTypeByName(member)
  13. if err != nil {
  14. return ETR_NOTSUPP
  15. }
  16. return kernel_struct_field_offset_helper(btfSpec, typ, field)
  17. }
  18. func kernel_struct_field_offset_helper(btfSpec *btf.Spec, typ btf.Type, field string) int32 {
  19. //var offset btf.Bits
  20. switch typ.(type) {
  21. case *btf.Struct, *btf.Union:
  22. var membersT []btf.Member
  23. switch t := typ.(type) {
  24. case *btf.Struct:
  25. membersT = t.Members
  26. case *btf.Union:
  27. membersT = t.Members
  28. }
  29. for _, member := range membersT {
  30. if member.Name == field {
  31. //fmt.Printf("Struct:%s,0x%x\n", member.Name, member.Offset.Bytes())
  32. return int32(member.Offset.Bytes())
  33. }
  34. if member.Name == "" {
  35. //fmt.Printf("下钻:%s,0x%x\n", member.Type, member.Offset/8)
  36. retval := kernel_struct_field_offset_helper(btfSpec, member.Type, field)
  37. if retval >= 0 {
  38. return int32(member.Offset.Bytes()) + retval
  39. }
  40. }
  41. }
  42. }
  43. return ETR_NOTEXIST
  44. }
  45. func bpf_table_pre_set_value(collectionSpec *ebpf.CollectionSpec, opts *ebpf.CollectionOptions, mapName string, data any) int {
  46. m, ok := collectionSpec.Maps[mapName]
  47. if ok {
  48. newMap, err := ebpf.NewMap(&ebpf.MapSpec{
  49. Type: m.Type,
  50. KeySize: m.KeySize,
  51. ValueSize: m.ValueSize,
  52. MaxEntries: m.MaxEntries,
  53. })
  54. if err != nil {
  55. return ETR_UPDATE_MAP_FAILD
  56. }
  57. //// Convert test_t to slice
  58. //numCPU := runtime.NumCPU()
  59. //off := make([]interface{}, numCPU)
  60. //for i := range off {
  61. // off[i] = data
  62. //}
  63. key := make([]byte, 4) // Assuming int key size is 4 bytes
  64. binary.LittleEndian.PutUint32(key, 0) // Assuming the key is an integer
  65. if err = newMap.Update(key, data, ebpf.UpdateAny); err != nil {
  66. fmt.Println(err)
  67. return ETR_UPDATE_MAP_FAILD
  68. }
  69. opts.MapReplacements[mapName] = newMap
  70. //opts.MapReplacements = map[string]*ebpf.Map{
  71. // mapName: newMap,
  72. //}
  73. } else {
  74. return ETR_UPDATE_MAP_FAILD
  75. }
  76. return ETR_OK
  77. }
  78. func bpf_table_set_value(collection *ebpf.Collection, mapName string, key uint32, data any) (int, error) {
  79. m, ok := collection.Maps[mapName]
  80. //for s, m2 := range collection.Maps {
  81. // fmt.Println(s, m2.String())
  82. //}
  83. //fmt.Println("bpf_table_set_value", m, mapName, data)
  84. if ok {
  85. k := make([]byte, 4) // Assuming int k size is 4 bytes
  86. binary.LittleEndian.PutUint32(k, key) // Assuming the key is an integer
  87. if err := m.Update(k, data, ebpf.UpdateAny); err != nil {
  88. return ETR_UPDATE_MAP_FAILD, err
  89. }
  90. } else {
  91. return ETR_UPDATE_MAP_FAILD, errors.New("cannot find map " + mapName)
  92. }
  93. return ETR_OK, nil
  94. }
  95. func test(collectionSpec *ebpf.CollectionSpec, opts *ebpf.CollectionOptions) {
  96. fmt.Println("collectionSpec.Maps start --")
  97. var newMap *ebpf.Map
  98. var err error
  99. m, ok := collectionSpec.Maps["test_heap"]
  100. if ok {
  101. newMap, err = ebpf.NewMap(&ebpf.MapSpec{
  102. Type: m.Type, // 设置 Map 的类型
  103. KeySize: m.KeySize, // 设置 Key 的大小
  104. ValueSize: m.ValueSize, // 设置 Value 的大小
  105. MaxEntries: m.MaxEntries, // 设置最大条目数
  106. })
  107. if err != nil {
  108. fmt.Println("Failed to create map:", err)
  109. }
  110. data := &TestStruct{
  111. Test_id: 123123123,
  112. }
  113. // Convert test_t to slice
  114. numCPU := runtime.NumCPU()
  115. value := make([]TestStruct, numCPU)
  116. for i := range value {
  117. value[i] = *data
  118. }
  119. key := make([]byte, 4) // Assuming int key size is 4 bytes
  120. binary.LittleEndian.PutUint32(key, 0) // Assuming the key is an integer
  121. if err := newMap.Update(key, value, 0); err != nil {
  122. panic(err)
  123. }
  124. opts.MapReplacements["test_heap"] = newMap
  125. //opts.MapReplacements = map[string]*ebpf.Map{
  126. // "test_heap": newMap,
  127. //}
  128. }
  129. }