FreeBSD 9.3: man コマンド、出力異常

構築済みの 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 の問題は解決。

コメントを残す