(☝ ՞ਊ ՞)☝ウイーン
というわけで、こんにちは、Eject アドベントカレンダー 22日目ということで、昨日の
machshev さんに続き、島田がお送りします。
OSC界隈でも活発ですし、謎の世界進出も進みつつあるEjectソリューションなのですが、僕から見て以下の2派があるなぁという感じです。以下にちょっと説明します。
(Before Eject と After Eject)
Before Eject
OS、ソフトウェア、ミドルウェアで、CD-ROMドライブのトレイを開けるまでのフローを作る分野であると言えます。多くの場合は最終的にLinuxのejectコマンドを実行すると思いますが、それまでにラッパーを通してアプリにしたり、プロトコルにしたりといった作例がこれまであります。
一方、これらを自由に扱えるのはプログラマやLinux/BSDユーザ中心で、普通のユーザにはもしかして近寄りがたい部分が未だあるのかもしれません。
After Eject
では、After Eject と言えば、CDのトレイが開いた運動を、何かしらのエネルギーに変換する分野と言えるでしょう。ピタゴラ装置のトリガーが動いたあとの挙動、と言えば分かるでしょうか。
なので、恐らくオープンソースというよりは、Make等、ものづくりの分野に携わる方々が得意とするところじゃないかなと思います。僕の知る人とかは、アイデアはあるんだけど...という話を聞くのですが、この原因がまさに「アイデアはあるけど、手を動かす術が分からない」状態であるわけです。
このように、一言で Eject ソリューションといっても、少なくとも2つの分野があり、扱う方によって、得意不得意はどうしてもあるのかなという印象があります。
もちろん、各論も大切であり、それぞれ片方だけで論じても面白いし必要なのですが、両輪が相互にまわってこそ、楽しいEjectソリューションになると考えています。
今後は、ものづくりの分野でもEjectに興味を持っていく人を増やすべく、僕も模索していければいいかなぁと思ってる次第です。(Make は大規模すぎるので、手頃なところでニコ技等のコミュニティでしょうか...?)
ということで、しょっぱな硬い話で失礼しました。僕の方からは、2日に渡って適当なネタをお送りできればと思います。今日は Before Eject な話、23日は After Eject な話となります。
Before Ejectネタ : Linux Live CDのEject事情
さて、僕は
opencocon という名前の Live CD ディストリビューションを作っています。CD をほとんど必須とするので、Eject とは縁があるような気がします。しかし、Eject するまでは結構長い道のりが必要となってしまいました。これまでの記録から、Eject できるようになるまでの試行錯誤をお送りします。
事情その1 : initramfs vs initrd
まず僕が取り組んだのは、Live CD を作るにあたってある意味当たり前の機能、すなわち、「Live CD の終了後に CD ドライブを Eject する」ことでした。しかし、最初に作った Live CD (opencocon v1)ではそれができませんでした。
この点、実はここで語るよりも、Plamo Linux で有名な、こじまさんが書いている記事が分かりやすいですし、opencocon でもまったく同じ結果になりました。
"とりあえず動くものができたので,P-Plamo 0.1としてメーリングリストで紹介したところ,「終了時にDVDをejectして欲しい」というリクエストがありました。〜当初は,終了処理の最後にでもejectコマンドを実行すればいいだろう,と簡単に考えていましたが,調べ始めたところ,かなり深刻な問題に気づきました。" ---
ソースコード・リテラシーのススメ 第23回 ソースコード・リテラシー【実践編 2】
一言で何が嵌ったかというと、「initramfs でなく、initrd を使わないと Eject できない」ということでしょうか。
詳しい説明はばっさり割愛しますが、恐らく組み込みLinuxをご存知の方であれば、何を今更 initrd 使うねんと言いそうですし、
Kernel のドキュメントを見ても、initrd はやり方が古いとか書かれてしまっています。
しかし、initrd は Live CD に必要な機能を入れるために必要だったのです。そう、
すべては Eject のためだけなのです。
というわけで、その後 initrd に切り替え、コードの多くを書き換えた末、
opencocon v4 からは無事、終了後に Eject できるようになりました。その詳細は非常にどろどろとしている上、1年以上前の話なのでカットしますが、失敗CDの山を積んでしまったことだけは確かです...。
(opencocon 終了後のEject画面。ちなみに、お決まりのパターンは「kon-kon!」です)
事情その2 : たびたび壊れる対応
しかし、一旦は綺麗にできた感じがする opencocon の Eject 機能もたびたび壊れました。主に Kernel や基本的なコンポーネント (uClibc や busybox)のバージョンを上げた際に決まって何かがエンバグするのですが、Eject も度々できなくなってしまいました。
直近ですと opencocon v8 なのですが、気がついたら Eject できなくなっていたままリリースしてしまい(申し訳ありません...)、デバッグモードで何回 eject コマンドを手で叩いてもうまく動きませんでした。
opencocon は通常、容量節約のため busybox コマンドに同梱された eject を使用します。多分それの相性が悪くなったんだろう、ということで急遽本物の eject コマンドをバンドルするようにしました。パッケージ管理システム(opkg)の関係で、本物の eject は
「eject.eject」という、何とももにょもにょする感じのコマンド名になってしまいましたが、これを実行することでなんとか乗りきりました。それが現時点で最新リリースの opencocon v8a です。
(毎度おなじみ opencocon のメニュー画面)
事情その3 : Copy to RAM で Ejectしたい
Live CD はなぜ簡単に Eject できないのでしょうか? 答えは簡単で、CDにシステムの全てが収録されているからです。
もう少し詳しく言いますと、Live CD 内に squashfs と呼ばれるファイルシステムでシステム全体を固められたファイル(squashfs ファイル)を、CD 上から読み込んでいるためです。そのため、強制的に Eject すると、システム全体が止まってしまいます。CDドライブが2個以上ある時はその限りではないのですが、1個だけでは、想像の通り Eject することはできません。
しかし、抜け道はあります。squashfs ファイルをどこか別の場所にコピーし、CDから読み込むべきファイルを無くせばよいのです。
いくつかのディストリビューションにはそんな機能が実装されており、例えば、
Slax や
Porteus には Copy to RAM という機能があります。
(Slax の起動画面。Copy to RAM の起動項目がある。ついでに F1 で詳細な説明がある)
これを選択すると、squashfs ファイルをRAMディスクにまるごとコピーし、デスクトップ環境の起動後は CD を Eject してもよい状態となります。Slax や Porteus はファイルシステム全体のサイズが数百MB程度ですので、現在のコンピュータであれば、メモリをそれほど圧迫することはないでしょう。なので、あえて Eject するためのLive CDディストリビューションには、このような要件にすることは必須に近いと言えます。
では、opencocon でも実装しよう!ということで...と、その先は今年のKOF(関西オープンフォーラム)で発表したネタから抜粋するこんな感じです(PDFですが、
事の経過はこちらをご覧ください。Webビューワなのは
こちらからどうぞ)。
(KOFで発表したスライドから抜粋。しかし中はほぼEject話だったり)
一言で何がいけなかったかというと、「Linux の cp コマンドは非同期なので、sync してファイル処理を終わらせないと Eject できない」ということでした。なんと間抜けな...orz。
いやはや。Before Eject もここまで奥深いものがあるのか、となんとなく思ったこの頃です。
あれこれありましたが、その甲斐あって、 opencocon v8a では Copy-to-RAM として実装しました。メモリが256MB以上あれば、是非こちらで動かしてみてください。
起動途中に Eject するので驚くと思いますw。
(opencocon v8a の起動画面。ここで Copy-to-RAM を選択しましょう。)
今後は
本当は opencocon で意図的にリモート Eject する仕組みを作ろうかなと思い、下準備をしているところです。内部的には Python をバンドルし始めたり等しているのですが、グルーとなる部分の構想があまり固まっていないのもまた事実ですし、本来クライアント専用OSと謳っている opencocon にサーバ的機能を加えてもよいのか?といった葛藤などがあったりします。この点はまた追っていくとしましょう。
長文失礼しました。明日は menonon さんです(☝ ՞ਊ ՞)☝ウイーン