ãããã
ååã®è¨äºã§ã以ä¸ã®ãããªæ§æè¦ç´ ãBPFããã°ã©ã ã«æä½éå¿ è¦ãªæ å ±ã ã¨çµè«ã¥ãã¾ããã
å¿ è¦ãªã»ã¯ã·ã§ã³ strtab BPFããã°ã©ã ã»ã¯ã·ã§ã³ with æ£ããåå ã©ã¤ã»ã³ã¹ symtab å¿ è¦ãªã·ã³ãã«ãã¼ãã« BPFããã°ã©ã ã®é¢æ°å ã©ã¤ã»ã³ã¹ã®å ´æ
ä»åã¯å®éã«ãã¤ããªãä½ã£ã¦ãã¼ããã¦ã¿ã¾ãã
ãã¼ã«ãä½ã£ã¦ãã話
RubyKaigi takeout 2021 ã§è©±ãã¨æããã§ããï¼ã¾ã ãã¼ã¯è©³ç´°ã¯ã¢ããããã¦ãã¾ããï¼ã Rucy ã¨ããååã®ãPure Rubyã®ã¹ã¯ãªããã ãã§BPFã®ãã¤ããªãã¼ã«ãä½æã§ããSDKãéçºãã¦ãã¾ãï¼CO-REã«ã§ãããã¯ã¾ã 調æ»ä¸ã§ãï¼ã
ãåç¥ã®éã RbBCC ãä½ã£ã¦ããã®ã§ãããæ¨ä»ã®BPFãã¼ã«ã®æ½®æµã®å¤åã«å¯¾å¿ãã¦æ°ããããã¸ã§ã¯ããå§ããã¨ãããã¨ã§ããä¾ãã°:
ãã®ä¸æºåã®ä¸ã¤ã¨ãã¦ãRubyã¹ã¯ãªããããBPFãã¤ããªãä½æã§ããå¿ è¦ãããã¾ããã¡ãªã¿ã«Rustã®å ´åãä¾ãã° RedBPF ã®ãããªãã®ãããã¾ããåè:
Rucy ã®é²æ: Ruby DSLããELFãã¡ã¤ã«ãä½ã
ä»ã®ã¨ããããRuby DSLããELFãã¡ã¤ã«ãä½ãããã¨ãã§ããããã«ãªã£ã¦ãã¾ãã
åé ã®å¿ è¦ãªã»ã¯ã·ã§ã³ã¨ã·ã³ãã«ãã¼ãã«ãå®ç¾©ããDSLã¯ä»¥ä¸ã®ãããªæãã
include Rucy ELFFile.define do |elf| elf.header do |e| e.type ET_REL e.machine EM_BPF e.section do |scn| scn.name ".strtab" scn.type SectionType::STRTAB end e.section do |scn| scn.name "license" scn.symname "__license" scn.type SectionType::LICENSE scn.data "GPL\x00" end e.section do |scn| scn.name "cgroup/dev" scn.symname "my_prog" scn.type SectionType::PROG scn.data "\xb7\x00\x00\x00\x00\x00\x00\x00" + "\x95\x00\x00\x00\x00\x00\x00\x00" end e.section do |scn| scn.name ".symtab" scn.type SectionType::SYMTAB end end end
çãä¸ã®è¬ã®ãã¤ããªãã¤ã¾ãBPFã®IRãæ°ã«ãªãæãã§ããããã®ã³ã³ãã¤ã©ã¯ã¾ã å®æãã¦ããªãã®ã§ããã£ãããã³ãã¢ã»ã³ãã«ãããã®ã§ãã
rucyã®ã¯ã¼ã¯ã¹ãã¼ã¹ã« rucy-elfgen
ã¨ãããã®ãããã®ã§ã以ä¸ã®ããã«ãµã³ãã«ã³ã¼ããèµ°ããã¾ãã
rucy-elfgen$ cargo run --example elf_dsl -- \ examples/elf_dsl.rb ~/test.bin
ãã㧠~/test.bin
ã«ELFãã©ã¼ãããã®ãã¤ããªãã§ããã
$ llvm-readelf -a ~/test.bin | head -25 ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: REL (Relocatable file) Machine: EM_BPF Version: 0x1 Entry point address: 0x0 Start of program headers: 0 (bytes into file) Start of section headers: 216 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 0 (bytes) Number of program headers: 0 Size of section headers: 64 (bytes) Number of section headers: 5 Section header string table index: 1 There are 5 section headers, starting at offset 0xd8: Section Headers: [Nr] Name Type Address Off Size ES Flg Lk Inf Al [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 [ 1] .strtab STRTAB 0000000000000000 000040 000036 00 0 0 1 [ 2] license PROGBITS 0000000000000000 000076 000004 00 WA 0 0 1 [ 3] cgroup/dev PROGBITS 0000000000000000 000080 000010 00 AX 0 0 8 [ 4] .symtab SYMTAB 0000000000000000 000090 000048 18 1 1 8 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), O (extra OS processing required), G (group), T (TLS), C (compressed), x (unknown), o (OS specific), E (exclude), p (processor specific) Elf file type is REL (Relocatable file) Entry point 0x0 There are 0 program headers, starting at offset 0 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align Section to Segment mapping: Segment Sections... None .strtab license cgroup/dev .symtab There are no relocations in this file. Symbol table '.symtab' contains 3 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 4 OBJECT GLOBAL DEFAULT 2 __license 2: 0000000000000000 16 FUNC GLOBAL DEFAULT 3 my_prog There are no section groups in this file.
DSL ã§ã®å®ç¾©ã¨è¦æ¯ã¹ã¦ãã ãããæ£ãããã©ã¼ãããã®ELFå½¢å¼ã§ãã
ã¾ããBPFããã°ã©ã ãæ£å¸¸ã«çµã¿è¾¼ã¾ãã¦ãã¾ãã
$ llvm-objdump -d ~/test.bin /home/vagrant/test.bin: file format elf64-bpf Disassembly of section cgroup/dev: 0000000000000000 <my_prog>: 0: b7 00 00 00 00 00 00 00 r0 = 0 1: 95 00 00 00 00 00 00 00 exit
æ製BPFããã°ã©ã ããã¼ããã
ãã®å æ¥ã®å®é¨ã®éã¨åãããã°ã©ã ãï¼ãã¡ã¤ã«åã ãå¤ãã¦ï¼èµ°ããã¦ã¿ã¾ãã
$ sudo mkdir /sys/fs/cgroup/unified/test-bpf-based-device-cgroup $ sudo ./load_dev_cgroup $ sudo bpftool prog ... 29: cgroup_device name my_prog tag a04f5eef06a7f555 gpl loaded_at 2021-08-12T09:12:35+0000 uid 0 xlated 16B jited 37B memlock 4096B
ãã¼ãã«æåãã¾ãããä»åã¯ãå®è³ªã©ããªããã¤ã¹ã«ã retrun 0
ãè¿ããããªããã°ã©ã ã®ãããã©ããªããã¤ã¹ã«ãã¢ã¯ã»ã¹ã§ããªãã¯ãã§ãã
$ echo $$ | sudo tee /sys/fs/cgroup/unified/test-bpf-based-device-cgroup/cgroup.procs 1858 $ head -c 10 /dev/urandom | hexdump -C head: cannot open '/dev/urandom' for reading: Operation not permitted
ãã£ã«ã¿ãªã³ã°ã«æåãã¦ããããã§ãã $ echo $$ | sudo tee /sys/fs/cgroup/unified/cgroup.procs
ã®ããã«å½è©²ã°ã«ã¼ãããå¤ããã°ãå
ã®ããã« /dev/urandom ã«ã¢ã¯ã»ã¹å¯è½ãªç¶æ
ã«æ»ãã¾ãã
ã¨ãããã¨ã§ï¼rodataããªãã±ã¼ã·ã§ã³ãªã©ãèæ ®ãã¹ããã¨ã¯ä»ã«ãããããããã¾ãã...ï¼ Ruby ã¹ã¯ãªããããvalidãªBPFãã¤ããªãä½æã§ããããã«ãªãã¾ããã
ãã¨ã¯ãä¸èº«ã®BPFã®insnãRubyã®ã³ã¼ãããçæã§ããããã«ãªãã°ããã£ãã§ãããã¨ããæããªã®ã§ãå¼ãç¶ããã£ã¦ãããããªãã
9æä¸æ¬ã«ãããªã話ãã§ãããããå¼ãç¶ã調æ»ãç¶ãã¾ãã