rbbcc 0.11.1 → 0.11.2

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: 30e4967edcbc916ed8e11549202d7c6dd8283554e9d75a3e3f88ac1a58466110
4
+ data.tar.gz: 6668b27c98059c41509b33b9fe8d8effff4001a709df2b6ec944687f020591da
5
5
  SHA512:
6
- metadata.gz: d40bb0cc232b51f25cc6970580c00bcb52c13cf7423f5082f3bbb447b9ea5d5a59acb958a68df4b3a3639bf86ac8ee72a673313d009cdb18be9eec52dc3176a9
7
- data.tar.gz: e9af3796aa61f7f76b0122e13b2ec6c0958c8d33edeb6c0d34a5813e0f38e7f1cbd46eb267290a3935b381d94815cb7b4479d5adfeee428c709124b7456e3fa4
6
+ metadata.gz: 8a08a60ce0dcd05c27be3388eb9e8fbe9c6cba7b877d0e55b0df348d6023586a90d4d4d7b52ec5312c2b8241fd1dbc09cd350153ecc6f9fc0fb852c1c89655a9
7
+ data.tar.gz: 689770db707201cc089c43fb4997a685c05af2b4d717c25c8891d4e5351909c9eb4c5ca0e8d19e86fe2a88e60e30dde1bd5a4eec359dc0e775ed39f32054e485
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.2)
5
5
  fiddle
6
6
 
7
7
  GEM
@@ -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
@@ -300,9 +323,9 @@ module RbBCC
300
323
  end
301
324
 
302
325
  class ArrayTable < TableBase
303
- def initialize(bpf, map_id, map_fd, keytype, leaftype, name: nil)
326
+ def initialize(bpf, map_id, map_fd, keytype, leaftype, name: nil, keysize: nil, leafsize: nil)
304
327
  super
305
- @max_entries = Clib.bpf_table_max_entries_id(bpf.module, map_id)
328
+ @max_entries = Clib.bpf_table_max_entries_id(bpf.module, map_id) if bpf
306
329
  end
307
330
 
308
331
  # 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.2"
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.2
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