9front kernel

あけおめ、ことよろ。

知的書評合戦ビブリオ・バトルと言うのがあって、参加者がこれと思う本の応援演説を競うものだそうだ。

より多くの人にその本を読んでみたいと思わせたら勝ちとか。このビブリオバトルの平和版を、ビブリオトークと言うそうだ。

『IT研究者のひらめき本棚』は、IT業界に身を置く著名な方が、一人一冊づつ、推薦図書を挙げ、思い思いの方法で応援演説したものが40冊挙げてある。

オイラーも読んだ事がある、『ハッカーと画家』 とか、『プログラム書法』や『Lisp』なんてのが出てた。あと、待ち行列を解説した書籍を二人の方が推薦されていたのは意外だった。オイラーが名著だと思っていた『SICP』は、選外だったよ。

ならば、オイラーからの一冊は、『プログラミングHASKELL』だな。世に有るHaskell本に比べて、圧倒的に薄い本だ。でもHaskellの本質を鋭く解説してる。

そう言えば、Cフラフラ語で有名なあの人が、 C++の入門書を書くためにHaskellを学ぶことにしたらしい。面白い切り口で、Haskellの悪口を期待したいな。

plan9port (aka p9p) install in Debian

Plan9portなんていう記事を見ていたら、Linuxでは何の苦労もなくインストール出来るよって説明されてた。ならば追試してみよう。再現出来れば、科学の発展に寄与出来るからね。Plan 9 from User Space(こちらが本家)

gitで取ってきたのを/tmpに展開。なんたってお試しですから、場所はここで十分です。

deb9:plan9port-master$ ./INSTALL
+ Mailing list: https://groups.google.com/group/plan9port-dev
+ Issue tracker: https://github.com/9fans/plan9port/issues/
+ Submitting changes: https://github.com/9fans/plan9port/pulls                  
* Resetting /tmp/plan9port-master/config
* Compiler version:
        gcc version 6.3.0 20170516 (Debian 6.3.0-18)
* Running on Linux: checking for NPTL...
        NPTL found.
        fontsrv dependencies not found.
* Building mk...
>>> pwd
>>> cd /tmp/plan9port-master/src/lib9
9c _p9dialparse.c
 :
nfs3.c:3980:49: note: ...this statement, but the latter is misleadingly indenteas if it is guarded by the ‘if’
  if(sunenumunpack(a, ea, &a, &i) < 0) goto Err; x->status = i;
                                                 ^
>>> cd /tmp/plan9port-master/src/cmd/devdraw; mk all
9c -I/usr/include x11-alloc.c
x11-inc.h:13:22: fatal error: X11/Xlib.h: No such file or directory
 #include <X11/Xlib.h>
                      ^
compilation terminated.
mk: 9c -I/usr/include x11-alloc.c  : exit status=exit(1)
mk: for i in ...  : exit status=exit(1)
mk: for i in ...  : exit status=exit(1)

なんとなく、plan9の雰囲気を醸し出してますなあ、なんて眺めていたら、パンチを喰らったぞ。ヘッダーファイルが無いと言って、Russ Cox(p9pの作者さん)が臍を曲げちゃった。 全く、Linuxってやつは腐ってる。どのパッケージにヘッダーが有るか調査。

deb9:plan9port-master$ apt-file search Xlib.h
 :
libx11-dev: /usr/include/X11/Xlib.h

で、こいつを入れて再度コンパイル。

>>> cd /tmp/plan9port-master/src/cmd/devdraw; mk all
9c -I/usr/include x11-alloc.c
x11-inc.h:17:28: fatal error: X11/IntrinsicP.h: No such file or directory
 #include <X11/IntrinsicP.h>
                            ^
compilation terminated.
mk: 9c -I/usr/include x11-alloc.c  : exit status=exit(1)
mk: for i in ...  : exit status=exit(1)
mk: for i in ...  : exit status=exit(1)
deb9:plan9port-master$ apt-file search X11/IntrinsicP.h
libxt-dev: /usr/include/X11/IntrinsicP.h

2発目のパンチを喰らった。嫌気が差してきたぞ。

>>> cd /tmp/plan9port-master/src/cmd/fontsrv; mk all
9c -I/usr/include -I/usr/include/freetype2 x11.c
x11.c:3:35: fatal error: fontconfig/fontconfig.h: No such file or directory
 #include <fontconfig/fontconfig.h>

3発目、忍耐が要りますなあ。なんか、リナではコンパイルに必要なパッケージを先に見繕って、教えてくれるような設備が有ったような気がするけど、何と言うやつだったかなあ?

>>> cd /tmp/plan9port-master/src/cmd/rio; mk all
9c -I/usr/include -DDEBUG -DSHAPE -DDEBUG_EV -DDEBUG event.c
event.c:9:34: fatal error: X11/extensions/shape.h: No such file or directory
 #include <X11/extensions/shape.h>

4発目、いいかげん堪忍袋の緒が切れますよ。この怒りを誰にぶつければ良い? そりゃ、帝王のリーナスに決まってるだろうね。

* Installing everything in /tmp/plan9port-master/bin...
* Cleaning up...
* Renaming hard-coded /usr/local/plan9 paths...
* Building web manual...
* Done.

* Add these to your profile environment.
        PLAN9=/tmp/plan9port-master export PLAN9
        PATH=$PATH:$PLAN9/bin export PATH

やっと怒りが通じたか、最後まで行って、設定の指南が出て来た。んだけど、お試しなんで 超いい加減な方法で試してみる。

deb9:plan9port-master$ cd bin/
deb9:bin$ PATH=`pwd`:$PATH
deb9:bin$ 9 rlwrap rc

rlwrapをかませておくと、ヒストリーが効いて便利です。まあ、rioのGUIを使うのが嫌いな 人の生活の知恵でもあります。

deb9:tmp$ du -sh plan9port-master/
207M    plan9port-master/

こんなもので、plan9の香りに触れられるのはいいな。ソースが付いていて見放題と言うのが、リナよりアドバンテージが高いと思うぞ。リナは使うだけのWindows代替品ですからね。 (ああ、これあくまでも個人の感想ですんで、石を投げない、ネットで火祭りはご遠慮願います。)

ここまで終わりにしても良かったんだけど、プチ疑問が出てきた。それは、いきなり9cなんて 使ってるけど、これって鶏卵問題だよな。この疑問が解決しないと寝起きが悪いぞ。

まっさらにして、zipを展開。binの中身を拝見。

deb9:bin$ ls -F
9*      B*        ipso*     nroff*    sig*    troff2png*  wintext*
9a*     bundle*   kill*     osxvers*  slay*   u*          wmail*
9ar*    disk/     label*    ps*       spell*  unmount*    yesterday*
9c*     doctype*  lc*       psfonts*  src*    upas/
9fs*    E*        lookman*  psu*      ssam*   u.rc*
9l*     fossil/   macedit*  psv*      stack*  venti/
9.rc*   fs/       man*      quote1*   start*  vmount*
adict*  g*        mount*    quote2*   stop*   vwhois*
awd*    Getdir*   nobs*     samsave*  tref*   web*

これだけ既に用意されてるって事は、スクリプトの類だな。疑問が氷解したよ。何のこっちゃと いぶかる向きもあろうかと思うので、9cを紐解いてみる。

#!/bin/sh

test -f $PLAN9/config && . $PLAN9/config

tag="${SYSNAME:-`uname`}-${OBJTYPE:-`uname -m`}-${CC9:-cc}"
case "$tag" in
*FreeBSD*gcc*)  usegcc ;;
*FreeBSD*clang*)        useclang ;;
*DragonFly*|*BSD*)      usegcc ;;
*Darwin-x86_64*)
   :
# N.B. Must use temp file to avoid pipe; pipe loses status.
xtmp=/tmp/9c.$$.$USER.out
$cc -DPLAN9PORT -I$PLAN9/include $cflags "$@" 2>$xtmp
status=$?
quiet $xtmp
rm -f $xtmp
exit $status

こんな具合に動いている環境によってccを切り替えてコンパイルしてる。9cとか9lとかは、 OSネイティブなコンパイル環境へのつなぎスクリプトでした。なかなか上手な手法だなあ。

折角再展開したんで、コンパイルに要した時間を測ってみたら、下記のようになった。

real    4m14.647s
user    3m4.232s
sys     0m27.364s

mount

さっさとリナにお暇して、 Plan 9 from User Space(plan9port)を使う とか、格調高く Authentification sur 9grid.fr とか言う、おフランスのサイトを見てたんだ。 そしたら、何と、下記の操作で、(本物の)Plan9のエリアを、手元に持ってこれるとと出てた。

そのやり方は、plan9側で輸出用の準備をする。

on Plan 9:
% aux/listen1 tcp!*!17007 /bin/exportfs -a -A tcp!*!0

unix側で、受け入れるとな。

on plan9port:
$ factotum
$ 9import host path mtpt

この際なんで、FreeBSDにもp9pを入れた。手間をかけずに、develのportsに有ったものだ。 (正確にはpkg版。9やsrc類は省略されてたので、OpenBSDから分けてもらった。)

[fb11: ~]$ 9 9import -A xxx.xxx.xxx.xxx /sys/src/9 /home/sakae/plan9
9import: bad remote tree: can't read tree

折角ソースが有るんだから、落ちたあたりを覗いてみる。

        threadsetname("writing tree name %s", tree);
        n = write(fd, tree, strlen(tree));
        if(n < 0)
                sysfatal("can't write tree: %r");

        strcpy(buf, "can't read tree");

        threadsetname("awaiting OK for %s", tree);
        n = read(fd, buf, sizeof buf - 1);
        if(n!=2 || buf[0]!='O' || buf[1]!='K'){
                if (timedout)
                        sysfatal("timed out connecting to %s", na);
                buf[sizeof buf - 1] = '\0';
                sysfatal("bad remote tree: %s", buf);
        }

ツリーが読めないって、無い物ねだりした? 制限がかかっている?(authを無視する設定なんだけどな)よう分からんな。

MacFUSE 9P Bridge

こちらも参考にしたけど、一番易しいauth無しでもエラーになっちゃった。これはもう、ここで 踏みとどまっていても進展なさそう。

そもそも、plan9側のツリーをマウントしたい理由は、ソースをemacsあたりで開いてみたかったから。別の手を考える。

tar

そんなの簡単、tarでまとめて、ftp送りしちゃえ。plan9のtarって世間一般に流通してるものと一緒? 一応確認しておかないと、足元をすくわれるぞ。ああ、unixのやつと基本は一緒だった。それはいいんだけど、面白い例と言うか、懐かしい使い方が出てた。

     EXAMPLES
          Tar can be used to copy hierarchies thus:

               @{cd fromdir && tar c .} | @{cd todir && tar xT}

shallow-copy(浅いコピー)じゃなくて、deep-copy(深いコピー)のやり方。リナだと、cpなんたらオプションで、指定dir以下を(再帰的に)ごっそりコピー出来るけど、生憎Solarisのやつにそんな機能は無し。

(注: shalliw/deep なんて言葉は、bindingと共に使うのが普通。100歩ゆずると、pythonあたりのlistのコピーの所で出て来るけどな。)

で、tarを使えとな。solaris風に書くと、

cd fromdir; tar cf - src | (cd todir; tar xf -)

これで、fromdir/src以下をごっそりtodirにcp出来る。この技を、出張中のカリフォーニアの某所で披露したら、japan-magicだといたく感心された。もう遥か昔の話。

そう言えば、plan9には、tailコマンドが有るくせに、対となるheadコマンドが無いんだ。 lispでcdrが有るのにcarが無いという居心地の悪さ。ああ、今更car/cdrなんて古すぎるか。 Haskellで言うと、head/tailだな。やっぱりplan9は狂っているぞ。

と、思ったら、tailのmanの最後の方に、さりげなくheadの代替方法が書いてあった。

          sed 10q file
               Print the first 10 lines of a file.

意地でも、余計なコマンド(head)は入れたく無かったんでしょうね。それともミニマリストを 標榜するschemerが、plan9の開発者に混じっていた。

便利ならそれでいいじゃん主義のlinuxはunixではありません。だからlinuxって商標取ってるじゃん。

9fs

term% 9fs 9front
post...
post...
post...
term% ls /n
/n/9front
/n/9front.org
/n/9front.org!7734
/n/bugs
/n/contrib
/n/contrib.9front.org
/n/extra
/n/fqa
/n/hardware
/n/iso
/n/lists
/n/other
/n/pkg
/n/sites
/n/sources

本当は、下記をやりたかったんだけど、つい手が滑った。これって、公式に公開されてるやつかな。mailing listにアクセス出来るようだ。

term% 9fs 9fat
term% ls /n
/n/9
/n/9fat
/n/9front
  :

kernel

上で9fatを見たかったのは、9frontがどう動いているか知りたかったため。そのとっかかり。 初期化プロセスなんていう解説も有るしね。

そして、カーネルの解説書。

Notes on the Plan 9 tm 3rd edition Kernel Source

こちらは、Plan9の紹介というか副読本

Introduction to OS Abstractions Using Plan 9 From Bell Labs

[fb11: 9]$ ls
TAGS    boot/   ip/     libc/   mkfile  pc/     port/

カーネルのソース参照のため、emacs用にタグファイルを作っておいた。 ざっとソースをみた所、pcの中はボトムーハーフなコードが、portの中はトップーハーフなOSコードが収納されてるっぽい。bootはOSをメモリーにロードして起動を行うやつか。ipはネット回り、libcはカーネルに密接に関わっているから境界を確かめるために持ってきておいた。

psだけじゃなくてpstreeなんてのが有ったので試してみた。これなかなか良い趣向。

term% pstree | p
1           ├bootrc /bin/bootrc
107         │└/386/init -t
302         │ └rc -c '. /rc/bin/termrc; home=/usr/$user; cd && . ./lib/profile'
458         │  └rio -i riostart
3           ├mouse
5           ├alarm
7           ├paqfs
 :
225         ├factotum
272         ├cwfs64x [srvo]
273         ├cwfs64x [srvi stdio]
274         ├cwfs64x [srvo]
275         ├cwfs64x [srvi #s/cwfs]
276         ├cwfs64x [con]
 :
484         ├rc -c '/bin/window -x bin/mytelnetd '
485         │└mytelnetd ./bin/mytelnetd
492         │ └/usr/glenda/bin/mylisten1 -t tcp!*!2323 /usr/glenda/bin/chat1
 :
1083        ├chat1 /usr/glenda/bin/chat1
1085        │├tr -d \015
1086        │└/bin/rc -i
1168        │ └pstree

sysinfo

どんなハードで動いているか調べてみたいな。で、思い出したのがsysinfo

term% sysinfo > LOG
cat: can't open #c/swap: '#c/swap' file does not exist
aux/icanhasvmx: CPU does not support VMX
pcmcia: opening #y/pcm0attr: '#y/pcm0attr' file does not exist
cat: can't open /mnt/apm/ctl: '/mnt/apm/ctl' does not exist

ログを取っておいて、後でゆっくり眺める算段。なんだけど、どうもstderrに出て来るやつは 無視されるようだ。エラーも含めてログするには、どうやる? 後で役にたつと思うので、調べておく。

term% sysinfo > LOG >[2=1]
term% sysinfo >[2=1] | tee LOG

これで良いみたい。但し、stderrをstdoutへ回す意味の所は、一気に続けて書く事。これを守らないと意図したものに成らない。

このsysinfoの結果は9front.orgのWebサイトに匿名で送信出来るようになってた。 開発者に貢献をお願いしましょう。って、debianみたいだな。

% cd '#ec'; for(i in *){echo $i '=' `{cat $i}}
*bootscreen = 1024x768x16 r5g6b5 0xe0000000 16777216
*e820 = 1 0x0000000000000000 0x000000000009fc00 2 0x000000000009fc00 0x000000000
00a0000 2 0x00000000000f0000 0x0000000000100000 1 0x0000000000100000 0x000000003
fff0000 3 0x000000003fff0000 0x0000000040000000 2 0x00000000fec00000 0x00000000f
ec01000 2 0x00000000fee00000 0x00000000fee01000 2 0x00000000fffc0000 0x000000010
0000000
bootargs = local!/dev/sdC0/fscache
bootfile = 9pc
monitor = vesa
mouseport = ps2
vgasize = 1024x768x16

これがbootの状態か。

term% pci -v
0.0.0:  brg  06.00.00 8086/1237   0
        Intel Corporation 440FX - 82441FX PMC [Natoma]
0.1.0:  brg  06.01.00 8086/7000   0
        Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II]
0.1.1:  disk 01.01.8a 8086/7111   0 4:0000d001 16
        Intel Corporation 82371AB/EB/MB PIIX4 IDE
0.2.0:  vid  03.00.00 80ee/beef  11 0:e0000008 16777216
        InnoTek Systemberatung GmbH VirtualBox Graphics Adapter
0.3.0:  net  02.00.00 1022/2000  10 0:0000d021 32 1:f0000000 4096
        Advanced Micro Devices, Inc. [AMD] 79c970 [PCnet32 LANCE]
0.4.0:  base 08.80.00 80ee/cafe   9 0:0000d041 32 1:f0400000 4194304 2:f0800008 16384
        InnoTek Systemberatung GmbH VirtualBox Guest Service
0.5.0:  aud  04.01.00 8086/2415  11 0:0000d101 256 1:0000d201 64
        Intel Corporation 82801AA AC'97 Audio Controller
0.6.0:  usb  0c.03.10 106b/003f  11 0:f0804000 4096
        Apple Inc. KeyLargo/Intrepid USB
0.7.0:  brg  06.80.00 8086/7113  10
        Intel Corporation 82371AB/EB/MB PIIX4 ACPI

こちらは、pciバスにぶら下がっているデバイスね。念のため、vboxで動いているOpenBSDのdmsgから、関連しそうな部分の抜き出してみた。

pciide0 at pci0 dev 1 function 1 "Intel 82371AB IDE" rev 0x01: DMA, channel 0 co
nfigured to compatibility, channel 1 configured to compatibility
em0 at pci0 dev 3 function 0 "Intel 82540EM" rev 0x02: apic 2 int 19, address 08
:00:27:e2:70:c1
auich0 at pci0 dev 5 function 0 "Intel 82801AA AC97" rev 0x01: apic 2 int 21, IC
H
ac97: codec id 0x83847600 (SigmaTel STAC9700)

あれ、NICの認識状況が違うなあ。

vboxの設定を見たら、NICにはIntel PRO/1000 82540ENがセレクトされてた。インストール時にOSの種別によって、よさそうなハードを見繕ってくれるという親切設計になってるのかな。

etc

tmux のキャプチャ機能を使った emacs とシェルの連携

Emacsの補完&検索を超強化する