約一ヶ月間悩んでいた、「あるときから突然 FreeBSD 9.3 で portsnap を実行すると metadata is corrupt. で /usr/ports の更新を完了できない」というトラブルがようやく解決しました。
# portsnap fetch 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 Sat Sep 3 09:10:09 JST 2016 to Sat Sep 10 11:51:52 JST 2016. Fetching 5 metadata patches. done. Applying metadata patches... done. Fetching 5 metadata files... /usr/sbin/portsnap: cannot open 2cc0c22af8635de9427a30535bf238fc0f7d5d1d634230d208ec3edb9a7b8a80.gz: No such file or directory metadata is corrupt.
結論としては、man コマンドが正常動作しなくなった理由と同じく、システムがクラッシュした影響を受けていたようです。
portsnap コマンドを使用すると、portsnap fetch を実行した時点で “metadata is corrupt.” となる場合があります。portsnap はデフォルトでは /var/db/portsnap にワークファイルを保存して ports を管理していますが、エラーの意味としては、このディレクトリ下のファイルに破損があるということを意味しているようです。
過去に私が管理しているマシンで発生した時は、/var/db/portsnap と /usr/ports を新しくしたら直りました。
今回も同じだろうと、/usr/db/portsnap と /usr/ports を一度削除して構築し治してみたのですが、結果に変化無し。
検索エンジンで検索してみると、/usr/db/portsnap を初期化しても解決しないというレポートが何件か見つかりました。この場合は、/etc/portsnap.conf にある OSバージョンと一致しないINDEXをコメントアウトすることが解決策になると書かれていました。
# List of INDEX files to build and the DESCRIBE file to use for each #INDEX INDEX-7 DESCRIBE.7 #INDEX INDEX-8 DESCRIBE.8 INDEX INDEX-9 DESCRIBE.9 #INDEX INDEX-10 DESCRIBE.10
やってみましたが、症状に変化無し。
portsnap fetch はエラーで終わりますが、portsnap update は、ダウンロード出来た範囲の ports 更新をインストールすることが出来ますので、手間ではありますが毎回手作業で更新すれば ports をメンテナンスすることは出来ます。それに ports はパッケージのオプションを変更したい場合に活用するので、気にはなるものの、バイナリーメンテナンスはできるので、しばらく我慢することが出来ていました。
portsnap サーバーに実際にファイルが欠けているんじゃないの?と当初は思ったものの、これだけ長い期間コマンドが失敗して、portsnap サーバー管理者が気づかないわけ無い。自分のサーバーに問題があるはず・・・と、先週から、再度いろいろ試しています。
今回の症状で気づいたことは、
cannot open 2cc0c22af8635de9427a30535bf238fc0f7d5d1d634230d208ec3edb9a7b8a80.gz: No such file or directory
という .gz ファイル名が毎回変わること。
「06b16e3b46d0ffdaee42fe80df8fcd811a17d6e8aeb7aa5447303b64342d10be.gz: No such file or directory」だったり、「30aeacb152126162a90796d60256d77164394b67860af25bf6342da7dc7ae2b6.gz: No such file or directory」だったり。
また、正常なサーバーの /var/db/portsnap は、
# ll /var/db/portsnap/ total 4600 -rw-r--r-- 1 root wheel 2272309 9月 10 12:38 INDEX drwxr-xr-x 2 root wheel 2314752 9月 10 12:41 files/ -rw-r--r-- 1 root wheel 451 9月 3 11:58 pub.ssl -rw-r--r-- 1 root wheel 272 9月 10 12:36 serverlist -rw-r--r-- 1 root wheel 272 9月 10 12:36 serverlist_full -rw-r--r-- 1 root wheel 45 9月 10 12:36 serverlist_tried -rw-r--r-- 1 root wheel 758 9月 10 12:36 tINDEX -rw-r--r-- 1 root wheel 85 9月 10 12:36 tag
というディレクトリ構成ですが、エラーが出るサーバーは以下のように
total 4552 -rw-r--r-- 1 root wheel 2270119 9月 3 12:00 INDEX -rw-r--r-- 1 root wheel 325 9月 10 03:30 filelist drwxr-xr-x 2 root wheel 2249216 9月 3 09:24 files -rw-r--r-- 1 root wheel 650 9月 10 03:30 patchlist -rw-r--r-- 1 root wheel 451 9月 3 11:58 pub.ssl -rw-r--r-- 1 root wheel 272 9月 10 03:30 serverlist -rw-r--r-- 1 root wheel 272 9月 10 03:30 serverlist_full -rw-r--r-- 1 root wheel 45 9月 10 03:30 serverlist_tried -rw-r--r-- 1 root wheel 758 9月 3 11:58 tINDEX -rw-r--r-- 1 root wheel 758 9月 10 03:30 tINDEX.new -rw-r--r-- 1 root wheel 85 9月 3 11:58 tag -rw-r--r-- 1 root wheel 85 9月 10 03:30 tag.new
となり、ファイル数が違います。ちなみに、No such file となるファイル名は、filelist に記述されていると判明。
ここまで症状を特定できたものの、その後は進展無しで堂々巡り。
昨日、お風呂に入っている時ひらめきました。そうだ、デバッグオプションだ!
お風呂から出た後、FreeBSDサーバーに接続し、「man portsnap」としてみると・・・・・
NAME portsnap — fetch and extract compressed snapshots of the ports tree SYNOPSIS portsnap [-I] [-d workdir] [-f conffile] [-k KEY] [-l descfile] [-p portsdir] [-s server] command ... [path] DESCRIPTION The portsnap tool is used to fetch and update compressed snapshots of the FreeBSD ports tree, and extract and update an uncompressed ports tree. In a normal update operation, portsnap will routinely restore modified files to their unmodified state and delete unrecognized local files. This behavior is different to cvs(1) and cvsup(1). OPTIONS The following options are supported: -d workdir Store working files (e.g. downloaded updates) in workdir. (default: /var/db/portsnap, or as given in the configuration file.) -f conffile Read the configuration from conffile. (default: /etc/portsnap.conf) -I For the update command, update INDEX files, but not the rest of the ports tree. -k KEY Expect a public key with given SHA256 hash. (default: read value from configuration file.) -l descfile Merge the specified local describes file into the INDEX files being built. The descfile should be generated by run‐
って、デバッグオプション、無いじゃない・・・・ガックリ。
続けて、バイナリーかスクリプトなのかをチェックしてみることに。
# which portsnap /usr/sbin/portsnap # file /usr/sbin/portsnap /usr/sbin/portsnap: POSIX shell script, ASCII text executable
幸いシェルスクリプトでした。中を見てみると、
# $FreeBSD: releng/9.3/usr.sbin/portsnap/portsnap/portsnap.sh 265753 2014-05-09 08:07:05Z delphij $
#### Usage function -- called from command-line handling code.
# Usage instructions. Options not listed:
# --debug -- don't filter output from utilities
# --no-stats -- don't show progress statistics while fetching files
usage() {
cat <
デバッグオプション あるじゃない!マニュアルに出てこないだけでした。
早速使ってみたところ・・・・
# portsnap --debug fetch Looking up portsnap.FreeBSD.org mirrors... 7 mirrors found. Fetching snapshot tag from ec2-ap-northeast-1.portsnap.freebsd.org... latest.ssl 100% of 256 B 71 kBps 00m00s done. Fetching snapshot metadata... 67ee43e4798e8b7dc9a25eb3e233a7b8ed7d21a35889c0100% of 758 B 206 kBps 00m00s done. Updating from Sat Sep 3 09:10:09 JST 2016 to Sat Sep 10 12:02:42 JST 2016. Fetching 5 metadata patches... /usr/libexec/phttpget ec2-ap-northeast-1.portsnap.freebsd.org tp/ce32d0a6d457444b39208a3850b475b26f5ac0164a969d5031a3935b88a8b166-2cc0c22af8635de9427a30535bf238fc0f7d5d1d634230d208ec3edb9a7b8a80.gz tp/d1637210e8da68fd2ee844f078bf72519add9068dba84c3a1ec5f786f74d73fa-3c5ddcb4c01b05a39fe127db36a7f1408d522a2890237b482293aa8750cb243a.gz tp/d1637210e8da68fd2ee844f078bf72519add9068dba84c3a1ec5f786f74d73fa-3c5ddcb4c01b05a39fe127db36a7f1408d522a2890237b482293aa8750cb243a.gz tp/4edda449f631dc2deddaa5c49af6c4de90d84593a3288ddaee618e93893aa6dc-fdbd7eefbd47edd77664a09b42fdf7d2d1b17db2411ceb58b6d9a6299772510f.gz tp/5869e2b59a225336cf106d8951633d3bc5e9ad4423a48e411e45c7691305ef9a-e7c6df6deeadac159933b740b2ab185c88beb130fd3679675c3812e502c4298c.gz xargs: /usr/libexec/phttpget: No such file or directory done. Applying metadata patches... done. Fetching 5 metadata files... /usr/libexec/phttpget ec2-ap-northeast-1.portsnap.freebsd.org f/2cc0c22af8635de9427a30535bf238fc0f7d5d1d634230d208ec3edb9a7b8a80.gz f/3c5ddcb4c01b05a39fe127db36a7f1408d522a2890237b482293aa8750cb243a.gz f/3c5ddcb4c01b05a39fe127db36a7f1408d522a2890237b482293aa8750cb243a.gz f/fdbd7eefbd47edd77664a09b42fdf7d2d1b17db2411ceb58b6d9a6299772510f.gz f/e7c6df6deeadac159933b740b2ab185c88beb130fd3679675c3812e502c4298c.gz xargs: /usr/libexec/phttpget: No such file or directory /usr/sbin/portsnap: cannot open 2cc0c22af8635de9427a30535bf238fc0f7d5d1d634230d208ec3edb9a7b8a80.gz: No such file or directory metadata is corrupt.
/usr/libexec/phttpget コマンドがエラーを出しているのか〜。では、phttpget コマンドのデバッグオプションを試そうと、phttpget の man を取ろうとしたら、man がない!
# man phttpget No manual entry for phttpget
では、phttpget コマンドの –help オプションを使おうと、「/usr/libexec/phttpget –help」 とすると、phttpget コマンド自体がない!
おいおい。関連コマンドの消失がエラーの原因だったのかよ〜〜〜。ガックリ。コマンドがないのだったらそうとわかるエラーを出して欲しいものです。
確かに、portsnap で問題ないサーバーでは、
# ll /usr/libexec/phttpget -r-xr-xr-x 1 root wheel 14716 8月 27 2015 /usr/libexec/phttpget
と、コマンドが存在しています。原因がわかれば後は簡単。幸い、/usr/src は存在しているので、
# whereis phttpget phttpget: /usr/src/usr.sbin/portsnap/phttpget # cd /usr/src/usr.sbin/portsnap/phttpget # make install install -s -o root -g wheel -m 555 phttpget /usr/libexec/phttpget
これで、やっと portsnap が復活しました。
# portsnap fetch 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 Sat Sep 3 09:10:09 JST 2016 to Sat Sep 10 12:02:42 JST 2016. Fetching 5 metadata patches... done. Applying metadata patches... done. Fetching 0 metadata files... done. Fetching 733 patches.....10....20....30....40....50....60....70....80....90....100....110....120....130....140....150....160....170....180....190....200....210....220....230....240....250....260....270....280....290....300....310....320....330....340....350....360....370....380....390....400....410....420....430....440....450....460....470....480....490....500....510....520....530....540....550....560....570....580....590....600....610....620....630....640....650....660....670....680....690....700....710....720....730. done. Applying patches... done. Fetching 27 new ports or files... done.
1ヶ月前に、OS がクラッシュした時に、/usr 上のファイルが何個か吹っ飛んだのですが、いろいろコマンドやファイルが無くなってしまっているようです。
なんにしても、portsnap fetch がエラーで機能しないという問題は解決しました。困った時はお風呂の中でゆっくり考えるのが私には一番!