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 +4 -4
- data/Gemfile.lock +1 -1
- data/examples/pin_maps_a.rb +88 -0
- data/examples/pin_maps_b.rb +71 -0
- data/lib/rbbcc/clib.rb +1 -0
- data/lib/rbbcc/table.rb +30 -7
- data/lib/rbbcc/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 30e4967edcbc916ed8e11549202d7c6dd8283554e9d75a3e3f88ac1a58466110
|
|
4
|
+
data.tar.gz: 6668b27c98059c41509b33b9fe8d8effff4001a709df2b6ec944687f020591da
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8a08a60ce0dcd05c27be3388eb9e8fbe9c6cba7b877d0e55b0df348d6023586a90d4d4d7b52ec5312c2b8241fd1dbc09cd350153ecc6f9fc0fb852c1c89655a9
|
|
7
|
+
data.tar.gz: 689770db707201cc089c43fb4997a685c05af2b4d717c25c8891d4e5351909c9eb4c5ca0e8d19e86fe2a88e60e30dde1bd5a4eec359dc0e775ed39f32054e485
|
data/Gemfile.lock
CHANGED
|
@@ -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
|
-
|
|
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,
|
|
132
|
+
bpf, map_id, map_fd,
|
|
133
|
+
keysize || sizeof(keytype),
|
|
134
|
+
leafsize || sizeof(leaftype)
|
|
121
135
|
@keytype = keytype
|
|
122
136
|
@leaftype = leaftype
|
|
123
|
-
@
|
|
124
|
-
|
|
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,
|
|
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
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.
|
|
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
|