More info...

2009-09-17

私は如何にして高性能ファンレスPCから超小型LinuxマシンにMediawikiを実質数時間の作業で移行したか。

ある日、オフィスに行くとキムラデービーの木村さんに面白いマシンがあると言うので見せて貰った。

マシンと言っても、小さい白い箱からプラグがニュッと出ているだけである。そう、一昔前に話題になったあのSheevaplugである。

Sheevaplugはニュースで見て知って居たが、実物を見るのは初めてだ。とはいっても、実際に稼働しているものを見たわけではなく箱から出したばかりのものを見せて貰っただけである。実物を見た第一印象は、軽い!小さい!の一言だ。この小さな箱でサクサクとUbuntu Linuxが動いてたったの$99(送料別)というから、俺が欲しくなるのは当たり前というものである。Sheevaplugを知らない人のために、簡単にSheevaplugのスペックを紹介しよう。
  • ARM 1.2GHz CPU
  • 512MB RAM
  • 512MB フラッシュメモリ
  • ギガビットイーサネット
  • SDカードアダプタ
  • USB 2.0 x1
  • 110mm (L) x 69.5mm (W) x 48.5 mm (H)
少々RAMやフラッシュメモリが貧弱な気はするが、$99ならば十分納得のスペックである。しかも完全ファンレスだから無音。そして19W程度の低消費電力。家庭でこっそりと使いたい男性諸氏にとって何とも有り難い仕様ではないだろうか。家庭にも財布にも優しいとはこのことである。

詳しい仕様などについては、Sheevaplugを販売しているGlobal Technologies社のページを見て頂きたい。ここまで低価格な製品に仕上げられたのは、ひとえにSystem-On-a-Chipだからであろう。(それでも安すぎるが、それはβ版という扱いだからだろうか。)

なんでこのSheevaplugが欲しかったかというと、MySQL Practice Wikiを運用するためのハードウェアをもっと小型のものにしたかったからだ。完全に無音で、低消費電力で、運用が楽ちんなもの。今は静音PCの老舗オリオスペックで購入したHFX MicroにSolaris 10をインストールして使っているのだが、さらにもっと静かで低消費電力でコンパクトなものに変えたかったのである。(ついでにHFX Microを他の用途で利用したくなったからである。)

このSheevaplug、色々弄ってみたがとても素直でいいこちゃんである。あれよあれよという間に設定が進み、電源を入れてからものの数時間程度の実作業でWikiを移行することが出来てしまった。まあ、ぶっちゃけMediawikiを移行したかっただけなので大した作業は必要なかったといえばなかったのだが、こうも作業がすんなり運ぶのはちょっと感動である。あまりにも作業がスムーズだったので、「よく分からないから手を出しづらいな」と思っている人のために設定すべき内容を残しておくことにする。皆さんの購買意欲に繋がれば幸いである。いや、ホントコレ$99の割にちゃんと動いてお買い得ですよ、ちょっとそこの奥さん!

というわけでまずは購入についてであるが、日本に代理店がないので海外から直接取り寄せる必要がある。しかも購入できるのはGlobal Technologies社のWebサイトだけ。海外からなので送料はけっこうかかる。Fedexなら$34.77。Sheevaplug本体$99とあわせると合計$133.77なり。円高だから12000円ちょっと。それでも安い!

Sheevaplugが届いたらまずは電源投入!であるが、Sheevaplugにはボタンなどの類は一切なく、電源を入れるといきなりOSが起動する。しかもSheevaplugにはディスプレイアダプタというものが存在しないので、モニタに接続することもできない。どうやって操作すればいいのだろうか??

答えはUSBケーブルである。Sheevaplugの側面にはデバッグ用のミニUSBポートがついており、付属のケーブルを使ってパソコンと接続することによって操作が可能である。筆者の場合はMacを使って設定したのだが、MacからSheevaplugへ接続するための設定方法はHisao's Blogさんで紹介されているのでそちらを参照した。至って簡単である!(筆者は種々のサーバーマシンをメンテナンスしてきた経験があるので、この手のコンソールからマシンにアクセスするのは抵抗がないのだが、PCしか触ったことがない人はちょっと抵抗があるかも知れない。けど簡単だからやってみるといいよ!)

LinuxやWindowsを母艦にしたい場合には、このへんこのへんを参考にすると良いだろう。

USBのコンソールから接続すると、u-bootというファームウェア(PCでいうところのBIOSの役割に相当)が表示され、それからUbuntu Linuxが起動する。サーバー用途で利用したいので、もちろんOSには固定IPを割り当てたりDNSの設定をしたりするわけであるが、この辺の諸設定は普通のUbuntu Linuxとまったく同じである。のら犬にさえなれないさんで、設定すべき項目がよくまとめられているのでそちらを参照して欲しい。

諸設定が終わったら、今度はカーネルの更新を行う。デフォルトで搭載されているカーネルは、2.6.22.18なのだが、ファイルの書き込みが遅いらしい。そこで、カーネルを2.6.30.5へアップグレードしよう。といっても作業は簡単で、有志が作成してくれたスクリプトをイッパツ実行するだけである。

1. まずはwgetをインストールする。

shell> apt-get install wget

2. 実行出来る不思議なREADMEをゲットする。

shell> wget http://sheeva.with-linux.com/sheeva/README-2.6.30.5

3. READMEのパーミッションを変更して実行する。

shell> chmod 700 README-2.6.30.5
shell> ./README-2.6.30.5

するとこのスクリプトがカーネルのバイナリをダウンロードして、フラッシュメモリへの書き込みまで行ってくれる。簡単楽チンである。詳細な手順はHisao's Blogさんで紹介されているのでそちらを参照して欲しい。

さて、ここで問題になるのがデフォルトのフラッシュメモリが512MBしかないということである。流石にMediawikiしか利用しないといっても、これでは直ぐにデータが溢れてしまうことだろう。(パッケージも色々追加したいしね。)ならばSheevaplugに搭載されたSDカードスロットにSDカードを差し込んで利用すれば良い。SDカードは適宜事前に準備しておこう。筆者はちょっと奮発して、Sandiskの超速いヤツを購入した。SheevaplugよりもSDカードの方が高額だったのはご愛敬!である。SDカードを利用するには、u-Bootと呼ばれるファームウェアを更新する必要がある。u-BootはUSBケーブルでコンソールに接続し、OSが起動する前にキーを押すことで操作することができる。キーを押すタイミングは次の通り。(次はUSBケーブルを使って接続し、Sheevaplugを起動したときの出力例だ。)

       __  __                      _ _
        |  \/  | __ _ _ ____   _____| | |
        | |\/| |/ _` | '__\ \ / / _ \ | |
        | |  | | (_| | |   \ V /  __/ | |
        |_|  |_|\__,_|_|    \_/ \___|_|_|
 _   _     ____              _
| | | |   | __ )  ___   ___ | |_ 
| | | |___|  _ \ / _ \ / _ \| __| 
| |_| |___| |_) | (_) | (_) | |_ 
 \___/    |____/ \___/ \___/ \__| 
 ** MARVELL BOARD: SHEEVA PLUG LE 

U-Boot 1.1.4 (Aug 22 2009 - 11:36:42) Marvell version: 3.4.16

U-Boot code: 00600000 -> 0067FFF0  BSS: -> 006CF100

Soc: 88F6281 A0 (DDR2)
CPU running @ 1200Mhz L2 running @ 400Mhz
SysClock = 400Mhz , TClock = 200Mhz 

DRAM CAS Latency = 5 tRP = 5 tRAS = 18 tRCD=6
DRAM CS[0] base 0x00000000   size 256MB 
DRAM CS[1] base 0x10000000   size 256MB 
DRAM Total size 512MB  16bit width
Flash:  0 kB
Addresses 8M - 0M are saved for the U-Boot usage.
Mem malloc Initialization (8M - 7M): Done
NAND:512 MB

CPU : Marvell Feroceon (Rev 1)

Streaming disabled 
Write allocate disabled


USB 0: host mode
PEX 0: interface detected no Link.
Net:   egiga0 [PRIME], egiga1
Hit any key to stop autoboot:  0 <---- ココでキーを押す!

u-Bootはコマンドを入力して操作するのだが、以下は主なコマンドである。
  • help...コマンド一覧を表示する。
  • boot...OSを起動する。
  • printenv...環境変数を表示する。
  • setenv...環境変数を設定する。
  • saveenv...環境変数を保存する。(setenvだけではフラッシュメモリに書き込まれない。)
  • run...環境変数に設定されたコマンドを実行する。
  • mmcinit...SDカードを認識する。
  • bubt...u-Bootを更新する。
というわけで、bubtコマンドを使ってu-Bootを更新するわけである。更新する対象のu-Bootは、アクセス可能なtftpサーバーに事前に置いておかなければならない。Mac OS Xならば、デフォルトでtftpサーバーを利用することができる。u-Bootの新しいイメージを、/private/tftpbootディレクトリにコピーしよう。u-Bootのイメージは、Hisao's blogさんの方で配布されているのでそちらからダウンロードして欲しい。ついでに言うと詳細な更新手順もそちらに載っているので参照して欲しい。以下、実行手順例のダイジェストである。

Marvell>> setenv ipaddr 192.168.1.123
Marvell>> setenv serverip 192.168.1.100
Marvell>> setenv netmask 255.255.255.0
Marvell>> saveenv
Marvell>> bubt u-boot-rd88f6281Sheevaplug_400db_nand.bin

すると「Override Env parameters? (y/n)」と聞かれるので、必ず「n」を選択しよう。リセットすればいっちょあがりである。

Marvell>> reset

リセットが完了したらもう一度u-Bootに入り、mmcinitコマンドを実行しよう。これでSDカードを利用する準備は整った。OSを起動して、fdiskコマンドを利用するとSDカードを認識しているのが分かるだろう。

ここで次に考えるのは、恐らくSDカードからOSをブートすることが出来ないか?ということではないだろうか。実はこの作業、めちゃくちゃ簡単である。簡単であるにも関わらずその効果は絶大で、OSの起動がもの凄く高速化したり(u-Bootからものの5秒程度で起動するようになってしまう!)、SDカードから起動するようにしておけば、SDカードを差し替えることでOSを入れ替えるといった芸当も可能になり、超オススメなのである。SDカードからOSを起動する手順は次の通り。

1. パーティションを切る。

shell> sudo fdisk /dev/mmcblk0

パーティションの切り方はお好みで。筆者はswap用に1GB、残りをファイルシステム用に設定した。

2. ファイルシステムを作成する。

shell> sudo mkfs -t ext3 /dev/mmcblk0p1
shell> sudo mkswap /dev/mmcblk0p2
shell> sudo mount /dev/mmcblk0p1 /mnt

3. OSをコピーする。

shell> sudo cp -ax / /mnt
shell> sudo cp -a /dev /mnt

4. カーネルを/mntにコピーする。

カーネル本体はREADME-2.6.30.5を実行したときにダウンロードされているはずなので、これを使う。ファイルの場所は/mntではなく/mnt/bootでも構わない。/mnt/uImageとしてリンクを作成しておこう。

shell> sudo mv /root/sheeva-2.6.30.5-uImage /mnt
shell> sudo ln /mnt/sheeva-2.6.30.5-uImage /mnt/uImage

ついでに/mnt/etc/fstabを編集して、スワップを追加しておこう。

/dev/mmcblk0p2 none swap sw 0 0

5. u-Bootを設定する。

OSを全てSDカードにコピーしたら、再起動してu-Bootへ入ろう。そしてbootargs環境変数を変更し、「root=/dev/mtdblock1」となっているところを「root=/dev/mmcblk0p」に書き換えよう。また、OSを起動する前にu-Bootでmmcinitコマンドを実行する必要があるが、これはbootcmd環境変数の先頭に「mmcinit;」という一文を追加することで対処可能である。

6. OSを起動する。

OSはSDカードから起動しただろうか?これまでの一連の作業はPlug Wikiのページ(英語)にも載っているので、そちらも参照して欲しい。上記の手順は筆者が多少アレンジしたものである。

上記の設定では、SDカードが抜かれている場合にOSが起動しない。さらに一歩進んでu-Bootを設定すると、SDカードがある場合にはSDカードから、SDカードがない場合には内蔵のフラッシュメモリからOSが起動する・・・という具合に動作させることが可能である。この手順はのら犬にすらなれないさんで紹介されているので、そちらを参照して欲しい。

さて、ここまで来れば後は通常のUbuntu Linuxとまったく同じように操作が可能である。ディスク容量もそこそこあるので、あまり神経質になる必要もない。(あえて解説する必要すらないかも知れない。)しかし、こんな風にすればちゃんと出来ますよ!ということを紹介するために、実際に筆者が行った設定を紹介しておく。

1. MySQLのビルド(笑)

いきなりコレかよ!?と思うかも知れないが、MySQLerたるものまずはMySQLをコンパイルしたくなるのが人情というものだろう。MySQLをビルドするには、build-essentialおよびlibncursesw5-devパッケージをインストールする必要がある。

shell> sudo apt-get install libncursesw5-dev build-essential

ま、以下はお好みで。

shell> sudo apt-get install libtool bzr

MySQL Community Serverのソースコードをダウンロードサイトから入手し、解凍し、おもむろに...

shell> ./configure [オプション色々] && make

を実行する。さすがにSheevaplugのCPUではビルドに時間が掛かってしまう。筆者はコンパイル中に外食していたので実際にどれぐらい掛かったかは不明であるが、見るからにコンパイルが遅いので相当時間を要するのだろう。無事にビルドが完了したら

shell> sudo make install

でMySQLのインストールは完了である。/etc/mysql/my.cnfを編集しよう。ついでにソースコードに含まれるsupport-files/mysql.serverを/etc/init.dにコピーし、MySQL Serverが自動で起動するようにしておくといいだろう。

shell> sudo cp support-files/mysql.server /etc/init.d
shell> update-rc.d mysql.server defaults

データディレクトリの初期化とか諸々の設定に関しては説明を割愛する。筆者はMySQL 5.1.38に含まれるInnoDB Pluginを利用したかったのでソースコードからビルドしたが、まあ、ふつうは自分でビルドするよりはUbuntu標準のMySQLパッケージを利用するといいだろう。その場合のインストール方法は以下。

shell> sudo apt-get install mysql-server mysql-client

2. Apache/PHPのインストール

MySQL Practice Wikiは、Wikipediaと同じMediawikiを使って構築している。MediawikiはPHPで記述されているので、ApacheやらPHPやらをインストールする。

shell> sudo apt-get install apache2 php5 php5-mysql

3. データ移行

あとは既存のマシン(HFX Micro)からMySQLのデータをmysqldumpを使って移行し、利用しているMediawikiのファイル(ApacheのDocumentRoot以下)を全てコピーすれば作業は完了である。めでたしめでたし!!

以下、Sheevaplugを利用するにあたって参考になるサイトをリストアップしておく。この投稿を読んで「興味がわいたよ!」と思ってくれたギーク諸氏は、ぜひSheevaplugを試してみて頂きたい。さすがに発売からかなり経過しており、なおかつOSも標準的なLinuxなので、Sheevaplugは結構使えるというのが筆者の感想である。


PlugWiki
http://plugcomputer.org/plugwiki/

SheevaPlug@Pukiwiki
http://mizupc8.bio.mie-u.ac.jp/pukiwiki/index.php?SheevaPlug

Yu's Blog
http://notepad4yu.wordpress.com/

Hisao's Blog
http://www.alpha.or.jp/

のら犬にさえなれない
http://xeon.cocolog-pikara.com/blog/

Ubuntu Weekly Recipe: 第69回 GW特別企画・電源プラグ型コンピューターSheevaPlugの使い方(1):基礎編
http://gihyo.jp/admin/serial/01/ubuntu-recipe/0069

Ubuntu Weekly Recipe: 第70回 GW特別企画・電源プラグ型コンピューターSheevaPlugの使い方(2):インストール編
http://gihyo.jp/admin/serial/01/ubuntu-recipe/0070

2009-09-08

GPLの境界線

GPLを利用するにあたって度々議論されるのが「プログラムの境界」という問題である。GPLソフトウェアを改良または組み込んで別のソフトウェアを作成すると、頒布する際に新しく作成したソフトウェアのライセンスもGPLにしなければならない。ここで注意しなければいけないのは、どこまでがそのソフトウェアの「境界」なのかということである。言い換えると、どこまでが「GPLソフトウェアを組み込んだ」状態なのかということである。自分のソフトウェアをGPLで頒布しようと考えている人にとっては、境界線はあまり意識しなくてもいいテーマである。優れたGPLソフトウェア資産は利用し放題のワンダーランドである。しかしGPL以外のライセンスを利用したいと考えている人にとっては、どこまでならGPLのソフトウェアを利用しても構わないのか?ということを明確に把握していないと、後で著作権法違反で訴えられることになってしまうので注意が必要である。そのような問題があるとなるとGPLソフトウェアを毛嫌いするようになって、極端な人は「コンピュータ内でひとつでもGPLソフトウェアが動いていればそのコンピュータ全体をGPLにしなければいけないのか?」と考えてしまう人も出てくるだろう。GPLについての知識が乏しく、「得体の知れない恐ろしいライセンス」だと考えている人はそのような誤解をしてしまうかも知れないが、しかし実際はそのようなことはない。そのように恐怖してしまうのはGPLについてよく知らないからであり、GPLについて正しい知識を身につければ無闇に恐れることもなくなるだろう。より多くの人にGPLソフトウェアを利用して貰い、時には他のライセンスを用いて上手にGPLとつきあい、時にはGPLでソフトウェアをリリースして社会に貢献することができるよう、今日はGPLの境界線について説明しようと思う。

ズバリ、境界線はプロセス

多くのOSにはGPLソフトウェア、例えばGNU tarやGCC、gdb、bash、GNOME、MySQLなどがバンドルされている。商用ライセンスのもの、例えばMac OS X Serverなどである。GPLソフトウェアをバンドルするとOS全体をGPLにしてソースコードを公開しなければいけないんじゃないか?と思うかも知れないが、そのようなことはない。GPLにおいて、「ソフトウェアを一部に取り入れた」と見なされるのはプロセスまでである。従って、GPLと同一のプロセスで動作するようにしなければ、ライセンスをGPLにしなくても良いのである。いくらMySQL Serverをバンドルしていようが、Mac OS X ServerをGPLにしなくても良いのはこのためである。

同一のプロセスとして動作するということは、

  • 元のGPLソフトウェアを改造
  • GPLのライブラリをリンク

のいずれかをするということである。それ以外の場合は、安全にGPLと他のソフトウェアを組み合わせて利用することが出来るのである。

ここはMPLやCDDLなどのライセンスと大きく異なる点である。MPLやCDDLにおけるソフトウェアの境界線は「ソースコード」である。ライブラリをリンクしようが何しようが、元のソースコードに手を加えなければライセンスをMPLまたはCDDLにしなくても良い。このため、これらのライセンスはGPLとは非互換であり、コピーレフトの強制力はずっと緩い。(コピーレフトの観点からしても、互換性の点からしてもダメライセンスなのである。)

ネットワーク経由で利用する場合

GPLのサーバープログラムへネットワークを介して接続するクライアントプログラムを作成する場合、そのクライアントはGPLにしなければいけないのか?答えはNo!!である。上記の通りGPLソフトウェアの境界線はプロセスであり、ネットワークを介して接続する場合にはGPLの強制力は働かない。どのようなライセンスを採用するかは自由である。MPLでも、Apacheライセンスでも、プロプラエタリでも問題ない。

だったらMySQL Serverに接続するクライアントプログラムもGPL以外のライセンスを自由に採用してもいいのか?!と思うかも知れないが、ここには注意すべき点がある。クライアントプログラムがlibmysqlclientやConnector/J(JDBCドライバ)を利用する場合、これらのライブラリがGPLであるためリンクするとGPLの強制力が働いてしまう。MySQL Serverへ接続するプログラムをGPL以外のライセンスでリリースしたければ、これらのライブラリを利用せず自分で接続用のドライバを開発するか、libmysqlclientやConnector/Jの商用ライセンスを購入する必要がある。

インタープリターは?

もしインタープリターのライセンスがGPLだった場合はどうだろうか?実はGPLにはインタープリター上で動くプログラムに対する強制力はない。インタープリターがGPLであっても、インタープリター上で動くプログラムはGPLにしなくても良い。

ただし、インタープリターに拡張モジュールを追加した場合には注意が必要である。もしインター上で動くプログラムが拡張モジュールを利用するようであれば、そのプログラムはGPLにしなければいけない。この点はとても理解に苦しむ点かも知れない。何故ならばインタープリターがGPLでもGPLの強制力はないのに、そのインタープリターにGPLの拡張モジュールを追加した場合は強制力が働いてしまうからだ。

このようなややこしいルールが設定されている理由は明確で、それは抜け穴を塞ぐためである。もし、拡張モジュールとしてGPLのライブラリを利用しても良いのであれば、GPLのライブラリはインタープリターを介せばGPLの強制力が失われてしまうことになり、プロプラエタリな製品で利用し放題になってしまう。これではGPLの意義は失われてしまうだろう。優れたGPLライブラリがあり、そのライブラリを拡張モジュールとしてインタープリター上で動くプログラムで利用したければ、そのプログラムはGPLにしなければならないのである。

PHPやPerl、RubyなどでMySQL Serverへ接続するためのプログラムをGPLにしなければいけないのはこの制約があるからであり、これらのプログラムがMySQL Serverへ接続するための拡張モジュール(mysql拡張、mysqli拡張、DBD::mysql、MySQL/Rubyなど)はlibmysqlclientのバインディングになっているのである。GPLのlibmysqlclientを利用するため、例えインタープリター上で動くプログラムであってもGPLにしなければならないのである。