以下の解説は 2021 時点での 9front に基づいている
もしも「コンピュータは1つだけ」と言われれば、僕は MacBook を選ぶであろう。MacBook は現代の文具であり、何かを書くときに役に立つ。文具としてのコンピュータがなければ何もできないのが、現代の物書きであろう。
あとひとつと言われれば、それに何を求めるか?
Linux を候補に挙げる人が多いだろうが、クライアントとして使うなら、所詮は Mac に敵わない。また Mac に敵う日が来るとも思えない。サーバーとして Linux を勉強したいと言うなら、なぜかを考えた方が良い。職のためなら何も言わない。泥沼であっても勇敢に入り込まなくてはならない職業もあるのだから...
プログラミングが好きなら、Plan9 が良い。Plan9 はプログラミングの天才と言われる人たちが作り上げた、いわば芸術作品である。よく練り上げられた設計とプログラミングコードはそれだけで美しく、鑑賞に値する。他の OS はどうかと言えば、パッチワークの世界であり、荒れた密林の中を彷徨う感がある。それに比べると、Plan9 はよく整備された美しい庭園である。
Plan9 は小さいコンパクトな OS である。ソースコードの全てを見ることができる。OS がどのように動いているか、完全に調べることが可能である。解ったことを確認するために、カーネルレベルでの手軽な実験すら可能である。そのような OS は Plan9 以外には存在しない。
Plan9 は Mac の弱点を補ってくれる。Mac はとてもサーバーとして使えたものではない。設計コンセプトはあくまでも現代の文房具である。Mac の Time machine は履歴管理がなっていない。どこまで遡れば目的のファイルに出会えるか、全くわからないので、日常的には役に立った覚えがない。
以下では一番簡単なサーバー構成、すなわち1台のマシンが認証サーバー、ファイルサーバー、CPU サーバーを兼ねている構成を前提にして解説する。この構成が一番使いやすい。信頼できるユーザーしかいない場合、この構成で十分である。特にホームサーバーとしては...
以下では既に端末としての Plan9 が動いていると想定している。
また読者は、ネットワーク(IPv4 レベル)についてのある程度の知識を持ち、ホームルーターの役割を理解し、簡単な設定ができると仮定している。
僕の場合には家庭内に様々な種類のサーバーを抱えている。それらのサーバーに対して名前でアクセスしたいので、それを Plan9 のサーバーに任せている。
例えば FreeBSD をお試しにインストールして使ってみたいとしよう。標準インストールではクライアントとしてインストールするはずである。これをサーバーに変更したければ、名前を与え、固定した IP アドレスを与える必要がある。この部分は OS ごとにやり方が異なり、しかも複数の場所に設定箇所が散らばっているいることが多い。一苦労が要求される。しかし Plan9 のサーバーを持っていれば、そのような苦労は要らない。Plan9 のネットワークデータベースに数行を追加するだけで済む。家庭内のすべてのサーバーの名前と IP アドレスの設定が1箇所で行えるので見通しが良い。
これを持たないと OS ごとに異なる設定法に四苦八苦することになり、しかも全体の見通しがすこぶる悪い。
注意:
以下では、読者はホームルーターをある程度操作できることが想定されている。操作法はルーターごとに異なるので、ここでは解説しない。(ホームルーターのマニュアル参照のこと)
特に、Plan9 を DHCP サーバーとして動かす場合には、ホームルーターの DHCP サービスを停止する必要がある。このサービスは1セグメントに1つである!
ネットワークを設定するときには、動的 IP の範囲をあらかじめ定めておく必要がある。そのための具体的な方法はあとで解説する。家庭にインターネットを引くと、業者からホームルーターが提供される。これまでに僕が扱ってきたホームルーターの初期設定は、どれも、家庭内の IP アドレスの範囲は 192.168.0.*
(ここに '*
' は 0
から 255
である)であり、特に 192.168.0.1
はホームルーターのアドレスに設定されている。そこで、我が家の場合には DHCP によって割り当てる動的 IP の範囲を 192.168.0.100
から 192.168.0.249
までに設定している。残りは固定である。
ここでは簡単のために2つのコンピュータ(名前は hebe
と bsd
)から構成されるネットワーク構成を /lib/ndb/local
に反映させることを考える。実際には僕の場合には、この他に多数のコンピュータが /lib/ndb/local
に登場するのだが、ここでは省略されている。
# # files comprising the database, use as many as you like, see ndb(6) # database= file=/net/ndb file=/lib/ndb/local file=/lib/ndb/common # # entries defining the dns root. these will be overridden by any # authentic info obtained from the root. # dom= ns=A.ROOT-SERVERS.NET ns=B.ROOT-SERVERS.NET ns=C.ROOT-SERVERS.NET ns=D.ROOT-SERVERS.NET ns=E.ROOT-SERVERS.NET ns=F.ROOT-SERVERS.NET ns=G.ROOT-SERVERS.NET ns=H.ROOT-SERVERS.NET ns=I.ROOT-SERVERS.NET ns=J.ROOT-SERVERS.NET ns=K.ROOT-SERVERS.NET ns=L.ROOT-SERVERS.NET ns=M.ROOT-SERVERS.NET # # because the public demands the name localsource # ip=127.0.0.1 sys=localhost dom=localhost # # Home system # authdom=local auth=hebe ipnet=local ip=192.168.0.0 ipmask=255.255.255.0 ipgw=192.168.0.1 sys=bsd ether=6805ca00fc34 ip=192.168.0.2 dom=bsd.local proto=tcp sys=hebe ether=6805ca00fbd2 ip=192.168.0.6 dom=hebe.local proto=tcp fs=hebe
図1: Plan9 network database
このファイルは DNS サービスと DHCP サービスに使われる。
(それだけでなくネットワークに関する全ての情報がここで一括管理されている)
DHCP サービスは dhcpd
が行う。
このサービスは1セグメントに1つだけであり、重複してはならない。Plan9 のネットワークの場合には、ファイルサーバーがこれを行う。動的 IP の範囲を 192.168.0.100
から始めて、連続した 150 アドレスに設定するには
ip/dhcpd 192.168.0.100 150
/rc/bin/cpurc
はサーバーの初期化プロセスのために存在するのであるが、ここには一切手を加えないのが良い。ここは完全に配布者に任せるべきである。良い方法はサーバに名前を与えて、名前ごとに初期化が行われることである。
ファイルサーバーの名前(sysname
)を hebe
としよう。Plan9 の場合には、hebe
のためだけの初期化ファイルとして、目的ごとに
/cfg/hebe/cpurc
/cfg/hebe/service
/cfg/hebe/cpustart
/rc/bin/cpurc
の中で参照されている。dhcpd
の場合には cpustart
で起動すればよいはずである。
以前には他に /rc/bin/cpurc.hebe
も可能であったが、今は廃止されている。
既に端末としての Plan9 が動いていると仮定する。
すると
ls /dev/sd[C-F]*
9fat
が見えているはずである。これは DOS ファイルシステムであり、その内容を見るには9fs 9fat
hebe# dos: mount -c /srv/dos /n/9fat '#S/sdE0/9fat' mount -c /srv/dos /n/9fat '#σ/usb/sdUd6220.0/9fat' hebe#コマンド
dos:
は単にマウントのやり方を教えてくれる。この例のように usb も調べてくれる。さらに、9fat だけでなく普通の DOS パーティションのマウント方法も教えてくれる。表示されたものの中から好きなものを選べばよい。
この中に plan9.ini
が存在する。この内容の例を示す:
bootfile=9pc64 bootargs=local!/dev/sdE0/fscache -a tcp!*!564 #nobootprompt=local!/dev/sdE0/fscache -a tcp!*!564 nvram=/dev/sdE0/nvram mouseport=ps2intellimouse monitor=vesa vgasize=1920x1080x16 fs=192.168.0.6 auth=192.168.0.6 service=cpu fileserver=cwfs timezone=JST 32400 JST 32400 fsmempercent=50 sysname=hebe
plan9.ini
Plan9 のシステムが立ち上がるときに、役に立つ情報が plan9.ini
から読み取られる。
service=cpu
として立ち上げると NVRAM の設定をどうするか尋ねられるだろう。次の解説を見よ。
plan9.ini
の置き場所としては他にいくつかの選択肢があるが、ここでは詳細に立ち入らない。
IPv6 に問題があることに気付いた。原因は、今回のリリース(2021)にある可能性が高い。以前は働いていたのだ。
/lib/ndb/local
に IP アドレスを設定する。1つの ether
に対して複数の IP が指定されてよい。しかしややこしくなる。実際に問題になっているのは次のような例である:
(a) ip=192.168.0.6 (b) ip=2402:6b00:7e7a:6200::6 (c) ipv6=2402:6b00:7e7a:6200::6 (d) ipv6=2402:6b00:7e7a:6200:76d4:35ff:fe87:6245これらは1つの
ether
、 従って1つの sys
に割り当てられている。ipv6
が必要なのだろう? アドレスをみれば v4 か v6 の判別はつくはずではないか? マニュアル(NDB(6))を見るに DNS サービスとの関係らしい。実際 (b) の形式は DNS で無視されている1。
ここに挙げた IPv6 アドレスの左半分は接続業者が決める。右半分はこちらが決める。(d) の形式では、右半分は MAC アドレスを基にシステムが決める。そして、これがシステム内のネットワークで重要な役割を果たしている2。それゆえ /lib/ndb/local
に書かなくても、システムはこのアドレスを理解し、動いてくれる。(d) はある意味ではシステムにとってプライベートな情報で、外部に公開する必要はないはずである。従って (c) の形式で /lib/ndb/local
に書けばよいはずである。この形式は管理しやすく、多くの人が推奨している。
なお IPv6 で "::6
" にしているのは単に v4 アドレスの ".0.6
" から類推しやすいからである。
ところが我がシステムは (c) 形式のアドレスは、なぜか受け取れない3。多分バグだろう。次のリリースに期待しましょう。
補注: /lib/ndb/local
の情報を基に自動的に設定されるべきだと思うが、現状では次の補助的な操作が必要である:
hebe% ip=2402:6b00:7e7a:6200::6 hebe% ip/ipconfig ether /net/ether0 add $ip /64これによって
hebe
は "$ip
" で指定された IP を受け付けてくれる。"/64
" は省けない。lib/ndb/local
はsys=hebe ether=6805ca00fbd2 ip=192.168.0.6 ip=2402:6b00:7e7a:6200::6 ipv6=2402:6b00:7e7a:6200::6 dom=hebe.local proto=tcp fs=hebeにしておく。
/net/ipifc/0/status
が interface 管理に関する重要な情報を与えている。
取り消しは
hebe% ip=2402:6b00:7e7a:6200::6 hebe% ip/ipconfig ether /net/ether0 remove $ip /64である。"
/64
" は省けない。
以上のことは man IP(3) に詳しい。
/net/iproute
および /net/ipselftab
を見よ
netaudit
コマンドがある。困ったときに役に立つかも知れない。meg% netaudit env var $sysname=meg looks ok checking this host's tuple: sys=meg looks ok ip=192.168.0.10 looks ok ip=2402:6b00:7e7a:6200::10 looks ok dom=meg.local looks ok ether=001b21d5a3e9 looks ok checking the network tuple: we are in ipnet=local ipgw=192.168.0.1 looks ok dns=hebe looks ok auth=hebe looks ok fs=hebe looks ok checking auth server configuration: we are not the auth server(s): hebe if this is a mistake, set auth=meg or auth=meg.local run auth/debug to test the auth server meg%
/lib/ndb/dhcp
/sys/log/ipboot
Plan 9 は分散 OS である。
サーバーを、
NVRAM には次の情報が含まれる:
host owner は default では glenda であるが、誰でもよい。僕の場合には arisawa に設定している。この方が便利だから... この設定がどのように使われるかは、ps
コマンドを実行してみれば解る。
des key は host owner の password から生成される。password 長は8文字以上を与えるべきである。7文字以下の password から生成された des key からは、容易に元の password を導ける。
secstore を使わないなら secstore key は持たなくてもよい。
auth domain は /lib/ndb/local
に使われているものを設定する。
僕の場合には我が家のサーバー群は local domain として設定されている。それらに対して認証を行いたいのであれば local に設定する。
従って NVRAM によって
NVRAM の作成に失敗しても、破滅的にはならない。もう一度立ち上げると、再度 NVRAM の入力を求められるはずである。以下にもっと詳しい解説を加えておく。
NVRAM の置き場所は
PC の場合には(ATAを使っているとして)
/dev/sdXN/nvram
/dev/sdXN/9fat
/dev/fdNdisk
# floppy diskX
は C
,D
,E
,F
N
は 0,1
注意: /dev/nvram
が見えるが、これは関係ない。
文献[1]を見ると、plan9.ini
の中に
nvram=...
nvram=/dev/sdE0/nvram
nvram=/dev/sdE0/9fat # same as nvram=/dev/sdE0/9fat!plan9.nvr nvram=/dev/sdE0/9fat!xxx # xxx is a file name in root dir in 9fat
nvram=plan9.nvr
は NG.
plan9.ini
に nvram
の指定がない場合、9fat partition を
/dev/sdC0/9fat ... /dev/sdF0/9fat ... /dev/fd0disk /dev/fd1disk
plan9.nvr
があればそれを使う
なお文献[1]では /dev
とはしないで #S
としている。この段階ではファイルシステムが未完成だからである。
USB に NVRAM を置く場合には、plan9.ini
で明示的に置き場所を指定しなくてはならない。
Plan9 や 9front のインストラクションを読むと、いきなり本物の NVRAM を作っている。しかし感心しない。ここでは安全な NVRAM の作り方を紹介する。
練習のつもりで、一旦 ramdisk に NVRAM を作り、気に入ったら /dev/
のnvram
にコピーする。
以下で、"hebe#
" はサーバーのプロンプトである。
hebe# ramfs hebe# cd /tmp hebe# dd -if /dev/zero -of nvram -bs 512 -count 1 1+0 records in 1+0 records out hebe# ls -l --rw-rw-r-- M 44720 arisawa arisawa 512 Sep 10 16:57 nvram hebe# nvram=nvram auth/wrkey bad nvram des key bad authentication id bad authentication domain authid: arisawa authdom: local secstore key: password: # blackcat hebe% xd -c -r nvram 0000000 b v x bc 1e 87 e9 a3 00 00 00 00 00 00 00 00 0000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \t a 0000020 r i s a w a 00 00 00 00 00 00 00 00 00 00 0000030 00 00 00 00 00 00 00 00 00 00 00 f1 l o c a 0000040 l 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000060 00 00 00 00 00 00 00 00 00 00 00 00 14 e8 = c4 0000070 f9 87 | ; 06 8c 97 N fd 12 a6 ab i i 00 00 0000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 * 0000200 0000200 hebe%
ramdisk での nvram の作成に慣れたら (/dev/sdE0/nvram
に作るとして)
cp nvram /dev/sdE0/nvram
なお、ramdisk に作業用の NVRAM を作ったのは、安全な場所だからである。(ディスク上に作ると、消すのを忘れる)
補注: 現在の rwkey は問題を抱えている。/dev
に直接作ると、古いデータのゴミを残すのである。それでも実際には問題なく動作するのでバグとまでは言えないが、感心しない。NVRAM の下方に見える
14 e8 ...
/adm/keys
で使われている。
[1] /sys/src/libauthsrv/readnvram.c
[2] man authsrv(2)
Plan9 のサーバーを持っていると使い方の幅が広がる。僕のように Web のサーバーとは言わなくても、Plan9 サーバーは、NAS の代わりとしても、バックアップサーバーとしても優秀である。
ここでは最初に、MacBook を Plan9 サーバーにバックアップして行くことを考える。drawterm を使う。drawterm で Plan9 サーバにアクセスすると、サーバー側のファイルとクライアント(MacBook)側のファイルが一つのファイルシステムとして統一されて見える。MacBook のファイルは
/mnt/term/Users/arisawa/....
MacBook を使っている折を見て、時々バックアップのためのコマンドを投入する。バックアップは保険のようなものである。保険に過度な労力を使うことはなかろう。割り切ろう。
何もかもサーバー側にバックアップする必要はない。バックアップに値するファイルを判断するのは我々である。いつでもネットから取り寄せられるファイルはバックアップの価値がない。バックアップに値するのは、自分で作ったファイルだけであると言っても過言ではないだろう。僕はそのようなファイルをいくつかのフォルダーの中に置いている。それらの中のファイルの個数はそれほど多くはならない。僕の場合には、合わせても、せいぜい1万個程度である。
何か調べ物をすれば膨大な小さなメモのようなファイルが発生する。それらは大切な作業メモであるから、あとで簡単に検索できる必要がある。検索の問題に関しては、それ独自の議論が必要である。Mac の Spotlight は多くの問題を抱えている。それらも合わせて議論したい。
以下で紹介する backup は、次のツールを使っている
lr
9xa
cpdir
http:/netlib/cmd
に置いてある。
以下、mbook を MacBook の名前とする。mbook の $HOME
下の
adm bin doc info issues lib src
/usr/backup
に作るとする。hebe% cd /usr/backup/mbook hebe% ls -l d-rwxr-xr-x M 35548 arisawa arisawa 0 Oct 11 17:54 adm d-rwxr-xr-x M 35548 arisawa arisawa 0 Oct 11 17:24 bin --rwxr-xr-x M 35548 arisawa adm 356 Oct 11 18:41 brun d-rwxr-xr-x M 35548 arisawa adm 0 Aug 19 09:58 dist d-rwxr-xr-x M 35548 arisawa arisawa 0 Oct 11 17:29 doc d-rwxr-xr-x M 35548 arisawa adm 0 Apr 15 2017 info d-rwxr-xr-x M 35548 arisawa adm 0 Jul 15 12:38 issues d-rwxr-xr-x M 35548 arisawa adm 0 Jun 24 2017 lib d-rwxr-xr-x M 35548 arisawa adm 0 Jul 12 05:57 log d-rwxr-xr-x M 35548 arisawa adm 0 Oct 11 17:32 src hebe%
brun
は backup を取るためのサーバー側のスクリプトである。
hebe% cat brun #!/bin/rc # exec on hebe using drawterm # cd /usr/backup/mbook # brun # rfork e t=`{lr -nld 0 brun} last=$t(5) # mtime of brun from unix epoh echo $last slist=(adm bin doc src lib info log issues) s=/mnt/term/Users/arisawa for(d in $slist) lr -pft $last $s/$d/ | grep -v '\.dmg$' | 9xa cpdir -vm -x ../xlist $s/$d $d touch brun # the last brun hebe%
brun
の中にはバックアップを効率よく行うための工夫がある。
brun
を実行した時刻が brun
の time stamp として記録されている。次回の backup は、それ以降に変更された mbook 側のファイルに対して行えばよい。
それらは極く僅かである。
ls
コマンドには、時刻を unix epoh で表すオプションがない。lr
は再帰的にディレクトリの情報を表示する。これには、このオプションがある。また lr
は与えられた時刻以降に変更されたファイルだけを表示するオプションがある。
9xa
は Plan9 用の xargs
である。これと cpdir
を組み合わせて、ファイルのコピーを行っている。僕 adm
の中にある db.dmg
はバックアップの対象から外している。これはトップシークレットの情報が含まれる暗号化された Mac のファイルであり、管理を別にしている。こういうのは USB disk で管理するのが一番良いのだ。さらにこれを backup の対象から外したい理由がある。dmg ファイルは、中を見ただけで、time stamp が更新する。大きなファイルだけに非常に嫌だ。
/usr/backup/xlist
は backup から排除したいファイルパターンを指定する。僕の場合には
*/tmp/* */._* */.Trash* */.Rhistory */.Rdata */.CFUserTextEncoding */.DS_Store */.Spotlight-V100/* */.TemporaryItems/* */.HFS+* ._* .Trash* .Rhistory .Rdata .CFUserTextEncoding .DS_Store .Spotlight-V100/* .TemporaryItems/* .HFS+*となっている。これらは Plan9 を mbook にマウントしたときに作られた Mac の拡張属性である。こういうものは要らない。
注意: 最初の backup は
touch -t 0 brun
Plan9 上のファイルは、自動的に Plan9 の backup システムに乗る。従って、history
コマンドによって変更履歴を追って行ける。
僕は FreeBSD のサーバーと Linux(Ubuntu) のサーバーを家庭内で運営している。インストールした後に、メモをサーバー内に残すのであるが、蓄積されない。理由は簡単で、OS のバージョンアップのたびに、システムの調子がおかしくなり、フレッシュインストールを余儀なくされてきたからである。僕が作った文書のバックアップをちゃんと取っていれば後で苦労はしなかったであろうが、良い方法は持っていなかった。
もっとも僕の場合には、mbook 側から ssh と sshfs を使って Linux や FreeBSD を使うことが殆どである。その場合にはメモは mbook 上に残される。しかし本当は Linux や FreeBSD 上に残したほうが良いのだ。なぜなら直接操作しているときに mbook のメモは見れない。それに一般論としては、文書はオブジェクトに貼り付けるべし。
これまで、Plan9 は OpenSSH2 のサポートが弱くて ssh も sshfs も使えない場面が多かった。ところが今回、気が付いた。9front で OpenSSH2 がサポートされていて、ssh と sshfs がちゃんと動くのである。Cinap に感謝。sshfs が使えれば Plan9 側に容易に backup できる。
次は raspi
用に作ったもの。
hebe% cd /usr/backup/pi hebe% cat brun #!/bin/rc # exec on hebe # cd /usr/backup/pi # sshfs -m /n/pi -r / pi # brun # rfork e slist=(bin db doc src lib info log issues) for(t in $slist) cpdir -vm -x ../xlist /n/pi/home/pi/$t $t hebe%
mbook に比べて非常に簡単になっているのは、バックアップするファイルの個数が少ないからである。
FreeBSD の sshd は何故か古い。アクセスにパスワードの入力が求められる。
Ubuntu では factotum が使える。つまりパスワードの入力の手間が省ける。
この違いは重要である。Ubuntu の場合には cron job でバックアップが自動化される可能性があると言うことである。
今日、多数のレンタルサーバーが動いている。それらのバックアップシステムとして Plan9 が利用できないか、研究する価値があるのではないだろうか? うまく行けば、ユーザーから喜ばれるだろう。
Linux のバックアップには Linux サーバーを使ったら? ダメだろう。手入力でのパスワードが cron job の障害になる。
ネットワーを通じて OS をブートアップするために、現在ではどのマザーボードにも PXE boot の仕組みが準備されている。小さな OS であれば、この仕組を使って、多数の端末を均一に動かすことが可能である。
仮に大学の実習室がディスクレスの PC で運営できれば、どれほど管理が楽になるか? 一番故障しやすい部品を持たない。PC ごとに環境が均一になる。全ての PC は一箇所で管理できる。
大学でなくても、工場の PC では、このようなニーズは高いだろう。工場でなくても、事務所の PC も同様である。
残念ながら、現在普及している OS の kernel は大きすぎて、PXE boot での実行は困難を伴うはずである。さらに PXE boot ができたとしても、 OS 自体のネットワークへの対応は貧弱である。Plan9 は PXE boot に対応する理想的な OS である。
Plan9 の場合にはファイルサーバーの側に
Plan9 の本格運用では、複数のサーバーを立ち上げる必要がある。その場合、ファイルサーバーを立ち上げておいて、認証サーバーも CPU サーバーも、Plan9 端末も PXE boot で動かす。以下では端末を想定する。
/lib/ndb/local
/cfg/pxe/*
BIOS の設定は危険な作業であり、自信がなければ止めたほうが良い。廃棄覚悟で、まずは練習。目標はブートの順序の設定である。PXE を先頭に置く。
PC が立ち上がると ether の MAC アドレスが表示される。メモをとる。
/lib/ndb/local
我が家のシステムを例にとる。maia を Plan9 端末とせよ。/lib/ndb/local
に次のエントリーを入れる。
sys=maia dom=maia.local ether=6805ca0a0bf2 ip=192.168.0.3 bootf=/386/9bootpxe"
ether=
" の値は maia の MAC アドレス、"ip
=" は IP アドレスで好みのものを設定する。ただし 192.168.0.0
、192.168.0.1
、192.168.0.255
はダメ。DHCP で動的に割り当てる IP アド レスの範囲の外に置く。我が家では 192.168.0.100
から 192.168.0.250
までを動的に割り当てている。そのための具体的な方法は後に述べる。
amd64
kernel を使うのであるが、bootf
は 386
を使う。ブートの初期は 386
モードゆえ。
/cfg/pxe/*
/cfg/pxe/6805ca0a0bf2
bootfile=/amd64/9pc64 fs=192.168.0.6 auth=192.168.0.6 bootargs=tcp mouseport=ps2intellimouse monitor=vesa vgasize=1920x1080x16 service=terminal timezone=JST 32400 JST 32400 user=arisawa cpu=hebeこれは設定の1例である。
cpu=hebe
は必須ではない。192.168.0.6
は hebe
の IP である。OS がまともに動いていない段階で端末に与えられる情報であるから、fs
も auth
も IP で指定する必要がある。他方 cpu=hebe
は OS が立ち上がって、環境が整い、cpu
コマンドの実行を楽にするための環境変数であり、端末の立ち上がりには関係なく、サーバー名を名前で与えることができる。user=arisawa
を省略すると user=glenda
が想定される。
古い PC の PXE loader 例えば
Intel UNDI, PXE-2.0 (build 082)
9bootpxe+
が受け取れないと言って error になる。
対策: /386
に 9bootpxe
のコピー 9bootpxe+
を置けば解決する
Plan9 端末はディスクレスで動くのであるから、MB (mother board) から HD (hard disk) を切り離し、残りのハードウェアの診断に使える。僕もこの間、この方法でいくつかのトラブルを解決した。
こわ~いプログラムの実行環境として理想的である。何しろハングしても、リセットすれば足りる。ディスクを痛めることはない。
HD を取り付けたまま、PXE boot を第一 boot に設定すれば、立ち上がらない原因が判るかも知れない。
ここでは Plan9 を載せた起動可能な usbdisk は 9front の配布版
9front-xxxx.iso
Mac を例にとると、不要な usbdisk (1GB あれば十分)を差し込んで
mbook$ diskutil list ... /dev/disk3 (external, physical): #: TYPE NAME SIZE IDENTIFIER 0: FDisk_partition_scheme *2.0 GB disk3 1: 0x39 2.0 GB disk3s1 mbook$ sudo dd if=9front-xxxx.iso of=/dev/disk3 bs=512 mbook$これでおしまい!
of=/dev/...
" のところを間違わないように!diskutil list
" の違いに着目してもよい。/dev/disk*
も挿入の前後で違いが発生する。
インストール用の usbdisk 自体が、起動可能な usbdisk となっている。しかし、この usbdisk はインストール用に特化していて、お試し版としてある程度のことはできるが、これを元にして個人の好みを反映させようとすると難儀する。以下では勉強を兼ねて、他の方法を採る。
目標は 起動可能な usbdisk に Plan9 を載せ、完全に usbdisk 上で Plan9 を動かす事にある。昔、Plan9 の live CD 版があったが、それの usbdisk 版である。何しろ現在では usbdisk は安く、いくつも周りに散らばっていで、容量の小さなものは廃棄される時代である。ここで作る usbdisk は 2GB でも可能であったが、何回も何回もやり直しているうちに、disk full になってしまった、4BG あれば十分だろう。
僕がこのようなものを作ろうと思ったのは、ネットワークは不調、HD からも立ち上がらない古い PC の診断のためである。FreeBSD は black screen になる。昔どこかで使っていた Plan9 の HD も立ち上がらない...
なぜか、このところ、長年使ってきた2つの PC が立て続けにダメになった。重症らしく、廃棄することとした。そのために我が家の PC が不足気味になって、古いものを引っ張り出したのである。
なおこの記事は、Plan9 の HD を入れ替えるときに役に立つはずである。
以下はメモである。英文のメモだが、そのまま書く。
goal:
4GB usbdisk bootable 9front with 9pc64 kernel
assumption
you are working on the "pxe booted terminal".
The instructions below are based on 9front(2021) with 9pc64 kernel.
term% ls /dev/sdU* /dev/sdU5075c/ctl /dev/sdU5075c/data /dev/sdU5075c/esp /dev/sdU5075c/raw term% sdu=sdU5075c term% disk/mbr -m /386/mbr /dev/$sdu/data term% disk/fdisk -abw /dev/$sdu/data term% ls /dev/$sdu # confirmation /dev/sdU5075c/ctl /dev/sdU5075c/data /dev/sdU5075c/plan9 /dev/sdU5075c/raw term% disk/prep -bw -a^(9fat nvram fscache fsworm other swap) /dev/$sdu/plan9 9fat 204800 nvram 1 other 1070616 swap 204800 fscache 1070616 fsworm 5353084 term% ls /dev/$sdu # confirmation /dev/sdU5075c/9fat /dev/sdU5075c/ctl /dev/sdU5075c/data /dev/sdU5075c/fscache /dev/sdU5075c/fsworm /dev/sdU5075c/nvram /dev/sdU5075c/other /dev/sdU5075c/plan9 /dev/sdU5075c/raw /dev/sdU5075c/swap term% disk/format -b /386/pbs -d -r 2 /dev/$sdu/9fat /386/9bootfat /amd64/9pc64 add 9bootfat at clust 2 add 9pc64 at clust 4 Initializing FAT file system type hard, 12 tracks, 255 heads, 63 sectors/track, 512 bytes/sec Adding file /386/9bootfat, length 7960 add 9bootfat at clust 2 Adding file /amd64/9pc64, length 5228965 add 9pc64 at clust 4 used 5242880 bytes term% mount -c /srv/dos /n/9fat '#σ/usb'/$sdu/9fat # confirmation term% ls /n/9fat /n/9fat/9bootfat /n/9fat/9pc64 term% # you need to add your plan9.ini
my /tmp/plan9.ini
bootfile=9pc64 bootargs=local!/dev/sdU5075c/fscache -a tcp!*!564 # we need 564 not 9fs # usb boot is an emergency use. so avoid nobootprompt mouseport=ps2intellimouse monitor=vesa vgasize=1280x1024x16 fs=192.168.0.6 cpu=192.168.0.6 auth=192.168.0.6 #service=cpu service=terminal fileserver=cwfs timezone=JST 32400 JST 32400 fsmempercent=50 user=arisawa
cp /tmp/plan9.ini /n/9fat
term% cwfs64x -csC -f /dev/sdU5075c/fscache config: config /dev/sdU5075c/fscache config: service cwfs config: filsys main c(/dev/sdU5075c/fscache)(/dev/sdU5075c/fsworm) config: filsys other (/dev/sdU5075c/other) config: filsys dump o config: noauth auth disabled config: ream other config: ream main config: end current fs is "main" cmd_users: cannot access /adm/users 63-bit cwfs as of Tue Sep 21 22:49:33 2021 last boot Fri Oct 8 15:25:42 2021 term%確認:
term% ps # confirmation ... # many cwfs64x term% ls /srv # confirmation ... /srv/cwfs /srv/cwfs.cmd term% xd -c /dev/$sdu/fscache |p # confirmation 0000000 s e r v i c e c w f s \n f i l 0000010 s y s m a i n c ( / d e v / 0000020 s d U 5 0 7 5 c / f s c a c h e 0000030 ) ( / d e v / s d U 5 0 7 5 c / 0000040 f s w o r m ) \n f i l s y s o 0000050 t h e r ( / d e v / s d U 5 0 0000060 7 5 c / o t h e r ) \n f i l s y 0000070 s d u m p o \n n o a u t h \n 0000080 n e w c a c h e \n b l o c k s i 0000090 z e 1 6 3 8 4 \n d a d d r b i 00000a0 t s 6 4 \n i n d i r b l k s 00000b0 4 \n d i r b l k s 6 \n n a m e 00000c0 l e n 1 4 4 \n 00 00 00 00 00 00 00 00 00000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00q term%
停止:
term% echo halt >> /srv/cwfs.cmd halted at Fri Oct 8 15:44:36 2021. # need ENTER here term% ps # confirmation ... # no cwfs for /dev/$sdu term% ls /srv ... # no cwfs nor cwfs.cmd term%
now we can invoke cwfs64x
by
term% cwfs64x -sC -f /dev/sdU5075c/fscache current fs is "main" cmd_users: cannot access /adm/users 63-bit cwfs as of Tue Sep 21 22:49:33 2021 last boot Fri Oct 8 15:29:38 2021 term%NB: in invoking
cwfs64x
, drop "-c
":
we need to register users in prior to mount the fs
/usr/arisawa/doc/cwfs/newcwfs
assumption:
* cwfs is running
cwfs has a user table in memory.
authentication follows this table.
/adm/users
is the back up file.
term% con -C /srv/cwfs.cmd # the commands below are one time action users default # register default users. "adm" is in them. create /adm adm adm 775 d create /adm/users adm adm 644 newuser arisawa create /usr/arisawa arisawa arisawa 755 d create failed in walkto: arisawa # ctrl-\ + ENTER to exit >>>q # q to exit term%the error message says: failed to create /usr/arisawa
now we can mount and can use regular tools of Plan9.
term% mount -c /srv/cwfs /n/cwfs term% ls /n/cwfs /n/cwfs/adm term% cat /n/cwfs/adm/users -1:adm:adm: 0:none:adm: 1:tor:tor: 2:arisawa:arisawa: 10000:sys:: 10001:map:map: 10002:doc:: 10003:upas:upas: 10004:font:: 10005:bootes:bootes: term%
NB: any user can make the fs "allow mode" because auth is diabled by config.
it is assumed we are in clean world.
auth is complicated process. I donn't recommend auth for usb disk.
In real world, fs should run with auth enabled.
Then enter again config mode. run fs with "-c" flag, and then
config: noauth auth enabled config: end
NB: noauth is toggle switch, I dislike though.
assumption: cwfs is running and mounted on /n/cwfs
we need in "allow mode":
echo allow >> /srv/cwfs.cmd
Let's copy files to the usbdisk.
Make ready a prototype file
usbfsproto
http:usbfsproto
some of live files will be exported to the usbdisk.
these may be OK or NG.
after building namespace in the usbdisk, you can remove files that you donn't want to have in the usbdisk
term% disk/mkfs -s /root -d /n/cwfs usbfsproto processing usbfsproto file system made term%
proto examples:
/sys/lib/sysconfig/proto/*
error: "no frame buffer
"
I have consumed much time for this error.
suspect:
$monitor
or $vgasize
. look $monitor
or $vgasize
memory
command/sys/src/9/port/devdraw.c
try to set vgasize the smallest and do again.
command "memory
" on gaia to see what happend. the result:
total 7.96 GB total kernel 2 GB total user 5.77 GB used user 24.8 MB used kernel 6.16 MB used draw 0 BI have much memory.
black screen は VGA 出力で発生しやすい。HDMI や DVI と違って VGA は one way である。MB がサポートしている解像度と、ディスプレイがサポートしている解像度との交渉は、VGA ではやる余地がない。そして一致していないと black screen となる。従って black screen でうまくいかない時には DVI か HDMI ポートを試してみる価値がある。
我々は MB がサポートしている vgasize
の値を知り、それに基づいて vgasize
を設定するる必要がある。マニュアルによれば、この問題は aux/vga
コマンドで扱われるはずであるが、どうしたわけかバグがあって上手く行かない(2021)。
次のスクリプトは、この問題を扱う。
#!/bin/rc rfork e fn usage{ echo 'usage: vgasetup' echo 'usage: vgasetup [-t] vgasize' exit } [中略] @{rfork n; aux/realemu; aux/vga -m $monitor -l $1}
http:vgasetup
次のように使う:
term% vgasetup vgasetup 1280x1024x8 m8 packed vgasetup 1280x1024x16 r5g6b5 direct vgasetup 1280x1024x32 x8r8g8b8 direct vgasetup 1024x768x8 m8 packed vgasetup 1024x768x16 r5g6b5 direct vgasetup 1024x768x32 x8r8g8b8 direct vgasetup 640x480x32 x8r8g8b8 direct vgasetup 800x600x16 r5g6b5 direct vgasetup 800x600x32 x8r8g8b8 direct vgasetup 640x480x8 m8 packed vgasetup 800x600x8 m8 packed vgasetup 640x480x16 r5g6b5 direct vgasetup 1920x1080x8 m8 packed vgasetup 1920x1080x16 r5g6b5 direct vgasetup 1920x1080x32 x8r8g8b8 direct your vgasize: 1920x1080x16 term% vgasetup 1280x1024x16 term%これで成功すれば、グラフィックスモードに入り、マウスが使える。サイズの小さい方から試すのが無難かも...
一応テストオプション "-t
" を持っている。5秒間テストして、元に戻す。
vgasetup
の重要なコードは、Cinap のものを借用している。
USB ポートは USB2/USB3 の青色ポートを使う。この方が断然速い。9front はまだ USB3 をサポートはしていないけど...
USB だと動きがもっさりして使い物にならないかと思っていた。立ち上がりは確かに遅いのだか、一旦立ち上がってしまえば、サクサクと気持ちよく動く。
ポータビリティも良い。ただし BIOS で usb first にセットしなくてはならないので、他人の PC では使えない。
古い PC を扱うときには、i386 モードで動くものも作っておく必要があろう。
今回、この仕事をしていて VESA とか VGA とか、基本的なことがよく解っていないことに気付いた。定義(仕様書)はどこにあるの? 教えて貰えたら幸いです。
ところで僕の英文は下手だし、ひどく broken なのである。例えば
you are working on the "pxe booted terminal".
you are working on the "pxe booted terminal."
.
' をカッコの中に入れなくてはならない。Knuth は『ドキュメント算法』でこの問題に触れていて、「こんなルールは変なのだが要求されている」(趣旨)と述べている。しかし、いくら正しいと言われても、嫌なのである。そんなことを強制されると、意味が誤解される。この問題が RFC の文書の中でどのように扱われているかを調べたことがある。やっぱり僕のようにやっている。扱っている問題によっては、避けられないのだ。昔、英文の論文を書いたときもこの問題に出会って、僕流のやり方を通した。
ファイル管理に役に立つツールを紹介ししておく。多数あるが暇をみて徐々に追加する。
とりあえず "-f
"。
僕が愛用している "-f
" コマンドは
-f cmd arg arg ...
原理は簡単で、cmd
の実行中だけファイルシステムを allow mode にしているだけである。コマンドの内容を次に示す:
-f
Plan9 のファイルサーバーのオーナーは、ファイルサーバーに対して絶対的な権限を有する。それでも通常は permission に従う。unix のように root の下で permission を無視してなんでもやるのではない。そこで unix の世界では、"sudo
" が編み出された。"-f
" は unix の "sudo
" のように振る舞うがパスワードは求められない。プロセスを殺すには使えない。他人のプロセスを殺すのは CPU サーバーのオーナーの仕事である。