<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>jognote in silico</title>
	<atom:link href="http://insilico.jognote.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://insilico.jognote.com/blog</link>
	<description>ジョグノート開発ブログ エンジニアサイド</description>
	<lastBuildDate>Wed, 13 Aug 2008 06:33:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>cURL に HTTPS でアクセスできるように証明書を追加する</title>
		<link>http://insilico.jognote.com/blog/2008/08/13/curl-%e3%81%ab-https-%e3%81%a7%e3%82%a2%e3%82%af%e3%82%bb%e3%82%b9%e3%81%a7%e3%81%8d%e3%82%8b%e3%82%88%e3%81%86%e3%81%ab%e8%a8%bc%e6%98%8e%e6%9b%b8%e3%82%92%e8%bf%bd%e5%8a%a0%e3%81%99%e3%82%8b/</link>
		<comments>http://insilico.jognote.com/blog/2008/08/13/curl-%e3%81%ab-https-%e3%81%a7%e3%82%a2%e3%82%af%e3%82%bb%e3%82%b9%e3%81%a7%e3%81%8d%e3%82%8b%e3%82%88%e3%81%86%e3%81%ab%e8%a8%bc%e6%98%8e%e6%9b%b8%e3%82%92%e8%bf%bd%e5%8a%a0%e3%81%99%e3%82%8b/#comments</comments>
		<pubDate>Wed, 13 Aug 2008 06:33:54 +0000</pubDate>
		<dc:creator>odt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://insilico.jognote.com/blog/?p=28</guid>
		<description><![CDATA[ウェブサービスの開発をしていると、プログラムの中で HTTP で通信をするために cURL を使うことが多いと思います。
PHP からも cURL を使うための 便利なライブラリ があります。
普通の HTTP のリクエストを投げる場合は用意されたものをそのまま使えばいいのですが、HTTPS で通信を行いたい場合は、サイトによっては証明書が必要だったりします。
素のままの状態で、例えば https://mixi.jp/ にアクセスすると、次のようなエラーでアクセスすることができません。

% curl 'https://mixi.jp/'
curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
More details here: http://curl.haxx.se/docs/sslcerts.html
&#160;
curl performs SSL certificate verification by default, using a &#34;bundle&#34;
 of Certificate Authority (CA) public keys (CA certs). The default
 bundle [...]]]></description>
			<content:encoded><![CDATA[<p>ウェブサービスの開発をしていると、プログラムの中で HTTP で通信をするために <a href="http://curl.haxx.se/">cURL</a> を使うことが多いと思います。<br />
PHP からも cURL を使うための <a href="http://www.php.net/curl">便利なライブラリ</a> があります。</p>
<p>普通の HTTP のリクエストを投げる場合は用意されたものをそのまま使えばいいのですが、HTTPS で通信を行いたい場合は、サイトによっては証明書が必要だったりします。</p>
<p>素のままの状態で、例えば https://mixi.jp/ にアクセスすると、次のようなエラーでアクセスすることができません。</p>

<div class="wp_syntax"><div class="code"><pre class="text">% curl 'https://mixi.jp/'
curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
More details here: http://curl.haxx.se/docs/sslcerts.html
&nbsp;
curl performs SSL certificate verification by default, using a &quot;bundle&quot;
 of Certificate Authority (CA) public keys (CA certs). The default
 bundle is named curl-ca-bundle.crt; you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.</pre></div></div>

<p><a href="http://curl.haxx.se/docs/sslcerts.html">cURL &#8211; Details on Server SSL Certificates</a> によると、cURL には初期状態では証明書が入っていないようです。</p>
<blockquote><p>Until 7.18.0, curl bundled a severely outdated ca bundle file that was installed by default. These days, the curl archives include no ca certs at all. You need to get them elsewhere.</p></blockquote>
<p>なので、必要に応じて証明書を追加してやります。</p>
<p>上記の cURL のドキュメントによると、証明書を取得する方法はいくつかあるようなのですが、どれもうまくいかなかったので、試行錯誤の結果、うまくいった方法をここに書いておくことにします。</p>
<p>まず、お目当てのページに普通のウェブブラウザでアクセスします。ここでは Mac の Firefox を使うことにします。</p>
<p><a href="http://insilico.jognote.com/blog/wp-content/uploads/2008/08/curl_https_mixi_jp.png"><img src="http://insilico.jognote.com/blog/wp-content/uploads/2008/08/curl_https_mixi_jp-300x244.png" alt="" title="curl_https_mixi_jp" width="300" height="244" class="alignnone size-medium wp-image-30" /></a></p>
<p>ここで、右下にある鍵マークをダブルクリックして、Page Info の窓を出します。</p>
<p><a href="http://insilico.jognote.com/blog/wp-content/uploads/2008/08/curl_pageinfo.png"><img src="http://insilico.jognote.com/blog/wp-content/uploads/2008/08/curl_pageinfo.png" alt="" title="curl_pageinfo" width="500" height="426" class="alignnone size-full wp-image-34" /></a></p>
<p>Security タブに View Certificate というボタンがあるので、それをクリックし、詳細画面を出します。</p>
<p><a href="http://insilico.jognote.com/blog/wp-content/uploads/2008/08/curl_details.png"><img src="http://insilico.jognote.com/blog/wp-content/uploads/2008/08/curl_details.png" alt="" title="curl_details" width="500" height="562" class="alignnone size-full wp-image-35" /></a></p>
<p>Certificate Fields のどこかをクリックして選択しておいて、左下の Export ボタンをクリックします。</p>
<p><a href="http://insilico.jognote.com/blog/wp-content/uploads/2008/08/curl_save_format.png"><img src="http://insilico.jognote.com/blog/wp-content/uploads/2008/08/curl_save_format.png" alt="" title="curl_save_format" width="309" height="150" class="alignnone size-full wp-image-36" /></a></p>
<p>証明書の保存形式を聞かれるので、X.509 Certificate with chain (PEM)を選択します。ここが重要です。<br />
1つ上の X.509 Certificate (PEM) でよさそうですが、これだとうまくかないです。<br />
ただの PEM だと証明書が1つしか入っていませんが、with chain の方だと3つ入っていて、これが何らかの意味があるみたいです。</p>
<p>証明書に適当な名前をつけて保存します。ここでは mixi.crt としておきます。</p>
<p>必要な証明書を入手したら、これを既存の証明書ファイルに追加してやります。<br />
上記の cURL のドキュメントによると、cURL では証明書を一切持っていないと書いてありましたが、FreeBSD の ports や CentOS の rpm で入るパッケージにはいくつかの証明書が入っていました。</p>
<p>FreeBSD の cURL は、証明書を <code>/usr/local/share/curl/curl-ca-bundle.crt</code> から読み込んでいるので、ここに先ほどの mixi.crt を追加してやります。</p>

<div class="wp_syntax"><div class="code"><pre class="text"># cat mixi.crt &gt;&gt; /usr/local/share/curl/curl-ca-bundle.crt</pre></div></div>

<p>curl-ca-bundle.crt は root でないと書き込めないので、root 権限で作業するなり、一時的のパーミッションを変更するなりして作業をします。</p>
<p><code>curl-ca-bundle.crt</code> の PATH は cRUL をコンパイルする時にオプションで指定できるようになっていて、システムによって PATH が違う場合があります。<br />
FreeBSD では <code>/usr/local/share/curl/curl-ca-bundle.crt</code> に設定されていて curl の ports パッケージに含まれていましたが、CentOS では <code>/usr/share/ssl/certs/ca-bundle.crt</code> に設定されていて、curl ではなく openssl のパッケージに含まれていました。</p>
<p><code>curl-ca-bundle.crt</code> の PATH がわからない時には、<code>libcurl.so</code> の中を直接覗いてやると、それらしい文字列が含まれています。</p>

<div class="wp_syntax"><div class="code"><pre class="text">% strings /usr/local/lib/libcurl.so.4 | grep bundle
/usr/local/share/curl/curl-ca-bundle.crt</pre></div></div>

<p>証明書を追加した後では、ちゃんとアクセスできるようになります。</p>
<p>以上、curl で https でアクセスするための証明書を追加する方法でした。</p>
]]></content:encoded>
			<wfw:commentRss>http://insilico.jognote.com/blog/2008/08/13/curl-%e3%81%ab-https-%e3%81%a7%e3%82%a2%e3%82%af%e3%82%bb%e3%82%b9%e3%81%a7%e3%81%8d%e3%82%8b%e3%82%88%e3%81%86%e3%81%ab%e8%a8%bc%e6%98%8e%e6%9b%b8%e3%82%92%e8%bf%bd%e5%8a%a0%e3%81%99%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>34</slash:comments>
		</item>
		<item>
		<title>iPhone のメールを Mew で読む</title>
		<link>http://insilico.jognote.com/blog/2008/07/17/iphone-%e3%81%ae%e3%83%a1%e3%83%bc%e3%83%ab%e3%82%92-mew-%e3%81%a7%e8%aa%ad%e3%82%80/</link>
		<comments>http://insilico.jognote.com/blog/2008/07/17/iphone-%e3%81%ae%e3%83%a1%e3%83%bc%e3%83%ab%e3%82%92-mew-%e3%81%a7%e8%aa%ad%e3%82%80/#comments</comments>
		<pubDate>Thu, 17 Jul 2008 02:26:15 +0000</pubDate>
		<dc:creator>odt</dc:creator>
				<category><![CDATA[emacs]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://insilico.jognote.com/blog/?p=26</guid>
		<description><![CDATA[7月11日、iPhone が発売されましたね。前日、表参道には長蛇の列ができていましたが、販売店によっては当日開店時間に行けば普通に入手できたところもあったみたいですね。
さて、iPhone を契約すると i.softbank.jp ドメインのメールアドレスがもらえるわけですが、このメールは imap を使って読み、smtp を使って送信する普通のメールなので、iPhone 上だけでなく、imap が使える MUA ならば PC など他の端末でもメールを読み書きすることができます。
例えば Emacs 上で動作する MUA である Mew で iPhone のメールを読むためには、~/.mew.el に次のように設定します。

(setq mew-name &#34;Jog Note&#34;)
(setq mew-user &#34;jognote&#34;)
(setq mew-mail-domain &#34;i.softbank.jp&#34;)
(setq mew-smtp-server &#34;smtp.softbank.jp&#34;)
(setq mew-smtp-port &#34;587&#34;)
(setq mew-smtp-user &#34;jognote&#34;)
(setq mew-proto &#34;%&#34;)
(setq mew-imap-user &#34;jognote&#34;)
(setq mew-imap-server &#34;imap.softbank.jp&#34;)
(setq mew-fcc &#34;%Sent Messages&#34;)

iPhone の smtp は通常の 25 番ポートではなく 587 番ポートで動作しているので、mew-smtp-port でポート番号を指定します。また、iPhone の smtp [...]]]></description>
			<content:encoded><![CDATA[<p>7月11日、iPhone が発売されましたね。前日、表参道には長蛇の列ができていましたが、販売店によっては当日開店時間に行けば普通に入手できたところもあったみたいですね。</p>
<p>さて、iPhone を契約すると i.softbank.jp ドメインのメールアドレスがもらえるわけですが、このメールは imap を使って読み、smtp を使って送信する普通のメールなので、iPhone 上だけでなく、imap が使える MUA ならば PC など他の端末でもメールを読み書きすることができます。</p>
<p>例えば Emacs 上で動作する MUA である <a href="http://www.mew.org/">Mew</a> で iPhone のメールを読むためには、~/.mew.el に次のように設定します。</p>

<div class="wp_syntax"><div class="code"><pre class="text">(setq mew-name &quot;Jog Note&quot;)
(setq mew-user &quot;jognote&quot;)
(setq mew-mail-domain &quot;i.softbank.jp&quot;)
(setq mew-smtp-server &quot;smtp.softbank.jp&quot;)
(setq mew-smtp-port &quot;587&quot;)
(setq mew-smtp-user &quot;jognote&quot;)
(setq mew-proto &quot;%&quot;)
(setq mew-imap-user &quot;jognote&quot;)
(setq mew-imap-server &quot;imap.softbank.jp&quot;)
(setq mew-fcc &quot;%Sent Messages&quot;)</pre></div></div>

<p>iPhone の smtp は通常の 25 番ポートではなく 587 番ポートで動作しているので、<code>mew-smtp-port</code> でポート番号を指定します。また、iPhone の smtp はメールを送信するためにユーザ認証を行うので、<code>mew-smtp-user</code> にユーザ名を指定します。</p>
<p><code>mew-fcc</code> に <code>%Sent Messages</code> を設定しておくと、送信したメールが <code>%Sent Messages</code> に保存され、Mew で書いたメールも iPhone で読めるようになります。これを設定しないと Mew が動作しているマシンの <code>+backup</code> に保存されます。</p>
<p>これで <code>emacs -f mew</code> もしくは Emacs を起動した後で <code>M-x mew</code> とすれば Mew で iPhone のメールを読み書きできるようになります。</p>
]]></content:encoded>
			<wfw:commentRss>http://insilico.jognote.com/blog/2008/07/17/iphone-%e3%81%ae%e3%83%a1%e3%83%bc%e3%83%ab%e3%82%92-mew-%e3%81%a7%e8%aa%ad%e3%82%80/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[Xen]DomainUをさくっと作る方法</title>
		<link>http://insilico.jognote.com/blog/2008/06/09/xendomainu%e3%82%92%e3%81%95%e3%81%8f%e3%81%a3%e3%81%a8%e4%bd%9c%e3%82%8b%e6%96%b9%e6%b3%95/</link>
		<comments>http://insilico.jognote.com/blog/2008/06/09/xendomainu%e3%82%92%e3%81%95%e3%81%8f%e3%81%a3%e3%81%a8%e4%bd%9c%e3%82%8b%e6%96%b9%e6%b3%95/#comments</comments>
		<pubDate>Mon, 09 Jun 2008 11:44:17 +0000</pubDate>
		<dc:creator>odt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[linux xen]]></category>

		<guid isPermaLink="false">http://insilico.jognote.com/blog/?p=25</guid>
		<description><![CDATA[ジョグノートでは開発や実験を行うための環境として Xen を使っています。
Xen のバーチャルマシンは DomainU と呼ばれていて、DomainU の作成方法としてはここで紹介されているように virt-install を使う方法が一般的なようです。
しかし virt-install はいろいろな仮想化技術をラップするライブラリである libvirt を使っていて、Xen の DomainU を作成するために Xen 以外のソフトウエアのお世話になるのは少々大袈裟な気がします。
なので Xen の機能のみ使って DomainU を作成できればと思い、調べてみました。基本的にはここにある方法で作業を進めていきます。
以下は CentOS 5.0 が動いている Domain0 上で CentOS 4.6 がインストールされた DomainU を作成するための手順です。
DomainU を新規に作成する場合には OS のインストーラを DomainU として走らせる必要があり、まずはインストーラのための DomainU の設定ファイルを作成します。
インストーラのための設定ファイルを /etc/xen/centos4.installation として以下のように作成します。
ちなみに /etc/xen は root 以外はディレクトリの中に入ることもできないので、実際に作業をする時には sudo bash などして root 権限でシェルを立ち上げてから作業をしたほうがやりやすいでしょう。

kernel = &#34;/var/lib/xen/images/vmlinuz-CentOS4.6-Installer&#34;
ramdisk = &#34;/var/lib/xen/images/initrd-CentOS4.6-Installer.img&#34;
extra = [...]]]></description>
			<content:encoded><![CDATA[<p>ジョグノートでは開発や実験を行うための環境として <a href="http://www.xen.org/">Xen</a> を使っています。</p>
<p>Xen のバーチャルマシンは DomainU と呼ばれていて、DomainU の作成方法としては<a href="http://www.centos.org/docs/5/html/5.1/Virtualization_Guide/task-virt-lab1.html">ここ</a>で紹介されているように <a href="http://virt-manager.et.redhat.com/">virt-install</a> を使う方法が一般的なようです。<br />
しかし virt-install はいろいろな仮想化技術をラップするライブラリである <a href="http://libvirt.org/">libvirt</a> を使っていて、Xen の DomainU を作成するために Xen 以外のソフトウエアのお世話になるのは少々大袈裟な気がします。</p>
<p>なので Xen の機能のみ使って DomainU を作成できればと思い、調べてみました。基本的には<a href="http://wiki.centos.org/HowTos/Xen/InstallingCentOSDomU">ここ</a>にある方法で作業を進めていきます。</p>
<p>以下は CentOS 5.0 が動いている Domain0 上で CentOS 4.6 がインストールされた DomainU を作成するための手順です。</p>
<p>DomainU を新規に作成する場合には OS のインストーラを DomainU として走らせる必要があり、まずはインストーラのための DomainU の設定ファイルを作成します。<br />
インストーラのための設定ファイルを <code>/etc/xen/centos4.installation</code> として以下のように作成します。<br />
ちなみに <code>/etc/xen</code> は root 以外はディレクトリの中に入ることもできないので、実際に作業をする時には <code>sudo bash</code> などして root 権限でシェルを立ち上げてから作業をしたほうがやりやすいでしょう。</p>

<div class="wp_syntax"><div class="code"><pre class="text">kernel = &quot;/var/lib/xen/images/vmlinuz-CentOS4.6-Installer&quot;
ramdisk = &quot;/var/lib/xen/images/initrd-CentOS4.6-Installer.img&quot;
extra = &quot;text ks=http://somewhere/devel-ks.cfg&quot;
name = &quot;centos4.dev&quot;
memory = &quot;256&quot;
disk = [ 'tap:aio:/var/lib/xen/images/centos4.dev.img,xvda,w', ]
vif = [ 'mac=00:16:3e:5b:b3:ec, bridge=xenbr0', ]
uuid = &quot;722e88f7-99bd-47ac-b644-89dab714ee22&quot;
vcpus=1
on_reboot = 'destroy'
on_crash = 'destroy'</pre></div></div>

<p>設定ファイルの記述については <code>man xmdomain.cfg</code> で調べることができます。このインストーラを走らせるための設定ファイルの要点を見ていきます。</p>
<p>まず kernel と ramdisk にはインストーラ用のものを指定します。これは CentOS のインストーラの ISO9660 イメージに含まれていて、<code>/images/xen/{vmlinuz,initrd.img}</code> がそれぞれカーネルとシステムイメージになります。<br />
これらは例えば次のようにして ISO9660 イメージから取り出して、設定ファイルで指定した場所にコピーしておきます。</p>

<div class="wp_syntax"><div class="code"><pre class="text">% sudo mount -o loop /path/to/CentOS-4.6-i386-binDVD.iso /mnt
% sudo cp /mnt/images/xen/vmlinuz /var/lib/xen/images/vmlinuz-CentOS4.6-Installer
% sudo cp /mnt/images/xen/initrd.img /var/lib/xen/images/initrd-CentOS4.6-Installer.img</pre></div></div>

<p>次に extra にはインストーラを起動する時に指定するパラメータを指定します。ここではコンソールでインストールを行うので text と、後述するインスールの自動化のための Kickstart ファイルへの PATH を指定しておきます。</p>
<p>name はこの DomainU につける名前で、他とかぶらないようなわかりやすい名前を適当につけておきます。memory は 256 を指定しています。これ以上少ないと確かインストーラにメモリが少ないと怒られたり、インストールした後も運用上問題があったような気がするので、256MB 以上を割り当てたほうがいいでしょう。</p>
<p>disk では DomainU がハードディスクとして扱うためのイメージファイルを指定します。ここで指定したファイルは実際に存在しなければいけないので、インストーラを走らせる前に作成しておきます。<br />
<a href="http://wiki.centos.org/HowTos/Xen/InstallingCentOSDomU">参考にしたCentOSのWiki</a>の記述によると、virt-install では</p>

<div class="wp_syntax"><div class="code"><pre class="text"># dd if=/dev/zero of=/srv/xen/mailserver.img oflag=direct bs=1M seek=2047 count=1</pre></div></div>

<p>のようにして 2GB のファイルを作成する場合でも、作成する時点では最小限の大きさにしておいて、ファイルへの書き込みと共にサイズが成長していくような作り方をしているようですが、この方法で作成するとインストール中とか yum update してる時とかファイルサイズが大きくなるような作業をしている時に膨大な時間がかかります。確かOSのインストールに4時間ほどの時間がかかりました。なので</p>

<div class="wp_syntax"><div class="code"><pre class="text"># dd if=/dev/zero of=/srv/xen/mailserver.img oflag=direct bs=1M count=2048</pre></div></div>

<p>のようにして、あらかじめ所定の大きさのファイルを作成しておいたほうが快適に DomainU を使うことができます。<br />
なおディスクイメージのサイズですが、コンパイラなどの開発環境や Apache や MySQL などの動作環境をインストールすると 4GB でもすぐにいっぱいになってしまうので、8GB くらいで作成しておいたほうが後々の使い勝手がよいです。次のようにして 8GB のディスクイメージを作成します。</p>

<div class="wp_syntax"><div class="code"><pre class="text">% sudo dd if=/dev/zero of=/var/lib/xen/images/centos4.dev.img oflag=direct bs=1M count=8192</pre></div></div>

<p>vif ではネットワークインターフェースの設定をします。mac に指定する mac address は<a href="http://www.centos.org/docs/5/html/Virtualization-en-US/ch19s21.html">ここ</a>で紹介されている、次のような Python のスクリプトを使って生成します。最初の <code>0x00, 0x16, 0x3e,</code> は Xen が取得しているベンダコードです。</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #808080; font-style: italic;">#! /usr/bin/python</span>
<span style="color: #808080; font-style: italic;"># macgen.py script generates a MAC address for Xen guests</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">random</span>
mac = <span style="color: black;">&#91;</span> 0x00, 0x16, 0x3e,
<span style="color: #dc143c;">random</span>.<span style="color: black;">randint</span><span style="color: black;">&#40;</span>0x00, 0x7f<span style="color: black;">&#41;</span>,
<span style="color: #dc143c;">random</span>.<span style="color: black;">randint</span><span style="color: black;">&#40;</span>0x00, 0xff<span style="color: black;">&#41;</span>,
<span style="color: #dc143c;">random</span>.<span style="color: black;">randint</span><span style="color: black;">&#40;</span>0x00, 0xff<span style="color: black;">&#41;</span> <span style="color: black;">&#93;</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">':'</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: #008000;">map</span><span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> x: <span style="color: #483d8b;">&quot;%02x&quot;</span> <span style="color: #66cc66;">%</span> x, mac<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>これを macgen.py などと適当な名前で保存して、次のようにして実行します。</p>

<div class="wp_syntax"><div class="code"><pre class="text">% python macgen.py
00:16:3e:1b:82:61</pre></div></div>

<p>uuid には同一の Domain0 上で実行する他の DomainU とかぶらない一意な値を指定します。これは uuidgen コマンドを用いて作成することができます。</p>

<div class="wp_syntax"><div class="code"><pre class="text">% uuidgen
722e88f7-99bd-47ac-b644-89dab714ee22</pre></div></div>

<p>on_reboot と on_crash には destroy を指定しておきます。こうしておくとインストーラが終了すると DomainU も終了してくれます。</p>
<p>RedHat 系の Linux のインストーラである Anaconda はKickstart と呼ばれる設定ファイルを用意しておくことにより、インストールの手順を自動化することができます。Kickstart については<a href="http://fedoraproject.org/wiki/Anaconda/Kickstart">ここ</a>が参考になります。<br />
ここでは次の内容で Kickstart ファイルを作成します。</p>
<pre lang=text>
install
url --url http://somewhere/centos
lang en_US.UTF-8
network --device eth0 --bootproto static --ip 192.168.109.49 --netmask 255.255.255.0 --gateway 192.168.109.254 --nameserver 192.168.109.1
rootpw itsasecret
firewall --enabled --trust=eth0 --port=22:tcp,80:tcp
authconfig --enableshadow --enablemd5
selinux --disabled
timezone --utc Asia/Tokyo
bootloader --location=mbr --driveorder=xvda --append="console=xvc0"
reboot

# Partitioning
clearpart --all --initlabel --drives=xvda
part /boot --fstype ext3 --size=100 --ondisk=xvda
part / --fstype ext3 --size=1024 --grow
part swap --fstype swap --size=512

%packages
@core
@development-libs
@development-tools
@legacy-software-development
</pre>
<p>この Kickstart ファイルも要所を見ていきます。</p>
<p>url には CentOS のインストールイメージがあるところを指定しておきます。外部のサイトを指定してもよいですが、それだとネットワークの回線が細いとインストールに時間がかかるので、インストーラの ISO9660 のイメージをダウンロードしておいて、上述のように ISO9660 イメージをシステムにマウントして、インストールイメージが入っているディレクトリが http で見えるように設定しておくといいでしょう。</p>
<p>lang には en_US.UTF-8 を指定します。日本語が通らないかもしれないコンソールで作業をすることが多いので、必ず表示できる設定を選んでおいたほうがよいかと思います。ただ、何故かここで un_US.UTF-8 を選んだのにインストールの時には確認のプロンプトが表示されました。ここは自動化しないのですかね。</p>
<p>network には静的にアドレスを割り振るように設定しました。DHCP Client にするための設定は<a href="http://fedoraproject.org/wiki/Anaconda/Kickstart">上述のWiki</a>に詳しい解説があります。</p>
<p>root のパスワードもここで指定します。</p>
<p>firewall は iptables の設定です。ここでは ssh と http の通信は通すように設定しておきます。</p>
<p>selinux は使わないので disabled を指定しておきます。</p>
<p>timezone は Asia/Tokyo を指定します。ここで指定できる値は、既にOSが入っている環境なら <code>/usr/share/zoneinfo</code> の中にあるファイルの名前を見れば一覧できます。</p>
<p>ハードディスクのパーティッションの切り方は clearpert と part によって指定します。<br />
まずは全てのパーティッションを削除します。そして /boot に 100MB、スワップに 512MB、/ に残りの容量を割り当てます。<br />
最近の RedHat 系の Linux はデフォルトで LVM を使ってパーティッションを構成していますが、DomainU として運用する場合、LVM のディスクイメージを Domain0 から見る場合に手順がいろいろと面倒なので、古典的な方法でパーティッションを切った方が運用しやすいです。<br />
Domain0 から LVM で構成されたディスクイメージをマウントするための方法としては<a href="http://ken-etsu-tech.blogspot.com/2007/01/lvmxen.html">このへん</a>が参考になります。</p>
<p>パッケージは必要最小限のものだけインストールします。本当に必要最小限のものだけなら core のみを指定すればいいのですが、それだと gcc をはじめとした開発環境がインストールされないので、development-libs, development-tools, legacy-software-development も指定しておきます。</p>
<p>作成した Kickstart ファイルは、インストーラが動く DomainU から http で見えるところに置いておきます。</p>
<p>ここまでできたら、インストーラを動かすための DomainU を作成します。</p>

<div class="wp_syntax"><div class="code"><pre class="text">% sudo xm create -c /etc/xen/centos4.installation</pre></div></div>

<p>Kickstart に記述した手順で次々とインストーラの画面が切り替わっていきます。</p>
<p>インストールが終了したら、DomainU の設定ファイルをインストーラ用のものから実際に運用するものに置き換えます。修正個所は次の通りです。</p>

<div class="wp_syntax"><div class="code"><pre class="diff"><span style="color: #888822;">--- centos4.dev.installer     <span style="">2008</span><span style="">-06</span><span style="">-04</span> <span style="">16</span>:<span style="">14</span>:<span style="">33.000000000</span> <span style="">+0900</span></span>
<span style="color: #888822;">+++ centos4.dev       <span style="">2008</span><span style="">-06</span><span style="">-04</span> <span style="">15</span>:<span style="">41</span>:<span style="">19.000000000</span> <span style="">+0900</span></span>
<span style="color: #991111;">-kernel = &quot;/var/lib/xen/images/vmlinuz-CentOS4<span style="">.6</span>-Installer&quot;</span>
<span style="color: #991111;">-ramdisk = &quot;/var/lib/xen/images/initrd-CentOS4<span style="">.6</span>-Installer.img&quot;</span>
<span style="color: #991111;">-extra = &quot;text ks=http://somewhare/devel-ks.cfg&quot;</span>
 name = &quot;centos4.dev&quot;
 memory = &quot;<span style="">256</span>&quot;
 disk = <span style="">&#91;</span> 'tap:aio:/var/lib/xen/images/centos4.dev.img,xvda,w', <span style="">&#93;</span>
 vif = <span style="">&#91;</span> 'mac=<span style="">00</span>:<span style="">16</span>:3e:5b:b3:ec, bridge=xenbr0', <span style="">&#93;</span>
 uuid = &quot;722e88f7-99bd-47ac-b644-89dab714ee22&quot;
<span style="color: #00b000;">+bootloader=&quot;/usr/bin/pygrub&quot;</span>
 vcpus=<span style="">1</span>
<span style="color: #991111;">-on_reboot = 'destroy'</span>
<span style="color: #991111;">-on_crash = 'destroy'</span>
<span style="color: #00b000;">+on_reboot = 'restart'</span>
<span style="color: #00b000;">+on_crash = 'restart'</span></pre></div></div>

<p>kernel と ramdisk の指定をやめて bootloader を指定します。これでハードディスクイメージにインストールされたカーネルから起動するようになります。extra もインストーラのための指定で実運用には必要ないので削除します。on_reboot と on_crash には restart を指定しておきます。</p>
<p>設定ファイルを作成したら、次のようにして起動します。</p>

<div class="wp_syntax"><div class="code"><pre class="text">% sudo xm create -c /etc/xen/centos4</pre></div></div>

<p>これでインストールした OS が正常に起動すれば DomainU 作成完了です。</p>
<p>以上、virt-install のお世話にならず Xen の機能のみを使って DomainU を作成する方法でした。</p>
]]></content:encoded>
			<wfw:commentRss>http://insilico.jognote.com/blog/2008/06/09/xendomainu%e3%82%92%e3%81%95%e3%81%8f%e3%81%a3%e3%81%a8%e4%bd%9c%e3%82%8b%e6%96%b9%e6%b3%95/feed/</wfw:commentRss>
		<slash:comments>133</slash:comments>
		</item>
		<item>
		<title>さくらの専用サーバに入っている FreeBSD 5.4-RELEASE を 6.3-RELEASE にリモートアップデートしてみた</title>
		<link>http://insilico.jognote.com/blog/2008/05/14/%e3%81%95%e3%81%8f%e3%82%89%e3%81%ae%e5%b0%82%e7%94%a8%e3%82%b5%e3%83%bc%e3%83%90%e3%81%ab%e5%85%a5%e3%81%a3%e3%81%a6%e3%81%84%e3%82%8b-freebsd-54-release-%e3%82%92-63-release-%e3%81%ab%e3%83%aa/</link>
		<comments>http://insilico.jognote.com/blog/2008/05/14/%e3%81%95%e3%81%8f%e3%82%89%e3%81%ae%e5%b0%82%e7%94%a8%e3%82%b5%e3%83%bc%e3%83%90%e3%81%ab%e5%85%a5%e3%81%a3%e3%81%a6%e3%81%84%e3%82%8b-freebsd-54-release-%e3%82%92-63-release-%e3%81%ab%e3%83%aa/#comments</comments>
		<pubDate>Wed, 14 May 2008 05:39:36 +0000</pubDate>
		<dc:creator>odt</dc:creator>
				<category><![CDATA[freebsd]]></category>
		<category><![CDATA[server]]></category>

		<guid isPermaLink="false">http://insilico.jognote.com/blog/2008/05/14/%e3%81%95%e3%81%8f%e3%82%89%e3%81%ae%e5%b0%82%e7%94%a8%e3%82%b5%e3%83%bc%e3%83%90%e3%81%ab%e5%85%a5%e3%81%a3%e3%81%a6%e3%81%84%e3%82%8b-freebsd-54-release-%e3%82%92-63-release-%e3%81%ab%e3%83%aa/</guid>
		<description><![CDATA[現在、ジョグノートで借りている さくらインターネット のサーバで、古いものは FreeBSD の 5.x 系が入っています。
先日 7.0 がリリースされて、6.x シリーズも Legacy になったので、そろそろ 5.x 系も 6.x 系にアップグレードすることにしました。
基本的には handbook にある通りに作業をすればよいわけですが、物理的に完全に隔離された場所にサーバがあり、コンソールはおろか、リセットスイッチさえ押せないので、全ての作業をリモートから行う必要があります。
handbook の手順だと、一旦シングルユーザモードでの再起動が必要になりますが、リモートでアップグレードを行う場合には、そうするわけにはいきません。
マシンに接続されているキーボードにアクセスすることができないので、ブートマネージャにシングルユーザモードで起動する旨を伝えることもできないし、仮にさくらの人に何とかしてもらうことにして、シングルユーザモードで起動しても、telnet や ssh で中に入ることはできません。
シングルユーザモードですから、直接 root で作業をするしかないのです。
ということで、途中でシングルユーザモードでの再起動をしないで全ての作業を行う、というのが、今回のアップグレードの要になります。
さて、作業の手順です。
まずは cvsup を用いて最新版のソースを取ってきます。
/usr/share/examples/cvsup/standard-supfile あたりを参考に、次の内容でファイルを用意します。


*default host=cvsup2.jp.FreeBSD.org
*default base=/var/db
*default prefix=/usr
*default release=cvs tag=RELENG_6_3
*default delete use-rel-suffix

src-all

余談ですが、host として指定した cvsup2.jp.FreeBSD.org は、実はYahoo! JAPANのサーバだったりします^^;
Yahoo! JAPAN は FreeBSD のヘビーユーザとしても有名ですね。


; &#60;&#60;&#62;&#62; DiG 9.3.4-P1 &#60;&#60;&#62;&#62; cvsup2.jp.FreeBSD.org
;; global options:  printcmd
;; Got answer:
;; -&#62;&#62;HEADER&#60;&#60;- opcode: [...]]]></description>
			<content:encoded><![CDATA[<p>現在、ジョグノートで借りている <a href="http://www.sakura.ad.jp/">さくらインターネット</a> のサーバで、古いものは FreeBSD の 5.x 系が入っています。<br />
先日 7.0 がリリースされて、6.x シリーズも Legacy になったので、そろそろ 5.x 系も 6.x 系にアップグレードすることにしました。</p>
<p>基本的には <a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/makeworld.html">handbook</a> にある通りに作業をすればよいわけですが、物理的に完全に隔離された場所にサーバがあり、コンソールはおろか、リセットスイッチさえ押せないので、全ての作業をリモートから行う必要があります。</p>
<p>handbook の手順だと、一旦シングルユーザモードでの再起動が必要になりますが、リモートでアップグレードを行う場合には、そうするわけにはいきません。<br />
マシンに接続されているキーボードにアクセスすることができないので、ブートマネージャにシングルユーザモードで起動する旨を伝えることもできないし、仮にさくらの人に何とかしてもらうことにして、シングルユーザモードで起動しても、telnet や ssh で中に入ることはできません。<br />
シングルユーザモードですから、直接 root で作業をするしかないのです。</p>
<p>ということで、途中でシングルユーザモードでの再起動をしないで全ての作業を行う、というのが、今回のアップグレードの要になります。</p>
<p>さて、作業の手順です。</p>
<p>まずは cvsup を用いて最新版のソースを取ってきます。<br />
<code>/usr/share/examples/cvsup/standard-supfile</code> あたりを参考に、次の内容でファイルを用意します。</p>
<pre>
<code>
*default host=cvsup2.jp.FreeBSD.org
*default base=/var/db
*default prefix=/usr
*default release=cvs tag=RELENG_6_3
*default delete use-rel-suffix

src-all
</code></pre>
<p>余談ですが、host として指定した cvsup2.jp.FreeBSD.org は、実は<a href="http://www.yahoo.co.jp/">Yahoo! JAPAN</a>のサーバだったりします^^;<br />
Yahoo! JAPAN は FreeBSD のヘビーユーザとしても有名ですね。</p>
<pre>
<code>
; &lt;&lt;&gt;&gt; DiG 9.3.4-P1 &lt;&lt;&gt;&gt; cvsup2.jp.FreeBSD.org
;; global options:  printcmd
;; Got answer:
;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 6497
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;cvsup2.jp.FreeBSD.org.         IN      A

;; ANSWER SECTION:
cvsup2.jp.FreeBSD.org.  3600    IN      CNAME   mukku.bsd.yahoo.co.jp.
mukku.bsd.yahoo.co.jp.  900     IN      A       203.216.196.85

;; Query time: 5 msec
;; SERVER: 210.188.224.10#53(210.188.224.10)
;; WHEN: Tue May 13 19:05:18 2008
;; MSG SIZE  rcvd: 90
</code></pre>
<p>作成したファイルを引数に指定して cvsup を実行。</p>
<pre>
<code>
% sudo cvsup -L 2 -g ~/releng_6_3-supfile
</code></pre>
<p><code>/usr/src</code> 以下が 6.3-RELEASE の状態になります。</p>
<p>FreeBSD のソースからのアップグレードを解説しているサイトでは、いろんなところで <code>/usr/src/UPDATINGM</code> を熟読するように、と書いてあります。<br />
でも、とてもじゃないけど全部熟読して理解できるほど FreeBSD に精通していないので、さらっと全体を眺めることにしました。</p>
<p>ここからは、作業のログを取っておくことにします。script コマンドを使うと、それ以降に端末に流れる文字をファイルに記録しておくことができます。</p>
<pre>
<code>
% script ~/upgrade.log
</code></pre>
<p>カーネルには GENERIC の設定をそのまま使うので、特にパラメータは指定することなく次のように実行します。</p>
<pre>
<code>
% cd /usr/src
% sudo make buildworld
% sudo make buildkernel
% sudo make installkernel
% sudo make installworld
</code></pre>
<p>どうやら 6.x からは audit グループが必要なようで、audit グループが無い状態で installworld しようとしたら、次のエラーが出て先に進めませんでした。</p>
<pre>
<code>
ERROR: Required audit group is missing, see /usr/src/UPDATING.
*** Error code 1 [#uea0ff7f]

Stop in /usr/src.
*** Error code 1 [#ca3dda06]

Stop in /usr/src.
</code></pre>
<p>他の 6.x 系のサーバの <code>/etc/group</code> を参考にしながら、次のようにしてグループを作成しました。</p>
<pre>
<code>
% sudo pw groupadd audit -g 77
</code></pre>
<p>ちなみに、audit のことはちゃんと <code>/usr/src/UPDATING</code> に書いてありました。</p>
<p>本来であれば installkernel の後でシングルユーザモードで起動して、その後に installworld, mergemaster とするそうですが、ここでは一気にやってしまうことにします。</p>
<p>installworld が済んだら mergemaster の実行に移ります。<br />
これを実行することにより <code>/etc</code> 以下を新しいバージョンに対応させます。</p>
<p>基本的には <code>i</code> を押して、新しいファイルをインストールするのですが、<code>/etc/group</code> とか自分で編集した記憶があるファイルは上書きしてしまわないように注意が必要です。<br />
<code>diff</code> 形式で差分が表示されているので、古いファイルを元に新しいファイルの内容を加えたり、新しいファイルに古い設定を加えたりしてマージします。<br />
特に <code>/etc/master.passwd</code> のマージは要注意です。</p>
<p>mergemaster で <code>m</code> によるマージの作業は、癖があってとても使いやすいとは言えないものでした。<br />
それでも、<code>l</code> とか <code>l</code> とか <code>el</code> とか押しながら、何度も途中で最初から編集をやり直しながら、マージしたファイルをインストールしていきます。</p>
<p>mergemaster が完了したら、OS を再起動します。<br />
ここで、もしかして何かの設定がおかしくて ssh で入れないことも考えられるので、telnet でのログインを有効にしておきます。</p>
<p>FreeBSD では telnet は inetd 経由で起動されるので、<code>/etc/inetd.conf</code> を次のように設定しておきます。</p>
<pre>
<code>
% diff -cu inetd.conf.orig inetd.conf
--- inetd.conf.orig    2008-05-14 12:48:16.000000000 +0900
+++ inetd.conf 2008-05-14 13:16:16.000000000 +0900
@@ -12,7 +12,7 @@
 #ftp  stream  tcp6    nowait  root    /usr/libexec/lukemftpd  ftpd -l -r
 #ssh  stream  tcp     nowait  root    /usr/sbin/sshd          sshd -i -4
 #ssh  stream  tcp6    nowait  root    /usr/sbin/sshd          sshd -i -6
-#telnet       stream  tcp     nowait  root    /usr/libexec/telnetd    telnetd
+telnet        stream  tcp     nowait  root    /usr/libexec/telnetd    telnetd
 #telnet       stream  tcp6    nowait  root    /usr/libexec/telnetd    telnetd
 #shell        stream  tcp     nowait  root    /usr/libexec/rshd       rshd
 #shell        stream  tcp6    nowait  root    /usr/libexec/rshd       rshd
</code></pre>
<p>いよいよ再起動です。ちゃんと OS が上がってくるか緊張します。</p>
<pre>
<code>
% sudo /sbin/shutdown -r now
</code></pre>
<p>1,2分くらいして、ping が返ってくるようになりました。<br />
無事 ssh でもログインできるようです。<br />
<code>uname -a</code> して OS のバージョンが新しくなっていることを確認します。</p>
<pre>
<code>
FreeBSD localhost 6.3-RELEASE-p2 FreeBSD 6.3-RELEASE-p2 #0: Tue May 13 10:43:20 JST 2008     root@localhost:/usr/obj/usr/src/sys/GENERIC  i386
</code></pre>
<p>OS のバージョンが上がっていることを確認できたら、再起動前に設定した telnet のポートをすぐに閉じます。<br />
<code>/etc/inetd.conf</code> の該当行をコメントアウトし、</p>
<pre>
<code>
% sudo kill -HUP `sudo cat /var/run/inetd.pid`
</code></pre>
<p>のようにして SIGHUP を送れば OK です。</p>
<p>OS のバージョンアップの次は、ports の再コンパイルです。<br />
GENERIC では COMPAT_FREEBSD5 が設定されているので、FreeBSD 5.x 系のバイナリもそのまま動くと思われがちですが、中には動かないものもあるので、インストールされている ports は全て再コンパイルしてインストールすることにします。</p>
<p>まずは ports collection のアップデート。</p>
<pre>
<code>
% sudo cvsup -L 2 -h cvsup2.jp.FreeBSD.org /usr/share/examples/cvsup/ports-supfile
</code></pre>
<p>次に現在インストールされているパッケージの整合性のチェック。</p>
<pre>
<code>
% sudo pkgdb -F
</code></pre>
<p>もし <code>pkgdb -F</code> で</p>
<pre>
<code>
---&gt;  Checking the package registry database
[Updating the pkgdb &lt;format:bdb_btree&gt; in /var/db/pkg ... /var/db/pkg/pkgdb.db: unexpected file type or format -- Invalid argument; rebuild needed] [Rebuilding the pkgdb
&lt;format:bdb_btree&gt; in /var/db/pkg ... /var/db/pkg/pkgdb.db: unexpected file type or format -- Invalid argument: Cannot update the pkgdb!]: Cannot update the pkgdb!]
&lt;/format:bdb_btree&gt;&lt;/format:bdb_btree&gt;</code></pre>
<p>のようなエラーが出た場合には、</p>
<pre>
<code>
% sudo rm /var/db/pkg/pkgdb.db /usr/ports/INDEX*.db
% sudo pkgdb -fu
</code></pre>
<p>とすればよさそうです。</p>
<p>一気にアップグレード。</p>
<pre>
<code>
% sudo portupgrade -afr
</code></pre>
<p>ports を含め、インストールされている全てのバイナリが新しくなったら、古いバイナリは削除してやります。</p>
<pre>
<code>
% cd /usr/src
% sudo make check-old
% sudo make delete-old
% sudo make delete-old-libs
</code></pre>
<p>アップグレートが完了したら、新しい OS のバイナリを作るための作業ディレクトリである <code>/usr/obj</code> も削除すると、<code>/usr</code> の空き容量が増えます。調べてみると、けっこうな容量を使っています。</p>
<pre>
<code>
% du -sh /usr/obj
734M    /usr/obj
</code></pre>
<p>handbook によると、</p>
<pre>
<code>
# cd /usr/obj
# chflags -R noschg *
# rm -rf *
</code></pre>
<p>とあり、schg フラグを落としてから削除するようにとのことだが、実際にどれくらい schg フラグが立っているファイルがあるのかと調べてみると、</p>
<pre>
<code>
% find /usr/obj -flags schg
</code></pre>
<p>1つも見つかりませんでした。なので chflags しないで直接削除しても大丈夫そうです。</p>
<p>また、GENERIC をそのまま使ってビルドした場合は、作ったバイナリがそのまま他のマシンでも使えるので、</p>
<pre>
<code>
% cd /usr; sudo tar zcf - obj src | ssh remotehost 'cd /usr; sudo tar zxf -'
</code></pre>
<p>のようにして他のマシンにもコピーすれば、コピーした先のマシンでは</p>
<pre>
<code>
% sudo make installkernel
% sudo make installworld
% sudo mergemaster
</code></pre>
<p>だけを実行すればよく、時間の節約になります。</p>
<p>以上、完全リモート操作による FreeBSD のメジャーバージョンアップの手順でした。</p>
]]></content:encoded>
			<wfw:commentRss>http://insilico.jognote.com/blog/2008/05/14/%e3%81%95%e3%81%8f%e3%82%89%e3%81%ae%e5%b0%82%e7%94%a8%e3%82%b5%e3%83%bc%e3%83%90%e3%81%ab%e5%85%a5%e3%81%a3%e3%81%a6%e3%81%84%e3%82%8b-freebsd-54-release-%e3%82%92-63-release-%e3%81%ab%e3%83%aa/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>JogNoteの写真投稿機能はMogileFSを使って実装されています</title>
		<link>http://insilico.jognote.com/blog/2008/04/17/jognote%e3%81%ae%e5%86%99%e7%9c%9f%e6%8a%95%e7%a8%bf%e6%a9%9f%e8%83%bd%e3%81%afmogilefs%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e5%ae%9f%e8%a3%85%e3%81%95%e3%82%8c%e3%81%a6%e3%81%84%e3%81%be%e3%81%99/</link>
		<comments>http://insilico.jognote.com/blog/2008/04/17/jognote%e3%81%ae%e5%86%99%e7%9c%9f%e6%8a%95%e7%a8%bf%e6%a9%9f%e8%83%bd%e3%81%afmogilefs%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e5%ae%9f%e8%a3%85%e3%81%95%e3%82%8c%e3%81%a6%e3%81%84%e3%81%be%e3%81%99/#comments</comments>
		<pubDate>Thu, 17 Apr 2008 09:00:57 +0000</pubDate>
		<dc:creator>odt</dc:creator>
				<category><![CDATA[mogilefs]]></category>

		<guid isPermaLink="false">http://insilico.jognote.com/blog/2008/04/17/jognote%e3%81%ae%e5%86%99%e7%9c%9f%e6%8a%95%e7%a8%bf%e6%a9%9f%e8%83%bd%e3%81%afmogilefs%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e5%ae%9f%e8%a3%85%e3%81%95%e3%82%8c%e3%81%a6%e3%81%84%e3%81%be%e3%81%99/</guid>
		<description><![CDATA[今日、JogNoteの記録に写真を投稿できる機能をリリースしました。
この写真投稿機能は、ストレージとしてMogileFSを使っています。
システム構成を図にすると、次のような感じになっています。

ちなみにこの図はgliffyというブラウザ上で図が作成できるサービスのフリーアカウント版で作りました。
使用しているサーバは、さくらインターネットの専用サーバです。回線は10Mスタンダードで、OSはCentOS 4を使用しています。前にFreeBSDにMogileFSをインストールする記事を書きましたが、あれからいろいろ問題が起こり、安定運用させるためにはLinux上で動作させるほうが安心、ということで、CentOS上で稼働させることにしました。
外部からのリクエストを一手に引き受けるリバースプロキシは、MogileFSのサーバ群だけでなく、JogNote本体のサービスの入口でもあります。リバースプロキシにはnginxというhttpdを使用しています。
MogileFSは3台のマシンで動作しており、そのうち2台でデュアルマスタによる冗長化をしたMySQLと、MogileFSを便利に使うためのラッパーAPIが動作しています。このラッパーAPIは、写真のアップロードやサムネイルの生成、アクセストークン付きのURLの発行などを行います。
ウェブ上の情報を探してた限りだと、現在のところMogileFSを用いてウェブサービスを運用しているところは、そんなに多くないように思います。JogNoteの一部としてMogileFSを運用し、そこで得たノウハウをここで紹介できたらいいなと思っています。
]]></description>
			<content:encoded><![CDATA[<p>今日、JogNoteの記録に写真を投稿できる機能をリリースしました。<br />
この写真投稿機能は、ストレージとして<a href="http://www.danga.com/mogilefs/">MogileFS</a>を使っています。</p>
<p>システム構成を図にすると、次のような感じになっています。</p>
<p><a href="http://insilico.jognote.com/blog/wp-content/uploads/2008/04/storage_architecture.png" title="jognote storage system"><img src="http://insilico.jognote.com/blog/wp-content/uploads/2008/04/storage_architecture.png" alt="jognote storage system" /></a></p>
<p>ちなみにこの図は<a href="http://www.gliffy.com/">gliffy</a>というブラウザ上で図が作成できるサービスのフリーアカウント版で作りました。</p>
<p>使用しているサーバは、<a href="http://www.sakura.ad.jp/">さくらインターネット</a>の専用サーバです。回線は10Mスタンダードで、OSはCentOS 4を使用しています。前にFreeBSDにMogileFSをインストールする記事を書きましたが、あれからいろいろ問題が起こり、安定運用させるためにはLinux上で動作させるほうが安心、ということで、CentOS上で稼働させることにしました。</p>
<p>外部からのリクエストを一手に引き受けるリバースプロキシは、MogileFSのサーバ群だけでなく、JogNote本体のサービスの入口でもあります。リバースプロキシには<a href="http://nginx.net/">nginx</a>というhttpdを使用しています。</p>
<p>MogileFSは3台のマシンで動作しており、そのうち2台でデュアルマスタによる冗長化をしたMySQLと、MogileFSを便利に使うためのラッパーAPIが動作しています。このラッパーAPIは、写真のアップロードやサムネイルの生成、アクセストークン付きのURLの発行などを行います。</p>
<p>ウェブ上の情報を探してた限りだと、現在のところMogileFSを用いてウェブサービスを運用しているところは、そんなに多くないように思います。JogNoteの一部としてMogileFSを運用し、そこで得たノウハウをここで紹介できたらいいなと思っています。</p>
]]></content:encoded>
			<wfw:commentRss>http://insilico.jognote.com/blog/2008/04/17/jognote%e3%81%ae%e5%86%99%e7%9c%9f%e6%8a%95%e7%a8%bf%e6%a9%9f%e8%83%bd%e3%81%afmogilefs%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e5%ae%9f%e8%a3%85%e3%81%95%e3%82%8c%e3%81%a6%e3%81%84%e3%81%be%e3%81%99/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MogileFSの冗長化機能のテストをしてみる</title>
		<link>http://insilico.jognote.com/blog/2008/03/14/mogilefs%e3%81%ae%e5%86%97%e9%95%b7%e5%8c%96%e6%a9%9f%e8%83%bd%e3%81%ae%e3%83%86%e3%82%b9%e3%83%88%e3%82%92%e3%81%97%e3%81%a6%e3%81%bf%e3%82%8b/</link>
		<comments>http://insilico.jognote.com/blog/2008/03/14/mogilefs%e3%81%ae%e5%86%97%e9%95%b7%e5%8c%96%e6%a9%9f%e8%83%bd%e3%81%ae%e3%83%86%e3%82%b9%e3%83%88%e3%82%92%e3%81%97%e3%81%a6%e3%81%bf%e3%82%8b/#comments</comments>
		<pubDate>Fri, 14 Mar 2008 05:46:52 +0000</pubDate>
		<dc:creator>odt</dc:creator>
				<category><![CDATA[mogilefs]]></category>

		<guid isPermaLink="false">http://insilico.jognote.com/blog/2008/03/14/mogilefs%e3%81%ae%e5%86%97%e9%95%b7%e5%8c%96%e6%a9%9f%e8%83%bd%e3%81%ae%e3%83%86%e3%82%b9%e3%83%88%e3%82%92%e3%81%97%e3%81%a6%e3%81%bf%e3%82%8b/</guid>
		<description><![CDATA[昨日の記事で、今度はLinux上にXenのDomainUを複数用意して実験をすると書きましたが、実験環境を用意するのに時間がかかるので、FreeBSD 6.2上の mogstored に複数の device を用意することで、冗長化機能のテストをしたいと思います。
物理的な host を複数台用意しても、その上には device を作成し、ファイルは device の上に作成される domain と class の上に生成されるので、host は1台でも device を複数用意すれば、同じような実験ができるものと考えられます。
さて、今回はMogileFS上の device が突然壊れた場合でもちゃんと冗長化機能が働いているかどうかの実験をしたいと思います。
多くの場合、あるファイルは2個所に存在していれば十分な冗長性が確保できると考えられます。仮に片方のストレージが物理的に壊れてしまっても、もう片方が生きていればファイルの消失は避けられます。2台のストレージが同時に壊れる可能性は、そんなに高くはないでしょう。
MogileFSで2個所のストレージを定義するためには、device を2つ作成する必要があります。
しかし、本当に2つで大丈夫でしょうか？
仮に2つの device うちの1つが壊れたとします。すると、この時にMogileFS上には各々のデータは1つしか存在しないことになります。1つの device が壊れている間に追加されるデータもまた、1つしか作成されていないことになります。
すぐに壊れた device を復旧することができればいいですが、常にそうできるとも限らないので、device は3つ以上あると運用上都合がよいと考えられます。3つのうち1つが壊れてしまっても、壊れたことがわかった時点ですぐにその device をMogileFSから切り離せば(device の状態を dead にする)、その device に保存されていたデータはMogileFSの冗長化機能によって他の2つの device のどちらかに作成されます。この間に新たに追加されるデータもまた、この2つの device 上に作成されます。そして、2つの device で運用できている間に壊れた device を復旧して、また3つの構成に戻せばよいのです。
では、MogileFS上に3つの device を作成してみます。
まずは現在の状態をチェックしてみます。


% sudo -u mogile mogadm --trackers=127.0.0.1:6001 check
Checking trackers...
  127.0.0.1:6001 [...]]]></description>
			<content:encoded><![CDATA[<p>昨日の記事で、今度はLinux上にXenのDomainUを複数用意して実験をすると書きましたが、実験環境を用意するのに時間がかかるので、FreeBSD 6.2上の <code>mogstored</code> に複数の <code>device</code> を用意することで、冗長化機能のテストをしたいと思います。<br />
物理的な <code>host</code> を複数台用意しても、その上には <code>device</code> を作成し、ファイルは <code>device</code> の上に作成される <code>domain</code> と <code>class</code> の上に生成されるので、<code>host</code> は1台でも <code>device</code> を複数用意すれば、同じような実験ができるものと考えられます。</p>
<p>さて、今回はMogileFS上の <code>device</code> が突然壊れた場合でもちゃんと冗長化機能が働いているかどうかの実験をしたいと思います。</p>
<p>多くの場合、あるファイルは2個所に存在していれば十分な冗長性が確保できると考えられます。仮に片方のストレージが物理的に壊れてしまっても、もう片方が生きていればファイルの消失は避けられます。2台のストレージが同時に壊れる可能性は、そんなに高くはないでしょう。</p>
<p>MogileFSで2個所のストレージを定義するためには、<code>device</code> を2つ作成する必要があります。</p>
<p>しかし、本当に2つで大丈夫でしょうか？</p>
<p>仮に2つの <code>device</code> うちの1つが壊れたとします。すると、この時にMogileFS上には各々のデータは1つしか存在しないことになります。1つの <code>device が壊れている間に追加されるデータもまた、1つしか作成されていないことになります。</code></p>
<p>すぐに壊れた <code>device</code> を復旧することができればいいですが、常にそうできるとも限らないので、<code>device</code> は3つ以上あると運用上都合がよいと考えられます。3つのうち1つが壊れてしまっても、壊れたことがわかった時点ですぐにその <code>device</code> をMogileFSから切り離せば(<code>device</code> の状態を <code>dead</code> にする)、その <code>device</code> に保存されていたデータはMogileFSの冗長化機能によって他の2つの <code>device</code> のどちらかに作成されます。この間に新たに追加されるデータもまた、この2つの <code>device</code> 上に作成されます。そして、2つの <code>device</code> で運用できている間に壊れた <code>device</code> を復旧して、また3つの構成に戻せばよいのです。</p>
<p>では、MogileFS上に3つの <code>device</code> を作成してみます。<br />
まずは現在の状態をチェックしてみます。</p>
<pre>
<code>
% sudo -u mogile mogadm --trackers=127.0.0.1:6001 check
Checking trackers...
  127.0.0.1:6001 ... OK

Checking hosts...
No devices found on tracker(s).
</code></pre>
<p>まだ <code>host</code> も <code>device</code> も登録していないので、何も表示されています。<br />
では、<code>host</code> を登録してみます。</p>
<pre>
<code>
% sudo -u mogile mogadm --trackers=127.0.0.1:6001 host add localhost --status=alive
% sudo -u mogile mogadm --trackers=127.0.0.1:6001 check
Checking trackers...
  127.0.0.1:6001 ... OK

Checking hosts...
  [ 1] localhost ... OK

Checking devices...
  host device         size(G)    used(G)    free(G)   use%   ob state   I/O%
  ---- ------------ ---------- ---------- ---------- ------ ---------- -----
  ---- ------------ ---------- ---------- ---------- ------
             total:     0.000      0.000      0.000   0.00%

</code></pre>
<p>localhostで動作する <code>mogstored</code> を <code>host</code> に登録することができました。<code>--status</code> オプションに <code>alive</code> を指定したので、<code>OK</code> になっています。<code>--status</code> オプションを指定しないとデフォルトでは <code>down</code> です。</p>
<p>続いて <code>device</code> を登録してみます。<code>mogadm</code> コマンドを実行する前に、実際にファイルを格納するためのディレクトリを作成しておきます。</p>
<pre>
<code>
% sudo -u mogile mkdir -p /home/mogile/var/mogdata/dev{1,2,3}
</code></pre>
<p>ディレクトリを作成したら、<code>mogadm</code> コマンドにて <code>device</code> を登録します。</p>
<pre>
<code>
% sudo -u mogile mogadm --trackers=127.0.0.1:6001 device add localhost 1 --status=alive
% sudo -u mogile mogadm --trackers=127.0.0.1:6001 device add localhost 2 --status=alive
% sudo -u mogile mogadm --trackers=127.0.0.1:6001 device add localhost 3 --status=alive
% sudo -u mogile mogadm --trackers=127.0.0.1:6001 check
Checking trackers...
  127.0.0.1:6001 ... OK

Checking hosts...
  [ 1] localhost ... OK

Checking devices...
  host device         size(G)    used(G)    free(G)   use%   ob state   I/O%
  ---- ------------ ---------- ---------- ---------- ------ ---------- -----
  [ 1] dev1            62.495      8.305     54.190  13.29%  writeable   0.0
  [ 1] dev2            62.495      8.305     54.190  13.29%  writeable   0.0
  [ 1] dev3            62.495      8.305     54.190  13.29%  writeable   0.0
  ---- ------------ ---------- ---------- ---------- ------
             total:   187.486     24.915    162.571  13.29%
</code></pre>
<p>ちゃと登録できているようです。</p>
<p>それでは <code>domain</code> と <code>class</code> を登録してみます。</p>
<pre>
<code>
% sudo -u mogile mogadm --trackers=127.0.0.1:6001 domain add testdomain
% sudo -u mogile mogadm --trackers=127.0.0.1:6001 domain list
 domain               class                mindevcount
-------------------- -------------------- -------------
 testdomain           default                   2
% mogadm --trackers=127.0.0.1:6001 class add testdomain testclass
% mogadm --trackers=127.0.0.1:6001 class list
 domain               class                mindevcount
-------------------- -------------------- -------------
 testdomain           default                   2
 testdomain           testclass                 2
</code></pre>
<p><code>mindevcount</code> はMogileFS上に最低いくつのコピーを作成するか、という値です。ここでは2なので、2個所にファイルが保存される、ということになります。コピーを作成する数を明示的に指定するためには <code>--mindevcount=3</code> のようにしてオプションを指定します。</p>
<p>さて、下準備ができたところで、実際にファイルを置いてみましょう。<br />
MogileFS ClientはPerlによるAPIが用意されていますが、プログラムを組まなくても <code>mogtool</code> という付属のツールを使えばとりあえずファイルを置いたり消したりするくらいのことはできます。<br />
では、ファイルを置いてみます。</p>
<pre>
<code>
% echo 'hello mogilefs.' &gt; hellomogilefs.txt
% sudo -u mogile mogtool --trackers=127.0.0.1:6001 --domain=testdomain --class=testclass inject hellomogilefs.txt hellomogilefs
file hellomogilefs: 6effbe3656628417f044194d21ae8559, len = 16
Spawned child 1461 to deal with chunk number 1.
        chunk 1 saved in 0.14 seconds.
Child 1461 successfully finished with chunk 1.
Beginning replication wait: 1
% sudo -u mogile mogtool --trackers=127.0.0.1:6001 --domain=testdomain --class=testclass locate hellomogilefs

http://127.0.0.1:7500/dev1/0/000/000/0000000002.fid

http://127.0.0.1:7500/dev3/0/000/000/0000000002.fid

#2 paths found
</code></pre>
<p>2個所にファイルが置かれたことがわかります。</p>
<p>では <code>dev1</code> が壊れたことにして、<code>dev1</code> のstatusを <code>dead</code> にしてみます。</p>
<pre>
<code>
% sudo -u mogile mogadm --trackers=127.0.0.1:6001 device mark localhost dev1 dead
% sudo -u mogile mogadm --trackers=127.0.0.1:6001 check
Checking trackers...
  127.0.0.1:6001 ... OK

Checking hosts...
  [ 1] localhost ... OK

Checking devices...
  host device         size(G)    used(G)    free(G)   use%   ob state   I/O%
  ---- ------------ ---------- ---------- ---------- ------ ---------- -----
  [ 1] dev2            62.495      8.306     54.190  13.29%  writeable   0.0
  [ 1] dev3            62.495      8.306     54.190  13.29%  writeable   0.0
  ---- ------------ ---------- ---------- ---------- ------
             total:   124.991     16.611    108.380  13.29%
</code></pre>
<p><code>dev1</code> がなくなりました。<code>dev1</code> に置かれていたファイルはどうなったでしょうか。</p>
<pre>
<code>
% sudo -u mogile mogtool --trackers=127.0.0.1:6001 --domain=testdomain --class=testclass locate hellomogilefs

http://127.0.0.1:7500/dev2/0/000/000/0000000002.fid

http://127.0.0.1:7500/dev3/0/000/000/0000000002.fid

#2 paths found
</code></pre>
<p>ちゃんと <code>dev2</code> にコピーされていました。</p>
<p>以上、MogileFSのレプリケーション機能がちゃんと動作することが確認できました。画像などデータベースに格納するには大きいデータを冗長性を考慮して保持したい場合には便利なシステムだと思います。</p>
]]></content:encoded>
			<wfw:commentRss>http://insilico.jognote.com/blog/2008/03/14/mogilefs%e3%81%ae%e5%86%97%e9%95%b7%e5%8c%96%e6%a9%9f%e8%83%bd%e3%81%ae%e3%83%86%e3%82%b9%e3%83%88%e3%82%92%e3%81%97%e3%81%a6%e3%81%bf%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>MogileFSのmogstoredは同じホストで複数動かせない</title>
		<link>http://insilico.jognote.com/blog/2008/03/13/mogilefs%e3%81%aemogstored%e3%81%af%e5%90%8c%e3%81%98%e3%83%9b%e3%82%b9%e3%83%88%e3%81%a7%e8%a4%87%e6%95%b0%e5%8b%95%e3%81%8b%e3%81%9b%e3%81%aa%e3%81%84/</link>
		<comments>http://insilico.jognote.com/blog/2008/03/13/mogilefs%e3%81%aemogstored%e3%81%af%e5%90%8c%e3%81%98%e3%83%9b%e3%82%b9%e3%83%88%e3%81%a7%e8%a4%87%e6%95%b0%e5%8b%95%e3%81%8b%e3%81%9b%e3%81%aa%e3%81%84/#comments</comments>
		<pubDate>Thu, 13 Mar 2008 07:32:40 +0000</pubDate>
		<dc:creator>odt</dc:creator>
				<category><![CDATA[mogilefs]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://insilico.jognote.com/blog/2008/03/13/mogilefs%e3%81%aemogstored%e3%81%af%e5%90%8c%e3%81%98%e3%83%9b%e3%82%b9%e3%83%88%e3%81%a7%e8%a4%87%e6%95%b0%e5%8b%95%e3%81%8b%e3%81%9b%e3%81%aa%e3%81%84/</guid>
		<description><![CDATA[昨日、FreeBSD 6.2上にMogileFS環境を構築するための記事を書きました。今日はMogileFSに実際にストレージスペースの設定をしてファイルを置いてみて、さらにストレージの一部が突然壊れてしまった場合にちゃんとスケールできるかどうか確認するための記事を書こうと思い、記事にするための実験をしていました。
1台のマシンを使って複数台で構成されるMogileFSの環境を作るために、 mogstored を異なるポートで複数起動しようとしたのですが、そこで手詰まりとなりました。1つのホストで動かすことのできる mogstored は1つだけのようです。
次のように2つ分の mogstored の設定ファイルと docroot で指定したディレクトリを用意して、 mogstored を起動させました。
/home/mogile/etc/mogstored1.conf


httplisten=0.0.0.0:7500
mgmtlisten=0.0.0.0:7501
docroot=/home/mogile/var/mogdata1

/home/mogile/etc/mogstored2.conf


httplisten=0.0.0.0:7502
mgmtlisten=0.0.0.0:7503
docroot=/home/mogile/var/mogdata2



% sudo -u mogile mkdir -p /home/mogile/var/mogdata{1,2}
% sudo mogstored --daemonize --config=/home/mogile/etc/mogstored1.conf
% sudo mogstored --daemonize --config=/home/mogile/etc/mogstored2.conf

とりあえず起動はします。


% ps auxww &#124; grep mogstored
root    89967  0.0  2.5 11560 11028  ??  S     3:18PM   0:00.45 mogstored (perl)
root [...]]]></description>
			<content:encoded><![CDATA[<p>昨日、<a href="http://insilico.jognote.com/blog/2008/03/12/mogilefs%e3%82%92freebsd-62%e4%b8%8a%e3%81%ab%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%99%e3%82%8b/">FreeBSD 6.2上にMogileFS環境を構築するための記事</a>を書きました。今日はMogileFSに実際にストレージスペースの設定をしてファイルを置いてみて、さらにストレージの一部が突然壊れてしまった場合にちゃんとスケールできるかどうか確認するための記事を書こうと思い、記事にするための実験をしていました。</p>
<p>1台のマシンを使って複数台で構成されるMogileFSの環境を作るために、 <code>mogstored</code> を異なるポートで複数起動しようとしたのですが、そこで手詰まりとなりました。1つのホストで動かすことのできる <code>mogstored</code> は1つだけのようです。</p>
<p>次のように2つ分の <code>mogstored</code> の設定ファイルと <code>docroot</code> で指定したディレクトリを用意して、 <code>mogstored</code> を起動させました。</p>
<p><code>/home/mogile/etc/mogstored1.conf</code></p>
<pre>
<code>
httplisten=0.0.0.0:7500
mgmtlisten=0.0.0.0:7501
docroot=/home/mogile/var/mogdata1
</code></pre>
<p><code>/home/mogile/etc/mogstored2.conf</code></p>
<pre>
<code>
httplisten=0.0.0.0:7502
mgmtlisten=0.0.0.0:7503
docroot=/home/mogile/var/mogdata2
</code></pre>
<pre>
<code>
% sudo -u mogile mkdir -p /home/mogile/var/mogdata{1,2}
% sudo mogstored --daemonize --config=/home/mogile/etc/mogstored1.conf
% sudo mogstored --daemonize --config=/home/mogile/etc/mogstored2.conf
</code></pre>
<p>とりあえず起動はします。</p>
<pre>
<code>
% ps auxww | grep mogstored
root    89967  0.0  2.5 11560 11028  ??  S     3:18PM   0:00.45 mogstored (perl)
root    89968  0.0  0.6  3124  2596  ??  S     3:18PM   0:00.05 mogstored [diskusage] (perl)
root    89969  0.0  0.6  3140  2608  ??  S     3:18PM   0:00.15 mogstored [iostat] (perl)
root    89970  0.0  1.1  5240  4736  ??  S     3:18PM   0:00.16 mogstored [fidsizes] (perl)
root    89974  0.0  2.5 11560 11048  ??  S     3:18PM   0:00.47 mogstored (perl)
root    89975  0.0  0.6  3124  2596  ??  S     3:18PM   0:00.05 mogstored [diskusage] (perl)
root    89976  0.0  0.6  3140  2608  ??  S     3:18PM   0:00.14 mogstored [iostat] (perl)
root    89978  0.0  1.1  5240  4736  ??  S     3:18PM   0:00.16 mogstored [fidsizes] (perl)
</code></pre>
<p>この状態で2つのStorage ServerをTrackerに登録しようとしたところでコケます。<br />
1つ目は登録できます。当然ですね。</p>
<pre>
<code>
% sudo -u mogile mogadm --trackers=127.0.0.1:6001 host add localhost --port=7500
% sudo -u mogile mogadm --trackers=127.0.0.1:6001 check
Checking trackers...
  127.0.0.1:6001 ... OK

Checking hosts...
  [ 1] localhost ... skipping; status = down
No devices found on tracker(s).
</code></pre>
<p>2つ目は次のようなエラーを吐いて登録できません。</p>
<pre>
<code>
% sudo -u mogile mogadm --trackers=127.0.0.1:6001 host add localhost --port=7502
Host already exists.
</code></pre>
<p>ホスト名がかぶってるからいけないのかと思い、 <code>/etc/hosts</code> に次のような記述を追加して、再度登録しようかと思いましたけど、やっぱり駄目です。</p>
<pre>
<code>
% cat /etc/hosts | grep mogstored
127.0.0.1               mogstored1.localhost
127.0.0.1               mogstored2.localhost
% sudo -u mogile mogadm --trackers=127.0.0.1:6001 host add mogstored2.localhost --port=7502
Failure creating host: dup Duplicate name/number used.
</code></pre>
<p>今度はエラーメッセージは違いますけど、やっぱり登録できません。インストールしたり設定をいじってみたところ、1台のホストで複数台の <code>mogstored</code> が動作してもよさそうなのですが、登録できないことにはしょうがありません。</p>
<p>では、どの段階で登録をはじいているのか、ソースコードを追ってみました。</p>
<p>まず、<code>Failure creating host: dup Duplicate name/number used.</code> のエラーですが、これは <code>MogileFS/Worker/Query.pm</code> の中の <code>err_line</code> というサブルーチンで定義されています。</p>
<pre>
<code>
# first argument: error code.
# second argument: optional error text.  text will be taken from code if no text provided.
sub err_line {
    my MogileFS::Worker::Query $self = shift;

    my $err_code = shift;
    my $err_text = shift || {
        'dup' =&gt; "Duplicate name/number used.",
        'after_mismatch' =&gt; "Pattern does not match the after-value?",
        'bad_params' =&gt; "Invalid parameters to command; please see documentation",
        'class_exists' =&gt; "That class already exists in that domain",
        'class_has_files' =&gt; "Class still has files, uanble to delete",
        'class_not_found' =&gt; "Class not found",
        'db' =&gt; "Database error",
        'domain_has_files' =&gt; "Domain still has files, uanble to delete",
        'domain_exists' =&gt; "That domain already exists",
        'domain_not_empty' =&gt; "Domain still has classes, unable to delete",
        'domain_not_found' =&gt; "Domain not found",
        'failure' =&gt; "Operation failed",
        'host_exists' =&gt; "That host already exists",
        'host_mismatch' =&gt; "The device specified doesn't belong to the host specified",
        'host_not_empty' =&gt; "Unable to delete host; it contains devices still",
        'host_not_found' =&gt; "Host not found",
        'invalid_chars' =&gt; "Patterns must not contain backslashes (\\) or percent signs (%).",
        'invalid_checker_level' =&gt; "Checker level invalid.  Please see documentation on this command.",
        'invalid_mindevcount' =&gt; "The mindevcount must be at least 1",
        'key_exists' =&gt; "Target key name already exists; can't overwrite.",
        'no_class' =&gt; "No class provided",
        'no_devices' =&gt; "No devices found to store file",
        'no_domain' =&gt; "No domain provided",
        'no_host' =&gt; "No host provided",
        'no_ip' =&gt; "IP required to create host",
        'no_port' =&gt; "Port required to create host",
        'none_match' =&gt; "No keys match that pattern and after-value (if any).",
        'plugin_aborted' =&gt; "Action aborted by plugin",
        'state_too_high' =&gt; "Status cannot go from dead to alive; must use down",
        'unknown_command' =&gt; "Unknown server command",
        'unknown_host' =&gt; "Host not found",
        'unknown_state' =&gt; "Invalid/unknown state",
        'unreg_domain' =&gt; "Domain name invalid/not found",
    }-&gt;{$err_code} || $err_code;

    my $delay = '';
    if ($self-&gt;{querystarttime}) {
        $delay = sprintf("%.4f ", Time::HiRes::tv_interval($self-&gt;{querystarttime}));
        $self-&gt;{querystarttime} = undef;
    }

    my $id = defined $self-&gt;{reqid} ? "$self-&gt;{reqid} " : '';

    $self-&gt;send_to_parent("${id}${delay}ERR $err_code " . eurl($err_text));
    return 0;
}
</code></pre>
<p><code>dup</code> というのは、このエラーのキーのようですね。<br />
では、このエラーを吐き出しているところを調べてみます。</p>
<p><code>MogileFS/Store.pm</code> に <code>create_host</code> というホストを登録するのではないかと思われるサブルーチンを発見しました。</p>
<pre>
<code>
# return ne hostid, or throw 'dup' on error.
# NOTE: you need to put them into the initial 'down' state.
sub create_host {
    my ($self, $hostname, $ip) = @_;
    my $dbh = $self-&gt;dbh;
    # racy! lazy. no, better: portable! how often does this happen? :)
    my $hid = ($dbh-&gt;selectrow_array('SELECT MAX(hostid) FROM host') || 0) + 1;
    my $rv = $self-&gt;conddup(sub {
        $dbh-&gt;do("INSERT INTO host (hostid, hostname, hostip, status) ".
                 "VALUES (?, ?, ?, 'down')",
                 undef, $hid, $hostname, $ip);
    });
    return $hid if $rv;
    die "db failure";
}
</code></pre>
<p>同じファイルにある <code>conddup</code> というサブルーチンで <code>INSERT</code> クエリを発行しているので、<code>conddup</code> が <code>dup</code> を投げるのでしょう。</p>
<p><code>conddup</code> は次の通り。やはりここでthrowされています。</p>
<pre>
<code>
# run a subref (presumably a database update) in an eval, because you expect it to
# maybe fail on duplicate key error, and throw a dup exception for you, else return
# its return value
sub conddup {
    my ($self, $code) = @_;
    my $rv = eval { $code-&gt;(); };
    throw("dup") if $self-&gt;was_duplicate_error;
    return $rv;
}
</code></pre>
<p>では、なぜ <code>INSERT</code> に失敗して <code>dup</code> が throw されてしまったのでしょうか。DBのスキーマを見てみることにします。</p>
<pre>
<code>
% mysql --host=127.0.0.1 --port=13306 -u mogile -p mogilefs
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 54
Server version: 5.0.45-log MySQL Community Server (GPL)

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql&gt; show fields from host;
+---------------+-----------------------------+------+-----+---------+-------+
| Field         | Type                        | Null | Key | Default | Extra |
+---------------+-----------------------------+------+-----+---------+-------+
| hostid        | mediumint(8) unsigned       | NO   | PRI |         |       |
| status        | enum('alive','dead','down') | YES  |     | NULL    |       |
| http_port     | mediumint(8) unsigned       | YES  |     | 7500    |       |
| http_get_port | mediumint(8) unsigned       | YES  |     | NULL    |       |
| hostname      | varchar(40)                 | YES  | UNI | NULL    |       |
| hostip        | varchar(15)                 | YES  | UNI | NULL    |       |
| altip         | varchar(15)                 | YES  | UNI | NULL    |       |
| altmask       | varchar(18)                 | YES  |     | NULL    |       |
+---------------+-----------------------------+------+-----+---------+-------+
8 rows in set (0.00 sec)
</code></pre>
<p>なるほど。<code>hostname</code> がユニークキーになっていますね。これでは登録できません。</p>
<p>ここを手動でUNIQUE制約を外してしまうこともできますが、きっと何か理由があってUNIQUEにしていることと思うのでこのままにしておいて、1つのホスト内で複数の <code>mogstored</code> を動作させるのは諦めました。</p>
<p>今度はLinux上にXenのDomainUを複数用意して、そこでMogileFSの冗長化実験をしたいと思います。</p>
]]></content:encoded>
			<wfw:commentRss>http://insilico.jognote.com/blog/2008/03/13/mogilefs%e3%81%aemogstored%e3%81%af%e5%90%8c%e3%81%98%e3%83%9b%e3%82%b9%e3%83%88%e3%81%a7%e8%a4%87%e6%95%b0%e5%8b%95%e3%81%8b%e3%81%9b%e3%81%aa%e3%81%84/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>MogileFSをFreeBSD 6.2上にインストールする</title>
		<link>http://insilico.jognote.com/blog/2008/03/12/mogilefs%e3%82%92freebsd-62%e4%b8%8a%e3%81%ab%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%99%e3%82%8b/</link>
		<comments>http://insilico.jognote.com/blog/2008/03/12/mogilefs%e3%82%92freebsd-62%e4%b8%8a%e3%81%ab%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%99%e3%82%8b/#comments</comments>
		<pubDate>Wed, 12 Mar 2008 09:24:44 +0000</pubDate>
		<dc:creator>odt</dc:creator>
				<category><![CDATA[freebsd]]></category>
		<category><![CDATA[mogilefs]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://insilico.jognote.com/blog/2008/03/12/mogilefs%e3%82%92freebsd-62%e4%b8%8a%e3%81%ab%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%99%e3%82%8b/</guid>
		<description><![CDATA[MogileFSという分散ファイルシステムがあります。これは大雑把に言うと、ネットワーク上にある複数台のマシンをストレージとみなすことにより、分散ファイルシステムを実現したものです。MogileFS上に保存するファイルにはプライオリティをつけることができ、その重要度によって必要分だけMogileFS上にコピーが作成されます。各々のストレージマシンは取り外しが簡単にできるようになっていて、突然マシンが故障してファイルが取り出せなくなっても、そのマシンを使わないように設定すれば、他のマシンに保存してあったファイルを元に、また別のマシンに必要分だけコピーが生成されます。
MogileFSについてのもっと詳しい説明は、以下のページがとても参考になります。

Six Apart &#8211; Tech Talk Blog: 分散ファイルシステム MogileFS について
Six Apart &#8211; Tech Talk Blog: MogileFS のインストールと初期設定

ちなみに、MogileFSはmemcachedで有名なDanga InteractiveのBrad Fitzpatrickさんが開発したものです。
MogileFSはPerlで書かれており、CPANにも登録されているので、CPAN経由でインストールするのが楽そうです。
ですが、MogileFSについてよく知らないし、他の現在運用中の何かと競合してしまっても困るので、完全に独立したディレクトリにPerlをインストールして、そこにsvnから取ってきた最新のMogileFSをインストールすることにしました。
MogileFSのインストール方法は本家のwikiが参考になります。
また、MogileFSの司令塔であるTrackerは非root権限で動作させる必要があるので、MogileFSのための専用のアカウントを作成することにします。


% sudo groupadd mogile -g 60056
% sudo useradd mogile -u 60056 -g mogile -s /usr/sbin/nologin

ユーザmogileのホームディレクトリは /home/mogile になるので、/home/mogile 以下にMogileFS環境を構築していきます。
まずはPerlを /home/mogile/perl にインストールします。
CPANからPerlのソースを取ってきて展開します。


% sudo -u mogile mkdir /home/mogile/src
% cd /home/mogile/src
% sudo -u mogile wget 'http://www.cpan.org/src/perl-5.10.0.tar.gz'
% sudo -u mogile tar zxvf perl-5.10.0.tar.gz
% [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.danga.com/mogilefs/">MogileFS</a>という分散ファイルシステムがあります。これは大雑把に言うと、ネットワーク上にある複数台のマシンをストレージとみなすことにより、分散ファイルシステムを実現したものです。MogileFS上に保存するファイルにはプライオリティをつけることができ、その重要度によって必要分だけMogileFS上にコピーが作成されます。各々のストレージマシンは取り外しが簡単にできるようになっていて、突然マシンが故障してファイルが取り出せなくなっても、そのマシンを使わないように設定すれば、他のマシンに保存してあったファイルを元に、また別のマシンに必要分だけコピーが生成されます。</p>
<p>MogileFSについてのもっと詳しい説明は、以下のページがとても参考になります。</p>
<ul>
<li><a href="http://www.sixapart.jp/techtalk/2006/10/dev_mogilefs.html">Six Apart &#8211; Tech Talk Blog: 分散ファイルシステム MogileFS について</a></li>
<li><a href="http://www.sixapart.jp/techtalk/2006/10/dev_mogilefs_install.html">Six Apart &#8211; Tech Talk Blog: MogileFS のインストールと初期設定</a></li>
</ul>
<p>ちなみに、MogileFSは<a href="http://www.danga.com/memcached/">memcached</a>で有名な<a href="http://www.danga.com/">Danga Interactive</a>の<a href="http://bradfitz.com/">Brad Fitzpatrick</a>さんが開発したものです。</p>
<p>MogileFSはPerlで書かれており、CPANにも登録されているので、CPAN経由でインストールするのが楽そうです。</p>
<p>ですが、MogileFSについてよく知らないし、他の現在運用中の何かと競合してしまっても困るので、完全に独立したディレクトリにPerlをインストールして、そこにsvnから取ってきた最新のMogileFSをインストールすることにしました。<br />
MogileFSのインストール方法は<a href="http://mogilefs.pbwiki.com/HowTo">本家のwiki</a>が参考になります。<br />
また、MogileFSの司令塔であるTrackerは非root権限で動作させる必要があるので、MogileFSのための専用のアカウントを作成することにします。</p>
<pre>
<code>
% sudo groupadd mogile -g 60056
% sudo useradd mogile -u 60056 -g mogile -s /usr/sbin/nologin
</code></pre>
<p>ユーザmogileのホームディレクトリは <code>/home/mogile</code> になるので、<code>/home/mogile</code> 以下にMogileFS環境を構築していきます。</p>
<p>まずはPerlを <code>/home/mogile/perl</code> にインストールします。</p>
<p>CPANからPerlのソースを取ってきて展開します。</p>
<pre>
<code>
% sudo -u mogile mkdir /home/mogile/src
% cd /home/mogile/src
% sudo -u mogile wget 'http://www.cpan.org/src/perl-5.10.0.tar.gz'
% sudo -u mogile tar zxvf perl-5.10.0.tar.gz
% cd perl-5.10.0
</code></pre>
<p>多くのオープンソースのツールに付属する <code>autoconf</code> による <code>configure</code> ではなくて、<code>Configure</code> という独自のシェルスクリプトを走らせることによりコンパイルオプションの設定をします。</p>
<pre>
<code>
% sudo -u mogile ./Configure -des \
&gt; -Dmyhostname=localhost -Dperladmin=mogile@localhost \
&gt; -Dcc=/usr/bin/gcc -Dprefix=/home/mogile/perl \
&gt; -Dusethreads -Duseithreads -Duselargefiles
</code></pre>
<p><code>-des</code> は、基本的にデフォルトの設定を使うという意味のオプションです。これを指定しないと、うんざりするくらいの量の質問に答えることになります。<br />
<code>-Dusethreads -Duseithreads</code> を指定してスレッドを有効にします。スレッドを有効にしておかないと、後でCPANからインストールするIO::AIOのインストールが途中で失敗します。<br />
その他のオプションについてはportsのMakefileやCentOSのspecファイルなんかを参考にして適当に指定します。</p>
<p><code>Configure</code> でコンパイルオプションの設定をしたら、<code>make</code> してバイナリを作ります。</p>
<pre>
<code>
% sudo -u mogilge make
</code></pre>
<p><code>make</code> が終了したら <code>make test</code> も実行します。いくつかのテストでコケますが、気にしないことにします。</p>
<pre>
<code>
% sudo -u mogile make test
</code></pre>
<p><code>make install</code> でprefixに指定したPATHにインストールします。ここでは <code>/home/mogile/perl</code> にインストールされます。</p>
<pre>
<code>
% sudo -u mogile make install
</code></pre>
<p>実行中のシェルで <code>/home/mogile/perl/bin/perl</code> が一番先に検索されるようにPATHを通しておきます。</p>
<pre>
<code>
% export PATH="/home/mogile/perl/bin:$PATH"
</code></pre>
<p><code>which</code> したり <code>perl -v</code> したりして、所定の場所のPerlが呼び出されて、バージョンが <code>5.10.0</code> になっていれば大丈夫です。</p>
<pre>
<code>
% which perl
/home/mogile/perl/bin/perl
% perl -v

This is perl, v5.10.0 built for i386-freebsd-thread-multi

Copyright 1987-2007, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

</code></pre>
<p>Perl本体のインストールが済んだら、MogileFSを動作させるために必要なモジュールをCPANからインストールします。</p>
<ul>
<li><code>YAML</code></li>
<li><code>IO::AIO</code></li>
<li><code>Sys::Syscall</code></li>
<li><code>Perlbal</code></li>
<li><code>Net::Netmask</code></li>
<li><code>Gearman::Server</code></li>
<li><code>Gearman::Client::Async</code></li>
<li><code>Gearman::Client</code></li>
<li><code>Danga::Socket</code></li>
<li><code>IO::WrapTie</code></li>
<li><code>DBI</code></li>
<li><code>DBD::mysql</code></li>
</ul>
<p>素のままのPerlでMogileFSのServerをインストールしようとすると次のようにWarningが出ます。</p>
<pre>
<code>
% cd /home/mogile/src/mogilefs-src/server
% perl Makefile.PL
Checking if your kit is complete...
Looks good
Warning: prerequisite Danga::Socket 1.56 not found.
Warning: prerequisite Gearman::Client 1.07 not found.
Warning: prerequisite Gearman::Client::Async 0.93 not found.
Warning: prerequisite Gearman::Server 1.08 not found.
Warning: prerequisite Net::Netmask 0 not found.
Warning: prerequisite Perlbal 1.53 not found.
Warning: prerequisite Sys::Syscall 0.22 not found.
Writing Makefile for mogilefs-server
</code></pre>
<p><code>IO::WrapTie</code> はClientをインストールする時に、<code>IO::AIO</code> は <code>mogstored</code> を起動する時に、<code>DBI</code>, <code>DBD::mysql</code> は <code>mogilefsd</code> を起動する時に、<code>YAML</code> はCPAN実行中のどこかで、それぞれ必要です。</p>
<p>また、CPANを最初に走らせるとCPANのための設定についていろいろ聞かれるので、これも適当に答えておきます。</p>
<p>モジュールをインストールする際にtestが失敗するためにインストールできないものがけっこうあります。ここではとりあえずインストールしたいので、</p>
<pre>
<code>
cpan&gt; force install modulename
</code></pre>
<p>として強制的にインストールしてしまうことにします。</p>
<p>必要なモジュールのインストールが済んだら、いよいよMogileFSのインストールにうつります。</p>
<p>まずは、svnからソースをチェックアウトしてきます。</p>
<pre>
<code>
% cd /home/mogile/src
% sudo -u mogile svn checkout http://code.sixapart.com/svn/mogilefs/trunk mogilefs-src
</code></pre>
<p>Server,Client,Utilsの順番でインストールしていきます。この段階でまだ足りないモジュールがあるようなら、随時インストールすることにします。<br />
また、MogileFSも <code>make test</code> で失敗しますが、これも気にせずインストールしてしまうことにします。</p>
<p>Serverのインストール。</p>
<pre>
<code>
% cd /home/mogile/src/mogilefs-src/server
% sudo -u mogile perl Makefile.PL
% sudo -u mogile make
% sudo -u mogile make test
% sudo -u mogile make install
</code></pre>
<p>Clientのインストール。</p>
<pre>
<code>
% cd /home/mogile/src/mogilefs-src/api/perl/MogileFS-Client
% sudo -u mogile perl Makefile.PL
% sudo -u mogile make
% sudo -u mogile make test
% sudo -u mogile make install
</code></pre>
<p>Utilsのインストール。</p>
<pre>
<code>
% cd /home/mogile/src/mogilefs-src/utils
% sudo -u mogile perl Makefile.PL
% sudo -u mogile make
% sudo -u mogile make test
% sudo -u mogile make install
</code></pre>
<p>これでインストールは完了です。</p>
<p>次はMogileFSを動作させるための設定をします。</p>
<p>MogileFSを動作させるためには、以下の3つの設定が必要です。</p>
<ul>
<li>Database(<code>mysqld</code>)</li>
<li>Tracker(<code>mogilefsd</code>)</li>
<li>Storage Server(<code>mogstored</code>)</li>
</ul>
<p>Databaseの設定は、MogileFS付属の <code>mogdbsetup</code> というツールを使って行います。<br />
例えば <code>localhost</code> 上の <code>13306</code> 番ポートで動作している <code>mysqld</code> にMogileFS用のデータベースを作成するためには、次のように引数を指定して実行します。<br />
<code>--yes</code> オプションを指定すると、全ての質問にyesと答え、<code>--verbose</code> オプションは実際にツールが実行しているSQL文などをターミナルに表示します。</p>
<pre>
<code>
% sudo -u mogile mogdbsetup --dbhost=127.0.0.1 --dbport=13306 \
&gt; --dbname=mogilefs --dbuser=mogile --dbpassword=sekrit \
&gt; --yes --verbose
</code></pre>
<p>Trackerの設定は <code>mogilefsd.conf</code> に必要事項を記述することによって行います。<br />
デフォルトでは <code>/etc/mogilefs/mogilefsd.conf</code> が読まれますが、<code>-c</code> オプションによって <code>mogilefsd.conf</code><br />
の場所を指定できます。<br />
<code>/home/mogile/etc/mogilefsd.conf</code> を以下の内容で作成します。</p>
<pre>
<code>
db_dsn DBI:mysql:mogilefs;host=127.0.0.1;port=13306
db_user mogile
db_pass sekrit
conf_port 6001
listener_jobs 5
</code></pre>
<p>次のようにして <code>mofilefsd</code> を起動します。</p>
<pre>
<code>
% sudo -u mogile mogilefsd -c /home/mogile/etc/mogilefsd.conf --daemon
</code></pre>
<p>Storage Serverの設定は <code>mogstored.conf</code> で行います。<br />
デフォルトでは <code>/etc/mogilefs/mogstored.conf</code> が読まれますが、<code>mogilefsd</code> と同じく <code>--config</code> オプションによりconfの場所を指定することができます。<br />
<code>/home/mogile/etc/mogstored.conf</code> を以下の内容で作成します。</p>
<pre>
<code>
httplisten=0.0.0.0:7500
mgmtlisten=0.0.0.0:7501
docroot=/home/mogile/var/mogdata</code></pre>
<p><code>docroot</code> に指定したディレクトリを作成します。</p>
<pre>
<code>
% sudo -u mogilefs mkdir /home/mogile/var/mogdata
</code></pre>
<p>次のようにして <code>mogstored</code> を起動します。<code>mogstored</code> はroot権限で起動します。</p>
<pre>
<code>
% sudo mogstored --daemonize --config=/home/mogile/etc/mogstored.conf
</code></pre>
<p>MogileFSの設定をするためには <code>mogadm</code> というツールを使います。<br />
早速 <code>mogadm</code> を使用してTrackerに接続してみます。</p>
<pre>
<code>
% mogadm --trackers=127.0.0.1:6001 check
Checking trackers...
  127.0.0.1:6001 ... OK

Checking hosts...
No devices found on tracker(s).
</code></pre>
<p>まだ <code>hosts</code> の設定をしていないので何もデバイスが無いと言われていますが、<br />
Trackerはちゃんと動作しているようです。</p>
<p>これでシステムとしてのMogileFSは出来上がりです。</p>
]]></content:encoded>
			<wfw:commentRss>http://insilico.jognote.com/blog/2008/03/12/mogilefs%e3%82%92freebsd-62%e4%b8%8a%e3%81%ab%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%99%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>[Pidgin]現行Yahoo!メッセンジャーでPidginの文字化けを回避するためのパッチとWindowsバイナリ</title>
		<link>http://insilico.jognote.com/blog/2008/02/26/pidgin%e7%8f%be%e8%a1%8cyahoo%e3%83%a1%e3%83%83%e3%82%bb%e3%83%b3%e3%82%b8%e3%83%a3%e3%83%bc%e3%81%a7pidgin%e3%81%ae%e6%96%87%e5%ad%97%e5%8c%96%e3%81%91%e3%82%92%e5%9b%9e%e9%81%bf%e3%81%99%e3%82%8b/</link>
		<comments>http://insilico.jognote.com/blog/2008/02/26/pidgin%e7%8f%be%e8%a1%8cyahoo%e3%83%a1%e3%83%83%e3%82%bb%e3%83%b3%e3%82%b8%e3%83%a3%e3%83%bc%e3%81%a7pidgin%e3%81%ae%e6%96%87%e5%ad%97%e5%8c%96%e3%81%91%e3%82%92%e5%9b%9e%e9%81%bf%e3%81%99%e3%82%8b/#comments</comments>
		<pubDate>Tue, 26 Feb 2008 06:46:25 +0000</pubDate>
		<dc:creator>odt</dc:creator>
				<category><![CDATA[c]]></category>
		<category><![CDATA[pidgin]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[yahoo]]></category>

		<guid isPermaLink="false">http://insilico.jognote.com/blog/2008/02/26/pidgin%e7%8f%be%e8%a1%8cyahoo%e3%83%a1%e3%83%83%e3%82%bb%e3%83%b3%e3%82%b8%e3%83%a3%e3%83%bc%e3%81%a7pidgin%e3%81%ae%e6%96%87%e5%ad%97%e5%8c%96%e3%81%91%e3%82%92%e5%9b%9e%e9%81%bf%e3%81%99%e3%82%8b/</guid>
		<description><![CDATA[PidginというIM(Instant Messenger)クライアントがあります。これはMSN MessengerとかYahoo!JAPAN Messengerとか、他にもいろいろなプロトコルに対応した便利なIMクライアントです。Linux上でも動作するので、普段から便利に使っています。
なのですが、ウェブ版Yahoo!メッセンジャーのリリースのタイミングで、メッセージをやりとりするための文字コードがSHIFT-JISからUTF8に変更になったようで、pidginから送ったメッセージが相手に表示されなかったり文字化けを起こしたりするようになってしまいました。
 2008年2月26日をもって「バージョン7.0.1.0未満」のWindows版Yahoo!メッセンジャー、および「バージョン2.5」のMacintosh版Yahoo!メッセンジャーのサポートを終了させていただきました。
とあるので、これまでSHIFT-JISとUTF8と両方の文字コードをサポートしていたけど、これからはUTF8一本に統一します、ということかもしれないですね。
仕事でもプライベートでもメッセンジャーを愛用していて、これが使えなくなってしまうととても不便です。
なので、これを回避するためのパッチを作ってみました。


#
# old_revision [d77adf1b9a4b44f121620f20e2643602e3f6776e]
#
# patch "libpurple/protocols/yahoo/util.c"
#  from [6a72fcc2054413ee7791e5c5cc62b6b18f4bcce0]
#    to [2a3725bcc455684e1c1bb42bd4982cc322732f38]
#
============================================================
--- libpurple/protocols/yahoo/util.c    6a72fcc2054413ee7791e5c5cc62b6b18f4bcce0
+++ libpurple/protocols/yahoo/util.c    2a3725bcc455684e1c1bb42bd4982cc322732f38
@@ -114,18 +114,15 @@ char *yahoo_string_encode(PurpleConnecti
        char *ret;
        const char *to_codeset;

-     [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://pidgin.im/">Pidgin</a>というIM(Instant Messenger)クライアントがあります。これはMSN MessengerとかYahoo!JAPAN Messengerとか、他にもいろいろなプロトコルに対応した便利なIMクライアントです。Linux上でも動作するので、普段から便利に使っています。<br />
なのですが、<a href="http://webmessenger.yahoo.co.jp/">ウェブ版Yahoo!メッセンジャー</a>のリリースのタイミングで、メッセージをやりとりするための文字コードがSHIFT-JISからUTF8に変更になったようで、pidginから送ったメッセージが相手に表示されなかったり文字化けを起こしたりするようになってしまいました。</p>
<blockquote><p> 2008年2月26日をもって「バージョン7.0.1.0未満」のWindows版Yahoo!メッセンジャー、および「バージョン2.5」のMacintosh版Yahoo!メッセンジャーのサポートを終了させていただきました。</p></blockquote>
<p>とあるので、これまでSHIFT-JISとUTF8と両方の文字コードをサポートしていたけど、これからはUTF8一本に統一します、ということかもしれないですね。</p>
<p>仕事でもプライベートでもメッセンジャーを愛用していて、これが使えなくなってしまうととても不便です。</p>
<p>なので、これを回避するためのパッチを作ってみました。</p>
<pre>
<code>
#
# old_revision [d77adf1b9a4b44f121620f20e2643602e3f6776e]
#
# patch "libpurple/protocols/yahoo/util.c"
#  from [6a72fcc2054413ee7791e5c5cc62b6b18f4bcce0]
#    to [2a3725bcc455684e1c1bb42bd4982cc322732f38]
#
============================================================
--- libpurple/protocols/yahoo/util.c    6a72fcc2054413ee7791e5c5cc62b6b18f4bcce0
+++ libpurple/protocols/yahoo/util.c    2a3725bcc455684e1c1bb42bd4982cc322732f38
@@ -114,18 +114,15 @@ char *yahoo_string_encode(PurpleConnecti
        char *ret;
        const char *to_codeset;

-       if (yd-&gt;jp &amp;&amp; utf8 &amp;&amp; *utf8)
-               *utf8 = FALSE;
+       if (yd-&gt;jp)
+               return g_strdup(str);

        if (utf8 &amp;&amp; *utf8) /* FIXME: maybe don't use utf8 if it'll fit in latin1 */
                return g_strdup(str);

-       if (yd-&gt;jp)
-               to_codeset = "SHIFT_JIS";
-       else
-               to_codeset = purple_account_get_string(purple_connection_get_account(gc), "local_charset",  "ISO-8859-1");
+       to_codeset = purple_account_get_string(purple_connection_get_account(gc), "local_charset",  "ISO-8859-1");
+       ret = g_convert_with_fallback(str, -1, to_codeset, "UTF-8", "?", NULL, NULL, NULL);

-       ret = g_convert_with_fallback(str, -1, to_codeset, "UTF-8", "?", NULL, NULL, NULL);
        if (ret)
                return ret;
        else
</code></pre>
<p>やっていることは簡単。これまでYahoo!JAPAN MessengerだったらメッセージをSHIFT-JISに変換して送信していたものを、今度からはUTF8のまま送るようにしただけです。</p>
<p>このパッチをあてて作った<a href="/pidgin-mtn.zip">Windowsバイナリ</a>を置いておくので、よかったら使ってみてください。</p>
]]></content:encoded>
			<wfw:commentRss>http://insilico.jognote.com/blog/2008/02/26/pidgin%e7%8f%be%e8%a1%8cyahoo%e3%83%a1%e3%83%83%e3%82%bb%e3%83%b3%e3%82%b8%e3%83%a3%e3%83%bc%e3%81%a7pidgin%e3%81%ae%e6%96%87%e5%ad%97%e5%8c%96%e3%81%91%e3%82%92%e5%9b%9e%e9%81%bf%e3%81%99%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[MySQL]mysqldはシグナル0を受けとるとどうする？</title>
		<link>http://insilico.jognote.com/blog/2008/02/18/mysqlmysqld%e3%81%af%e3%82%b7%e3%82%b0%e3%83%8a%e3%83%ab0%e3%82%92%e5%8f%97%e3%81%91%e3%81%a8%e3%82%8b%e3%81%a8%e3%81%a9%e3%81%86%e3%81%99%e3%82%8b%ef%bc%9f/</link>
		<comments>http://insilico.jognote.com/blog/2008/02/18/mysqlmysqld%e3%81%af%e3%82%b7%e3%82%b0%e3%83%8a%e3%83%ab0%e3%82%92%e5%8f%97%e3%81%91%e3%81%a8%e3%82%8b%e3%81%a8%e3%81%a9%e3%81%86%e3%81%99%e3%82%8b%ef%bc%9f/#comments</comments>
		<pubDate>Mon, 18 Feb 2008 10:36:07 +0000</pubDate>
		<dc:creator>odt</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://insilico.jognote.com/blog/2008/02/18/mysqlmysqld%e3%81%af%e3%82%b7%e3%82%b0%e3%83%8a%e3%83%ab0%e3%82%92%e5%8f%97%e3%81%91%e3%81%a8%e3%82%8b%e3%81%a8%e3%81%a9%e3%81%86%e3%81%99%e3%82%8b%ef%bc%9f/</guid>
		<description><![CDATA[MySQLには、mysqldを起動したり停止したりするためのツールmysql.serverが含まれています。バイナリディストリビューションの場合にはsupport-filesディレクトリの中にあります。
このツールの中でやっていることが知りたくてソースを読んでいたのですが、気になる記述がありました。

  'status')
    # First, check to see if pid file exists
    if test -s "$server_pid_file" ; then
      read mysqld_pid &#60; $server_pid_file
      if kill -0 $mysqld_pid 2&#62;/dev/null ; then
        log_success_msg "MySQL running [...]]]></description>
			<content:encoded><![CDATA[<p>MySQLには、mysqldを起動したり停止したりするためのツールmysql.serverが含まれています。バイナリディストリビューションの場合にはsupport-filesディレクトリの中にあります。</p>
<p>このツールの中でやっていることが知りたくてソースを読んでいたのですが、気になる記述がありました。</p>
<pre><code>
  'status')
    # First, check to see if pid file exists
    if test -s "$server_pid_file" ; then
      read mysqld_pid &lt; $server_pid_file
      if kill -0 $mysqld_pid 2&gt;/dev/null ; then
        log_success_msg "MySQL running ($mysqld_pid)"
        exit 0
      else
        log_failure_msg "MySQL is not running, but PID file exists"
        exit 1
      fi
</code></pre>
<p>これは、mysqldが動作しているのかどうかを調べるcase文の中なのですが、</p>
<pre><code>
'kill -0 $mysqld_pid'
</code></pre>
<p>mysqldのプロセスに対してシグナル <code>0</code> を送信しています。このシグナル <code>0</code> って何ですかね？<br />
FreeBSDで <code>/usr/include/sys/signal.h</code> の中を見て <code>0</code> が何かを探したのですが、見つけることができませんでした。</p>
<p>OS側でシグナル <code>0</code> に対する定義が無いとすれば、アプリケーション側で <code>0</code> に対して何か特別な扱いをしているのかもしれません。そこで、<a href="http://dev.mysql.com/downloads/mysql/5.0.html">MySQLのダウンロードページ</a>からバージョン5.0.51aのソースをダウンロードして、MySQLの中を追ってみることにしました。</p>
<p><code>sql/mysqld.cc</code> の <code>pthread_handler_t signal_hand(void *arg)</code> という関数が、送られてきたシグナルをトラップするための関数のようです。さて、この中の処理を追っていくと、</p>
<pre><code>
    default:
#ifdef EXTRA_DEBUG
      sql_print_warning("Got signal: %d  error: %d",sig,error); /* purecov: tested */
#endif
      break;                                    /* purecov: tested */
</code></pre>
<p>ちゃんと名前のついたシグナルについては上のほうの <code>case</code> 文で行うべき処理の記述があるのですが、<code>0</code> についてはなくて、<code>default</code> でまとめて引き受けられてしまうようです。そして、<code>default</code> の中では特に何もしていません。</p>
<p>つまり、MySQLは未定義のシグナルを受け取ると「何もしない」ということでした。<br />
mysql.serverの中で行われている <code>kill -0</code> は、指定された番号のプロセスが本当に存在するのかどうかを確認するため行っている、ということのようです。</p>
<p>前後の処理の流れから、おそらくそうであろう、と予想はしていましたが、気になって深追いしてみました。</p>
]]></content:encoded>
			<wfw:commentRss>http://insilico.jognote.com/blog/2008/02/18/mysqlmysqld%e3%81%af%e3%82%b7%e3%82%b0%e3%83%8a%e3%83%ab0%e3%82%92%e5%8f%97%e3%81%91%e3%81%a8%e3%82%8b%e3%81%a8%e3%81%a9%e3%81%86%e3%81%99%e3%82%8b%ef%bc%9f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
