構築済みの FreeBSD 9.3 サーバーの安定性テストをしています。
カスタマイズまで済ませて、あとは設置を待つのみで、その間、負荷を掛けて安定動作するかどうかを試していたところ、本日になってなんか変な動作をするコマンドがあることを発見しました。
問題のコマンドとは man コマンド。
コマンドのオプションを知りたくて、オンラインマニュアルを見ようと(例えば)man man と実行してみると、次のように出力されてしまいました。
# man man author(s) stored in cov*au!x!y author(s) stored in cov*au!x!y %Cô¹RÙîºÆõr7)wl=4à±‐The utility finds and displays online manual documentation pages. If is pro‐ vided, restricts the search to the specific section of the manu‐ al. Options that understands: Forces a specific colon separated manual path instead of the default search path. See Overrides the environment variable. Use specified pager. Defaults to if color support is enabled, or Overrides the environment variable, which in turn overrides the environment variable. Restricts man‐ ual sections searched to the specified colon delimited list. De‐ faults to Overrides the environment variable. Display all manual pages instead of just the first found for each argument. Print extra debugging information. Repeat for increased verbosity. Does not display the manual page. Emulate Display short help message and exit. Emulate Override the default architecture and machine settings allowing lookup of other platform specific manu‐ al pages. See for how this option changes the default behavior. Overrides the and environment variables. Force use of non‐local‐ ized manual pages. See for how locale specific searches work. Overrides the and environment variables. Use the list of given preprocessors before running or Valid preprocessors arguments: Overrides the environment variable. Send manual page source through allowing transformation of the manual pages to other for‐ mats. Display the location of the manual page instead of the contents of the manual page. The utility supports manual pages in different locales. The search behavior is dictated by the first of three environment variables with a nonempty string: or If set, will search for locale specific manual pages using the following logic: For example, if is set to will search the fol‐
全てのコマンドに関して、このように、固定長で改行される一列の文になってしまいます。これが、最初からなのか、突然こうなったのかははっきりしませんが、man コマンドは結構頻繁に使うので突然こうなった気がします。
ログインし直しても、OSをリブートしてもダメ。
きっかけとして、朝方、2度に渡りサーバーかリブートした(ログに記録が残っていた)ようで、これが影響している可能性があります。このリブート事件はまだ調査できていませんが、fsck は掛かって、無事に再起動しているので、OSに致命的なエラーは出ていないものと思っています。Boinc で CPUとメモリに負荷をかけ続けているので、温度が上がりすぎたのかな〜。BIOSレベルの温度保護はかけているので、それでリブートしたのかもしれません。とっても安定しているシステムを構築できたと感じていたんですが、ちょっと嫌な気分。
ユーザーを代えたり、シェルを代えたりしてみたのですが、症状に変化無く、いろいろと検索してみたところヒントが見つかりました。
man コマンドには -d というデバッグオプションがあります。
デバッグオプションでコマンドを実行すると、実際にどんなコマンドが発行されているかわかります。
# man -d man -- Using architecture: i386:i386 -- Using pager: more -- Using manual sections: 1:8:2:3:n:4:5:6:7:9:l -- Using locale paths: ja_JP.UTF-8:ja.UTF-8:en.UTF-8:. -- Using standard page width -- Searching for man -- Found manpage /usr/share/man/en.UTF-8/man1/man.1.gz -- Skipping catpage: not found or old -- Command: /usr/bin/zcat /usr/share/man/en.UTF-8/man1/man.1.gz | tbl | groff -S -P-h -Wall -mtty-char -man -Tutf8 -P-c | more
最後のコマンドを正常に動作している FreeBSD と比較してみればいいわけです。
zcat en.UTF-8/man1/man.1.gz | tbl | groff -S -P-h -Wall -mtty-char -man -Tutf8 -P-c | more
このコマンドを最後のコマンドから一つずつ削除して実行してみたところ、
more を削除した時の表示は異常のまま。(ページャーは一時停止制御だけなので、まあそうでしょう。)
次に、groff の部分まで削除して tbl まで実行してみると、この時の出力は、正常なサーバーの出力と同じ。つまり、groff(または groff が読み込んでいる設定) に何か異常が発生したと考えられます。
う〜ん、しかし、man や groff の設定ファイルってどこにあるんだろう? /etc/man.conf は使っていないし、/usr/local/etc/man.d/ の下には、デフォルトの perl5.conf しかありません。
groff に問題があるらしいことが判明したので、/usr/bin/groff じゃなく、/usr/local/bin/groff を使ってテストしてみたところ、次のようにちゃんとフォーマットされた書式で表示されました。
zcat man1/man.1.gz | tbl | /usr/local/bin/groff -S -P-h -Wall -mtty-char -man -Tascii -P-c | more
MAN(1) FreeBSD General Commands Manual MAN(1) NAME man - display online manual documentation pages SYNOPSIS man [-adho] [-t | -w] [-M manpath] [-P pager] [-S mansect] [-m arch[:machine]] [-p [eprtv]] [mansect] page ... man -f keyword ... man -k keyword ... DESCRIPTION The man utility finds and displays online manual documentation pages. If mansect is provided, man restricts the search to the specific section of the manual. Options that man understands:
groff を /usr/src から再インストールするというのが解決策のようなので、/usr/src/gnu/usr.bin/groff に cd して、make install しようとすると、次の状態。
root@pc:/usr/src/gnu/usr.bin/groff # make install ===> contrib (install) ===> contrib/mm (install) install -o root -g wheel -m 444 /dev/null /usr/share/tmac/mm/locale install: /usr/share/tmac/mm/locale: Not a directory *** [beforeinstall] Error code 71 Stop in /usr/src/gnu/usr.bin/groff/contrib/mm. *** [realinstall] Error code 1 Stop in /usr/src/gnu/usr.bin/groff/contrib. *** [realinstall] Error code 1 Stop in /usr/src/gnu/usr.bin/groff.
あっ、/usr/share/tmac/mm がおかしい。
ls コマンドで表示される mm ディレクトリが、ls -l コマンドでは表示されないし、ファイルのパーミッションがおかしいファイルがある!
# ls
X.tmac devtag.tmac html.tmac lbp.tmac mdoc.tmac psatk.tmac troffrc
Xps.tmac doc.tmac hyphen.ru lj4.tmac me.tmac psold.tmac troffrc-end
a4.tmac dvi.tmac hyphen.us m.tmac mm pspic.tmac tty-char.tmac
an-old.tmac e.tmac hyphenex.us man.local ms.tmac s.tmac tty.tmac
an.tmac ec.tmac koi8-r.tmac man.tmac mse.tmac safer.tmac unicode.tmac
andoc.tmac eqnrc latin1.tmac mandoc.tmac papersize.tmac tmac.orig_me www.tmac
composite.tmac europs.tmac latin2.tmac mdoc pic.tmac tmac.vgrind
cp1047.tmac html-end.tmac latin9.tmac mdoc.local ps.tmac trace.tmac
-r--r--r-- 1 root wheel 77724 7月 11 2014 m.tmac -r--r--r-- 1 root wheel 96 7月 11 2014 man.local -r--r--r-- 1 root wheel 36 7月 11 2014 man.tmac -r--r--r-- 1 root wheel 39 7月 11 2014 mandoc.tmac drwxr-xr-x 2 root wheel 512 7月 11 2014 mdoc/ -r--r--r-- 1 root wheel 2761 7月 11 2014 mdoc.local -r--r-Sr-- 1 root wheel 4131 7月 11 2014 mdoc.tmac -r--r--r-- 1 root wheel 31 7月 11 2014 me.tmac -r--r-Sr-- 1 root wheel 31 7月 11 2014 ms.tmac -r--r--r-- 1 root wheel 3538 7月 11 2014 mse.tmac -r--r--r-- 1 root wheel 3959 7月 11 2014 papersize.tmac
OSをシングルユーザーモードで再起動し、強制的に fsck を掛けてみたところ、複数ファイルがサルベージされたりクリアされたりで、/usr/share/tmac/mm ディレクトリは復活したかと思えば、、、、、消えてるじゃん。
pc32:/usr/share/tmac> lsf X.tmac doc.tmac hyphen.us man.local mse.tmac s.tmac troffrc-end Xps.tmac ec.tmac hyphenex.us man.tmac papersize.tmac safer.tmac tty-char.tmac a4.tmac eqnrc koi8-r.tmac mandoc.tmac pic.tmac tmac.orig_me tty.tmac an-old.tmac europs.tmac latin2.tmac mdoc/ ps.tmac tmac.vgrind unicode.tmac cp1047.tmac html-end.tmac lbp.tmac mdoc.local psatk.tmac trace.tmac www.tmac devtag.tmac hyphen.ru lj4.tmac me.tmac psold.tmac troffrc
このあと、mm ディレクトリを作成して、/usr/src/gnu/usr.bin/groff から make install。
無事に man コマンドが復活しました。
というか、今回の fsck はコンソールからしか操作できない状態だったので、気づかずにサーバーを送付して設置してからこの症状に気づいたら大変なことになるところでした。
Metadata is corrupt
余談ですが、その後、portsnap を発行しようとしたら、次の状況に。
# portsnap fetch && portsnap update Looking up portsnap.FreeBSD.org mirrors... 7 mirrors found. Fetching snapshot tag from ec2-ap-northeast-1.portsnap.freebsd.org... done. Fetching snapshot metadata... done. Updating from Sun Aug 14 03:03:59 JST 2016 to Sun Aug 14 22:03:48 JST 2016. Fetching 4 metadata patches. done. Applying metadata patches... done. Fetching 5 metadata files... /usr/sbin/portsnap: cannot open 47b5fddc5aa0cda2718a71f330b1ea0ed918795ce52c6f26668433f57a229d96.gz: No such file or directory metadata is corrupt.
ここにも影響が・・・・・
やむなく、portsnap を初期化 することにしました。
しかし、症状は解決せず。この47b5…….gz というファイルはサーバー側?予期せぬシャットダウンと関係なし??? とりあえずここに書いておくことにしますが・・・
portsnap fetch コマンドを発行すると、現時点で確実に metadata is corrupted となり、発行するタイミングにより、47b5…….xxx.gz ファイルのファイル名が頭から異なっています。以前から継続利用しているサーバーでは発生せず、最近インストールしたものにだけ発生するようです。
ディスク上の bad sector? と考え、portsnap -d オプションで、/var/db/portsnap を別のパーティションに移してみましたが、症状に違いが見られません。別に新規インストールした FreeBSD で比較してみれば何かわかるかもしれませんが、すぐには準備できず。
そして、約1ヶ月の時が流れる……..
原因は man のフォーマットが壊れたことと同様、/usr ディスクの一部ファイルが破損した事によるものでした。phttpget ファイルを /usr/src から修復して portsnap の問題は解決。