«前の日記(2011-04-05) 最新 次の日記(2013-05-21)»

cheep, cheep, cheep...


2011-05-07

_ 今日の日記の要旨

skype を 64bit linux にインストール後しばらくすると「Please reinstall Skype」 というメッセージが表示される場合には, root で prelink -u -a した後に prelink パッケージを削除することで問題が解決するかも知れない.

……って事のためだけに,だらだらと長文を書いたというのが真の要旨か.

_ [linux][debian] skype と prelink と amd64 の微妙な問題

最近は amd64 なディストリビューション向けにも skype のバイナリが用意されている.……がこれは実は,32ビットバイナリをパックして,64ビットディストリビューションにインストールできるよう依存関係を記述しただけのモノ.今回は,それが原因でいろいろとハマったという話.

skype を debian/amd64 な環境にインストールしてしばらくすると,標準エラー出力に以下のようなエラーメッセージが表示されて, skype が起動できないようになる.

/usr/lib/gio/modules/libgvfsdbus.so: wrong ELF class: ELFCLASS64
Failed to load module: /usr/lib/gio/modules/libgvfsdbus.so

同時にエラーメッセージの表示されたダイアログが表示される.エラーメッセージは「Please reinstall Skype」.

確かに,メッセージに従って skype のパッケージを再インストールすると症状は一時的に改善される.……が,何日か経過するとまた起動しなくなってしまう.そもそも,なんでパッケージの再インストールでダイナミックリンクの問題が直るんだ.こんな訳の分からん問題のために,何十MBのファイルを再インストールするなんてやってらんねー.

コンソールのエラーログの意味は,32ビット実行ファイルが64ビットの共有ライブラリを読み込もうとしてエラーになっているという事.しかし,インストール直後は大丈夫なのに,後からおかしくなる意味が分からない.

このあたりのメッセージを検索して原因を調べてみると,関係がありそうで無いページ*1が大量に引っ掛かるのだが, 答えが載っているのはこのフォーラムの議論だった.

どういう問題だったかというと, prelink という,オブジェクトの動的リンクを事前に計算しておいて,プロセスの起動 (正確には exec 後のダイナミックリンカの処理) を高速化する仕組みがある.これが,64bit環境にインストールされた 32bit オブジェクトを取り扱う際に,誤って 64bit のライブラリをリンクするように指定してしまうという事があるという事のようだ. prelink は cron で定期的に実行されるので, skype のパッケージをインストールした直後には prelink が効いておらず,そのため正しく起動する.

さて, prelink は計算した動的リンクの情報を記録するために,実行ファイルを書換えるようだ.この情報を削除するためには,実行ファイルを書換える権限のあるユーザ (早い話が root) で「prelink -u 実行ファイル」というコマンドを実行すれば良い.とりあえず,上記のコマンドで skype から prelink の情報を削除して, skype を実行してみると問題なく起動するようになった.あとはこの状態を維持できれば良いのだが, cron で prelink が実行されると元の木阿弥になってしまう. prelink が skype の実行ファイルだけを無視するように設定できれば良いのだが,どうやらそんな都合の良い仕組みは無さそうだ.

cron で prelink が実行された直後に prelink -u を実行するというのも一つの手だが,そんな面倒な事をするより prelink 事態を削除してしまおうと決めた.具体的な作業としては, prelink -u -a を実行したあとに, prelink パッケージを削除.おそらく,ダイナミックリンカの処理が占める割合は昔に比べて減っているので,性能への影響は微小だと予想される.

*1 ディストリビューションがリリース前の時の欠陥だとか, linux32 コマンド経由で起動しろだとか