ICTSC2018 本戦 問題解説: Upgrade QEMU; Ubuntu 16.04 -> 18.04
問題文
Ubuntu 16.04 にて、以下の操作で QEMU の API である QMP を使ってディスクの追加を行っていたが、 Ubuntu 18.04 では動作しなかった。 Ubuntu 18.04で同じ動作をするように QMP の操作を見直してほしい。$ cd
$ qemu-system-x86_64 -uuid c01769df-766c-49e3-9c8c-d148e9557975 -name guest=test,debug-threads=on -msg timestamp=on -nodefaults -no-user-config -S -no-shutdown -global kvm-pit.lost_tick_policy=discard -chardev socket,id=charmonitor,path='monitor.sock',server,nowait -mon chardev=charmonitor,id=monitor,mode=control -boot menu=on,strict=on -k en-us -rtc base=utc,driftfix=slew -global kvm-pit.lost_tick_policy=delay -no-hpet -smp 1,sockets=1,cores=1,threads=1 -m 512M -realtime mlock=off -device VGA,id=video0,bus=pci.0 -vnc 0.0.0.0:0 -serial stdio
$ qmp-shell -v -p ~/monitor.sock (QEMU) blockdev-add options='{"driver":"qcow2","id":"virtio0","file":{"driver":"file","filename":"/home/admin/cirros-0.4.0-x86_64-disk.img"}}' (QEMU) device_add driver=virtio-blk-pci bus=pci.0 scsi=off drive=virtio0 id=virtio-disk0 bootindex=1 (QEMU) cont # 起動
情報
Ubuntu 18.04
IPアドレス:192.168.11.1
ユーザー:
admin
パスワード:
QMPisUndocumented
Ubuntu 16.04
IPアドレス:192.168.11.2
ユーザー:
admin
パスワード:
QMPisUndocumented
問題のゴール状態
Ubuntu 18.04 においてもVMが起動しているトラブルの概要
VM を管理する QEMU には、プロセスを立ち上げたあとに制御するために QMP と呼ばれる JSON RPC API が存在する。Ubuntu 16.04(QEMU emulator version 2.5.0 (Debian1:2.5+dfsg-5ubuntu10.30)) から
Ubuntu 18.04 (QEMU emulator version 2.11.1(Debian 1:2.11+dfsg-1ubuntu7.7)) へのアップグレードには破壊的な更新が存在し、
それがもとで BlockDev の追加ができないというトラブルである。
解説
この問題は、バージョンアップへの対応を行えるかという点と QEMU を理解しているかという点を確認する問題でした。詳しい説明は割愛しますが、 QEMU Machine Protocol(以下QMP)においてデバイスを接続する場合は、
QEMU プロセスと外部(ホストOS側)を接続する
blockdev-add
や netdev_add
と、QEMU に接続された外部デバイスをゲストOSに接続する
device_add
という命令を使用します。今回の問題では
blockdev-add
の仕様が変わったことによってトラブルが発生していました。http://qemu.11.n7.nabble.com/Adding-an-overlay-with-blockdev-add-fails-with-quot-Parameter-driver-is-missing-quot-td468076.html
つまり、Ubuntu 16.04 にて動作するクエリは以下のとおりですが、
{
"execute":"blockdev-add",
"arguments":{
"options":{
"driver":"qcow2",
"id":"virtio0",
"file":{
"driver":"file",
"filename":"/root/cirros.qcow2"
}
}
}
}
Ubuntu 18.04 では以下のようになります。
{
"execute":"blockdev-add",
"options":{
"driver":"qcow2",
"node_name":"virtio0",
"file":{
"driver":"file",
"filename":"/root/cirros.qcow2"
}
}
}
よって,qmp-shellでは以下のように操作をすることで今回の問題が解決します。
$ qemu-system-x86_64 -uuid c01769df-766c-49e3-9c8c-d148e9557975 -name guest=test,debug-threads=on -msg timestamp=on -nodefaults -no-user-config -S -no-shutdown -global kvm-pit.lost_tick_policy=discard -chardev socket,id=charmonitor,path='monitor.sock',server,nowait -mon chardev=charmonitor,id=monitor,mode=control -boot menu=on,strict=on -k en-us -rtc base=utc,driftfix=slew -global kvm-pit.lost_tick_policy=delay -no-hpet -smp 1,sockets=1,cores=1,threads=1 -m 512M -realtime mlock=off -device VGA,id=video0,bus=pci.0 -vnc 0.0.0.0:0 -serial stdio
$ qmp-shell -v -p ~/monitor.sock
(QEMU) blockdev-add driver=qcow2 node-name=virtio0 file='{"driver":"file","filename":"/home/admin/cirros-0.4.0-x86_64-disk.img"}'
(QEMU) device_add driver=virtio-blk-pci bus=pci.0 scsi=off drive=virtio0 id=virtio-disk0 bootindex=1
(QEMU) cont
回答例
この問題のUbuntu 16.04上にあるQEMUとUbuntu 18.04上にあるQEMUのバージョンが異なることにより、受け付けるQMPクエリの構造が異なることで今回のトラブルが発生しておりました。そのため、QEMUプロセス起動後のQMP Shellでの操作を以下のように変更することで解決します。
(QEMU) blockdev-add driver=qcow2 node-name=virtio0 file='{"driver":"file","filename":"/home/admin/cirros-0.4.0-x86_64-disk.img"}' (QEMU) device_add driver=virtio-blk-pci bus=pci.0 scsi=off drive=virtio0 id=virtio-disk0 bootindex=1 (QEMU) cont
採点基準
– 18.04でQMPを使ってVMが立ち上がる (100%)“