ToC • 1) What is BPF? Has it something to do with us? • 2) What is Rucy for, and Why? • 3) What is going on behind Rucy • Overview, BPF Opcode and mruby VM Opcode, Transpilation • 4) Conclusion, demo aiming at the future ࠓ͢༰Ͱ͢ɻ 3VDZͷΛ͢Δલʹલఏ͕ࣝͨ͘͞Μ͋ΔͷͰɺॱ࣍આ໌͍͖ͯ͠·͢ɻ
BPF is: • One of the latest Linux SOTAs • Used, for example, in the following areas: • Networking • Server Tracing (Observability) • Do you know DTrace? What BPF can do is almost like that. • Device Access Auditing for containers #1'-JOVYͷ࠷ઌٕज़ͷҰͭͰ͢ɻωοτϫʔΫɺύϑΥʔϚϯεɾτϨʔεɺ ίϯςφ෦ͷσόΠεΞΫηε੍ޚͷ෦ͳͲͰΘΕ͍ͯ·͢ɻ
To begin with: Can BPF be used via Ruby? • The answer is Yes. • I created RbBCC • BCC is a BPF SDK for Python, and Lua... • I need Ruby’s one. So created. • BCC uses FFI(ctypes) to access libbcc, then RbBCC uses Fiddle. • RbBCC can do basic traces as BCC do. • RbBCC is one of the results of a Ruby Association Grant in 2019. (*) https:/ /github.com/udzura/rbbcc Thanks, ko1-san #1'3VCZ͔Β͑·͔͢ʁ͑ʮ:FTʯͰ͢ɻ 3C#$$ͱ͍͏ͷΛ͍·͢ɻ3VCZΞιγΤʔγϣϯͷάϥϯτରͰ͋Γ·͢ɻ
BCC’s pitfalls • Tools with (Rb)BCC do the whole BPF compilation process • When it starts tracing - Just In Time • It causes: • 1) overhead • 2) large number of files required to build • The compilation process needs LLVM, clang and kernel headers. ͔͠͠ɺ#$$ʢ3C#$$ʣɺτϨʔεͷ࠷ॳʹ#1'ϓϩάϥϜΛͦͷͰίϯύΠϧ͠·͢ɻ ΦʔόʔϔουɺίϯύΠϧʹඞཁͳڥͷංେԽͳͲ͕͋Γ·͢ɻ
Brand-new BPF tool for Ruby • Linux community recommends to precompile the "BPF binary” • As tools using on-the-fly build are such problematic • Tools should be served as “One Binary” ✴ There are also mechanisms to absorb differences in execution environments such as the kernel version. ✴ These portable one-binary commands are called BPF CO-RE (Compile Once, Run Everywhere). BPF Tracing Program Userspace Part (C, Rust, Go...) BPF Binary (Bytecodes) + ͳͷͰࣄલʹίϯύΠϧͨ͠ʮ#1'όΠφϦʯͷར༻͕ਪ͞Ε·͢ɻ ϓϩάϥϜຊମʹ#1'όΠφϦΛ݁߹ͯ͠ɺϫϯόΠφϦͰఏڙՄೳͰ͢ɻ
“One Binary” in Ruby • mruby seems to be the best way • to achieve the "one binary for everything" goal. • But - "BPF binary” can only be created in C, effectively NSVCZΛ͑ϫϯόΠφϦΛ࡞Δ͜ͱ͕Ͱ͖ͦ͏Ͱ͢ɻ Ͱ͕͢ɺʮ#1'όΠφϦʯ༻ҙ͠ͳ͍ͱ͍͚·ͤΜɻ͜Ε࣮࣭తʹ$ݴޠͰ͔͠ॻ͚·ͤΜɻ
Making a BPF binary • We need to pass the C code to the clang command: • I decided to make a tool that enable Rubyists - • To make "BPF binaries" without writing any C code! ✴ In fact, Rust can create BPF binaries using RedBPF crate. But - this is RubyKaigi. 🆕 ͡Ό͋ɺશ෦3VCZͰॻ͚ΔΑ͏ʹ͠·͠ΐ͏ɻ
Summary so far: • BPF is an emerging Linux technology • used in fast firewalls, lightweight tracers, and containers security. • You can use BPF technology from Ruby via BCC. • But BCC is problematic because it compiles on the fly. • Precompiled "One binary" is recommended. • You need to write C language for the "BPF binary" part. • Writing every part of BPF program in Ruby is a desire of Rubyists. ͜͜·Ͱͷ·ͱΊͰ͢ɻ ͱʹ͔͘ɺ#1'ʹؔΘΔͯ͢ͷύʔτΛ3VCZͰॻ͖ͨ͋͘Γ·ͤΜ͔ʁ
Reprise: what is Rucy • Rucy is a “Ruby Compiler” to BPF target. • In other words: • Rucy generates “BPF binary” directly from a plain-old Ruby script. ✴ Rucy is named after “Ruby Compiler” (Ru-C -> Rucy) 3VDZʢ3V$ʣʮ3VCZ$PNQJMFSʯͰ͢ɻ ͩ͘Μͷʮ#1'όΠφϦʯΛɺ3VCZεΫϦϓτ͔ΒίϯύΠϧͯ͠ੜ͠·͢ɻ
BPF OpCode Overview • BPF has its own VM and OpCode set. • The VM can use 10 registers • BPF instructions are basically 64bit fixed length • Instruction classes are: LD, LDX, ST, STX, ALU, JMP, and ALU64 • Layout: ASCII C Struct #1'ɺಠࣗͷϨδελϚγϯ7.Λ࣋ͪ·͢ɻͷϨδελ͕͋Γɺ ໋ྩ͓͓ΉͶCJUͷݻఆͰ͢ɻόΠφϦϨΠΞτεϥΠυͷ௨ΓͰ͢ɻ
Mruby OpCode Overview • Like CRuby, mruby has its VM and OpCodes • can use 65536 registers, recommended to use only 256. • Instructions are in variable length • It depends on what kind of operands it will take. • The sizes of the operand variable ... • B (8 bits), S (16 bits), W (24 bits), and Z (no operand) NSVCZϨδελϚγϯͷ7.͕͋Γ·͢ɻϨδελͨ͘͞Μ͑·͢ɻ ໋ྩՄมͰ͢ɻ#ɺ4ɺ8ɺ;ͷΦϖϥϯυ͕͋Γ·͢ɻ
More: if state to JUDGE/GOTO / / save GOTO label info / / Check r3 as “u32” Traspilation Code: ࣍ͷ໋ྩͰʮ3͕θϩ͔൱͔ʯΛݕࠪͯ͠(050͢Εɺ શମͱͯ͠01@&201@+.1/05Λ༁͢Δ͜ͱ͕Ͱ͖·ͨ͠ɻ
Conclusion • We can create a BPF binary object from Ruby script directly. • This BPF object + mruby + libbpf = whole command binary • Less context switch for programers • Shared data structures (in the future? Not yet implemented...) 3VCZΛίϯύΠϧͯ͠#1'Λ࡞Γ·ͨ͠ɻશ෦3VCZͰॻ͚Δͱศརͩͱࢥ͍·͢ɻ কདྷ3VCZͷΫϥεͰɺΧʔωϧͱϢʔβϥϯυͷσʔλߏΛڞ༗Ͱ͖Εͱɻকདྷɻ
Restrictions and aiming at the future • Only implemented the really minimum BPF functionality. • 🙆: Generate very basic BPF opcodes • 🙆: Call BPF-specific helper functions (e.g. bpf_trace_printk()) • 🙅: Handle a BPF Map data structure • 🙅: Inject parameters via rodata, ... • Gradually implement all of them. See you soon! ݱࡏɺຊʹ࠷ݶͷػೳ͔࣮͍ͯ͠͠·ͤΜ͕ɺͨͱ͑#1'.BQͷར༻ͳͲɺ ॱ࣍ඞཁͦ͏ͳػೳΛ࣮͍͖͍ͯͨ͠ؾ࣋ͪ͋Γ·͢ɻ