先週の5/24(土)に生まれて初めて勉強会に行ってまいりました。
※正確には読書会です。
はじめてのOSコードリーディング 読書会 (15) – connpass

はじめてのOSコードリーディング ~UNIX V6で学ぶカーネルのしくみ (Software Design plus)
- 作者: 青柳隆宏
- 出版社/メーカー: 技術評論社
- 発売日: 2013/01/09
- メディア: 単行本(ソフトカバー)
- 購入: 56人 クリック: 1,959回
- この商品を含むブログ (29件) を見る
UNIX V6とはUNIXカーネルのバージョン6のソースコードで、10,000行程度でOSに必要な実装がなされているため、カーネルのコードリーディングにはちょうどよい教材なのだそうです。
ただ、それでもLions本は読み解くのが相当難しいらしいですが・・・。
こういった集まりに参加するのはほんとに初めてなので、
会場はどういったものなのか、どのような人たちが集まって
どのような会話が繰り広げられるのかといったいろいろと想像してドキドキでした。
辿り着くまで
会場は池袋駅近くのビルでした。
まだ東京に来て慣れないので、迷う可能性も考えて2時間前には出発しました。
・・・案の定迷いました。
池袋駅まで来たのは良かったけれども、いったいどこから地上に出られるのかわからない!
案内図を見ると出口がいっぱいある・・・。
どれかそれっぽい出口を出て看板を見るとそこには東京メトロのロゴが・・・。
僕は確かにJRの駅で降りたはず・・・と混乱しながらGoogleマップをたよりにやっとこさ会場にたどり着きました。
会場についてから
会場にはもうすでに2名ほどの方がいらっしゃいました。
少しくして主催者の @7shi さんまでそろい、僕も含めて9名で開催されました。
念のため自分のMBAも持って行っていたのですが、みなさんも全員ノートPCやらMBPやらお持ちでした。
メモをとったり、UNIX V6のソースコードを見たりするときに便利でした。
さりげなくまわりを見渡すと
- 人気投票艦娘一覧のポスターが!
- 本棚には技術系の本がいっぱい。
なんだかとても親近感を覚えながらも読書会は開幕しました。
@7shi さんのプレゼンテーション
ここで @7shi さんが次の日のイベントで発表されるプレゼンのリハーサルを聞かせていただきました。
に参加されるとのことでした。
↓
V6のPDP-11からx86プロセッサへの移植作業をし始めた!
- 16bit(リアルモード=8086)動作限定
- BIOS経由の同期アクセスのみ
その他やることとしては
ちょっとした小話ですが、V1は全部アセンブラで書かれているそうです(!)
ちなみにEXEを作って遊ばれていたとのことでしたが、C言語のソースをVSでビルドするというレベルの話ではなくて、
機械語を自分の手で書いて遊ばれていたそうです、すごい・・・。
BSDカーネルの設計と実装 読書会
これから本題かと思いましたが、「BSDカーネルの設計と実装 読書会 (22)」が同時に開催されるようです。
これについては僕も予想していなかったのですが、隣の方に本を見せていただきながら
読書会に参加させていただきました。
ありがとうございます!

- 作者: マーシャル・カークマキュージック,ジョージ・V.ネヴィル‐ニール,砂原秀樹,Marshall Kirk McKusick,George V. Neville‐Neil,歌代和正
- 出版社/メーカー: アスキー
- 発売日: 2005/10/18
- メディア: 単行本
- クリック: 122回
- この商品を含むブログ (57件) を見る
こちらの本は絶版になっています。購入するには中古で購入する必要があります。
歌代和正さん訳の本とのことで、Perl界隈で有名な方だそうです。
って、あとで調べてみたら jcode.pl を開発された方ですか!
そりゃ有名なはずですね・・・。
以降の話は全体的に8.6ソフトアップデートに関するお話でした。
ジャーナリングとは根本的に違うようです。
8.6.8 新規ディレクトリエントリの依存管理
8.6.9 新規ディレクトリの依存管理
以下、かいつまんで単語レベルでぶつ切りに並べてありますが、
ボイスレコーダー等で正確にトレースしたわけではないので、
私の書いていることは話半分に聞いてください。
- ビットマップ
- ディスク上の対応
- 依存関係がある
- ビットマップを作成する前にinodeを作成するとまずい
- どの段階で電源が切れても大丈夫なように依存関係を管理する手法
- あとでfsckをかければ直る程度になる
8.6.10 ディレクトリエントリの削除にかかわる依存処理
- ソフトアップデート
- ディスク上の話
8.6.11 ファイルの短縮
100MB→0バイトにすること。ファイルの削除ではない。
-
8.6.13 ディレクトリエントリの名称変更にかかわる依存性管理
- diradd
- dirrem
- BをXに変える
8.6.14 ファイルの削除に関する依存管理
8.6.15 ソフトアップデートがfsyncをサポートするための条件
- inodeのビットマップ書き出しが完了しているか
- FreeBSD3.xのころにソフトアップデートが導入された
ここで 7shi さんからこんな体験談を聞きました。
- 大量のソースコード削除してみる
- プロンプトは戻ってきてもずっとディスクアクセスが続く
- dfの結果がなかなか減らない
-
これがソフトアップデートの結果?
-
今やってる本はFreeBSD5.2の本
このあたりでZFS(ズィーエフエス)やBtrfs(バター エフエス)の話も出ましたね。
ZFSは使ったことがありますが、重複排除機能がすばらしいですね、
2GBのファイルをcpしてもディスク上の使用量は4GBとはならずほぼ2GBでとどまります。
ただ面白いことにdfの結果は全体的な容量が増えたような結果を返すんですよね。
ただ、お話にも出てましたがメモリは積んだら積んだ分だけめっちゃくちゃメモリ食います。
ここで巨大なファイルの読み込みの仕組みの話。
- ディスクとメモリがマップされる
- 必要になったらメモリに読み込む
- 4GBとかデカイ動画ファイルはメモリマップしてファイルの中身を読み書きするらしい。
- ページキャッシュ
今年の秋頃新板が出る予定(ただし英語、ZFSの話とかも入る)
-
8.6.17 fsckに必要なソフトアップデートの条件
-
ソフトアップデート + fsckでは
lost+found
ディレクトリに退避される- いっぱいになっちゃう(何がいっぱいになっちゃうのかは忘れてしまいました。。。)
8.6.18 ソフトアップデートの性能
- 同期とソフトアップデートではかなり性能差がある
- 同期: 27時間15分
- ソフトアップデート: 19時間50分
はじめてのOSコードリーディング 読書会 (15)
10分ほど休憩を挟んでいよいよ本題です。
本日の内容は 第11章のパイプ(p.348) からです。
僕はp.60のforkシステムコールのところまで。
さすがにここまで追いつくことはできませんでした・・・。
第11章 パイプ
パイプはパイプのストレージ領域 PIPSIZ(4096)
に少しずつためながら流し込んでいますが、
ls | sort
この場合の sort コマンドを実行した時はどうなるの?
という疑問が上がりました。
ソート側のバッファにパイプから流れてくる内容をためてからソートしているはずとの予測が出てきました。
@7shiさんから、V6のソートのソースコードは短いですよ~とのお話を頂いたので、この場で読み込んでみる形と相成りました。
このころはlibc自体は発展途上
sort.cの中でテンポラリファイルの作成処理等をやってる
/* src/s2/sort.c */ i = lspace = sbrk(0);/* 135 */ while(brk(a) == -1) a =- 512; brk(a =- 512); /* for recursion */ a =- i; nlines = ((a-L)>>1) & 077777; nlines =/ 5; ntext = nlines*8; tspace = lspace+nlines;/* 143 */ file = "/usr/tmp/stmXaa"; loop: filep = file; while(*filep != 'X') filep++; for(*filep = 'a';;(*filep)++) { if(stat(file, lspace) < 0) { a = creat(file, 0600); if(a >= 0) break; } if(*filep == 'z') { if(file[1] != 't') { file = "/tmp/stmXaa"; goto loop; } mess("Cannot locate temp\n"); exit(1); } } close(a); filep++; if ((signal(2, 1) & 01) == 0) signal(2, term); nfiles = eargc; if(!mflg) { ibuf[0] = -1; sort(); close(0); } for(a = mflg?0:eargc; a+N < nfiles; a=+N) { newfile(); merge(a, a+N); } if(a != nfiles) { oldfile(); merge(a, nfiles); } error = 0; term(); } sort() { register char *cp; register *lp, c; int done; int i; int f; done = 0; i = 0; do { cp = tspace;/* 197 */ lp = lspace;/* 198 */ while(lp < lspace+nlines && cp < tspace+ntext) {/* 199 */ *lp++ = cp; while((*cp++ = c = getc(ibuf)) != '\n') { if(c >= 0) continue; cp--; close(ibuf[0]); if(i < eargc) { if((f = setfil(i++)) == 0) ibuf[0] = 0; else if(fopen(f, ibuf) < 0) cant(f); } else break; } if(c < 0) { done++; lp--; break; } }
私には難しくてあんまり理解できませんでした・・・。
- gnu global?
- カーネル側とlibc側のgetcがある
- getcはシステムコールのもの?
- 一般的なパイプ
- isatty
-
パイプから来てるのか、標準入力から来てるのか
-
teeコマンドの動き
-
今ならカーネルのバッファに
-
パイプを何段もつないだ場合にエラーとなる
- pipeシステムコールがいくつも呼ばれてFILE構造体がたくさん確保されてENFILEエラーが発生する
ちょっとここで小話がありました。
- V1アセンブラはプリントアウトしたソースからOCRで復元したものだそうですw
-
prele(リリース)は
root/usr/sys/ken/pipe.c
に定義されているのにパイプと関係ないところからいくつも呼ばれているw
/* * Unlock a pipe. * If WANT bit is on, * wakeup. * This routine is also used * to unlock inodes in general. */ prele(ip) int *ip; { register *rp; rp = ip; rp->i_flag =& ~ILOCK; if(rp->i_flag&IWANT) { rp->i_flag =& ~IWANT; wakeup(rp); } }
plock()
- トイレと同じ原理
- 開けて!
参考としては
- p.161, 166
- lightning bolt
- 割り込み
以下、覚書です。
雑談
読書会も終盤にさしかかりました。
あまった時間で参加者の方からこういった勉強会に参加してきたよというお話を伺えました。
- OSvもくもく会#1 〜OSvで遊んでみよう〜 – connpass
-
C++11で実装されている
- KVMを開発してた人が書いたOS
- Library OS
- VMごとに1つのアプリ
- カーネル空間とユーザ空間の区別がない
- ミドルウェアとしてはCassandra, Tomcatも当然動く
- mrubyも動くらしいがELFがそのまま動くわけじゃない
- PICK(?)をつけて共有ライブラリで・・・
- memcached, haproxyも動く
- ファイルサイズはJVMを入れるとかなりでかい
- ZFS intent log ジャーナルみたいなもの
- Fedora向けのOpenJDKには一切手を入れていない
要約すると1つのOS単位でAPサーバが気軽に立てられる、いかにもクラウド指向なOSのようです。
おわりに
と、ここで18時も過ぎた頃でお開きとなりました。
この場で引き続きラテン語講座も開かれるようでしたが、僕はこのへんで失礼させていただきました。
今回勉強会に参加されていた方たちともいろいろなお話ができてとても刺激になりました。
池袋駅までの帰り道では勉強会に参加されていた方といろいろな世間話をさせていただきました。
さっそくTwitterでフォロー申請させていただきました。
いろいろとコアな方と交流出来て楽しかったです。
次回6/21(土)も続きがあるようですので、是非参加してみたいと思います。
今度は迷わないようにするぞ。
それではそれでは。