May 01, 2008

fsck_hfs Invalid extent entry

サーバが昨日より故障していました。アクセスして戴いた皆様におかれましてはご不便をおかけしました、この度ようやく復活できたようです。

サーバはPowerMac G3(350MHz) + MacOSXの10.2.8で構成してあるのですが、そろそろHDDが寿命のようです、という事情は以前の記事等で察していただけるかと思います。早く新しいMacMiniサーバへ乗り換えたいのですが、なかなかまとまった時間(次のGW4連休がチャンスと睨んでいます)をとることができずに、ずるずる使い続けていました。そしてコトが起こったのです。

コトの発端はバージョン管理を行うCVS(Current Version System)をeclipse上からssh経由(extssh)で使っている際に発生しました。ssh経由での接続には成功するものの、ファイルの同期を行おうとすると、create_adm_p /tmp/cvs-serv(pid)/(dir) : File too large というエラーが表示されます。ディスクには余裕があったので、File too largeの部分に引っかかりながらも、サーバ側のcvsの動作を疑いました。サーバ側のcvsコマンドはソースよりコンパイルしてあったので、状況を追うのは簡単でした。ソースからcreate_adm_pをヒントにエラーの発生箇所を検索します。

find . \( -name "*.c" -o -name "*.h" \) -exec grep -n create_adm_p {} \; -print | less

調べた結果cvsの中でシステムコールであるmkdir関数を使用して/tmpに一時ディレクトリを作成しようとした際にエラーが起きたようです。ということでcvs自体は問題がないようです。加えて手動で/tmpの下にディレクトリを切ることはできたので、この時点ではファイルシステムが何となく怪しいという程度にしか状況を解析できませんでした。

一度この状況で放置をしていたのですが、さらに困ったことがおきました。scpで単純なファイルをコピーしようとすると、やはりFIle too largeと言われるようになりました。更にサーバにローカルログインしてファイルを作成しても同じ現象が発生します。この時点で完全にディスクが怪しいという確信を得られたので、ブートディスクのチェック fsck_hfs -fd / をしてみると、Invalid extent entryなるエラーが発生していました。どうやらファイルシステムが破壊されつつあるようです。

Appleの技術情報『ディスクユーティリティおよび fsck を使用して、起動時の問題を解決する、あるいはディスクをメインテナンスする 』によると、このような場合はセーフブートによる回復やシングルユーザモードでの回復処理の実行によって状況が打開されるとあります。しかしながら今回発生したInvalid extent entryのエラーは修復されませんでした。検索によれば、純正のコマンド(fsck_hfs)やツール(Disk First Aid)等で回復できない類のエラーもあり、その場合には市販のソフトを導入して解決することが可能であるという情報も見受けられました。

しかしながら市販のソフトを導入したところで回復する見込みが100%でないことを考えると、ここで頑張る価値はあると考えました。まずは詳細なエラー情報を入手するため、fsck_hfsコマンドに改造を施しました。fsck_hfsをビルドするのに必要となるソースをdarwin(MacOSXと共通なopen sourceの部分)の開発者サイトから入手します。目的のコードは10.2.8/diskdev_cmds-208.11.2になります。

入手したソースに対して適宜手を加え、Invalid extent entryを発生させている部分を絞り込みました。 fsck_hfs.tproj/dfalib/CatalogCheck.cにあるCheckFile関数内でCheckFileExtents関数からの返却値がエラー(405行目付近)となっているようです。どうやらファイルシステム内のファイルを管理しているテーブルで異常で発生しており、その問題箇所と関連するファイルの名前はCheckFile関数のローカル変数filenameをprintfで吐き出すことで得られました。

ここまでわかったので、ファイルシステムのテーブルを直接修正しようかとも考えましたが、とりあえずおとなしく当該ファイルをrmコマンドで削除してみました。するとfsck_hfsで別のエラーが確認されるも、技術情報に従ってシングルユーザモードで起動、fsck -rfd / を行うと今度は全てのエラーが修復されました。これで無事解決に至りました。

この問題を振り返ってみると、サーバのHDDにバットセクタが発生している可能性が高いのではないかと考えられます。特にファイルシステムのテーブル部分は頻繁にアクセスがかかるので数年間の負荷に耐え切れずに今回のようなエラーが発生したのではないでしょうか。いずれにしても、できる限り早く新サーバに乗り換えたほうが先進衛生上好ましいようです。

14:25 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク | コメント (2) | トラックバック
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/635

May 03, 2008

Super Sylphide 進捗状況(17) -- I/O拡張基板 動作確認済み

オートパイロットシステムSuper Sylphideですが、以前紹介した4枚目の基板であるI/O拡張基板の動作確認がとれました。基板の写真を晒すことにします。

IOModule.jpg
表と裏

何のことはない、XilinxのFPGA(spartan3)とそのコンフィギュレーション用PROMが載っただけのボードですが、電源部分を1チップで3種類の電源(+1.2,+2.5,+3.3、うち+1.2と+3.3はスイッチングで効率がよい)を生成するTPS75003という馴染みのないチップを使ったために動作確認を取り付けるまでに少々難儀しておりました。1チップといっても外付け部品はかなり必要(FPGAが載っていない面の部品はほぼ電源関係)であり、その中のダイオードのフットプリントを誤ったため短絡がおこっていました。MOSFETが煙を吹く様は心臓によくないですね(苦笑)。

電源部分の問題解消後にはXilinxの開発ツールに含まれる書込みソフトiMPACTでデバイスが無事認識されました。

IOModule_iMPACT.png
認識された時のiMPACT

IOModule_with_XParallel.jpg
純正パラレルケーブル互換の基板で繋いで見ました

これでサーボをそろそろ動かせそうですが、VHDLの書き方をできる限り早く思い出さなければなりません。使わない言語でも1ヶ月に1度くらいは触ったほうがいいのかもしれませんね。

i2cでサーボ信号をコントロールするような実装をすることにしました。

09:31 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク | コメント (0) | トラックバック
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/636

May 07, 2008

サーバの移行 -- G3からMacMiniへ

日付の上ではGWが終わってしまいましたが、この休みを利用して何とか新サーバに移行することができました。この記事を書いている現在はもう新サーバ上でこのサイトは稼働しています。まだまだ試験運用中ですので、不具合等があったらご指摘いただけると助かります。

詳細な(かつ、ほとんどの方には必要でない)技術情報については、また個別の記事にしようと思いますが、ここまでの作業工程を箇条書きにしておこうと思います。

全て終わった現在から見ると、たいした作業量でないように見えますが、色々と躓きつつ進んでいるので時間はかなりかかりました。そしてまた一段とMacOSXという一般的ではないものについて詳しくなりました(笑)

※MovableTypeの設定に一部あやまりがありました。トラックバックURL等がローカルアドレスになっていたようです。odawaraさん、ご指摘ありがとうございました。

01:24 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク | コメント (3) | トラックバック
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/637

May 09, 2008

MovableType 2.661をapache2+mod_perl2で動作させる

リクエストを戴きましたので、MovableType 2.661(以下MT 2.661)をapache2+mod_perl2上で動作させるまでに行った記録を記しておこうと思います。おそらく相当ニッチな要望だと思いますが(笑)。

コトの経緯を軽く説明しておきますと、MT 2.661はかなり古いCMSですが、このサイトのMT 2.661は自分の使い勝手がいいようにかなり改造を施してしまったので、なかなか最新バージョンに移ろうという気になれないでいました。そうこうしているうちにサーバーを最近立て替えたこともあり、以前のapache1.3 + mod_perl1.3環境から卒業してapache2+mod_perl2に対応する必要がてできました。その後MT自体は進化をとげメジャーバージョンが4になり、新しい環境にも標準で対応しているようなのですが、やはり使い慣れたMT 2.661を使い続けたい、だから移植しよう、というのがこの記事の動機となっています。

とりあえずapache1.3+mod_per1.3からapache2+mod_perl2にl変更するにあたってポイントとなる点は大きく2つに大別できると思います。

1つはapache2では並行動作のモードが複雑になった(従来のprefork動作以外にもmulti-thread動作等が選べる)ため、その上で動くmod_perl2がスクリプトを起動方法が変更になったようです。特にスクリプトを書く側にとって深刻な点は、起動時のディレクトリが必ずしもスクリプトの存在するディレクトリにならないことです。MT 2.661においても例外ではなく、MT 2.661では動作に必要となるサブモジュールの位置を、スクリプトが存在するディレクトリからの相対パスで求めているため、これは非常に大きな問題となります。先達はchdirでなんとか解決しようとされたり、apache2の構成方法にもよりますが従来どおりの動作が期待されるPrefork版のPerlハンドラを渡して解決しようとされたりしています(chdirが好ましくないことやPrefork版モジュールは本家mod_perl2のサイトで言及されています)。

もう一つの問題はmod_perl2でAPIの名前や動作がかなり変更されたことです。名前が変更されたことは書き換えで対応すればよいようで、これも先達によって『MT3.3をmod_perl2で動かすpatch(その1)』等で書き換え方法が公開されています。動作の変更点としては、MT 2.661で状態遷移を記録するために使用していたApache::Request::paramというものがありますが、Apache2::Request::paramでは変数を足すことができなくなった(『Apache2::Request PORTING from 1.X』参照)のが響いています。

以上2点を踏まえて、apache2+mod_perl2上でMT 2.661を動作するようにしました。変更点をまとめたdiffファイル(patchコマンドで適用可能形式)を公開するとともに、apache2+mod_perl2側の設定を以下に示します。

PerlSetEnv MT_DIR /usr/local/share/web/MovableType/
PerlSetEnv MTConfig /usr/local/share/web/MovableType/mt.cfg
Alias /mt/ "/where/to/mt/"
PerlModule ModPerl::Registry
PerlModule Apache::DBI
<Directory "/where/to/mt/">
    <Files *.cgi>
        SetHandler perl-script
        PerlResponseHandler ModPerl::Registry
        PerlSendHeader Off
    </Files>
</Directory>
<Location /mt>
    Options ExecCGI
    Order Allow,Deny
    Allow from all
</Location>
<Location /mt/db>
    Order Deny,Allow
    Deny from all
</Location>

1つ目の問題点、実行時のディレクトリの問題については環境変数渡し+@INCをスクリプト内で変更することでサブモジュールを見えるようにしました。@INCの変更はBEGINブロックで対応しないようにしましたが、これは『[perl]ModPerl::{PerlRun,Registry,RegistryPrefork}でのカレントディレクトリ、BEGINブロック、@INCの扱いメモ』に基づいています。
今回示した解決方法以外にも、試してはいませんがPerlOptions +Parent と PerlSwitches -I(mt/lib) 等を使った解決方法が考えられると思います。

2つ目の問題点は、先達の書き換え方法、並びにApache2::Requestに対して、paramが書き換え可能なApache2::RequestSubclassというラッパークラスを定義することで対応しました。このアイデアは『Apache2::Request::param で set / add できない』より戴きました。

問題点がでてきたら変更を考えていますが、以上の作業で現在のところ問題なく動作しています。

※ファイルのアップロードでこけることがありました。またしてもメソッド名が変更(size => upload_size、fh => upload_fh)になっていたようです。上記diffに追加してMT-2.661.CMS.pm.diffも mt/lib/MT/App/CMS.pm に対して適用してください。

10:06 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク | コメント (0) | トラックバック
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/638

May 11, 2008

cvs2svnで文字コードが混在するcharsetを設定する

サーバを移行した際に、ファイルのバージョン管理システムをCVSからより便利なSubversionに移行しました。僕の近辺ではバージョン管理システムを導入している方というのがほとんどいないのが現状ですが、もうこの便利さは嫌というほど思い知らされているので、日付ごとのディレクトリを切って管理をしている様子を見るといつも信じられない気持ちでいっぱいになります(笑)。というわけでこのシステムを使いやすく運用することにはかなり命をかけており、そんな状況での移行でした。

移行については、参考にしたサクラエディタの『cvs2svnによるリポジトリ変換』のようにcvs2svnを使い、なおかつ拡張子に基づいてファイルの種類(svn:mime-type)や文字コード(charset)をcvs2svnに教えてあげるauto-propsという設定ファイルを記述すれば、大抵のことはうまくいきます。しかしながら、ソースの文字コードが混在している(例えばWeb系のスクリプトはUTF-8で、M$関係のソースはMS932(Shift-JISの友達)で等)複数のプロジェクトを管理していたため、auto-propsで拡張子に基づいた文字コードを設定してしまうと、例えばTracなどを使って管理している内容をそのままWebで公開する際に少々まずいことがおきるようです。そこで対策を考えてみました。

はしめはauto-propsの設定ファイルをうまく表現することで対応できないかとも考えてみたのですが、auto-propsが拡張子を基準として動作しているため、この方法では不可能と判断しました。仕方がないのでcvs2svnのソースを改変しようかとも考えたのですが、たまたま上述の参考リンクで行われているcvs2svn --dump-onlyというコマンドで吐き出されるダンプファイルの形式が理解しやすいことを発見したので、これをcvsadmin loadでリポジトリに格納する前に修正することにしました。

修正に用いたRubyスクリプトはcvs2svn_mod_charset.rbです(再利用の際、プロジェクト名は修正してください)。使い方はcat (cvs2svn --dump-onlyしたダンプファイル) | ruby cvs2svn_mod_charset.rb | cvs2admin load where/to/svnrootです。非常に安直なスクリプトですが、ダンプファイルの形式が(同じく安直な)HTTPプロトコルの形式に似ていることもあり、おそらく多くの場合はこれで対応可能だと思います。

10:46 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク | コメント (0) | トラックバック
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/639

May 20, 2008

RubyでアップローダCGI

ファイルをネット上でやり取りしなければならない事情がでてきまして、せっかくなので自習がてらCGIで動作するアップローダを作成してみました。前回web系のプログラミングをしたのは実に1年以上前のことなのでかなり感覚が鈍っていましたが、過去の遺産である『Trackback機能付き掲示板』を利用することで、何とか数時間でこさえることができました。せっかくなのでコードを公開したいと思います。RSSも吐いてくれます。

動作しているデモもあわせて公開します。なおデモなのでアップロードできるファイルのサイズ制限を10KBと厳しめ設定してあります。

作成にあたってはRubyを利用しましたが、標準添付ライブラリの CGI + PStore + ERB に助けられました。簡単なCGIを作るについては、これはかなり強力な組合せだと思います。

23:07 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク | コメント (0) | トラックバック
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/640

May 23, 2008

Amontec JTAGkey-Tiny (FT2232) を Xilinx iMPACTから使う

FTDIのFTCJTAG.dllの仕様(リード、ライトが最低2bitsから)にブチ切れつつ、漸く完成しました。FPGAのプログラムをダウンロードする際、これまではパラレルポート+自作JTAGアダプタを使ってきたのですが、あまりの遅さについつい、Xilinx純正のダウンロードソフトであるiMAPCTから、純正以外のJTAGケーブルをコントロールできるようなプロキシソフトをこさえてしまいました。完成した現在では、前に購入したFTDIのFT2232を搭載したAmontec JTAGkey-Tiny経由で、iMAPCTからダウンロードをサクサク行えています。

実は世の中には既に便利なSVF Player(JTAG操作を記述したSVFファイルを様々なJTAGケーブルを通して実行するためのソフト、当然データのダウンロードもできる)があるので、ダウンロードを高速にしたいという要望だけみれば、今回作成したソフトはかなり車輪の再発明です。しかしながら、今回こさえたものはXilinxの純正ツールであるiMPACTから直接使えるので、ダウンロードを行う際にわざわざSVFファイルを書き出し、SVF Playerを起動する必要がこれでなくなりました。快適です。

動作原理ですが、リモートケーブルの概念を利用しています。これは書込みを指示するiMPACTが実行されているPCとJTAGケーブルが接続されているPCが異なる場合、操作の指示をTCP/IPでJTAGケーブル側のPCに転送するので、そのプロトコルさえわかれば純正ケーブル以外のJTAGケーブルにも対応できるというわけです。このプロトコルはsourceforge.netで開発が行われているxilprgのcblsrvで実装例がありましたので、これを下地にJTAGkeyに搭載されているFT2232に対応するよう改造を行いました。

プロトコルの構造は単純だったので、改造ポイントはすぐにわかりましたが、ここで冒頭の問題にはまりました。FT2232でJTAGをコントロールするためのFTDIが提供しているFTCJTAG.dllは制御の単位が最低2bitsであったことです。結局可変長のビット配列クラスlong_bits.hを用意してビット単位の切り貼りを行うことで解決しましたが、この制限が何に由来するものなのかよくわかりません。なおlong_bits.hの使い方はlong_bits_test.cppを参考にどうぞ。

ソースとコンパイル済みのバイナリのセット cblsrv-0.1_ft2232.zipを公開します。実行方法は以下のとおりです。指定したポート番号を、iMPACTの[option]->[Cable Setup]-[Cable Location]でlocalhost:(ポート番号)のように指定してください。

cblsrv.exe -c amontec -p (ポート番号)

動作確認はiMPACTの8.2と10.1で行いましたが、いずれも快適に動作しています。

※以下、修正情報です。
2008/05/26 高橋さんのご指摘があり、JTAGkeyのポート割り当てに関するバグを修正し、ファイルを差し替えました。
2008/05/27 long_bits.hでメモリ割り当てをしくじっているバグがありました。修正済みのものと差し替えました。
2008/06/29 もしTCKが早すぎて対象機器が動作しないようでしたら、ft2232jtag.hの49行目dwClockDivisorの値を大きくしてリビルドしてみてください。

※※いえながさんによると、VC2008がインストールされていない環境では、実行に際して『Microsoft Visual C++ 2008 再頒布可能パッケージ (x86)』が必要とのことです。

※※※(2009/8/8) この記事は意外と需要があるようなので、メンテナンスを行いました。下記コメントで10.1.2で動かなくなる問題を解決してくださったNakagawaさんのコードをマージし、修正版 cblsrv-0.1_ft2232_r3832.zip を新たに上げておきます。修正箇所はnakatomoの文字列で検出できます。またiMPACTのバージョンが古い場合は、IMPACT_VERSIONを、例えば80200のようにdefineするといいです。

※※※※(2010/2/4) さらに10.1.3, 11.1でも動くよう改修しました(cblsrv-0.1_ft2232_r4740.zip)。このバージョンはコードを修正することなく8.2でも使えることが確認できています。
改修内容は主にlong_bits.hのバグ(ビットシフトで問題があった)を取ったのと、WRITE_SHIFT(0x20)やWRITE_SHIFT_LAST(0x30)といったJTAG TAPのステートマシーンをPAUSEで維持しなければならないコマンドへの対応をしてあります。また現状認識している問題としては、11.1で動かないこと(解消しました)、FPGA本体へのbitファイルダウンロードがうまくいかないことがある(PROMへのダウンロードは問題なし)ことの21点です。

※※※※※(2010/3/3) FTCJTAGのDllバージョンによって問題が発生することを認識しました。FTCJTAGのバージョンは1.9(現時点で最新は2.0ですので少し古い)を使ってください。Dllのバージョンチェックを行うようにしたもの、また1.9を添付したもの(cblsrv-0.1_ft2232_r4788.zip)をリリースします。

※※※※※※(2010/3/19) FTCJTAGのバグ(詳細はこちら)を解消しました。修正されたdllを添付し、さらにFT2232H/4232Hに対応したcblsrv-0.1_ft2232_r4804.zipをリリースします。PROMだけでなく、FPGAへのダウンロードも成功する確率が飛躍的に高くなりました。

※※※※※※(2010/4/27) Alpha Projectさんの製品であるUSBマルチJTAGアダプタHJ-LINK/USB と組み合わせて使う方法が紹介されています。

14:08 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク | コメント (24) | トラックバック
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/641