libvirt-0.9.10 にバージョンアップして 0.8.7 に戻したら起動しているVMが認識できなくて困った

Scientific Linux 6.0 で KVM + libvirtd で仮想環境を構築していて、libvirt-0.8.7-18.el6_1.1.x86_64 → libvirt-0.9.10-21.el6.x86_64 に update したところ、libvirtd が起動時に Segmentation falt するという現象に遭遇。

Caught Segmentation violation dumping internal log buffer:


    ====== start of log =====

s:474 : i=10 w=11
2012-07-12 03:58:32.715+00009220: debug : virEventPollDispatchHandles:474 : i=11 w=12
2012-07-12 03:58:32.715+00009220: debug : virEventPollDispatchHandles:474 : i=12 w=13
2012-07-12 03:58:32.715+00009220: debug : virEventPollDispatchHandles:488 : EVENT_POLL_DISPATCH_HANDLE: watch=13 events=1
2012-07-12 03:58:32.715+00009220: debug : qemuMonitorRef:201 : QEMU_MONITOR_REF: mon=0x7f05e4000a10 refs=4
2012-07-12 03:58:32.715+0000922: debug : qemuMonitorIOProcess:327 : QEMU_MONITOR_IO_PROCESS: mon=0x7f05e4000a10 buf={"return": {}, "id": "libvirt-1"}
 len=35
2012-07-12 03:58:32.715+00009220: debug : qemuMonitorJSONIOProcessLine:135 : Line [{"return": {}, "id": "libvirt-1"}]
2012-07-12 03:58:32.715+00009220: debug : virJSONValueFromString:948 : string={"return": {}, "id": "libvirt-1"}
2012-07-12 03:58:32.715+00009220: debug : virJSONParserHandleStartMap:825 : parser=0x7fff19dabac0
2012-07-12 03:58:32.715+00009220: debug : virJSONParserHandleMapKey:806 : parser=0x7fff19dabac0 key=0x1c48cd2
2012-07-12 03:58:32.715+00009220: debug : virJSONParserHandleStartMap:825 : parser=0x7fff19dabac0
2012-07-12 03:58:32.715+00009220: debug : virJSONParserHandleEndMap:854 : parser=0x7fff19dabac0
2012-07-12 03:58:32.715+00009220: debug : virJSONParserHandleMapKey:806 : parser=0x7fff19dabac0 key=0x1c48ce0
2012-07-12 03:58:32.715+00009220: debug : virJSONParserHandleString:786 : parser=0x7fff19dabac0 str=0x1c48ce6
2012-07-12 03:58:32.715+00009220: debug : virJSONParserHandleEndMap:854 : parser=0x7fff19dabac0
2012-07-12 03:58:32.715+00009220: debug : virJSONValueFromString:992 : result=0x1c21890
2012-07-12 03:58:32.715+00009220: debug : qemuMonitorJSONIOProcessLine:155 : QEMU_MONITOR_RECV_REPLY: mon=0x7f05e4000a10 reply={"return": {}, "id": "libvirt-1"}
2012-07-12 03:58:32.715+00009220: debug : qemuMonitorJSONIOProcess:206 : Total used 35 bytes out of 35 available in buffer
2012-07-12 03:58:32.715+00009220: debug : virEventPollUpdateHandle:151 : EVENT_POLL_UPDATE_HANDLE: watch=13 events=13
2012-07-12 03:58:32.715+000092Segmentation fault

これはこれで困るのだけど、よく分からないのでひとまず 0.8.7 の RPM で上書きしてバージョンを戻したところ、稼働中のはずの VM が shut off と認識されてしまう状態に。

# virsh list --all
 Id    Name                           State
----------------------------------------------------
 15    freenas                        shut off
 19    centos5                        shut off
 21    sl6                            shut off
  • QEMU のプロセスは動作していて、ネットワーク越しに問題なく VM は利用できる
  • resume, shutdown, console などの操作はすべて、起動していないという理由で (domain is not running) 拒否されてしまう

strace を取ってみたところ、/var/run/libvirt/qemu/{domname}.xml を読み込んだところで "internal error Unknown controller type 'usb'" というエラーが出ている。

open("/var/run/libvirt/qemu/sl6.xml", O_RDONLY) = 17
fstat(17, {st_mode=S_IFREG|0600, st_size=3091, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f78d5ceb000
read(17, "<!--\nWARNING: THIS IS AN AUTO-GE"..., 16384) = 3091
read(17, "", 12288)                     = 0
lseek(17, 0, SEEK_CUR)                  = 3091
lseek(17, 0, SEEK_SET)                  = 0
read(17, "<!--\nWARNING: THIS IS AN AUTO-GE"..., 4096) = 3091
read(17, "", 4096)                      = 0
read(17, "", 4096)                      = 0
close(17)                               = 0
munmap(0x7f78d5ceb000, 4096)            = 0
gettid()                                = 7166
write(2, "22:32:08.715: 7166: error : virD"..., 11122:32:08.715: 7166: error : virDomainControllerDefParseXML:2135 : internal error Unknown controller type 'usb'
) = 111

この XML ファイルは libvirtd が VM 起動時に作成するもの。タイムスタンプを見ると、libvirtd-0.9.10 にアップデートして起動した時刻と一致している。

[libvirt] Failure to migrate a guest from libvirt-0.9.10+ to libvirt-0.9 によると、0.9.5 以降の libvirtd は自動的に

<controller type='usb' index='0'/>

を追加するものの、それより前の libvirtd はこの記述が理解できないため読み込めない。ゆえに起動していることが認識できない、ということらしい。

手動で /var/run/libvirt/qemu/{domname}.xml から を削除して libvirtd を再起動することで復旧できた。

libvirtd のバージョンを下げるときには気を付けましょう、ということですね。