eBPFのヘルパー関数には bpf_get_prandom_u32()
というものがあります:
(Chromeの「この箇所へのリンク」を使いました)
bpf-helpers(7) - Linux manual page
これは色々な用途に使える(まず想像するのはサンプリングとか?)と思いますが、おみくじに使ってみました。
拙作 RbBCC で、 BCC + Ruby の例です。Python他でも似たようなコードは書けるでしょう:
#!/usr/bin/env ruby require 'rbbcc' b = RbBCC::BCC.new text: <<CODE BPF_HASH(lottery, int, int, 1); int kprobe__sys_sync(void *ctx) { bpf_trace_printk("Drawn\\n"); int key = 0; int got = bpf_get_prandom_u32() % 30 + 1; lottery.update(&key, &got); return 0; } CODE t = Thread.new do sleep 0.5 system "sync" end at_exit { t.join } loop do table = b.get_table('lottery', leaftype: 'int') if (got = table[0]) && got.to_bcc_value.nonzero? puts "Winner: #{got.to_bcc_value}" exit 0 end end
- 環境: 22.04.1-Ubuntu 5.19.0-46-generic
内容的には sync(2)
をtraceして、かつ、プログラムの中で裏で sync
コマンドを発行して引っ掛けてくじを引いていますね。
実行するとこんな感じです:
$ sudo /usr/local/bin/bundle exec ruby examples/lottery.rb Winner: 17
何が言いたいかというと、明日のイベントで『入門 eBPF』をプレゼントしますが、その抽選でeBPFを使う予定です。eBPFの実用性を示すために...。
そう!イベントのPRだったのです。まだ登録間に合いますので福岡市内に出られる方はぜひ。
という小ネタ日記...。