問題描述:
啓動一個虛擬機,創建三個快照,刪除第一個快照時報錯:合併磁盤失敗
通過測試,創建虛擬機(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