<?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>cuspy memo</title>
	<atom:link href="http://www.cuspy.org/blog/feed" rel="self" type="application/rss+xml" />
	<link>http://www.cuspy.org/blog</link>
	<description>2.5</description>
	<lastBuildDate>Sat, 27 Mar 2010 13:47:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>qemu-kvm の block migration を試してみたよ。</title>
		<link>http://www.cuspy.org/blog/archives/917</link>
		<comments>http://www.cuspy.org/blog/archives/917#comments</comments>
		<pubDate>Fri, 26 Mar 2010 14:25:11 +0000</pubDate>
		<dc:creator>hamano</dc:creator>
				<category><![CDATA[etc]]></category>

		<guid isPermaLink="false">http://www.cuspy.org/blog/?p=917</guid>
		<description><![CDATA[KVM で livemigration を行う際、ストレージは両方のホストからアクセス出来る必要がある(NFS や iSCSI などで)ってここに書いてあった。
http://www.linux-kvm.org/page/Migration
だから前回 iSCSIで試してみたのだけれど、なんと qemu-kvm 0.12 からブロックデバイスの migration が出来るようになったらしいので早速試してみた。

block migration するのは 10G の qcow イメージ、普通に debian をインストールして 844M 使用してある。

sayori:~# qemu-img info vda.qcow
image: vda.qcow
file format: qcow2
virtual size: 10G (10737418240 bytes)
disk size: 844M
cluster_size: 4096

これを sayori で起動。

sayori:~# qemu --enable-kvm -m 512 \
-drive file=vda.qcow,if=virtio,boot=on \
-net nic,macaddr=00:16:3E:00:FF:32,model=virtio

受け入れ側(wasabi)では、同じサイズのqcowイメージを用意してある必要があるのかな、と思ったら、単に touch するだけで良かった。

wasabi:~# touch vda.qcow
wasabi:~# qemu -enable-kvm -m 512 \
-drive [...]]]></description>
			<content:encoded><![CDATA[<p>KVM で livemigration を行う際、ストレージは両方のホストからアクセス出来る必要がある(NFS や iSCSI などで)ってここに書いてあった。</p>
<p><a href="http://www.linux-kvm.org/page/Migration" title="http://www.linux-kvm.org/page/Migration" target="_blank">http://www.linux-kvm.org/page/Migration</a></p>
<p>だから<a href="http://www.cuspy.org/blog/archives/877">前回</a> iSCSIで試してみたのだけれど、なんと qemu-kvm 0.12 からブロックデバイスの migration が出来るようになったらしいので早速試してみた。</p>
<p><a href="http://www.cuspy.org/blog/wp-content/uploads/2010/03/kvm_qemu_blockmigration.png"><img src="http://www.cuspy.org/blog/wp-content/uploads/2010/03/kvm_qemu_blockmigration.png" alt="" title="kvm_qemu_blockmigration" width="528" height="408" class="alignnone size-full wp-image-920" /></a></p>
<p>block migration するのは 10G の qcow イメージ、普通に debian をインストールして 844M 使用してある。</p>
<pre>
sayori:~# qemu-img info vda.qcow
image: vda.qcow
file format: qcow2
virtual size: 10G (10737418240 bytes)
disk size: 844M
cluster_size: 4096
</pre>
<p>これを sayori で起動。</p>
<pre>
sayori:~# qemu --enable-kvm -m 512 \
-drive file=vda.qcow,if=virtio,boot=on \
-net nic,macaddr=00:16:3E:00:FF:32,model=virtio
</pre>
<p>受け入れ側(wasabi)では、同じサイズのqcowイメージを用意してある必要があるのかな、と思ったら、単に touch するだけで良かった。</p>
<pre>
wasabi:~# touch vda.qcow
wasabi:~# qemu -enable-kvm -m 512 \
-drive file=vda.qcow,if=virtio \
-net nic,macaddr=00:16:3E:00:FF:32,model=virtio \
-incoming tcp:0:4444
</pre>
<p>これで準備完了。sayori のmonitor コンソールから migration を開始する。</p>
<pre>
(qemu) migrate -d -b tcp:wasabi:4444
</pre>
<p>進捗はこれで確認できる。</p>
<pre>
(qemu) info migrate
Migration status: active
transferred ram: 48 kbytes
remaining ram: 147792 kbytes
total ram: 147840 kbytes
transferred disk: 206848 kbytes
remaining disk: 10278912 kbytes
total disk: 10485760 kbytes
</pre>
<p>block migration と live migration は約 15分程度で完了した。<br />
block migration -&gt; live migration という流れなんだけど、 block migration 中は普通にguestは動作しているし、ファイルにもアクセスできる。オープン中のファイルも問題無し。<br />
正味の停止時間は5秒程度だった。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cuspy.org/blog/archives/917/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>qemu-kvm の live migration を試してみたよ。</title>
		<link>http://www.cuspy.org/blog/archives/877</link>
		<comments>http://www.cuspy.org/blog/archives/877#comments</comments>
		<pubDate>Sat, 20 Mar 2010 14:51:48 +0000</pubDate>
		<dc:creator>hamano</dc:creator>
				<category><![CDATA[etc]]></category>

		<guid isPermaLink="false">http://www.cuspy.org/blog/?p=877</guid>
		<description><![CDATA[QEMU/KVM の仮想環境(ゲスト)を止めずに別のホストに移す。
構成は以下ような感じ。


ホスト環境 sayori(192.168.1.12) で動作しているゲスト環境 guest(192.168.1.50)を別のホスト環境 wasabi(192.168.1.10) に live migration する。
ホストOS は debian lenny
ゲストOS も debian lenny
ゲストOS は PXE boot して、ルートファイルシステムはkujira(192.168.1.11)のiSCSIターゲットをマウントする。
qemu-kvm のバージョンは 0.12.3
sayori は Intel Core2 Duo で wasabi は AMD Opteron。ホストのCPUアーキテクチャは異なる。

この際、別ホストから guest へのTCPコネクションがどうなるか。と
guest 内で開きっぱなしのファイルがどうなるかを検証する。
rootfsの作成
iscsiターゲットのrootfsを作る。
debootstrapでお手軽サクサク。
パーティション切るとloopbackマウントがめんどいので切らない。

kujira:~# dd if=/dev/zero of=disk1.img seek=10G bs=1 count=0
kujira:~# mkfs.ext3 disk1.img
kujira:~# mkdir mnt
kujira:~# mount -t ext3 -o loop disk1.img mnt/
kujira:~# debootstrap lenny mnt/
kujira:~# echo [...]]]></description>
			<content:encoded><![CDATA[<p>QEMU/KVM の仮想環境(ゲスト)を止めずに別のホストに移す。<br />
構成は以下ような感じ。</p>
<p><a href="http://www.cuspy.org/blog/wp-content/uploads/2010/03/kvm_qemu_livemigration.png"><img src="http://www.cuspy.org/blog/wp-content/uploads/2010/03/kvm_qemu_livemigration.png" alt="" title="kvm_qemu_livemigration" width="528" height="408" class="alignnone size-full wp-image-878" /></a></p>
<ul>
<li>ホスト環境 sayori(192.168.1.12) で動作しているゲスト環境 guest(192.168.1.50)を別のホスト環境 wasabi(192.168.1.10) に live migration する。</li>
<li>ホストOS は debian lenny</li>
<li>ゲストOS も debian lenny</li>
<li>ゲストOS は PXE boot して、ルートファイルシステムはkujira(192.168.1.11)のiSCSIターゲットをマウントする。</li>
<li>qemu-kvm のバージョンは 0.12.3</li>
<li>sayori は Intel Core2 Duo で wasabi は AMD Opteron。ホストのCPUアーキテクチャは異なる。</li>
</ul>
<p>この際、別ホストから guest へのTCPコネクションがどうなるか。と<br />
guest 内で開きっぱなしのファイルがどうなるかを検証する。</p>
<h4>rootfsの作成</h4>
<p>iscsiターゲットのrootfsを作る。<br />
debootstrapでお手軽サクサク。<br />
パーティション切るとloopbackマウントがめんどいので切らない。</p>
<pre>
kujira:~# dd if=/dev/zero of=disk1.img seek=10G bs=1 count=0
kujira:~# mkfs.ext3 disk1.img
kujira:~# mkdir mnt
kujira:~# mount -t ext3 -o loop disk1.img mnt/
kujira:~# debootstrap lenny mnt/
kujira:~# echo guest > mnt/etc/hostname
kujira:~# umount mnt/
</pre>
<p>/etc/ietd.conf にこんな風に書く。</p>
<pre>
Target iqn.1999-05.net.hamano:dick1
        Lun 0 Path=/path/to/disk1.img,Type=fileio
</pre>
<h4>initramfsの作成</h4>
<p>iSCSIイニシエータとして機能する initramfsを作る。</p>
<pre>
% mkidr initrd
% cd initrd
% zcat /boot/initrd.img-2.6.26-2-686 | cpio -iv
</pre>
<p>init スクリプトの root file system をマウントする直前に以下の5行を追加。</p>
<pre>
ipconfig -t 60 ${DEVICE}
modprobe iscsi_tcp
iscsid -f &#038;
iscsiadm -m discovery -t sendtargets -p 192.168.1.11
iscsiadm -m node -T iqn.1999-05.net.hamano:dick1 -l
</pre>
<p>iSCSIターゲットをマウントするのに必要なファイルを配置、あと kernel module の libcrc32c.ko と crc32c.ko が必要。</p>
<pre>
% cp /usr/sbin/iscsid ./sbin/
% cp /usr/bin/iscsiadm ./bin/
% mkdir etc/iscsi/
% echo "InitiatorName=iqn.1999-05.net.hamano:hoge" > etc/iscsi/initiatorname.iscsi

% cp /lib/modules/2.6.26-2-686/kernel/lib/libcrc32c.ko lib/modules/2.6.26-2-686/kernel/lib
% mkdir lib/modules/2.6.26-2-686/kernel/crypto/
% cp /lib/modules/2.6.26-2-686/kernel/crypto/crc32c.ko lib/modules/2.6.26-2-686/kernel/crypto/
</pre>
<p>あと iscsid の中で getpwuid(3)呼んでいてユーザー名が root じゃなかったら蹴られてしまうので nss関連も適当に入れておく。</p>
<pre>
% cp /lib/libnsl.so.1 ./lib/
% cp /lib/libnss_files.so.2 ./lib/
% echo "root:x:0:0:root:/:/bin/sh" > etc/passwd
% echo "passwd: files" > etc/nsswitch.conf
</pre>
<p>この initrd に chroot して</p>
<pre>
# id
uid=0(root) gid=0
</pre>
<p>って帰ってくればひとまずOK</p>
<p>initramfsを固めて、tftpd サーバーに配置する。</p>
<pre>
% find ./ | cpio -o -H newc | gzip -9 > ../initrd.img-2.6.26-2-686
</pre>
<h4>PXE boot の設定</h4>
<p>pxelinux.cfg/default にこんな風に書く。パラメータに noresume を付けないと起動途中で止まってしまったので付けた。</p>
<pre>
default guest
label guest
    kernel vmlinuz-2.6.26-2-686
    append load initrd=initrd.img-2.6.26-2-686 root=/dev/sda noresume
</pre>
<h4>qemu-kvmのネットワーク設定</h4>
<p>wasabi, sayoriの両方のホストでtap50をブリッジする。<br />
この辺りいつもは qemu-ifup scriptで自動化しているけど今回は手動で。</p>
<pre>
wasabi:~# tunctl -u hamano -t tap50
wasabi:~# brctl addif br0 tap50
wasabi:~# ip link set tap50 up
wasabi:~# brctl show br0
bridge name bridge id       STP enabled interfaces
br0     8000.001e0bbc9da5   no      eth0
                                    tap50
</pre>
<h4>qemu-kvmの実行</h4>
<p>wasabi 側で待機する。</p>
<pre>
wasabi:~# qemu -enable-kvm -m 512 \
-net nic,macaddr=00:16:3E:00:FF:32,model=virtio \
-net tap,vlan=0,ifname=tap50,script=no,downscript=no -incoming tcp:0:4444
</pre>
<p>sayori 側でゲストを起動する。</p>
<pre>
sayori:~# qemu -enable-kvm -m 512 \
-net nic,macaddr=00:16:3E:00:FF:32,model=virtio \
-net tap,vlan=0,ifname=tap50,script=no,downscript=no -boot n
</pre>
<p>guest側でファイルをオープンしっぱなしにして、<br />
別のサーバーから guest にTCPコネクションを張っておく。</p>
<p>準備が整ったのでいざ Live Migration!<br />
sayori のモニターコンソールから</p>
<pre>
(qemu) migrate -d tcp:wasabi:4444
</pre>
<p>live migration の進捗はこれで確認できる。</p>
<pre>
(qemu) info migrate
Migration status: active
transferred ram: 8000 kbytes
remaining ram: 533648 kbytes
total ram: 541056 kbytes
(qemu) info migrate
Migration status: completed
</pre>
<p>migrationはだいたい5秒くらいで完了する。</p>
<h4>結果</h4>
<p>TCPコネクションは切れていない、オープン中のファイルも問題なく読み書き出来た。<br />
理論上出来ると解っていても実際に動かしてみるとなかなか感動。</p>
<h4>補足事項</h4>
<ul>
<li>qemu-kvm 0.11.1 では nic の virtio を有効にして PXE boot 出来ない。</li>
<li>最初、sayoriの kernel を 2.6.32.9、wasabi の kernel を 2.6.26.8 で試すと以下のエラーメッセージが出て失敗した。</li>
<pre>
Unknown savevm section or instance 'kvmclock' 0
load of migration failed
</pre>
<p>kernel 2.6.31.5 < -> kernel 2.6.26.8 で試すと成功した。kvmのバージョンは出来るだけ揃えた方が無難。
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.cuspy.org/blog/archives/877/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MALLOC_MMAP_THRESHOLD_ と MALLOC_MMAP_MAX_</title>
		<link>http://www.cuspy.org/blog/archives/866</link>
		<comments>http://www.cuspy.org/blog/archives/866#comments</comments>
		<pubDate>Sun, 21 Feb 2010 18:50:51 +0000</pubDate>
		<dc:creator>hamano</dc:creator>
				<category><![CDATA[etc]]></category>

		<guid isPermaLink="false">http://www.cuspy.org/blog/?p=866</guid>
		<description><![CDATA[malloc(3) を呼んだ時、glibc はヒープ領域から指定したサイズのチャンクを確保するが、ヒープ領域が足りなかった場合 glibc は brk(2) を呼んでヒープ領域を拡張するか、Anonymous Memory と呼ばれる領域を mmap(2) して新たなヒープ領域を作成する。
この動作を制御する環境変数が MALLOC_MMAP_THRESHOLD_ らしいのでこれを試しているのだけれど、効かなくて困った。
しかたがないので glibc のソースを読んでいると mmap(2) を使用する最大サイズを指定する MALLOC_MMAP_MAX_ というのも見つけた、これはばっちり効いたのでこれを使おう。
1M を 3回 malloc するだけのコード

#include &#60;stdio .h&#62;
#include &#60;stdlib .h&#62;

int main(){
    int i;
    for(i=0;i&#60;3;i++){
        malloc(1*1024*1024);
    }
    return 0;
}


% strace [...]]]></description>
			<content:encoded><![CDATA[<p>malloc(3) を呼んだ時、glibc はヒープ領域から指定したサイズのチャンクを確保するが、ヒープ領域が足りなかった場合 glibc は brk(2) を呼んでヒープ領域を拡張するか、Anonymous Memory と呼ばれる領域を mmap(2) して新たなヒープ領域を作成する。</p>
<p>この動作を制御する環境変数が MALLOC_MMAP_THRESHOLD_ らしいのでこれを試しているのだけれど、効かなくて困った。</p>
<p>しかたがないので glibc のソースを読んでいると mmap(2) を使用する最大サイズを指定する MALLOC_MMAP_MAX_ というのも見つけた、これはばっちり効いたのでこれを使おう。</p>
<p>1M を 3回 malloc するだけのコード</p>
<pre class="prettyprint">
#include &lt;stdio .h&gt;
#include &lt;stdlib .h&gt;

int main(){
    int i;
    for(i=0;i&lt;3;i++){
        malloc(1*1024*1024);
    }
    return 0;
}
</pre>
<pre>
% strace ./a.out
(略)
mmap2(NULL, 1052672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7c9b000
mmap2(NULL, 2101248, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7a9a000
mmap2(NULL, 3149824, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7799000
</pre>
<p>デフォルトではこんな風に、3回 mmap(2) が呼ばれる。<br />
MALLOC_MMAP_MAX_=0 にすると、</p>
<pre>
% strace env MALLOC_MMAP_MAX_=0 ./a.out
(略)
brk(0)                                  = 0x8efa000
brk(0x901b000)                          = 0x901b000
brk(0x911b000)                          = 0x911b000
brk(0x921b000)                          = 0x921b000
</pre>
<p>4回 brk(2) を呼ぶようになった。<br />
MALLOC_MMAP_MAX_=1 にすると、</p>
<pre>
% strace env MALLOC_MMAP_MAX_=1 ./a.out
(略)
mmap2(NULL, 1052672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7cfe000
brk(0)                                  = 0x94bc000
brk(0x95dd000)                          = 0x95dd000
brk(0x96dd000)                          = 0x96dd000
</pre>
<p>最初の malloc(3) だけ mmap(2) するようになった。<br />
単位はMbyte なのね。(MALLOC_TRIM_THRESHOLD_の単位は byte だったのに・・・)</p>
<p>これで完全に malloc(3) の中で mmap(2) を呼ぶこと無いかというと、そういう訳でもなくて、特定の条件下で mmap(2) する場合ある様なので困ったのう。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cuspy.org/blog/archives/866/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>spamassassin と wanderlust</title>
		<link>http://www.cuspy.org/blog/archives/858</link>
		<comments>http://www.cuspy.org/blog/archives/858#comments</comments>
		<pubDate>Fri, 12 Feb 2010 18:31:03 +0000</pubDate>
		<dc:creator>hamano</dc:creator>
				<category><![CDATA[etc]]></category>

		<guid isPermaLink="false">http://www.cuspy.org/blog/?p=858</guid>
		<description><![CDATA[spamassassin で

rewrite_header Subject ***SPAM***

などとやっている場合の偽陽性なメールに対して返信する時に
Re: ***SPAM*** ほにゃららについて
って件名のメールを送ってしまうのは失礼ではないか。
ということで、追加した wanderlust 向け elisp

(add-hook 'wl-draft-reply-hook
          (function
           (lambda ()
             (save-excursion
           [...]]]></description>
			<content:encoded><![CDATA[<p>spamassassin で</p>
<pre class="prettyprint">
rewrite_header Subject ***SPAM***
</pre>
<p>などとやっている場合の偽陽性なメールに対して返信する時に</p>
<p>Re: ***SPAM*** ほにゃららについて</p>
<p>って件名のメールを送ってしまうのは失礼ではないか。<br />
ということで、追加した wanderlust 向け elisp</p>
<pre class="prettyprint">
(add-hook 'wl-draft-reply-hook
          (function
           (lambda ()
             (save-excursion
               (beginning-of-buffer)
               (re-search-forward "^Subject: " (point-max) t)
               (while (re-search-forward
                       "\\*\\*\\*\\(SPAM\\|UNCHECKED\\)\\*\\*\\* *"
                       (save-excursion (end-of-line) (point)) t)
                 (replace-match ""))
               ))))
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.cuspy.org/blog/archives/858/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>20100123 simple</title>
		<link>http://www.cuspy.org/blog/archives/841</link>
		<comments>http://www.cuspy.org/blog/archives/841#comments</comments>
		<pubDate>Sat, 23 Jan 2010 08:39:23 +0000</pubDate>
		<dc:creator>hamano</dc:creator>
				<category><![CDATA[etc]]></category>

		<guid isPermaLink="false">http://www.cuspy.org/blog/?p=841</guid>
		<description><![CDATA[今日やったこと。
erl_interface の perl XS module Erlang-Interface-0.03 リリース。
http://search.cpan.org/~hamano/Erlang-Interface-0.03/
github にも push
http://github.com/hamano/perl-erlang-interface
Cのerl_interface に対応する低位インターフェースは用意できた。
あとは上位にオブジェクトインターフェースを用意したいのだけどノードのインスタンスを複数作るにはどうしたものか。
これを実装するにあたりooldaemonさんの記事が参考になった。
erl_interface メモ &#8211; cooldaemonの備忘録
あと自宅サーバーを復旧した。
wordpress 2.9.1 に upgrade、壊れたDBを修復した。
firefox が落ちる問題の調査。
uim か gtk の immodule が怪しいことは解った。
滅多に再現しないので得に進展なし。
以上。
追記:
firefoxがクラッシュする問題は、uim 1.5.6 以前の問題で 1.5.7 以降で修正されていることを @mnoguさんに教えてもらった。
http://bugs.freedesktop.org/show_bug.cgi?id=25139
]]></description>
			<content:encoded><![CDATA[<p>今日やったこと。<br />
erl_interface の perl XS module Erlang-Interface-0.03 リリース。<br />
<a href="http://search.cpan.org/~hamano/Erlang-Interface-0.03/">http://search.cpan.org/~hamano/Erlang-Interface-0.03/</a><br />
github にも push<br />
<a href="http://github.com/hamano/perl-erlang-interface">http://github.com/hamano/perl-erlang-interface</a></p>
<p>Cのerl_interface に対応する低位インターフェースは用意できた。<br />
あとは上位にオブジェクトインターフェースを用意したいのだけどノードのインスタンスを複数作るにはどうしたものか。</p>
<p>これを実装するにあたりooldaemonさんの記事が参考になった。<br />
<a href="http://d.hatena.ne.jp/cooldaemon/20080212/1202798456">erl_interface メモ &#8211; cooldaemonの備忘録</a></p>
<p>あと自宅サーバーを復旧した。<br />
wordpress 2.9.1 に upgrade、壊れたDBを修復した。</p>
<p>firefox が落ちる問題の調査。<br />
uim か gtk の immodule が怪しいことは解った。<br />
滅多に再現しないので得に進展なし。</p>
<p>以上。</p>
<p>追記:<br />
firefoxがクラッシュする問題は、uim 1.5.6 以前の問題で 1.5.7 以降で修正されていることを <a href="http://twitter.com/mnogu">@mnogu</a>さんに教えてもらった。<br />
<a href="http://bugs.freedesktop.org/show_bug.cgi?id=25139">http://bugs.freedesktop.org/show_bug.cgi?id=25139</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cuspy.org/blog/archives/841/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
