问题描述:
启动一个虚拟机,创建三个快照,删除第一个快照时报错:合并磁盘失败
通过测试,创建虚拟机(ubuntu1604,win7),启动虚拟机,创建两个快照,删除第一个快照,瘦终端自自动关闭
vdsm报错如下:
2018-07-20 17:00:50,641+0800 ERROR (jsonrpc/2) [jsonrpc.JsonRpcServer] Internal server error (init:607)
Traceback (most recent call last):
File “/usr/lib/python2.7/dist-packages/yajsonrpc/init.py”, line 602, in _handle_request
res = method(**params)
File “/usr/lib/python2.7/dist-packages/vdsm/rpc/Bridge.py”, line 198, in _dynamicMethod
result = fn(*methodArgs)
File “/usr/share/vdsm/API.py”, line 1349, in getAllVmIoTunePolicies
io_tune_policies_dict = self._cif.getAllVmIoTunePolicies()
File “/usr/share/vdsm/clientIF.py”, line 459, in getAllVmIoTunePolicies
‘current_values’: v.getIoTune()}File “/usr/share/vdsm/virt/vm.py”, line 2885, in getIoTune
result = self.getIoTuneResponse()
File “/usr/share/vdsm/virt/vm.py”, line 2898, in getIoTuneResponse
res = self._dom.blockIoTune(
File “/usr/lib/python2.7/dist-packages/vdsm/virt/virdomain.py”, line 47, in getattr
% self.vmid)
NotConnectedError: VM u’9e11571a-8ffb-4b64-bdfa-d5a38638be7e’ was not started yet or was shut down
qemu报错如下:
qemu-system-x86_64: /build/qemu-2.6+dfsg/block/io.c:1342: bdrv_co_do_pwritev: Assertion `!(bs->open_flags & 0x0800)’ failed.
2018-07-20 09:00:49.595+0000: shutting down, reason=crashed
libvirt到qemu的blockcommit调用用流程:
qemu中的blockcommit流程
qemu更更新磁盘preTop的head流程:(base<-top<-preTop)commit_complete
其中,对磁盘头的更新默认更新整个磁盘头,磁盘头中包含了该磁盘的parent磁盘。
问题在于top合并到base之后,系统会通过bdrv_pwritev向preTop磁盘中写入数据,如果该磁盘非active,则assert断言言会导致qemu crash,解决方
案为增加磁盘头例外。
结论
最后实测删除多次均不会导致qemu crash。
附qemu快照删除流程:
初始快照链:
base<-snap1<-snap2<-snap3<-active
其中除active层为rw,其余层均为ro
删除snap1:
1)snap1默认为base, snap2默认为top, snap3默认为preTop。
2)通过blockcommit将top层的改动覆盖到base层
3)复写preTop层的head,将其parent从top修改为base
4)手动删除top