ruby --jit, jail

友達の友達のお母上が、家の中でころんでしまって骨折し、入院したとか。担当になった医師は、あのジャガー横田の旦那さん。かなり凄腕の方らしい。彼を通じて、女房と共著の色紙を貰えるなら、一生の記念になるでしょう。

町の健康診断の後の保健師さんとの面接で、禁煙教室を勧められた。愛煙家なんで、今更無理です。ダメ出しで、高額納税者ですからって断った。

そしたら、運動教室もやってますから、こちらはいかがですかと勧められた。どうも根底には、メタボ対策があるようだ。 折角の機会なんで、こちらは受ける事にした。いやなら途中でも行かないって言う自由度がありますからね。

で、老人会だったよ。運動メニューも緩いものだった。講師曰く、歳取ったら転ばないようにしましょう。それが一番大事な事ですと。

下半身を鍛えましょう。バランス感覚をつけましょう。上半身はどうでもいいです。母も転んで、骨折し人工関節を入れていたから、身につまされますよ。

そんな訳で、正しいスクワットの練習。膝を90度以上曲げると、関節が壊れてしまうので、絶対だめよ。膝を前に出さない、踵に重心を置きつま先は浮かせるのがコツ。

次は、平均台に乗ったのをイメージして、すり足しながら歩きましょう。右足のつま先を左足の踵と接触させる。その状態から、片方の足を移動させ、着地時につま先と踵が接触させるように歩く。前進したりバックしたりしてね。

次の運動は、 片足立ちして浮いた方の足を、グルグル回しましょう。回す方向が時計回りなら、腕は反時計回りに回しましょう。 これで、ぼけそうになった脳に活をいれられるとか。

同じく、片足立ちして、浮いた方の足を前後、左右になるべく大きく振ってみましょう。この時、膝は曲げないで、真っすぐにして、振ってね。

みんな、下半身とバランス強化のメニューでした。

メタボ対策で、脂肪を燃焼させましょう。筋肉に負荷をかけるのが一番。背もたれの無い椅子に座って、後ろに背もたれがある事をイメージして、後ろに上半身をそってみましょう。エアー椅子だな。TVを見ながらでも簡単に出来ます。炬燵に寝転んでは愚の骨頂。

膝と手を床につけて、猫が怒った時に見せるように、背中を丸めましょう。そのままの体制で、 足を後ろに伸ばしましょう。この時、膝は床を離れる。 この体制で、30秒キープしましょう。やってみると、腹筋がブルブルしてくるぞ。もっと長くやると、額から汗が出て来る。血管プチィに注意して、余り頑張らなくてもいいよ。

ruby 2.6 --jit

前回気になったのを確認。リベンジの意味も込めて、FreeBSD 12.0上で実験。

$ ruby -v
ruby 2.6.1p33 (2019-01-30 revision 66950) [x86_64-freebsd12.0]

普通にconfigureしただけ。jitが組み込まれたか確認。 デフォでは、5回同じメソッドが起動されると、jitが発動されるそうな。

$ ruby --disable-gems --jit-verbose=1 --jit-save-temps -e "def a; nil; end; a;a;a;a;a; RubyVM::MJIT.pause"
JIT success (34.2ms): a@-e:1 -> /tmp/_ruby_mjit_p15406u0.c
Successful MJIT finish

本当にコンパイルしてるか更に確認。

$ ruby --disable-gems --jit-verbose=2 --jit-save-temps -e "def a; nil; end; a;a;a;a;a; RubyVM::MJIT.pause"
MJIT: CC defaults to /usr/bin/cc
MJIT: tmp_dir is /tmp
Creating precompiled header
Starting process: /usr/bin/cc /usr/bin/cc -w -Wfatal-errors -fPIC -shared -w -pipe -O3 -emit-pch -o /tmp/_ruby_mjit_hp15415u0.h.gch /home/sakae/MINE/include/ruby-2.6.0/x86_64-freebsd12.0/rb_mjit_min_header-2.6.1.h
start compilation: a@-e:1 -> /tmp/_ruby_mjit_p15415u0.c
Starting process: /usr/bin/cc /usr/bin/cc -w -Wfatal-errors -fPIC -shared -w -pipe -O3 -o /tmp/_ruby_mjit_p15415u0.o /tmp/_ruby_mjit_p15415u0.c -include-pch /tmp/_ruby_mjit_hp15415u0.h.gch -c -Wl,--compress-debug-sections=zlib -Wl,-soname,mjit_config.h
Starting process: /usr/bin/cc /usr/bin/cc -shared -Wfatal-errors -fPIC -shared -w -pipe -O3 -o /tmp/_ruby_mjit_p15415u0.so /tmp/_ruby_mjit_p15415u0.o -Wl,--compress-debug-sections=zlib -Wl,-soname,mjit_config.h
JIT success (33.4ms): a@-e:1 -> /tmp/_ruby_mjit_p15415u0.c
Stopping worker thread
Successful MJIT finish

soファイルが作成されて、それが遅延ロード可能になってた。コンパイルに35msぐらいかかるって事は、ロードとリンク時間を含めると、ペナルティーは50msぐらいかな。この些細な投資が、後で役立ってくれる事を期待。

実際に威力を見せてよね。どなたかのコードを引き写しました。

$ cat aa.rb
def calculate(a, b, n = 40_000_000)
  n.times.count do
    a = a * 16807 % 2147483647
    b = b * 48271 % 2147483647

    (a & 0xffff) == (b & 0xffff)
  end
end

raise unless calculate(65, 8921) == 588
p result: calculate(699, 124)

実行結果です。

$ time ruby --disable-gems aa.rb
{:result=>600}
        9.49 real         9.48 user         0.00 sys
$ time ruby --disable-gems --jit aa.rb
{:result=>600}
        5.57 real         5.64 user         0.22 sys

インタープリタ実行の59%の時間で、実行できました。逆に言うと既存の実行系が優秀とも言えるな。誰のおかげだ? そりゃ、笹田先生のグループだよ。

こんなのの裏方は、

$ wc mjit*
     877    3050   27816 mjit.c
     148     598    5502 mjit.h
     254    1126    9815 mjit_compile.c
    4226   17379  189827 mjit_compile.inc
    1261    5074   43266 mjit_worker.c
    6766   27227  276226 total

こういう人達です。よく観察してみましょう。そして、少し心配だった、FreeBSDにダイナミックロード機能が有るかなんだけど、当然有るよね。下記はその証拠

$ ldd ./ruby
./ruby:
         :
        libdl.so.1 => /usr/lib/libdl.so.1 (0x8006dd000)

mjit_worker.cにこんな説明図が掲載されてた。

   Here is a diagram showing the MJIT organization:

                 _______
                |header |
                |_______|
                    |                         MRI building
      --------------|----------------------------------------
                    |                         MRI execution
                    |
       _____________|_____
      |             |     |
      |          ___V__   |  CC      ____________________
      |         |      |----------->| precompiled header |
      |         |      |  |         |____________________|
      |         |      |  |              |
      |         | MJIT |  |              |
      |         |      |  |              |
      |         |      |  |          ____V___  CC  __________
      |         |______|----------->| C code |--->| .so file |
      |                   |         |________|    |__________|
      |                   |                              |
      |                   |                              |
      | MRI machine code  |<-----------------------------
      |___________________|             loading

ruby 2.6 on CentOS

気をよくしたオイラーは、CentOSにも入れてあげる事にした。

cent:build$ time  make -j4
 :
real    2m34.295s
user    6m22.225s
sys     1m10.886s

CPUを総動員すると、こんな時間でコンパイルが終了した。

そして、いつもの盥回しをします。10回転させてる。

cent:tmp$ cat tarai.rb
def tarai(x, y, z)
    if x <= y
      return y
    else
      tarai(tarai((x-1), y, z), tarai((y-1), z, x), tarai((z-1), x, y))
    end
end

10.times do tarai(12,6,0) end

その結果。

cent:tmp$ time ruby --disable-gems tarai.rb

real    0m4.667s
user    0m4.651s
sys     0m0.014s
cent:tmp$ time ruby --disable-gems --jit tarai.rb

real    0m2.175s
user    0m2.493s
sys     0m0.113s

jitを噛ませると、もっと大幅に加速されると思っていたけど、どうなんだろう? C語で書いた様にはいかないね。(golangだと、10回タライして、400msぐらいのはず)

こうして見比べてみると、 デフォで備わっているVM用のコンパイラーが優秀って事なんですかね。jitを過信するなかれ。適材適所だよ。

RubyとElixirで処理速度比べ遊びしてみた、皆大好き、たらい回し。 青木日記、懐かしいなあ! そして、こらは昭和の香がする、 モノタロウのタライ、今は亡き母を思い出す。

ここで、話はコロッと変わって、別なやつになる。別名、オイラーの浮気な記録!

さくらインターネットに移住しておちついたので、少しまとめっぽいやつを書いておく。 そして、多分使われているであろう技術も調べてみた。

lftp

さくらさんとことやり取りする時に lftp site に、お世話になった。設定を忘れないように残しておく。

sakae@fb12:~ % cat .lftprc
set ftp:ssl-auth TLS
set ftp:ssl-force true
set ftp:ssl-allow yes
set ftp:ssl-protect-list yes
set ftp:ssl-protect-data yes
set ftp:ssl-protect-fxp yes
set ssl:verify-certificate no
alias sakura='lftp -u foo ftp://foo.sakura.ne.jp'

起動方法が長ったらしいので、エイリアスに登録しておくと吉。

Who live in next house

さくらさんの所は、集合住宅。サーバーに同居人と言うか、何人かで住む仕組みになってる。 そうなると、迷惑な人が住んでいないか、気になるぞ。

ある人の解析によれば、200人ぐらいは詰め込まれているんではないかと。その人は、shell権限を持っていたので、wc で、数えたとか。

https://www.aguse.jp/

こちらにアクセスして、自分の家の情報を得ると、隣家も調べてくれるそうな。いわゆる、 同一サーバ上の他のウェブサイト って事ね。

bingで、 ip:xx.xx.xx.xx を検索する手もある。

調べてみたら、釣り船の宿とか、貸し会議室とか塾とかが同居してた。堅気の人達でよかったわい。ヤバイのは、個人契約で、何をやってる分らない場合だな。(それって、ひょっとしてオイラーの事かな?)

sakura support

/etcの部分を見ると面白い情報が載ってた。

FreeBSDのアップデートに伴う変更点

夜間工事で、レンタルサーバのOSである「FreeBSD」のバージョンを9.x系から11.x系へ変更しますとな。

現在の主流は、11.2もしくは、12.0だから、それと余り離れないようにしますって事ね。 それに伴い、Go言語が使えるようになるってね。まあ、オイラーは関係ないけどね。

トレースルート(tracert、traceroute)の実行方法なんてのが案内されてる。って事は、使っていいよって事ね。

関連で、VPSサーバー標準のCentOSの防御法も指南してる。

nmapしちゃ駄目ですか? それはね、 火器監製レーダーを照射させるに等しい行為だからね。覚悟してからやれ。

大丈夫だよ、相手は大人のさくらさんだから鷹揚なのさ。子供の火遊びには、きっと笑っているよ。 もし何か文句を言ってきたら、先制防御の為の点検ですって主張しよう。

hop

そんじゃ、tracerouteぐらいは、やってみれ。

Windows上の仮想マシンから実行すると、2hop目から結果が*になって使い物にならない。よって、Windowsのtracertを使え。負けた気になる、有痛だ。素直にパソコン丸ごとlinuxって言う、debian(32Bit機)を使う。幸せを満喫。

仮想マシン(vbox or vmware)はNATにしてる。これって、仮想マシンは奥の院てか、関所で固められて守られている江戸城だな。箱根の関所あたりでは、入鉄砲出女を厳しく取り締まっていた(と、この間読んだ本に書いてあった)。NATも関所なんだな、特殊なパケットは通過させない仕組みになってるのだろう。

どうしても仮想マシンでtracerouteしたかったら、ネットワーク構成をブリッジ方式にすればいいのかな。まて、WSLでdebianが入っているけど、これもNATかな? ip address したら、Windows側で実行するipconfigと同じものが見えた。と、言う事は、、、、、。

結果を出すと、色々と差しさわりがありそうなので割愛。オイラーの所から17hop(経由)で到達したよ。 さくらさんのエリアに入るまで、グダグダと引き回されてる。東京から大阪へ行って、そこにある、さくらさんの導入口に吸いこまれるって具合。

ネットワーク的には遠いな。リアル世界では、7hopぐらいで、世界中の人に繋がるとか言うね。 本当かどうか、検討してみるか。

冒頭の枕に書いた人脈、友達の友達の母が、横田夫妻と繋がった。この人脈を通じて、トランプ野郎に親書を届ける事を考える。電子メールだと途中で消えて無くなる事もあるしね。

横田プロバイダーまでルートが出来れば、後はよしなに計らってくれるだろう。たとえば、日本の親分あーべちゃんがプロレスファンなら、横田さんとはツーカーのはず。そうなれば、日本の一大人脈拠点(ネットワーク用語だとIXって言うんだな)を通じて、太平洋を渡れる。なんたって、ノーベル平和賞に推薦するぐらい親しい仲ですからね。

直接、横田さんとことあーべちゃんがつながらなくても、間に政界の人をクッションにおけば、それでつながるだろう。大きな拠点は、IP番号とは違うAS番号とか言う制度で、縦横無尽につながる世界ですから。

政界にコネがなくても、別ルートが可能なはず。プロレスの特技を生かせば、アメリカのそれなりのプロレス協会に知古が有るでしょう。そのルートを通して太平洋を渡ってもいいな。あるいは、旦那が医師と言う特権を使って、アメリカにルートが開けるでしょう。

こう考えて来ると、人間世界の方が、よっぼど世界が狭いと思えるぞ。上で吟味したのをhop(経由)数に直してみれ。つくづく狭いな。

rctl

さくらさんとこを内偵した人が書いていたけど、diskの使用量制限、quotaは設定したあったとか。当然だわな。でも、それ以外のリソース制限はどうする。ulimit -a とかで列挙される類ね。これらを大家であるさくらさんが、きっちりと管理したい。それに答えるのが、rctlですな。

自由な設定が可能な最新リソース制御機能

この記事は古いので、現在とちょっと事情が違う。今は少し便利になってる。

sakae@fb12:~ % sudo rctl
rctl: RACCT/RCTL present, but disabled; enable using kern.racct.enable=1 tunable

制御するかどうかは、カーネル変数で設定可能。但し、変更出来るタイミングはboot時のみ。 よって、loader.confに書いてから、bootする。(delayの方は、boot時のだえもん君との対面時間を極力短くしたいために入れたものです)

sakae@fb12:~ % cat /boot/loader.conf
autoboot_delay=1
kern.racct.enable=1

jail

いよいよ監獄と言うか刑務所の登場です。これ、kernelは共通に使って、ユーザーランドだけを独立に動かしましょって機構。隔離されると、よそ様は何をやってるかという情報(プロセス)が見えなくなる。

集合住宅にはうってつけ。 以前、ウブで、armを模倣させたけど、あんな感じね。

刑務所の説明は、ハンドブックに出てるんだけど、 FreeBSDで、ドキュメントからハンドブックを選んでも出てこない。英語版しか解説が載っていないからね。英語に切り替えよう。

Chapter 14. Jailsに詳しい説明がある。なーに、ググルさんに日本語化させて読むのさ。

FreeBSD 12.0が親。この中に刑務所を建設する。塀の中は、ちょいと時代がかったVerにしておこうか。本家には古いのが無いので、 日本のサイト、さくらさんとこへ行く。

9.3なんてのが置いてある。まだ現役だから後生大事に保持してるのね。必要なのは、とりあえずの所、base.txzだ。これが有れば、骨組だけは、構築(ただ展開するだけだけどね)

仮想化ソフトウェア - FreeBSD - jail

$ ls -lh base.txz
-rw-r--r--  1 sakae  sakae    68M Feb 18 16:13 base.txz
$ du -sh jail/
312M    jail/

tgzを展開すると、4.6倍に膨れあがった。こういう感覚は肌で覚えておかないとね。

jailの中は、文字通り、刑務所の塀の中。世間と隔離されています。今は塀の中は基本的な機能しか入れてないけど、たとえば囚人にITに優れた人がやってきたとしましょう。そんな場合は、懲役で、ソフト開発をさせたい。(今の日本に、そういう柔軟性は無いと思うけど)

こういう時は、コンパイラーのセットぐらいは用意しなきゃならんな。なんてのは、OpenBSDとごっちゃになった人の言う事で、コンパイラーはbase.txzに含まれている。manも入っている。

jailの性格と言うか、設定を親側に用意する。

$ cat /etc/jail.conf
j9 {
        jid = 9;
        name = j9;
        path =/home/sakae/jail;
        ip4.addr = xx.xx.xx.xx;
        host.hostname = jail9.hoge.net;
        allow.raw_sockets;
        exec.start = "/bin/sh /etc/rc";
        exec.stop = "/bin/sh /etc/rc.shutdown";
        interface = em0;
        mount.devfs;
}

刑務所の運用開始と、概要調査

$ sudo service jail onestart j9
Starting jails: j9.
$ jls -v
   JID  Hostname                      Path
        Name                          State
        CPUSetID
        IP Address(es)
     9  jail9.hoge.net                /usr/home/sakae/jail
        j9                            ACTIVE
        2
        xx.xx.xx.xx

閉鎖する時は、stopだな。

まだ塀の中には誰もいないはずなので、監察官が入所してみる。

$ sudo jexec j9 /bin/sh
# ls
.cshrc          boot            libexec         rescue          tmp
.profile        dev             media           root            usr
COPYRIGHT       etc             mnt             sbin            var
bin             lib             proc            sys

ちょっと省いてしまったけど、監察官の身の安全の為、速攻でパスワードを設定しよう。囚人から身を守る唯一の方策ですから。

# ps -awx
 PID TT  STAT    TIME COMMAND
 997 ??  SsJ  0:00.02 /usr/sbin/syslogd -s
1049 ??  SsJ  0:00.03 sendmail: accepting connections (sendmail)
1054 ??  IsJ  0:00.01 /usr/sbin/cron -s
1104  2  SJ   0:00.03 /bin/sh
1126  2  R+J  0:00.00 ps -awx

あら、メールシステムが動いてる。これは停止しておこう。

# cat /etc/rc.conf
sendmail_enable='NONE'
# uname -a
FreeBSD jail9.hoge.net 12.0-RELEASE-p3 FreeBSD 12.0-RELEASE-p3 GENERIC  amd64

ユーザーランドは9.3なんだけど、カーネルは親の12.0が使われている。

次は囚人の受け入れ準備。囚人は番号で呼ばれるんだけど、それじゃあんまりなんで、ゴルゴ13を模したアカウントを用意。独房もね。

# adduser
Username: g13
Full name: g13
Uid (Leave empty for default):
Login group [g13]:
Login group is g13. Invite g13 into other groups? []:
Login class [default]:
Shell (sh csh tcsh nologin) [sh]:
Home directory [/home/g13]:
Home directory permissions (Leave empty for default):
Use password-based authentication? [yes]:
Use an empty password? (yes/no) [no]:
Use a random password? (yes/no) [no]:
Enter password:
Enter password again:
Lock out the account after creation? [no]:
Username   : g13
Password   : *****   (g13-007)
Full Name  : g13
Uid        : 10001
Class      :
Groups     : g13
Home       : /home/g13
Home Mode  :
Shell      : /bin/sh
Locked     : no
OK? (yes/no): y
adduser: INFO: Successfully added (g13) to the user database.
Add another user? (yes/no): no
Goodbye!

パスワードは忘れそうなんで、メモしといた。(それじゃ、だめじゃん) まあ、ム所の中に暗殺をしにきたか、007が潜入操作にきたかって、シチエーションを思いうかべれば、暗記はできそうだけどね。

$ sudo service jail onestop j9
Password:
Stopping jails: j9.
$ jls
   JID  IP Address      Hostname                      Path

一応、閉所しとくか。なお、この方法は、ワンショットなので悪しからず。 通常は、 /etc/rc.conf に jail_enable="YES" と指定しておくと、起動時からjailが開所するようになるぞ。

$ sudo jexec -U g13 j9 /bin/tcsh
g13@jail9:/ % cd
g13@jail9:~ % id
uid=10001(g13) gid=10001(g13) groups=10001(g13)
g13@jail9:~ % pwd
/usr/home/g13

これ、収監の手続例、/bin/tcsh は、省略可能。 派手な囚人服を着せる代わりに、派手なプロンプトが出て来るように、tcshを指定してみたんだ。

ログイン当初は入り口に放置されるので(本来なら、ここでケツの穴まで調べられる、身体検査を受けるはず)、自分で独房へ行く事。変な特権(wheel)とかが無いので、所内で暴れる事も制限される。

g13@jail9:~ % exit
exit
$ id
uid=1001(sakae) gid=1001(sakae) groups=1001(sakae),0(wheel),5(operator)

正規の手順を踏んで、出所した。出所と同時に、色々な権利を取り戻したぞ。 wheelでrootになれる権利。operatorで、shutdownして電源を落とす権利だ。

頑張って、jail break (脱獄)を試みるのも楽しいかも知れない。アプルは、次々に手を打ってきて、ipadとかからの脱獄は難しくなってるそうだから。 仮に脱獄出来ても、秘中の秘で、世の中には出回らないと思うけど。

最後に、刑務所を潰して更地にする方法を書いておく。FreeBSDは、rm -rf / なんていう悪戯から保護するため、ちょっとした防御が施されている。

chflags -R noschg /home/sakae/jail/*
rm -R /home/sakae/jail/*

安全に『危険シェル芸』ができるスタートアップスク

さくらさんとこの人が数年前のLLゴングに登壇して、遊んでいたそうだ。