MegaCLI と DELL OMSA の rpm パッケージがコンフリクトする件

LSIRAID カードをコントロールするコマンドラインユーティリティ MegaCLI とDELL の OMSA で rpm パッケージが衝突していて困った。どうやら別々の rpm パッケージで同じファイルを梱包しているのが問題らしい。

ファイルをよく観察したところ、LibUtils が無くなっても問題ないじゃないか。ということで調べてみたら、他にも困っている人が居て LibUtils のダミーパッケージを作って回避していたので、同じ方法でとりあえずの問題回避をすることにした。

やり方はここに有るとおりに spec ファイルを作って rpmbuild し、~/rpmbuild/RPM/ 以下に作られたダミーパッケージを sudo rpm -ivh してやるだけ。

Becky の bmf ファイルを eml ファイルに変換するスクリプト

メールボックスの Quota 溢れのためメールを IMAP サーバーからローカルに落としまくったのだが、ローカルで検索が速いソフトが無くて結構困っていた。検索できないならローカルに落としたくない。

色々探したら MailStore というソフトが結構便利そうなんだけど試用してみたら日本語の検索が上手く行かない。こりゃだめだ、と思っていたら実は単語区切りの認識がダメなだけで日本語自体の検索はできるらしい。たとえば"楽天"を検索すると出てこないけど"*楽天*"として単語区切りに関わらずマッチを探すと大丈夫。私はこの仕様でそれほど困らないので MailStore を頑張って使ってみることにした。

しかし困ったことに MailStore は私が溜めている Becky のファイル(bmf)をインポートできない。そこで適当にコンバーターを書いてみた。日本語の変換とかだるいし、どうせ MailStore で読むんだからファイル名は適当で良いよね、ということで Message-ID をファイル名にし、Message-ID が付いていない奇特なメールは Date ヘッダの中身をファイル名にすることにした。これがコードである。私の何年分かのメールを食わせてもちゃんと動いているように見える(on Windows)。

IPMIでサーバーの電源を遠隔でon/offをする方法

ほとんど自分用の備忘録だが書いておく。

まず、大前提として IPMI を使ってリモートからサーバーの状態を確認orコントロールするためには BIOS の設定画面から IPMI 用に IP を振ったりユーザーやパスワードを予め登録しておく必要がある。これはもう済んでいるものとする。

以下のコマンドで電源やファンの状態を確認できる。

sudo ipmitool -H IPMIに振ったアドレス -U ユーザー名 chassis status

実行例はこんな感じ。targetserver-ipmi は、対象サーバーの IPMI に振った IP アドレス(に解決する名前)である。

[admin@myserver ~]$ sudo ipmitool -H targetserver-ipmi -U username chassis status
Password: (ここでパスワードを入力)
System Power         : on
Power Overload       : false
Power Interlock      : inactive
Main Power Fault     : false
Power Control Fault  : false
Power Restore Policy : always-off
Last Power Event     :
Chassis Intrusion    : inactive
Front-Panel Lockout  : inactive
Drive Fault          : false
Cooling/Fan Fault    : false

電源の状態だけ確認したい場合(or 電源の状態ぐらいしか確認できないしょぼいハードの場合)、

sudo ipmitool -H IPMIに振ったアドレス -U ユーザー名 power status

で確認できる。

また、電源の on/off は

sudo ipmitool -H IPMIに振ったアドレス -U ユーザー名 power on
sudo ipmitool -H IPMIに振ったアドレス -U ユーザー名 power off

で実行できるので、サーバーから ping も帰ってこないレベルに達したら power off してしばらく待って power on することで運が良ければサーバーが回復する。

GlusterFS 3.3.x 以降で brick として使っていないはずのディレクトリに GlusterFS をマウントしようとしたら "brick として使っています" というエラーが出る問題

brick のディレクトリに誤って GlusterFS をマウントしてしまう人が跡を絶たないので、FUSE でマウントする時にそのマウントポイントが brick になっていないかどうかをチェックするという仕様になったのだそうだ。

そして、brick かどうかのチェックには拡張アトリビュートを使っているので、「現在は brick ではない」ディレクトリであっても「以前 brick として用いていたので拡張アトリビュートが存在する」ディレクトリは "brick として使用中" として判定されてしまう。

解決策は「自分で拡張アトリビュートを削除する」ことだそうです。仮にマウントポイントとして使いたいディレクトリを /gluster とすると、

sudo getfattr -m . -d /gluster

とすることで使っているアトリビュート名の一覧が出てくるので、それを一個一個削除していけばOKです。バージョンによって使っている拡張アトリビュートは違うみたいなんですが、気持ち悪いので私はとりあえずglusterfsに関連しそうなものを全部消しておきました。こんな感じ。

sudo setfattr -x trusted.gfid /gluster
sudo setfattr -x trusted.glusterfs.dht /gluster
sudo setfattr -x trusted.glusterfs.test /gluster

あとは普通に /gluster にマウントするだけ。

GlusterFS 3.(2|3).x で transport-type を rdma から tcp に変更する方法

GlusterFS 3.2.x で "transport-type rdma" の設定をすると動作がおかしくなることが偶にあるようである。本家のフォーラムで、3.2.x あたりから rdma の設定はちゃんとテストされていないから動いていないかも、将来的には直すよ的な発言が出ていたので rdma から tcp に transport-type を変更することにした。

rdma から tcp に transport-type を変更するといっても Infiniband を使わない設定にするわけではなくて、IPoIB に切り替えることにした。ちなみに筆者が適当に行った(ddででっかいシーケンシャルファイルを読み書きするだけの)ベンチマークによれば、QDR Infiniband での rdma/tcp 間のスピード差は計測誤差範囲内であったので、これからもずっと tcp でいいや、と思ったということも移行の理由だ。

筆者の管理しているクラスターはホスト名が abc001, abc002 のように連番で振られていて、IPoIB の IP は abc001-ib, abc002-ib, ... のように -ib というサフィックスを付けたホストネームに割り当てられている。だから、rdma/tcp の切り替えを行うには peer の名前変更、brick の名前変更、volume の transport-type 変更など、変更箇所は多岐に渡る。

変更を行う前に全ての GlusterFS 領域を合うマウントし、glusterd, glusterfsd を全部落とした。オンラインでできるかもしれないけど、ダウンタイムがあっても良かったので安全策を取った。以下、設定ファイルの変更点を羅列する。

まず最初にホスト名の変更を行った。/etc/glusterd 以下にあるファイルを一つ一つ確認してホスト名らしき文字列があればそれに全て -ib というサフィックスを付けていった。数は覚えていないけど数重ファイルぐらい弄った気がする。

次に transport-type の変更を行った。grep -r で rdma という文字列を探し、問題ない場所は片っ端から tcp に変更した。これも結構なファイル数変更をしたと思う。

更に、/etc/glusterd/vols/ボリューム名/info に transport-type=1 と書かれた行があるが、これが rdma に対応しているので transport-type=0 に変更して tcp を用いる設定に変更する。

あと、/etc/glusterd/vols/ボリューム名/ボリューム名.マシン名.export-* というファイルのマシン名のところに -ib を付けるのを忘れずに。

ここまで変更を行った後に glusterd, glusterfsd を全て立ち上げ、GlusterFS 領域をマウントしなおしたらちゃんと動いた。

GlusterFS 3.2.x から 3.3.x へのアップグレード方法

諸事情によりGlusterFS 3.2.x から 3.3.x へのアップグレード方法(英語)を実行することになったので日本語訳を作った。以下の段落は全て元 blog 記事の日本語訳です。日本語としてなるべく自然になるように意訳多めです。括弧()の中の内容は全て訳注です。

1) 3.3.0 以前のバージョンとは互換性がないのでアップグレードする場合にはダウンタイムを覚悟してください。(下のコメント欄にローリングアップグレードも多分できる、サーバー・クライアント間プロトコル後方互換性にはものすごく気を遣って開発している、と書かれている。)
2) glusterd, glusterfs, glusterfsd のプロセスを全てのサーバー・クライアントマシンで止めて下さい。
3) glusterd のワーキングディレクトリのバックアップを取って下さい。ワーキングディレクトリの場所は普通 /etc/glusterd にあります。
4) GlusterFS 3.3.0 を全てのサーバーとクライアントにインストールしてください。3.3.0 ではデフォルトワーキングディレクトリが /var/lib/glusterd に変更されています。(下のコメント欄に質問があるが、「glusterdが生成するユーザーが書き換えてはいけないファイル」が /etc/glusterd にあったのでそれを /var/lib/glusterd に移動し、ユーザーが設定するファイルは従来通り /etc の下に置いているとのこと。)RPMもしくはソースからインストールした場合には /etc/glusterd の全ての中身は(自動的に) /var/lib/glusterd に移動します。すべてのサーバー上で 3) で作ったバックアップと(/var/lib/glusterdの)ディレクトリ構造が同じになっているかどうか確認してください。アップグレード中に追加でファイルが作られるのでファイル数は増えているはずですが、3) で取ったバックアップに存在しているファイルは全て /var/lib/glusterd にもあるはずなので、それを確認してください。
5) RPM でインストールした場合にはこの項目をスキップして 6) へ進んで下さい。RPMを使わなかった場合には、glusterd をアップグレードモードで立ち上げてください。(立ち上げると)必要な処理を行ったのちに glusterd は終了します。このあと glusterd を再度立ち上げて下さい。(コマンドで言うと)要するに
a) kill glusterd
b) glusterd --xlator-option *.upgrade=on -N
とすればよいわけです。この作業では、ボリュームファイルを作り直して"index" トランスレーターを設定します。このトランスレーターは 3.3.0 の予防的セルフヒールのような新しい機能の動作のために必要です。
c) glusterd を立ち上げて下さい

この a), b), c) の作業は全てのサーバー上で行う必要があります。

6) ここまででサーバー上の gluster サービスが全て稼働状態に戻りました。GlusterFS 3.3.0 のネイティブクライアントでボリュームをマウントしてください。

さあ、新しいバージョン 3.3.0 を試して、Freenode の #gluster や bugzilla, c.g.o (訳注:c.g.o ってなんでしょう?) に報告しよう!

この手順では全ての状況には対応できないかもしれないと思っています。だから、もし何か不足している点を見つけたら是非コメントしてほしいです。できるだけコメントを反映して書き換えたいと思います。

X10雑感

IBMが作っている X10 という並列計算向けの言語があるんだけれども、これが結構面白い。MPIでガリガリ書くのと比べるとゲノム解析との相性がずいぶん良さそうだ。いくつか不満点があるのでメモがわりに並べておく。

async の実装がタスクスチールではなくタスクキューになっているためか Cilk Plus 等と比べると少しタスク生成がやや重いように感じられる。ちゃんとベンチマーク取ってないけど体感で Cilk Plus 比で 5〜10 倍ぐらい粒度大きくしないとスケールしない感じである。

C++バックエンドを使った場合でも X10 ではガベージコレクションをする。実装は Boehm GC の保守的 GC を使っているようだ。先頭ポインタを必ず残す実装になっているようなのでそこまで効率悪くないのだろう。ガベージコレクションを行う実装、ということは頑張ればある程度スタックレスにする実装もできるのだとは思うが at 呼び出しでは呼び出し先・呼び出し元の両者でスタックを使っているようだ。何が言いたいかというと at をあまり連続で使えないのが結構不便である。段数が深くなると落ちるので、例えば巨大グラフを複数のマシンに分散しておいて、その上で DFS をするときにマシンを跨ぐ際に at で呼び出す、というのはできなかった。マシンを数百回またぐと落ちてしまう。

あとは、at 呼び出しはレイテンシが大きいのでこれをなんとかして隠蔽したい。具体的には async で作った大量のスレッドから出てくる複数の at 呼び出しをまとめてレイテンシを隠蔽、というのをやりたいんだが今のところこれは自分で書くしかない。TCP の nagle アルゴリズムみたいに自動でやるのはパフォーマンスをきっちり出すのが難しそうなので、プログラマがちょっとディレクティブを書いて複数区間の at を溜めてから実際に呼び出しを行うようにできると良いな、と思う。

最後に、「計算中に必要な並列度が変化するため、動的に Place を増減したい」というのが今の X10 だとできない。特に I/O で時間食ってる間は CPU を解放して(Sun Grid Engine 等のバッチスケジューラーに返して)おきたいんだけれどもそれはできない仕組みになっている。これは何れは実装されるのだとは思うが増やす方も減らす方も相当に実装が面倒なのが見えているので時間かかるだろうな。