Solaris 2.x/7 では、tmpfs はデフォルトで使用されますが、SunOS 4.1.4 では、tmpfs を使うための設定が、/etc/rc.local の中で、デフォルトではコメントアウトされています。
そこでまず、本当に tmpfs を使っているかどうか確認する必要があります。 以下のようなコマンドの出力が得られれば、tmpfs が使われています。
$ mount -p | grep swap swap /tmp tmp rw 0 0 $ df | grep swap swap 90196 32 90164 0% /tmp |
もし、tmpfs が使われていなかった場合は、/etc/rc.local
の中に書かれている
# mount /tmp
のコメントを外し、ついでに安全のため、
mount -v /tmp; chmod +t /tmp
と書き換え、さらに /etc/fstab
の中に、
swap /tmp tmp rw 0 0
という行を追加します。これでリブートすれば(または直接 mount /tmp
を実行すれば) tmpfs が使われるようになります。
$ cd /tmp $ mknod aaa p $ ln aaa bbb # must be hard-link (not symbolic-link) $ ls -l BAD TRAP: |
SunOS 4.1.4用の patch は何故か出ていません。そこで、SunOS 4.1.3用、または SunOS 4.1.3_U1用の patch を敢えて当てます。
100507-06 (SunOS 4.1.3用) または、
102396-01 (SunOS 4.1.3_U1用) の中の、
tmp_vnodeops.o のみを使います。
patch の中には、他にも tmp_*.o が入っていますが、これらは、すでに SunOS 4.1.4 には統合済みだったり(リリースノートによると100507-05 までは統合済み)、別の patch で更に置き換わるため、 必要ありません。
$ mkdir /tmp/aaa $ cd /tmp/aaa $ rmdir /tmp/aaa $ touch bbb $ cd / assertion failed: tp->tn_dir == NULL |
- ・ここまでの tmpfsカーネルpatch のまとめ
tmp_dir.o -- 103314-01 の tmp_dir.o で置き換え tmp_subr.o -- SunOS 4.1.4 オリジナルのまま tmp_tnode.o -- SunOS 4.1.4 オリジナルのまま tmp_vfsops.o -- SunOS 4.1.4 オリジナルのまま tmp_vnodeops.o -- 100507-06 または 102396-01 の tmp_vnodeops.o で置き換え
$ cd /tmp $ mkdir aaa $ chmod -w aaa $ cd aaa $ ln -s bbb ccc # must be symbolic-link (not hard-link) panic: kmem_free: block already free |
このバグの patch は、今現在もまだ出ていません。
以前は、workaround のためのプログラムを、カーネルに modload して解決したりもしました。
今ここに、adb で、カーネルの問題の部分を修正する方法を紹介します。
vmunix を adb で見て、以下の部分に注目して下さい。
tmp_symlink+164?i _tmp_symlink+0x164: call _tmp_memfree |
書き込み不可のディレクトリに、シンボリックリンクを作ろうとすると、 この部分を通ります。しかし、この時点で tmp_memfree() を呼ぶ必要はなく(すでに kmem_free されている)、この call 命令がバグの原因と判断しました。
これを nop で置き換えればバグが解決することを確認しています。
実際には、vmunix のバイナリ自体は修正せず、SunOS のブート時に以下のようなスクリプトを /etc/rc.local などから起動して、ロードされたカーネルを書き換えるという方法が 安全だと思います。
#!/bin/sh set - `echo 'tmp_symlink+164/i' | adb -k /vmunix /dev/mem | tail -1` if [ "$1" = '_tmp_symlink+0x164:' -a "$2" = 'call' -a "$3" = '_tmp_memfree' ] then echo \ 'tmp_symlink+164/i /W1000000 /i' | adb -k -w /vmunix /dev/mem else echo "$@" '-- not call _tmp_memfree' fi |
これら tmpfs のバグについて、正式な patch が出ることを望みたいものです。 また、いつか将来、SunOS 4.1.4 のソースが公開された場合には、自分で再度、上記バグの原因を検証したいとも 思っています。