2009/11/30

News Corp.がGoogle検索を拒否へ−Microsoft「Bing」と提携の動き - Enterprise Watch
- Reference: http://enterprise.watch.impress.co.jp/docs/series/infostand/20091130_332341.html

News Corp.がGoogle検索を拒否へ−Microsoft「Bing」と提携の動き - Enterprise Watch

なんだかGoogleニュースやらGoogleのキャッシュに記事を掲載されている新聞社が掲載拒否を申し立てようとしている模様です。

まぁ好きにすれば良いんだと思います。 Googleニュースの記事一覧は全文を載せていないし、読みたければクリックしてその記事に飛びますからね。

大手の新聞社が撤退すれば、Googleが記事を集めるために地方の独自性を持っているけれども小さい新聞社まで手を広げるかもしれないし、 その方がインターネットらしくて良いなぁ…。

Ubuntu 9.10でgit経由のカーネル再構築

ついでなので、gitからUbuntuカーネルコードをダウンロードする方法も試す事にしました。 VMWareで新しいCloneを作ったので、i386 Desktop版をインストールして最新の状態にアップデートした状態からのスタートです。

参考資料

後半の手順は前回のYet Another Diary::Ubuntu 8.10 (interpid)以降でのsystemtapと同じです。

あいかわらず本家のKernelCompileです。

そこからUbuntuのバージョン毎にgitを使った方法を載せているHow to compile a kernel for Ubuntu Karmicに飛んでいます。

事前準備

$ sudo apt-get install fakeroot kernel-wedge build-essential makedumpfile
$ sudo apt-get build-dep linux
$ sudo apt-get install git-core libncurses5 libncurses5-dev

カーネルコードの展開

今回はVMWare上の/homeに30GB分の別のHDDイメージを作成しました。"rsync -av"でデータを移してから/etc/fstabを編集して再起動しています。

$ cd
$ git clone git://kernel.ubuntu.com/ubuntu/ubuntu-karmic.git source
$ cd source
$ git checkout Ubuntu-2.6.31-15.50 -b rebuildtest

"debian.master/changelog"ファイルをみて、"2.6.31-15.50"が直近のリリースされたバージョン、"2.6.31-15.51"が作業中のUNRELEASEDバージョンだと分かります。

最後の"-b"オプションに続ける"rebuildtest"の部分は適当な名前をつけます。 これで~/sourceにkernelのgitリポジトリが構築できました。

試しに$ git branchを実行すると、自分が作成した"rebuildtest"プロジェクトの他に"master"というブランチ名が確認できます。 カーネル開発をする分けではないですが、最新のカーネルコードを取得したい場合には、まず"master"ブランチを最新に更新し、それから自分用の"rebuildtest"ブランチのコードに更新をかけるのが良いと思われます。

2009/12/09追記:
最新のカーネルコードにするためには、"git branch master"で一旦branchを変更してから"git pull"でリポジトリからコードを持ってきます。 参考資料にある手順は自分でカーネルコードに変更を加えている前提で書かれているため、マージの手順が面倒になっています。
単純に新しいカーネルコードをビルドするだけであれば、新しいブランチ名で"git checkout"の部分をやり直すのが簡単だと思います。

あとは前回と同じ

注意するところは、まだセットアップが完了していないので前回debian/rules updateconfigsを実行する代りに下記のコマンドで"debian/control.d"などを作成する必要があります。

$ debian.master/scripts/misc/kernelconfig oldconfig

この後で$ fakeroot debian/rules clean$ time AUTOBUILD=1 fakeroot debian/rules binary-mygenericのように進めていきます。

*.deb, *.ddebパッケージの作成完了まで90分ほどかかる見込みです。

linux-image-debugパッケージがない事の損失

linux-image-debugパッケージがapt-getできなくても、どこかのFTPサーバーに入っていれば良いのですが、残念ながらそうなっていないようです。

今回のような手順で"generic"パッケージを作っても、apt-getした"linux-image"と手元で作成した"linux-image-debug"は異なるものなので、systemtapをフルに使うためには今回作成したパッケージと一緒にインストールする必要があります。

systemtap以前はデバッグパッケージは開発者が文字通りデバッグ用に使うぐらいしか用途がなかったと思います。 しかし、これから普及が進めば問題が発生した場合、ある程度はサービスを停止せずに問題を絞り込む事ができると期待しています。

systemtap自体はこれだけで問題を解決するには難しいですけれど、server/clientの枠組みもできて、 原因を追求するために問題が起っている、そのマシンの状態を把握できるというのは必要なことです。

もしカーネル開発者が自分たちの視点だけで、肥大化するカーネルパッケージのサイズを絞り込む方法を考えるなら最初からビルドしないという選択肢もありそうですが、今後はせめて本番サーバーとして使われそうなLTSだけを対象にしてdebugパッケージをダウンロード可能にして欲しいところです。

2009/11/29

Ubuntu 9.10で$HOME直下の日本語名ディレクトリを英語名に変更

日本語localeでデスクトップ環境を使っている以上あたりまえですが、 ホームディレクトリに'文書'やら'音楽'やらのディレクトリが作成されています。

VMWare上に環境を作って気がついて、日本語名のディレクトリを英語名に変換してみました。

変更前

ダウンロード  テンプレート  デスクトップ  ドキュメント  ビデオ  ピクチャ  ミュージック  公開
$ cd ~/.config
$ rm user-dirs.locale
$ env LANG=en_US xdg-user-dirs-gtk-update

user-dirs.localeを削除すると、ログイン時にlocaleに合わせて英語名から日本語名への変換などをするか二度と聞いてこなくなります。 あとからやっぱり日本語に戻したいという場合には、$ env LANG=ja_JP xdg-user-dirs-gtk-updateとするか、$ echo en_US > ~/.config/user-dirs.localeとしてログイン仕直すと良いでしょう。

変更後

Desktop  Documents  Downloads  Music  Pictures  Public  Templates  Videos 

今回編集したuser-dirs.localeといったファイルについて知っていたわけではないのですが、 たまたま'文書'といった特徴的な単語があったので、次のようにfindを使って設定ファイルを探すのは楽でした。

$ find . -type f -exec grep 文書 {} \; -print

確認すること

"~/.config/user-dirs.dirs"ファイルの中身が対応する英語名に変更されているか確認しましょう。

$ cat .config/user-dirs.dirs
...
# 
XDG_DESKTOP_DIR="$HOME/Desktop"
XDG_DOWNLOAD_DIR="$HOME/Downloads"
XDG_TEMPLATES_DIR="$HOME/Templates"
XDG_PUBLICSHARE_DIR="$HOME/Public"
XDG_DOCUMENTS_DIR="$HOME/Documents"
XDG_MUSIC_DIR="$HOME/Music"
XDG_PICTURES_DIR="$HOME/Pictures"
XDG_VIDEOS_DIR="$HOME/Videos"

user-dirs.dirsを直接編集する

例えば'Videos'や'Music'を'Multimedia'といった名前にまとめたい場合には、まず$ mkdir ~/Multimediaのようにディレクトリを作成します。

次に"~/.config/user-dirs.dirs"を直接編集し、'Music'、'Videos'といった単語をMultimediaに変更します。

その上で'Music'、'Videos'にあるファイルを'Multimedia'に移動し、空になったディレクトリを削除すれば良いのですが、ちょっと面倒な感じもします。

作業自体は楽だし、すっきりしているのだけれど…

まぁこういう低レベルなところが制御できるのは心の底から嬉しいのですが、 その反面、徹底してGUIで制御しないことで、肝心な操作は端末で実行する必要があり、 初心者が嫌がるようなのも分からないではありません。

UNIXらしさはCUI環境やらemacs全画面表示やらにあるような気もしますが、 その”らしさ”をユーザーが決められる自由度がUNIX系OSに魅きつけられる理由だと自分では考えています。

そういう"自分らしさ"を持たないが故に初心者と呼ばれる人々を招き入れるために、Windowsライクな環境がエミュレートできる事は必要だと思います。 しかしGnomeみたいに使いやすい環境が簡単には作れるようになっていないのは残念ですね。

いじれるところはThemeぐらいかぁ。 内部のパラメータとGUIの設計が密になり過ぎているんですよね。 GUIの設計自体がそういうものだし、パフォーマンス優先だからしょうがないけれど、 ベースになる土台はGnomeもKDEも同じなのに見栄えと協調させる制御システムが別っていう世界にはならないよね。 ええ、そうでしょうとも。

2009/11/27

スパコンの仕分けにおける議論について

いまさらな感じもしますが、理化学研究所が神戸に建設しているスーパーコンピュータ(スパコン)に対して、来年度の予算計上をどのようにするか仕分けの議論としていろいろな意見がニュースに載っています。

そもそもスパコンの議論に限らず国家の予算を使う以上は、一定の成果の見込みや波及効果についての最低限のアセスメントや事業者に対してコミットメントを求める事はしなければいけない事だと思っています。

それが純粋に学術的な目的だとしても、そういうものだと皆が認識して進めていれば良いのだと思います。

今回の騒動で良かったこと

なにげに理化学研究所のハードルは上がっていると思います。 話題に上がったことで、スパコン作って終りみたいな事では済まされなくて、成果を求められているとプレッシャーを与えたでしょう。そうであって欲しいです。

ただNECの撤退とか、新規のインターコネクトと純粋なスカラ型スパコンで10PFLOPSを目指すように見えているとか、心配な点があります。

政府の姿勢を批判する事は簡単ですが、なぜ必要なのか、それが科学立国の面子を保つだけというのなら必要ないでしょう。 偉い人を出してきた方がマスコミも喜ぶんだろうけれど、「必要」というだけなら必要なくて、現場の人達はもっと語れると思うのですよ。 一連の騒動は、現場に重〜いプレッシャーを与えただろうし、この機会に上から下まで意識を合せて頑張って欲しいと思います。

今回は官僚もプロジェクトの必要性について、ちゃんと理解しているのか疑問でしたが、そういうことを語る必要ができたというのは、とても良い事だったといえるでしょう。 まぁ公開裁判にならないようなルール作りは必要ですが、透明性を高める事でプレッシャーを与えて、なおかつ、より高い投資対効果を生み出す事ができるはずです。

スパコンに求められるものとは

確かにスパコンを作る事自体が一つの重要な事業ではありますが、日本が目指す1位という判断基準もいろいろあります。

TOP500に載る事で一定の評価を得る事もできますが、実世界の問題を解決する高い実性能を叩き出す事も必要です。 地球シミュレーターはTOP500に載るためのベンチマーク性能では順位を落していますが、実計算では高い効率が売りの一つでもあります。 [ 地球シミュレーター 性能 ]

電力消費が尋常じゃないという指摘も地球シミュレーターにはありますが、 世界に誇る成果を挙げてきた事も事実ですし、それが世界1位だったという事実よりも重視するべき事ではないでしょうか。

何のためにスパコンを作るのか、スパコン自体が目的であればそれは一定の批判を受けてしかるべきと思います。

日本が核兵器開発をするなら、効率なんか無視してスカラ型のスパコンを作れば良いと思います。 きっといろいろな会社が買ってくれるでしょう。 流体系のモデルを使うなら、たぶんベクタ型スパコンを極める道が良いでしょう。

両方のタイプのスパコンを作るという話しならすっきりしますが、理化学研究所のスパコンはそもそもNECが撤退したことで、ベクタ型プロセッサを搭載するはずだった計画の変更を余儀無くされています。

NECの撤退で求めるスパコンを作れるのか

ある程度はスパコンを作る際に実世界に存在するどのような問題を解こうとしているのか、その効果がどの程度か考慮してしかるべきでしょう。

そこそこの問題を解くだけであれば、そこそこの性能を持つスパコンを複数作る方が経済的です。 一定の性能を持つスパコンを発注する企業に対する補助なんてのも考えられる案ではあります。

理化学研究所は次世代スパコンプロジェクトの説明の中で、いろいろな情報を公開していますが、その説明文の中の画像イメージがつぶれたままで判読不能だったり、やる気あるのかなぁという雰囲気を醸し出しています。 たぶん良く取って、売り込みが苦手なんですよね、きっと。

21個挙げられているターゲットアプリケーションをみると、現状で地球シミュレータやNEC SX-6で数〜数十GFLOPSの実効性能を出しているアプリケーションをずっと高いレベルに引き上げようとしている事がわかります。

こういった問題を解くために必要だと、それが出来て実世界にどのようなインパクトを与えるのか、そういう点で議論をして欲しいと思います。 学術的な成果だけでも良いと思うんですよ。それはそれで必要でしょ?って。

Ubuntu 8.10 (interpid)以降でのsystemtap

systemtapはUbuntu 8.10以降でもapt-get経由で提供されていますが、使うには少し問題がありそうです。

Ubuntu 9.10にsystemtapをapt-getで導入しましたが、linux-image-debug-*パッケージは提供されていませんでした。 systemtapの提案パッケージの中にはlinux-debug-2.6がありますが、リポジトリには存在していません。 関連する情報はいくつかUbuntuのバグデータベースなどにありました。

手元で確認したのは9.10だけですが、8.10からdebugパッケージがなくなっているようです。 理由として、デバッグ情報を含むことでパッケージリポジトリのサイズが大きくなってしまう事が挙げられています。

開発版では最新のdebug情報付きのカーネルが配布されていますが、1世代分しか提供されていないようです。 LTSでは提供して欲しいけれど、どうなるか情報はみつけられていません。 kernel teamのMLログを漁るしかないか…。

Ubuntu 9.10でのカーネル再構築

とりあえず手元の9.10でsystemtapを試すために、デバッグ情報付きのカーネルを作成する事にしました。 手順はKernelCompile [help.ubuntu.com] に従います。

ビルド環境
  • VMWare Workstation 6.5.3上のVM
  • CPU: 1つ (Host CPU Phenom II X4 940 の1コア)
  • OS: Ubuntu 9.10 i386版
  • Memory: 512MB (後半1.5GB)
  • HDD1: 8GB (/, ext3)
  • HDD2: 30GB (/home, ext3)

Googleで検索すると/usr/srcでlinux-source-2.6.31.tar.bz2を展開して、make-kpkgを使う方法がよくみつかりますが、Ubuntuのお勧めはgitから最新のアーカイブを取得する方法のようですね…。 今回は(2.)の"sudo apt-get build-dep" & "apt-get source"でカーネルのソースコードを展開する事にしました。

少し手順がわかりずらいかも。debian/scripts/misc/oldconfigはないので、$ debian/rules updateconfigsを使うしかないのですが、$ chmod a+x *は本文を良く読めばいいのだけれど、次のようにcdコマンドを使わずに実行できるよう書くべきかもしれません。

chmod a+x debian.master/scripts/misc/*

デバッグ情報を含むdebファイルを作成するために、debian.master/rules.d/i386.mkの中に"skipdbg = false"の設定を加える必要があります。

また"Alternate Build Method: The Old-Fashioned Debian Way"のセクションが同じページに並んでいるので、かなりまぎらわしく、間違ってこの手順も実行してしまわないか心配になります。

実際の再構築手順

まずは事前準備。

$ sudo apt-get install fakeroot kernel-wedge build-essential makedumpfile
$ sudo apt-get build-dep linux
$ sudo apt-get build-dep linux-image-$(uname -r)

いったん準備が終れば、カーネルのソースコードが必要な時にsudoを使わずに自分の権限でファイルを取得&展開できます。 カーネルのコンパイル用に適当なファイルシステムを準備して、任意のディレクトリ(以下、~/mykernel)を作成して移動するのが良いでしょう。

$ mkdir ~/mykernel
$ cd ~/mykernel
$ apt-get source linux-image-$(uname -r)
$ cd linux-2.6.31/
$ chmod a+x debian.master/scripts/misc/*
$ echo "skipdbg = false" >> debian.master/rules.d/i386.mk

最後の一行でi386.mkの最下行に"skipdbg = false"を加えます。 右辺は"false"でなくても"true"以外の文字列なら何でも良いようです。

ただskipdbgオプションは手順には載ってないですね。 このオプションは debian.master/rules.d/2-binary-arch.mk の中で使われていました。

$ cp debian.master/control.d/vars.generic debian.master/control.d/vars.mygeneric
$ tmpf=$(mktemp)
$ sed -e 's/^\(flavours.*\)$/\1 mygeneric/' debian.master/rules.d/i386.mk > $tmpf
$ diff $tmpf debian.master/rules.d/i386.mk
5c5
< flavours        = generic generic-pae 386 mygeneric
---
> flavours        = generic generic-pae 386 
$ cp $tmpf debian.master/rules.d/i386.mk
$ rm $tmpf

diffの引数は"oldfile, newfile"の順番ですが、そのままcpの引数に使えるように またmktempを使ってテンプファイルを作らなくても、"$tmpf"の個所は適当な新規のファイル名にしてもらえれば良いのですが、例として載せてみました。

$ cp debian.master/config/i386/config.flavour.generic debian.master/config/i386/config.flavour.mygeneric
$ cp ./debian.master/abi/2.6.31-15.49/i386/generic ./debian.master/abi/2.6.31-15.49/i386/mygeneric
$ cp ./debian.master/abi/2.6.31-15.49/i386/generic.modules ./debian.master/abi/2.6.31-15.49/i386/mygeneric.modules

$ debian/rules updateconfigs
$ fakeroot debian/rules clean
$ time AUTOBUILD=1 fakeroot debian/rules binary-mygeneric

CPUが複数コアを持っているようであれば、"CONCURRENCY_LEVEL=2"を付ける例にならうと良いでしょう。 make-kpkgを使った場合は、並列コンパイルが難しいようですから、こちらの方法を使う理由になるかもしれないですね。

コンパイルが終ると一つ上のディレクトリにdebパッケージが作成されます。

作成したパッケージの導入

同じバージョンに見えますが、埋め込まれているハッシュ値が違うのでdebugパッケージだけでは十分ではありません。

$ uname -r
2.6.31-15-generic
$ cd ..
$ sudo dpkg -i linux-headers-2.6.31-15-mygeneric_2.6.31-15.50_i386.deb linux-image-2.6.31-15-mygeneric_2.6.31-15.50_i386.deb linux-image-debug-2.6.31-15-mygeneric_2.6.31-15.50_i386.ddeb

あとは再起動をしてsystemtapの稼働を確認します。

systemtapの確認

単純なスクリプトで確認します。

$ sudo stap -v -e 'probe syscall.open { printf("%d %s\n", tid(), execname()) }'
1572 vmware-guestd
1222 hald-addon-stor
....

出力があれば完了です。 ひょっとすると何かの機能を呼び出したタイミングで不具合があるかもしれませんが、いまのところうまく動いているようです。

2009/11/26

"Systemtap tutorial"のまとめ

Systemtapは"DTrace"と"AWK”に触発された、GNU/Linuxカーネル内部を動的にトレースするためのツールです。 オフィシャルサイトで公開されている"Systemtap tutorial"は2007年の日付で、若干古いですが、PDF版の本文12ページの中で基本的な機能についてよくまとめられていると思います。 Reference Manualの方は2009年11月13日の日付で更新されているので、全ての機能について確認する事ができます。

使うだけなら基本的なサンプルだけをコピーして切り貼りしても問題ないと思いますが、 せっかく読んだのでリファレンスやマニュアルページの情報も加えてサンプルだけだと読み解くのが難しそうな点を中心にメモを残しておきます。

全体の構成

チュートリアルは以下のセクションに分けられています。 この流れに沿ってまとめていきます。

  1. Tracing
  2. Analysis
  3. Tapsets
  4. Further information

Tracing

Systemtapはカーネルが処理を行なう途中に"probe"を仕掛けることで、割り込む事ができます。 あたかも電子回路上にオシロスコープのプローブを当てるようなイメージと一致するのだと思います。 使うプローブの種類を変えれば、違うタイミングや内容を知る事ができるといったところでしょうか。

そういった様々なプローブはSystemtapがbuilt-inで提供していますが、その他に、 "tapset"と呼ばれるライブラリスクリプトの中でユーザーが任意のprobeを組み合せて新たなprobeを定義する事が可能になっています。

後でも出てきますが、このライブラリスクリプト群は通常"/usr/share/systemtap/tapset/"以下に配置されています。

例えば、あらかじめ準備されている"probe begin"や"probe end"を使えばstapが処理を始めたり、終えたりするタイミングで変数の初期化やレポートの出力といった処理を行なわせる事ができます。 ただエラーによって終了する場合は"probe end"は呼ばれないため、"probe error"を使う必要があります。

どのようなプローブ(probe points)が存在するのかは、stapprobes manual pageを参照してください。

ユーザーが記述しなければいけないプログラム本体の流れは、1.データの取得、2.若干の加工、3.出力、になると思います。

"データの取得"について、tid()、execname()等いくつかはチュートリアルに書かれていますが、全体はstapfuncs manual pageにまとめられています。

"データの加工"についての具体的な方法は、あまりチュートリアルには書かれていません。 C言語やAWKで一般的な範囲の四則演算やビット演算、条件式は準備されていて、詳細はリファレンスマニュアルにまとめられています。

"出力"については、とりあえずC言語の"printf"関数と似た構文を提供しています。 Ruby等では"%b"というと数値を2進数表記で表示してくれますが、systemtapではバイト列をそのまま表示してくれます。

"%1b"で1バイト分、"%2b"で2バイト分のバイナリを出力する事ができます。 使えるとは思えないけれど、”あ”をUTF8で表示しようと思ったら、次のようなコードになります。

probe begin {
  i = 8552931
  printf("%4b\n", i)
  exit()
}

Analysis

おそらく斜め読みをして、if,while,forなどのループ、式はC言語と似ているなぁというぐらいが分かると思います。

systemtapがawkを強く意識しているだけに、Perl同様に文字列の連結は"."を使って行なう点は少し注意が必要そうです。

あとは使う変数は基本的に全てスコープローカルになるので、probeやfunctionを跨って参照したい変数は、"global"によって宣言する必要があります。 さらに"global"宣言された変数は自動的にread, writeロックがかかるため、不用意に使う事は避けたいところです。

Analysis::Target variables

probeの中でだけ、特殊な変数"Target variables"が参照できます。 これはprobeを仕掛けてた個所のコンテキストにあるカーネル内部の変数にアクセスができるという機能です。 リファレンスマニュアルを見る限りでは、そのコンテキストにあるポインタ(*file)に"$file"のようにアクセスができるようになっています。ローカル変数へのアクセスは難しそうですね。

ここでは"target variables"ではない、"$"を使ってコマンドラインの引数にアクセスする方法が書かれています。 数値の場合は"$1"ですが、文字列の場合は"@1"のように"@"を使って書く必要があります。

// print_name_age.stp
probe begin {
  printf("name: %s, age: %d\n", @1, $2)
  exit()
}
$ sudo stap print_name_age.stp hoge 28
name: hoge, age: 28

"$<pointer>"と"$<数値>"は似ていても、"target variables"は"$<pointer>"だけなので、注意が必要です。

Analysis::Functions

functionについて、ここまで明記されていませんでしたが、probeの中に書く処理をまとめて記述するために使います。

ただし、前記の"Target variables"へのアクセスはできないため、functionの引数に指定するなどして渡す必要があります。functionの引数は値渡し(pass by value)なので必要に応じて結果はfunctionの戻り値として受け取ります。

Analysis::Arrays

次がarrayについてで、連想配列が使えますが、必ずglobalで宣言する必要があり、サイズはコンパイル時に決定されている必要があります。 宣言時に配列のサイズを省略すると、MAXMAPENTRIESのデフォルト値、2048で配列が確保されます。

arrayについての仕様でおもしろそうなところは、foo[4,"hello"]のようにindexに数値や文字列の組み合せが使えるというところでしょうか。 使ってしまえば、特にどうという事はないんですけどね、実用的な仕様だと思います。

わかりずらいのは"foreach ([a,b] in foo)"のところでしょうか。 説明は"simple loop in arbitrary sequence"とありますが、事前にfooがfoo[4,"helloworld"] = barのように宣言されている必要があります。

例1:ちゃんと動くシンプルな例

#!/usr/bin/stap
global ary
function print_ary() {
  foreach (k in ary) {
    printf("ary[%d] => %d\n",k, ary[k])
  }
}
probe begin {
  ary[0] = 3
  ary[1] = 5
  ary[2] = 1
  print_ary()
  exit()
}

例2:チュートリアルと似ていて、なおかつ"l+"と書く事でindexの第2要素を昇順(小さい→大きい)にソートしている。

#!/usr/bin/stap
global ary
function print_ary() {
  foreach ([k,l+] in ary) {
    printf("a[%d,%s] => %d\n", k, l, ary[k,l])
  }
}
probe begin {
  ary[0,"a"] = 3
  ary[1,"d"] = 5
  ary[2,"b"] = 1
  print_ary()
  exit()
}

上記のforeach()にある"k","l","ary"の各変数に"+"や"-"を追加する事で昇順や降順にソートさせる事ができます。具体的に動かして観察するのが良いでしょう。小さい工夫ですが、収集するデータによっては便利だと思います。

Analysis::Aggregates

データ収集用の特殊なデータ型です。 特殊にしたおまけにデータの解析、収集に便利そうな機能が付いてきます。 簡単にまとめると次のようになります。

  • データを格納する変数はarray型を使うため、おのずとglobalで宣言する必要がある
  • データを格納する時に"<<<"オペレータを使う
  • データへのアクセスは"@avg()"など'@'で始まる特殊な関数を使う

リファレンスをみても使える特殊関数は"@count", "@sum", "@min", "@max", "@avg", "@hist_linear", "@hist_log"だけのようです。

Analysis::Safety

いろいろな上限値などに触れられていますが、システムのデフォルト値はstap manual pageの"Safety and Security"の項目に書かれています。

Tapsets

"tap" + "sets"ぐらいの意味だと思いますが、/usr/share/systemtap/tapsetにインストールされているライブラリスクリプトについての解説です。

ユーザーが作成したスクリプトの中に未定義のprobeやfunctionがあると、/usr/share/systemtap/tapset/*.stpフィアルを順番に調べていき、対応する名前をみつけると自動的に読み込みます。 ただし、該当するprobeやfunctionがみつかったファイル全体の内容を読み込みます。

また複数のprobeを組み合せて一つのprobe名にする、aliasの機能があります。 応用すると、前処理をさせるといった目的に使う事もできます。

あとは*.stpファイルの中にC言語のコードを埋め込めるという"Embedded C"の機能でしょうか。 具体的な例はtapsetディレクトリを除く方が確実そうです。他に”embedded C"を使う際の注意点が列挙されています。

便利そうですが、あまりにも怖いのでVMWare上でテスト環境を作って試そうと思います。

Tapsets::Naming conventions

前述のとおりsystemtapはtapsetにあるファイルを全て確認して、必要に応じてファイル全体を取り込みます。 この仕様のため大勢がバラバラに開発したライブラリスクリプトで共通のglobal宣言した変数を使うなどした場合には、名前のバッティングが発生する可能性があります。

そこでガイドラインが掲載されていますが、常識的な個所を除くとだいたい次のような感じです。

  • 作成したtapset固有の名前を付ける (以下、TAPSET、とします)
  • function名など外部からアクセス可能なところは、"TAPSET_"で始まる名前をつける
  • global変数など内部的にアクセスする変数などには、"__TAPSET_"で始まる名前をつける

さいごに

結局はリファレンスに当たらないといけない事ばかりでしたが、systemtapは1.0もでてようやく安定するのでしょうか。

バージョン間の違いには詳しくありませんが、systemtap-1.0/NEWSファイルをみるとUbuntu 8.04 LTSのパッケージとして提供されている0.6.0から多くの機能が加えられ、変更されていることがわかります。

ずっと昔に大学の演習でSunOS 4のパフォーマンスアナライザーを使った時は、C言語用のライブラリだけが提供されていてsystemtapが裏でやっているような事を手作業でやっていたように記憶しています。 教育目的としても手軽に使えそうですね。

2009/11/24

systemtapの情報源

Linux版DTraceともいえるsystemtapのチュートリアルは2007年に作成された日付がありますが、一通り読んでみて入門としてはとても良くできているという印象を受けました。

次に関連する情報はないかなぁとGoogleで調べていたのですが、 そこでひっかかったのが、@ITで連載されていた”Linuxトラブルシューティング”シリーズの記事、「最終回 SystemTapで真犯人を捕まえろ!」でした。

systemtapに限らず全体的に内容が高度に見えて、でも切り口が日常的にどこかで発生していそうな事象を扱っている点が秀逸だと思います。 時間みつけて@ITの記事は抑えておいた方がいいかなぁ。

メモリ周りの思い出

昔の仕事でJavaを使っているときは、そのJavaの世界だけで起こる奇妙な現象には悩まされました。 JVM自体に問題があればsystemtapなんかでも分かるんでしょうけれど、Javaの世界で完結している場合にはGCのログファイルと解析ツールが必須になります。

最近ニコニコ動画でWPFを使ってGCの様子を可視化している動画をみましたが、”Javaの場合”、

  • まだ隙間があるのにいきなりコンパクション走るのか
  • コンパクションはもっと重い処理として表現して欲しい

などと思ったのは私だけでしょうか。

Javaの場合はトータルの空きメモリは10MBあっても、1MB分の配列を宣言するとOutOfMemoryExceptionが発生する場合という事もあり得ます。環境によっては100MBの空き領域でも厳しいかも。 JVMが使うメモリ内部の連続空き領域を考慮しないと、サーバーサイドのJavaプログラミングはできません。

Javaは原理的にはC++のようなdelete()を忘れるタイプのメモリリークは発生しませんが、それでもオブジェクトへの参照が残っていればGCの対象にはなりません。 そもそもコード中のオブジェクト参照を完全にコントロールできれば、C++でもdelete()を忘れるという事は起らないでしょう。

そんなわけでオブジェクトの管理ができていない事で全体のメモリ使用率が上がって、Compaction Phaseで動かせないオブジェクトが残る事とあわさってOutofMemoryExceptionが起ります。 世代別GCも採用が進んで問題は起りにくくなっていますが、Compactionは完璧ではないのにGCに頼ってできる事をしない開発者が増えないか心配です。

GCは開発者をサポートしますが、怠慢をフォローすることはできないでしょう。

ディスクの使用率がなぜか下がらないとか

ほかによくあったのはディスク使用率の警告がでて、サイズの大きなログファイルを削除したのに警告が収まらないというものでした。

ファイルを削除しても、それ以前にopen()されたファイルディスクリプタをclose()しなければいけないのに、ログを吐き続けているプログラムが一旦起動したら停止するまでclose()しない仕様だったりすると最悪です。 Javaなんかだと裏側のライブラリがそういう設計だったりして、必ずしも開発者の単純な落ち度ということでもないのですが、いろいろみていると全体の環境を把握して維持する事の難しさを実感します。

より深刻な問題なのはそういう説明をしても理解できないアプリケーション開発者でしょうか。 プログラミングでJavaだけを教えるのも悪い事ではいのですが、せめてJVMの設計と実装についての講義も必修にして欲しいです。

あれ、systemtapのドキュメントを読んでいたはずなのにJavaの話しになってる…。

2009/11/23

再起動せずにUbuntu 8.04 LTSでsystemtapを使う

systemtapは実行中のkernel内部の情報を取るためのユーティリティです。 RHELでの使い方はSystemTapによるライブカーネルプローブにさらっと載っています。

UbuntuというかDebianでは、debuginfoを含んだ"linux-image-debug-$(uname -r)"パッケージの中にはモジュールについてのデバッグ情報は含まれていません。 そのせいか解説しているWebサイトでは、いきなり"make menuconfig"を実行してカーネルのリコンパイルから説明しているものがあります。

カーネルが実行しているシステムコールだけを知りたかったので、debパッケージをそのまま使うことにしました。

systemtapを導入してもhelloworld.stp以外が動かない

導入するパッケージは2つです。

$ sudo apt-get install linux-image-debug-$(uname -r) linux-headers-$(uname -r)
$ sudo apt-get install systemtap

"$(uname -r)"は”uname -r"部分を実行した結果の文字列"2.6.24-25-generic"に置き換えられて、いま実行しているカーネルのバージョンに応じたデバッグイメージを取り込みます。 もしカーネルが更新されても常にデバッグイメージを最新にしたい場合には"linux-image-debug-generic"等を指定すると良いでしょう。

この状態で"/usr/share/doc/systemtap/examples"以下にあるプログラムを実行してみても、helloworld.stpを除くと実行に失敗するものがあります。

$ sudo stap /usr/share/doc/systemtap/examples/iotime.stp
semantic error: libdwfl failure (missing kernel debuginfo): No such file or directory while resolving probe point kernel.function("sys_open")?

何が悪いのか調べるために"strace"コマンドを使いました。

$ sudo strace stap /usr/share/doc/systemtap/examples/iotime.stp
...
open("/boot/.debug/vmlinux-2.6.24-25-server", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/debug/boot/vmlinux-2.6.24-25-server", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/boot/vmlinux-2.6.24-25-server.debug", O_RDONLY) = -1 ENOENT (No such file or directory)
...

いろいろな場所にあるデバッグイメージを探しに行きますが、見つけられないようです。 導入したdebパッケージ名から、どこにイメージがインストールされているか確認します。

$ dpkg -L linux-image-debug-2.6.24-25-server
/.
/boot
/boot/vmlinux-debug-2.6.24-25-server
...

微妙に名前が違うんですよね。まぁ安易にデバッグ情報にアクセスできるのも考えものなのかなぁ。 どこに置くべきか迷ったのですが、/boot/.debugを作成してリンクを張る事にしました。

$ sudo mkdir /boot/.debug
$ cd /boot/.debug
$ sudo ln -s ../vmlinux-debug-2.6.24-25-server vmlinux-2.6.24-25-server

これでsystemtapが使えるようになりました。

2009/11/21

Ubuntu 9.04 64bit版にCUDA 2.3 SDKを入れてみた

CUDA 2.3がUbuntu 8.04 LTS向けにはリリースされていないので、サブマシンに9.04 Desktop amd64版を新規にインストールしました。

CUDAはNVIDIAのサイトから入れてみましたが、いろいろ2.2 SDKとは構成が違っていて戸惑っています。 OpenCLとディレクトリ構成が同じになったようですね…。

"~/NVIDIA_GPU_Computing_SDK/C/"ディレクトリでmakeが成功するまでには、追加でつぎのようにパッケージの追加が必要でした。

  • $ sudo apt-get install g++
  • $ sudo apt-get install mesa-common-dev libglu1-mesa-dev libxi6-dev libxmu-dev libglut3-dev

これとは別に"openssh-server"パッケージを入れて、リモートから作業できるようにしています。

CUDA 2.2 Toolkitとの見た目の違い

ライブラリが32bit版と64bit版の両方が添付されているので、古いプログラムで/usr/local/cuda/libを"-L"オプションに指定している場合、32bitのライブラリがサーチパスに入ってるので、64bitのオブジェクトコードとリンクできずにエラーになります。おそらくcommon.mkを修正すれば良いと思われます。

この他にも古いCUDAプログラムをダウンロードしてきた場合、そこに含まれる"lib/libcutil.a"のコンパイルに失敗するといった事例が出ています。[ 参考URL::CUDPP 1.1 compile errors (and fixes) (gcc 4.3.3-5ubuntu4) ] いくつかファイルを修正する他に、CUDA 2.3 SDKをコンパイルしていれば、そこに含まれるlibcutil.aなどのライブラリファイルをlibディレクトリにコピーしてくるだけでも解決できます。

この変更のため環境変数LD_LIBRARY_PATHか"/etc/ld.so.conf.d/"以下のファイルで、"/usr/local/cuda/lib"を指定していれば"/usr/local/cuda/lib64"に変更する必要もあります。

2009/11/20

PowerShell 1.0でアプリの一覧を取ってみたものの

東京の寒さを報せるニュースをみていたら、街を歩く人達が自分よりも暖かそうな格好をしている事に気がつきました。うーん、油断してたかなぁ。でもまだここら辺は雪は降ってないし、大丈夫じゃないかなぁと思っています。

たまたまokwaveでWindowsに登録されているアプリケーションの一覧を取る方法について質問されているのをみました。 手元のWindowsXP Home SP3でpowershellを使う方法を試してみたところ、エラーになってしまいました。

PS C:\Documents and Settings\Owner> gwmi win32_product


IdentifyingNumber : {15DA9946-FB08-3742-A385-9F8AAA863D71}
Name              : Microsoft Visual F# Runtime 1.0
Vendor            : Microsoft Corporation
Version           : 10.0.21006
Caption           : Microsoft Visual F# Runtime 1.0

Get-WmiObject : エラーです
発生場所 行:1 文字:5
+ gwmi  <<<< win32_product

"gwmi"は"Get-WmiObject"のエイリアスです。 調べてみたところバグと認識されているものと挙動は同じようです。 [ 荒井省三のBlog::[PS]WMIの取り扱いについて ]

まだBeta版のVisualStudio2010を入れているので、まさかその関連でWMI周りも変ってしまったのかと思い、VMWareのスナップショットをVisualStudioを入れる前に戻して確認してみました。 結果は無事に動きましたが、関連についてはいまいちはっきりしません。

C:\Windows\System32\直下の最近変更されたdllを眺めてみても、wmi.dllとかは変更されていないし、VisualStudio2010が変な情報をレジストリに登録してしまったのかなぁ。そんなことあるんだろうか。

ソフトウェアのインベントリ(台帳)管理のためには、一覧の取得は重要な機能だと思うのですが、レジストリをみなきゃ確実じゃないとしたら、ちょっとインタフェースがいけていないなと思います。

まぁインベントリ管理ソフトウェアを使えという話しになるかもしれませんが、使った事がある人なら、情報整理のための追加で必要な膨大なマンパワーと価格を考えて発狂しそうになったことでしょう。

PowerShell 2.0を試してみる

2.0自体はマイクロソフトのサイトからダウンロード可能です。その際に1.0をアンインストールするように言われますが、プログラムの追加と削除で”更新プログラムの表示”オプションにチェックを入れないと一覧に表示されず、アンインストールできません。更新プログラムの一部なんですね…。

導入が終ると”すべてのプログラム”の"Accesories"フォルダの中にPowerShellのプログラムが導入されていました。昔どこかで試したIntegrated Scripting Environment (ISE)が入っています。

で、早速win32_productにアクセスして試してみると、似たようなエラーが起ります。

VisualStudio 2010 Ultimate beta2をアンインストールしてみる

beta2を入れる前にbeta1を削除する手順はあるのですが、beta2自身をアンインストールする手順はUltimate beta2のリリースノートの中ぐらいしか見当りませんでした。

正しい順番でアンインストールする必要があるならサポートプログラムが欲しいところです。 まだbetaだからしょうがないけど、製品版がでても同じなんだろうなぁ…。 まっさらな環境にbeta2をインストールしている場合のアンインストール順番は以下の通り。

  1. Uninstall all instances of Visual Studio 2010 products (for example, Visual Studio 2010 Ultimate).
  2. Web Deployment Tool (Web配置ツール)
  3. Silverlight 3 SDK (Microsoft Silverlight 3 SDK - 日本語)
  4. SQL Server 2008 Management Objects (SQL Server 2008 R2 Management Objects)
  5. SQL Server CLR Types (SQL Server System CLR Types)
  6. SQL Server 2008 (Microsoft SQL Server 2008)
  7. SQL Server 2008 Native Client (Microsoft SQL Server 2008 Native Client)
  8. SQL Server Compact 3.5 SP2 (Microsoft SQL Server Compact 3.5 SP2 Beta 日本語版)
  9. Visual Studio 2010 Tools for Office Runtime Beta 2 (Visual Studio 2010 Tools for Office Runtime Beta 2 (x86) 及び 同 Language Pack)
  10. The .NET Framework version 4 Language Pack (未導入)
  11. The .NET Framework version 4 Extended (reboot, if prompted) (Microsoft .Net Framework 4 Extended Beta 2)
  12. The .NET Framework version 4 Client (reboot, if prompted) (Microsoft .Net Framework 4 Client Beta 2)

"プログラムの変更と削除”の一覧に表示される時には、日本語の名前で登録されていたり、リストにある名前の通りではなく"Microsoft"が前に付いたりします。 ”SQL Server CLR Types”などは逆に"Microsoft"が前に付かないので、見過してしまいそうです。

また一連の操作の中で"Microsoft SQL Server 2008"を削除する時には、Windowsの再起動処理で失敗マークが付いてしまい、一旦再起動した後でなければアンインストールできませんでした。

明記されていませんが、Visual Studio 2010 Tools for Office Runtime Beta2 (x86)を削除する時には、同 Language Packも削除するべきでしょう。

”Microsoft .NET Framework 4 Beta 2 日本語 Language Pack”は導入されていませんでした。 "Microsoft .Net Framework 4 Extended"と"同 Client"を削除すると、対応するLanguage Packは自動的に削除されました。ここの挙動はOffice Runtimeと違いますね。

まぁBeta版ですからね。いいんですけれど、やっぱり面倒だなぁ。

途中から"gwmi win32_product"が動く

"Web Deployment Tool" (Web配置ツール)を削除して、Silverlight 3 SDKのアンインストールを始めてから、無事にアプリケーションの一覧が表示されるようになりました。

でも全部アンインストールしてから手動でSilverlight 3 SDKとWeb Deployment Toolをインストールしても現象は再現しませんでした。

PowerShellは良いんですけどね、この挙動だと仕事でインベントリ管理にはちょっと使えないかなぁ。

2009/11/15

財団法人が発行しているレポートをチェックしてみた

最近は政府の予算削減のために「仕分け」が行なわれている様子が中継されています。

10億の補助金を配るのに従業員8人の法人が5億の経費をかけているとかいわれて、監督官庁は雑多で定型的な作業なので法人に任せるのが適当とか受け答えしていたり、どこまでがネタかよく分からないですね。

そうはいっても独自に事業を行なっている法人もあるだろうし、どんな仕事しているのかなというわけで今回は「財団法人ソフトウェア情報センター」の平成20年度 調査研究報告書: ソフトウェアの適正取引に関する調査研究報告書 を読んでみました。

確かGoogleで「IT, 運用 ガイドライン」ぐらいのキーワードで探した中に含まれていたと思うのですが、いろいろおもしろかったです。

調査報告書なのに対象読者がいまいち不明

まとめた方々が法律家のようで、想定している読者が経営者なのかSIerのようなシステムを売るベンダなのか不明です。

なにか契約時に注意するべきチェックリストなどといった便利なものはなく、 雰囲気は大学3年生ぐらいが夏休みにまとめたレポートといったところでしょうか。

調査と報告はされていますが、とりたてて注目するべき研究成果はないようです。 まぁこの手の文書は発行する事が目的で注目される事を想定していないでしょうから、 それだけに読むとツッコみどころが満載です。

結論を知らないで読むとがっかりしそう

事実が羅列されていますが、それを踏まえて”ベンダ or ユーザは〜するべき”といった事は、ほとんど書かれていません。少しだけ”免責事項に入れておくと良い”といった記述がありますが、それは責任を回避する事しかできないので、より良いものを作るという根本的な問題解決にはなっていません。

後半にまとめられている結論は「ベンダの説明不足とユーザの勉強不足」という事になっています。それをどうすれば良いかは書かれていないと。

ちょっと編集してチェックリスト的なものにすれば実用的なのですけどね。 まぁ読者の設定もよく分からないし、ベンダが問題を回避するためだけの資料に使われそうです。

技術者が書いたものではないためか、より良いものをいかに作るのか、という話しではないです。

保守サポートは何年間提供するべきか

そもそも保守サポートを提供するべき年数についても、”いろいろ考えて合理的に決めてね”といった事が書かれているだけで、参考にするべきサンプルも事例も紹介されていなかったり、スルー力が大いに鍛えられる構成になっています。

そもそもこの前段は保守部品(HW)を提供しなかった業者に対する判例を紹介していて、後段のソフトウェアの保守性とは整合性が取れていないと思います。

たぶん読んでおいた方がよいページ

まぁ、この報告書は啓蒙以上の効果はなさそうですが、ちょっとgoogleで検索してみるとソフトウェアの契約に関連するトラブルとしては次のような内容をおさえておくのが良いと思います。

発注者側が不利益を被らないために何をするべきか

ソフトウェアほど幅のある物もないわけで、発注する側はどういった効率改善を期待するのか、 どう使うのか明確にイメージした上で発注する必要があります。それが難しいんですけどね。

コンピュータに詳しくない発注者側が面倒になって「とにかく作ってくれ」みたいな流れになると、最終的には全員が泣くことになります。 面倒でも理解できるまでは議論する必要もありますし、業界の常識をベンダに説明する必要もあります。

残念ながらシステム開発についてはベンダ側の実力によって、同じ人手をかけても出来上がってくるものには、とても使えるものから、ギリギリ使えないものまで、かなりの幅があります。

また残念ながらベンダは人手をかけずに最低限の使い勝手で納入する事ができれば利益を最大にできるインセンティブを持つので、信用できないと思えば発注しない事も大切でしょう。 まともなベンダはその事を知っていて顧客の信頼に答える事は何よりも大切だと理解しているはずです。

まともなシステム開発をしたいなら、顧客のパフォーマンスが最大限になるような業務フローの変更といった提案込みで話しをするべきだとも言えます。

発注側は自社できないから外注するのでしょうけれど、少なくとも自社のビジネスとシステムに詳しい人物を確保してコーディネータとして活躍してもらう事がこれからは増えてくるのだと思います。

発注する側はアウトソーシングと思っているかもしれませんが、 勘違いして自社の業務を理解している技術者が不在だとコーディネータになるべき人材がなくて悲惨な事になるでしょうね。

何が必要かって難しいですけれど、 ベンダは仕事をしない事で利益が最大になるインセンティブを持っている事を理解して、 発注者側が求めるものをしっかりイメージして、それを要件として文書できっちり出す事が重要だと理解する事でしょうね。

2009/11/10

Phenom II 940の電圧を少し下げてみたらハングアップ

折角Black Editionを使っているので、Phenom II 940の電圧を少し下げて電力消費が削減できないかなと思いました。

BIOSのメニューからCPU Voltageを1.35Vから0.1Vちょっと落してみたのですが、3.0GHzのままだといくつか不具合が発生しました。

  1. mplayerやvlcで動画を再生すると正しく描画されない
  2. BOINCで計算エラーが発生する
  3. デスクトップ上のアイコンにノイズが乗り、動画同様正確に描画されない
  4. 最終的には動画再生中にシステムがpingも通らなくなりハングアップ

症状と対策

対策は簡単で、元に戻すのも嫌だったので、電圧の低下と同じ比率でクロックを下げて2.8GHzにしています。

症状の方は深刻で、最初はCPU周りの変更で発生したとは考えられませんでした。 いろいろ変更していたのが災いしました。

普通にX11を使っている分にはgnome-terminalやFirefoxはちゃんと動いていたのに、最初は動画だけがうまく描画できないと思ったんですよね。それでも1、2秒間は普通にみえるので、最終的にシステムがハングアップするまで気がつきませんでした。

BOINCの計算結果がエラーになっていたのも気にはなりつつ原因はわからず…。 全てはクロックと電圧を同じ比率で下げて解決しました。

まとめ

オーバークロックしていると動画のエンコーディングに失敗するとブログ等に書かれています。 しかし画面描画の一部だけが悪くなると、ビデオカードやドライバを疑ってしまいそうです。

たぶん動画再生や計算でCPUのコアが一生懸命働いた時にだけ、計算結果がおかしくなってしまったのでしょう。

これはこれで良い経験なのかな…

2009/11/08

Ubuntu 8.04のディスクパフォーマンスは改善されたのか?

5月頃は4台の160GB HDDをRAID-10にしてみたり、RAID-1x2にしてみたりしていたのですが、6月頃にマザーボードとCPUを変更(Phenom II 940 & M4N78 Pro)して、さらにHDDまで500GBx2 Software RAID-1に変更しました。 その時にUbuntu 8.04.3をインストールして、いままで使ってきました。

数ヶ月使った体感としてディスクパフォーマンスが上ったように感じていたのですが、pdumpfsで取っている古い/etcのバックアップを比較した時に/etc/fstabに設定されている"relatime"オプションが以前は設定されていない事に気がつきました。

「おお、これが効いたのか?」と思ってみたものの、設定を外して再起動して、いろいろコンパイルしてみたり、写真をブラウズしてみたりしてみたものの、そんなに違いはないなぁというところに落ち着きました。

交換したHDDのパフォーマンスが良かったっていう事なんだと思います。 atimeを無用に更新する必要はないので、relatimeの設定は戻してそのまま使っています。 "noatime"を設定しても不都合はないけれど、statコマンドはたまに使うし少し過激な設定だと考えて設定していません。

いろいろチューニング

これをきっかけに少しチューニングしてみようか、という事でext3に"journal_data_writeback"オプションを設定してみました。これはジャーナリングをメタデータのみにする設定で、データ領域のジャーナルを省略する事でパフォーマンスを上げようという試みです。

新しいカーネルではext3のデフォルトがwritebackになるようですが、これはext4への移行に備えての準備という側面が強そうですね。パフォーマンスにマイナスになる理由はないのですが、それほどでもないという事でしょうか。

試しに使うにしても'/'に設定するのは少し面倒で、Ubuntuのフォーラムで手順が掲載されているのでそれに従うのが良いでしょう。 menu.lstとfstabに設定を書けば、tune2fsでマウントオプションを設定する必要はないと思うのですが、どれをみても設定する事になっていますね…。なぞだ…。

他のマシンにHDDを持っていってもwritebackモードでmountする必要性はないだろうしなぁ。fstabとtune2fsを使わないと有効にならないとか理由があるのかなぁ。

ちなみに、"mount -o remount,data=writeback"みたいな設定をしようとすると途中からジャーナルの方法は変えられないとエラーになります。'/'の設定を変更する度に再起動が必要になるのは少し面倒かな。

data=writebackの感想

使ってみて速いかというと、気持ち速くなったかもしれない、というのが感想です。 tar-ballの展開なんかも気持ち良く終るけれど、以前と比べてどうかというと、違いがあるかは微妙です。

全体的には改善されているかはともかく快適なのは間違いないですね。 以前ならたまにひっかかるような感じがした写真のサムネイルの更新処理なんかは、いまのところ何ともありません。これはしばらく使ってみないとなんともいえないでしょうね。

仕事用のマシンなら絶対に設定しないけれど、自分用のマシンならこれでも良いかなぁ。

さて、次はCPUのクロックでもいじってみることにしましょう。

2009/11/01

OpenLDAP: access権限の管理

olcAccessディレクティブの管理

slapd.confに代ってslapd.dを使っていると、Access権限(olcAccess)の管理が少しだけ面倒に思えてきます。 それはslapd.confのようにテキストエディタで古いものを削って、新しく付け足すわけではないから。

例えば最上位DNからの一括検索を拒否しつつ、パスワード情報は認証時以外には開示しない設定だとします。 slapd.dディレクトリの中で、アクセス権限は次のように管理されています。

olcAccess: {0}to dn.base="dc=example,dc=org" by * none
olcAccess: {1}to attrs="userPassword" by anonymous auth by * none
olcAccess: {2}to dn.children="dc=example,dc=org" by self read

この状態で下記のldifファイル(update.ldif)に対してldapmodifyを実行したとします。

dn: olcDatabase={1}bdb,cn=config
changetype: modify
replace: olcAccess
olcAccess: to dn.base="dc=example,dc=org" by * read
$ ldapmodify -x -W -D cn=admin,cn=config -f update.ldif

適当なところが一行置き換わるのかなと思いきや、3行だったolcAccessが1行に変更されています。

olcAccess: {0}to dn.base="dc=example,dc=org" by * read

不思議なことは何もないのですが、管理をする上では挙動をチェックして把握しておくのが重要だったりします。

管理用に何かWebベースやGUIなソフトウェアを使うかもしれません。 cn=config以下ならデータサイズが限られているので良いのですが、 データ件数が多いエントリをGUIなどのツールで開く時には、hard limitsに逹っするまでのサーバー側の負荷はもちろんですが、多くのエントリ情報を格納するツール側もそれなりのメモリを消費するためハングアップに気をつける必要があります。

台帳的な管理の手法

既に定義されているolcAccessの間に定義を挿入するというのは、少し面倒そうなので、簡単なシェルスクリプトを作成しました。

ツールは主に2つのパートから成ります。

  1. show_olcAccess.sh: 定義済みolcAccessエントリの確認ツール
  2. gen_access_ldif.sh: 一括登録、削除、更新用のldif生成ツール

どういう風に使えば便利そうかを想定すると…

$ ./show_olcAccess.sh > current.ldif ## olcAccessの行だけをcurrent.ldifに書き出す
$ vi current.ldif ## 追加したいolcAccess行を追加する
$ ./gen_access_ldif.sh < current.ldif | ldapmodify -x -W -D cn=admin,cn=config
## 最後は一気にldif形式のフォーマットを出力してldapmodifyに流し込む

show_olcAccess.sh: 定義済みolcAccessエントリの確認ツール

とりあえずは、"olcDatabase={1}bdb,cn=config"を決め打ちにしてolcAccessの各行を出力するようにします。

#!/bin/bash
ldapsearch -LLL -x -s base -W -D "cn=admin,cn=config" -b "olcDatabase={1}bdb,cn=config" olcAccess | while read line
do
  if /bin/echo -E "$line"|egrep ^olcAccess >/dev/null 2>&1 ; then
    l="$(/bin/echo -E "$line" | sed 's/{[0-9]*}//')"
    echo -E "$l"
  fi
done

これを実行すると次のような表示になります。

$ ./show_olcAccess.sh
olcAccess: to dn.base="dc=example,dc=org" by * none
olcAccess: to attrs="userPassword" by anonymous auth by * none
olcAccess: to dn.children="ou=accounts,dc=example,dc=org" by users read

わざわざ"olcAccess: {0}to"にある"{0}"の部分を取り去っているのは、後から編集する時に邪魔になるからです。 みるだけなら良いのですが、olcAccessを間に1行追加するのに、数字を全部後ろにずらしていくのは不毛でしょう。

gen_access_ldif.sh: 一括登録、削除、更新用のldif生成ツール

次はさきほど1行追加するのに使ったような"changetype: modify"を含むldapmodify用のLDIFファイルを生成します。

#!/bin/bash
db=${1:-"{1}bdb"}
opt="${2:-replace}"
## show header
echo "dn: olcDatabase=$db,cn=config"
echo "changetype: modify"
echo "$opt: olcAccess"
while read line
do
  echo -E "$line"
done

これを実行すると、LDIFファイルを出力します。 入力は”show_olcAccess.sh”で出力されたようなものです。

./gen_access_ldif.sh < access.ldif
dn: olcDatabase={1}bdb,cn=config
changetype: modify
replace: olcAccess
olcAccess: to dn.base="dc=example,dc=org" by * none
olcAccess: to attrs="userPassword" by anonymous auth by self read by * none
olcAccess: to dn.children="ou=accounts,dc=example,dc=org" by users read

もし既存の設定を消したければ、./gen_access_ldif.sh "" delete < access.ldif でできます。 複数のDBがあれば、第一引数に./gen_access_ldif.sh {2}hdbのように指定する事もできます。 次は、olcSuffixとolcDatabaseとの関連を一覧にできれば便利かなぁ。

まとめ

こういうスクリプトって本質的なものじゃないんですけれど、テンプレート+αな操作の場合は準備しておくと、 誰かに頼むとか、手順で置いておかなきゃいけない時に、作業が簡潔になり早くできたりして便利です。

ldapmodifyを実行する部分もスクリプトにしても良いですが、そこは本質的なところではないので。 また、これ以上作り込んでしまうと、トラブルシュートができない。

スクリプト化は勉強にならない、という批判もありそうですが、本物のマニュアル手順を"plan B"として載せておけば良いでしょう。

スクリプトの中で特殊な事はしていませんが、"$1"が未定義の場合に"{1}bdb"をセットするところはダブルクォートなしに書くと、そのまま展開されてしまいます。 ${1:-{1\}bdb}でも良さそうだけれど、ここら辺のドキュメントって見た事ないなぁ。