rbbcc 0.11.1 → 0.11.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6795c09c9054d789de4ce10626404bc7f6e5f7cdb12296e2344b270f2a7fa2a7
4
- data.tar.gz: e898c4bc91fcc3b7dff968a2daf44d667faf68c5ee9eef29b1eba4f14dc2d123
3
+ metadata.gz: e8d3afe6e07e84fee531b06fe921712104cf98af1df9181629aa50ce3eb610af
4
+ data.tar.gz: c044abba2b01c4e01307225ef2bc683bf8bee3f1718a8ea2420a7162675996b1
5
5
  SHA512:
6
- metadata.gz: d40bb0cc232b51f25cc6970580c00bcb52c13cf7423f5082f3bbb447b9ea5d5a59acb958a68df4b3a3639bf86ac8ee72a673313d009cdb18be9eec52dc3176a9
7
- data.tar.gz: e9af3796aa61f7f76b0122e13b2ec6c0958c8d33edeb6c0d34a5813e0f38e7f1cbd46eb267290a3935b381d94815cb7b4479d5adfeee428c709124b7456e3fa4
6
+ metadata.gz: bca1df23f844dce3d2389ad0d2d2986b49606c401b72257ddd8032140961ab2e88bb408492a311c892ecf26cdcca1eecfe4752ec092202d0910470f4943e4c54
7
+ data.tar.gz: 030abb5a6166a753919961b19028c391db09f7fdb9044e5039b1330f67cd8047d6738b84c07a1ea03a78952bd2958a3f97a77df58b9b16648a8ddd5055631a3c
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rbbcc (0.11.1)
4
+ rbbcc (0.11.3)
5
5
  fiddle
6
6
 
7
7
  GEM
@@ -20,7 +20,6 @@ require 'rbbcc'
20
20
  include RbBCC
21
21
 
22
22
  PROGRAM = <<~CLANG
23
- #include <linux/lsm_hooks.h>
24
23
  #include <linux/socket.h>
25
24
  #include <uapi/asm-generic/errno-base.h>
26
25
 
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # pin_maps_a.rb
4
+ # Program A: create HashMap/ArrayMap, hook execve, count up, and pin maps.
5
+ #
6
+ # Usage (root):
7
+ # sudo ruby examples/pin_maps_a.rb --pin-dir /sys/fs/bpf/rbbcc_pin_demo
8
+
9
+ require 'rbbcc'
10
+ require 'optparse'
11
+ require 'fileutils'
12
+
13
+ include RbBCC
14
+
15
+ BPF_TEXT = <<~CLANG
16
+ BPF_HASH(pin_hash_map, u32, u64, 1024);
17
+ BPF_ARRAY(pin_array_map, u64, 1);
18
+
19
+ int trace_execve(void *ctx) {
20
+ u64 zero = 0;
21
+ u32 pid = bpf_get_current_pid_tgid();
22
+ u32 idx = 0;
23
+ u64 *hval;
24
+ u64 *aval;
25
+
26
+ hval = pin_hash_map.lookup_or_try_init(&pid, &zero);
27
+ if (hval) {
28
+ __sync_fetch_and_add(hval, 1);
29
+ }
30
+
31
+ aval = pin_array_map.lookup(&idx);
32
+ if (aval) {
33
+ __sync_fetch_and_add(aval, 1);
34
+ }
35
+
36
+ return 0;
37
+ }
38
+ CLANG
39
+
40
+ options = {
41
+ pin_dir: '/sys/fs/bpf/rbbcc_pin_demo'
42
+ }
43
+
44
+ OptionParser.new do |opts|
45
+ opts.banner = 'Usage: pin_maps_a.rb [options]'
46
+
47
+ opts.on('--pin-dir DIR', 'Pin directory under bpffs') do |v|
48
+ options[:pin_dir] = v
49
+ end
50
+ end.parse!
51
+
52
+ b = BCC.new(text: BPF_TEXT)
53
+ b.attach_kprobe(
54
+ event: b.get_syscall_fnname('execve'),
55
+ fn_name: 'trace_execve'
56
+ )
57
+
58
+ hash_map = b['pin_hash_map']
59
+ array_map = b['pin_array_map']
60
+
61
+ # Initialize global counter slot.
62
+ array_map[0] = 0
63
+
64
+ FileUtils.mkdir_p(options[:pin_dir])
65
+ hash_path = File.join(options[:pin_dir], 'pin_hash_map')
66
+ array_path = File.join(options[:pin_dir], 'pin_array_map')
67
+
68
+ File.unlink(hash_path) if File.exist?(hash_path)
69
+ File.unlink(array_path) if File.exist?(array_path)
70
+
71
+ BCC.pin!(hash_map.map_fd, hash_path)
72
+ BCC.pin!(array_map.map_fd, array_path)
73
+
74
+ puts 'Pinned maps created.'
75
+ puts " hash map: #{hash_path}"
76
+ puts " array map: #{array_path}"
77
+ puts 'kprobe attached to execve. Run some commands in another terminal.'
78
+ puts 'Press Ctrl-C to stop Program A.'
79
+
80
+ begin
81
+ loop do
82
+ sleep 1
83
+ total = array_map[0]&.to_bcc_value || 0
84
+ puts "execve total count: #{total}"
85
+ end
86
+ rescue Interrupt
87
+ puts '\nStopping Program A...'
88
+ end
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # pin_maps_b.rb
4
+ # Program B: open pinned HashMap/ArrayMap with from_pin and read/update values.
5
+ #
6
+ # Usage (root):
7
+ # sudo ruby examples/pin_maps_b.rb --pin-dir /sys/fs/bpf/rbbcc_pin_demo
8
+
9
+ require 'rbbcc'
10
+ require 'optparse'
11
+
12
+ include RbBCC
13
+
14
+ options = {
15
+ pin_dir: '/sys/fs/bpf/rbbcc_pin_demo'
16
+ }
17
+
18
+ OptionParser.new do |opts|
19
+ opts.banner = 'Usage: pin_maps_b.rb [options]'
20
+
21
+ opts.on('--pin-dir DIR', 'Pin directory under bpffs') do |v|
22
+ options[:pin_dir] = v
23
+ end
24
+ end.parse!
25
+
26
+ hash_path = File.join(options[:pin_dir], 'pin_hash_map')
27
+ array_path = File.join(options[:pin_dir], 'pin_array_map')
28
+
29
+ unless File.exist?(hash_path) && File.exist?(array_path)
30
+ abort("Pinned map files are missing. Run pin_maps_a.rb first: #{options[:pin_dir]}")
31
+ end
32
+
33
+ # Explicitly pass key/leaf type and size; no type detection is performed.
34
+ hash_map = HashTable.from_pin(
35
+ hash_path,
36
+ 'unsigned int',
37
+ 'unsigned long long',
38
+ keysize: 4,
39
+ leafsize: 8
40
+ )
41
+ array_map = ArrayTable.from_pin(
42
+ array_path,
43
+ 'unsigned int',
44
+ 'unsigned long long',
45
+ keysize: 4,
46
+ leafsize: 8
47
+ )
48
+
49
+ puts 'Loaded pinned maps.'
50
+ puts " hash map fd: #{hash_map.map_fd}"
51
+ puts " array map fd: #{array_map.map_fd}"
52
+ puts " hash ttype: #{hash_map.ttype}"
53
+ puts " array ttype: #{array_map.ttype}"
54
+
55
+ puts 'Read existing values:'
56
+ puts " hash[1] = #{hash_map[1]&.to_bcc_value.inspect}"
57
+ puts " hash[2] = #{hash_map[2]&.to_bcc_value.inspect}"
58
+ puts " array[0] = #{array_map[0]&.to_bcc_value.inspect}"
59
+ puts " array[1] = #{array_map[1]&.to_bcc_value.inspect}"
60
+
61
+ hash_map[3] = 1
62
+ array_map[0] = (array_map[0]&.to_bcc_value || 0) + 1
63
+
64
+ puts 'Updated values:'
65
+ puts " hash[3] = #{hash_map[3]&.to_bcc_value.inspect}"
66
+ puts " array[0] = #{array_map[0]&.to_bcc_value.inspect}"
67
+
68
+ puts 'Iterate hash entries:'
69
+ hash_map.each_pair do |k, v|
70
+ puts " #{k.to_bcc_value} => #{v.to_bcc_value}"
71
+ end
data/lib/rbbcc/clib.rb CHANGED
@@ -194,6 +194,7 @@ module RbBCC
194
194
  extern 'int bpf_open_raw_sock(const char *name)'
195
195
  extern 'int bpf_attach_socket(int sockfd, int progfd)'
196
196
  extern 'int bpf_obj_pin(int fd, const char *pathname)'
197
+ extern 'int bpf_obj_get(const char *pathname)'
197
198
  end
198
199
  end
199
200
 
data/lib/rbbcc/table.rb CHANGED
@@ -115,13 +115,36 @@ module RbBCC
115
115
  include CPUHelper
116
116
  include Enumerable
117
117
 
118
- def initialize(bpf, map_id, map_fd, keytype, leaftype, name: nil)
118
+ class << self
119
+ def from_pin(path, keytype, leaftype, keysize: nil, leafsize: nil, **kwargs)
120
+ map_fd = Clib.bpf_obj_get(path)
121
+ if map_fd < 0
122
+ raise SystemCallError.new("Could not open pinned map", Fiddle.last_error)
123
+ end
124
+
125
+ new(nil, nil, map_fd, keytype, leaftype,
126
+ keysize: keysize, leafsize: leafsize, **kwargs)
127
+ end
128
+ end
129
+
130
+ def initialize(bpf, map_id, map_fd, keytype, leaftype, name: nil, keysize: nil, leafsize: nil)
119
131
  @bpf, @map_id, @map_fd, @keysize, @leafsize = \
120
- bpf, map_id, map_fd, sizeof(keytype), sizeof(leaftype)
132
+ bpf, map_id, map_fd,
133
+ keysize || sizeof(keytype),
134
+ leafsize || sizeof(leaftype)
121
135
  @keytype = keytype
122
136
  @leaftype = leaftype
123
- @ttype = Clib.bpf_table_type_id(self.bpf.module, self.map_id)
124
- @flags = Clib.bpf_table_flags_id(self.bpf.module, self.map_id)
137
+ if @bpf
138
+ @ttype = Clib.bpf_table_type_id(self.bpf.module, self.map_id)
139
+ @flags = Clib.bpf_table_flags_id(self.bpf.module, self.map_id)
140
+ else
141
+ @ttype = case self
142
+ when HashTable
143
+ Table::BPF_MAP_TYPE_HASH
144
+ when ArrayTable
145
+ Table::BPF_MAP_TYPE_ARRAY
146
+ end
147
+ end
125
148
  @name = name
126
149
  end
127
150
  attr_reader :bpf, :map_id, :map_fd, :keysize, :keytype, :leafsize, :leaftype, :ttype, :flags, :name
@@ -275,7 +298,7 @@ module RbBCC
275
298
  leaf.bcc_value_type = leaftype
276
299
  leaf
277
300
  when Integer
278
- ret = byref(leaf, keysize)
301
+ ret = byref(leaf, leafsize)
279
302
  ret.bcc_value_type = leaftype
280
303
  ret
281
304
  else
@@ -285,8 +308,10 @@ module RbBCC
285
308
 
286
309
  def byref(value, size=sizeof("int"))
287
310
  pack_fmt = case size
311
+ when sizeof("char"); "c"
288
312
  when sizeof("int") ; "i!"
289
313
  when sizeof("long"); "l!"
314
+ when sizeof("long long"); "q!"
290
315
  else ; "Z*"
291
316
  end
292
317
  ptr = Fiddle::Pointer.malloc(size)
@@ -300,9 +325,9 @@ module RbBCC
300
325
  end
301
326
 
302
327
  class ArrayTable < TableBase
303
- def initialize(bpf, map_id, map_fd, keytype, leaftype, name: nil)
328
+ def initialize(bpf, map_id, map_fd, keytype, leaftype, name: nil, keysize: nil, leafsize: nil)
304
329
  super
305
- @max_entries = Clib.bpf_table_max_entries_id(bpf.module, map_id)
330
+ @max_entries = Clib.bpf_table_max_entries_id(bpf.module, map_id) if bpf
306
331
  end
307
332
 
308
333
  # We now emulate the Array class of Ruby
data/lib/rbbcc/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RbBCC
2
- VERSION = "0.11.1"
2
+ VERSION = "0.11.3"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbbcc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.1
4
+ version: 0.11.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Uchio Kondo
@@ -96,6 +96,8 @@ files:
96
96
  - examples/mallocstack.rb
97
97
  - examples/networking/http_filter/http-parse-simple.c
98
98
  - examples/networking/http_filter/http-parse-simple.rb
99
+ - examples/pin_maps_a.rb
100
+ - examples/pin_maps_b.rb
99
101
  - examples/py-orig/sockblock.py
100
102
  - examples/ruby_usdt.rb
101
103
  - examples/sbrk_trace.rb