Fork me on GitHub

cuspy memo


qemu-kvm の block migration を試してみたよ。

2010/03/26 Friday 23:25:11

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 file=vda.qcow,if=virtio \
-net nic,macaddr=00:16:3E:00:FF:32,model=virtio \
-incoming tcp:0:4444

これで準備完了。sayori のmonitor コンソールから migration を開始する。

(qemu) migrate -d -b tcp:wasabi:4444

進捗はこれで確認できる。

(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

block migration と live migration は約 15分程度で完了した。
block migration -> live migration という流れなんだけど、 block migration 中は普通にguestは動作しているし、ファイルにもアクセスできる。オープン中のファイルも問題無し。
正味の停止時間は5秒程度だった。

No comments yet.

Leave a comment

You must be logged in to post a comment.

qemu-kvm の live migration を試してみたよ。

2010/03/20 Saturday 23:51:48

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 guest > mnt/etc/hostname
kujira:~# umount mnt/

/etc/ietd.conf にこんな風に書く。

Target iqn.1999-05.net.hamano:dick1
        Lun 0 Path=/path/to/disk1.img,Type=fileio

initramfsの作成

iSCSIイニシエータとして機能する initramfsを作る。

% mkidr initrd
% cd initrd
% zcat /boot/initrd.img-2.6.26-2-686 | cpio -iv

init スクリプトの root file system をマウントする直前に以下の5行を追加。

ipconfig -t 60 ${DEVICE}
modprobe iscsi_tcp
iscsid -f &
iscsiadm -m discovery -t sendtargets -p 192.168.1.11
iscsiadm -m node -T iqn.1999-05.net.hamano:dick1 -l

iSCSIターゲットをマウントするのに必要なファイルを配置、あと kernel module の libcrc32c.ko と crc32c.ko が必要。

% 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/

あと iscsid の中で getpwuid(3)呼んでいてユーザー名が root じゃなかったら蹴られてしまうので nss関連も適当に入れておく。

% 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

この initrd に chroot して

# id
uid=0(root) gid=0

って帰ってくればひとまずOK

initramfsを固めて、tftpd サーバーに配置する。

% find ./ | cpio -o -H newc | gzip -9 > ../initrd.img-2.6.26-2-686

PXE boot の設定

pxelinux.cfg/default にこんな風に書く。パラメータに noresume を付けないと起動途中で止まってしまったので付けた。

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

qemu-kvmのネットワーク設定

wasabi, sayoriの両方のホストでtap50をブリッジする。
この辺りいつもは qemu-ifup scriptで自動化しているけど今回は手動で。

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

qemu-kvmの実行

wasabi 側で待機する。

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

sayori 側でゲストを起動する。

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

guest側でファイルをオープンしっぱなしにして、
別のサーバーから guest にTCPコネクションを張っておく。

準備が整ったのでいざ Live Migration!
sayori のモニターコンソールから

(qemu) migrate -d tcp:wasabi:4444

live migration の進捗はこれで確認できる。

(qemu) info migrate
Migration status: active
transferred ram: 8000 kbytes
remaining ram: 533648 kbytes
total ram: 541056 kbytes
(qemu) info migrate
Migration status: completed

migrationはだいたい5秒くらいで完了する。

結果

TCPコネクションは切れていない、オープン中のファイルも問題なく読み書き出来た。
理論上出来ると解っていても実際に動かしてみるとなかなか感動。

補足事項

  • qemu-kvm 0.11.1 では nic の virtio を有効にして PXE boot 出来ない。
  • 最初、sayoriの kernel を 2.6.32.9、wasabi の kernel を 2.6.26.8 で試すと以下のエラーメッセージが出て失敗した。
  • Unknown savevm section or instance 'kvmclock' 0
    load of migration failed
    

    kernel 2.6.31.5 < -> kernel 2.6.26.8 で試すと成功した。kvmのバージョンは出来るだけ揃えた方が無難。

No comments yet.

Leave a comment

You must be logged in to post a comment.

MALLOC_MMAP_THRESHOLD_ と MALLOC_MMAP_MAX_

2010/02/22 Monday 03:50:51

malloc(3) を呼んだ時、glibc はヒープ領域から指定したサイズのチャンクを確保するが、ヒープ領域が足りなかった場合 glibc は brk(2) を呼んでヒープ領域を拡張するか、Anonymous Memory と呼ばれる領域を mmap(2) して新たなヒープ領域を作成する。

この動作を制御する環境変数が MALLOC_MMAP_THRESHOLD_ らしいのでこれを試しているのだけれど、効かなくて困った。

しかたがないので glibc のソースを読んでいると mmap(2) を使用する最大サイズを指定する MALLOC_MMAP_MAX_ というのも見つけた、これはばっちり効いたのでこれを使おう。

1M を 3回 malloc するだけのコード

#include <stdio .h>
#include <stdlib .h>

int main(){
    int i;
    for(i=0;i<3;i++){
        malloc(1*1024*1024);
    }
    return 0;
}
% 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

デフォルトではこんな風に、3回 mmap(2) が呼ばれる。
MALLOC_MMAP_MAX_=0 にすると、

% strace env MALLOC_MMAP_MAX_=0 ./a.out
(略)
brk(0)                                  = 0x8efa000
brk(0x901b000)                          = 0x901b000
brk(0x911b000)                          = 0x911b000
brk(0x921b000)                          = 0x921b000

4回 brk(2) を呼ぶようになった。
MALLOC_MMAP_MAX_=1 にすると、

% 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

最初の malloc(3) だけ mmap(2) するようになった。
単位はMbyte なのね。(MALLOC_TRIM_THRESHOLD_の単位は byte だったのに・・・)

これで完全に malloc(3) の中で mmap(2) を呼ぶこと無いかというと、そういう訳でもなくて、特定の条件下で mmap(2) する場合ある様なので困ったのう。

No comments yet.

Leave a comment

You must be logged in to post a comment.

spamassassin と wanderlust

2010/02/13 Saturday 03:31:03

spamassassin で

rewrite_header Subject ***SPAM***

などとやっている場合の偽陽性なメールに対して返信する時に

Re: ***SPAM*** ほにゃららについて

って件名のメールを送ってしまうのは失礼ではないか。
ということで、追加した wanderlust 向け elisp

(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 ""))
               ))))

No comments yet.

Leave a comment

You must be logged in to post a comment.

20100123 simple

2010/01/23 Saturday 17:39:23

今日やったこと。
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 メモ – 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

No comments yet.

Leave a comment

You must be logged in to post a comment.

Next Page >