1. 程式人生 > >解決虛擬機器建立快照後刪除報錯,重啟該虛擬機器後刪除成功的問題

解決虛擬機器建立快照後刪除報錯,重啟該虛擬機器後刪除成功的問題

問題描述:
在ovirt中,建立快照後刪除該快照失敗,只有重啟虛擬機器後該快照才能刪除

日誌中均出現如下報錯:

2018-02-19 01:51:45,792+0800 ERROR (jsonrpc/7) [virt.vm] (vmId=’a5935784-6d8a-4a4e-ab18-bb8c9b8cce9b’) Live merge failed (job: 7b217072-2149-4439-ab28-4a8bc52ada3d) (vm:4918)
Traceback (most recent call last):
File “/usr/share/vdsm/virt/vm.py”, line 4914, in merge
flags)
File “/usr/lib/python2.7/dist-packages/vdsm/virt/virdomain.py”, line 69, in f
ret = attr(*args, **kwargs)
File “/usr/lib/python2.7/dist-packages/vdsm/libvirtconnection.py”, line 123, in wrapper
ret = f(*args, **kwargs)
File “/usr/lib/python2.7/dist-packages/vdsm/utils.py”, line 926, in wrapper
return func(inst, *args, **kwargs)
File “/usr/lib/python2.7/dist-packages/libvirt.py”, line 674, in blockCommit
if ret == -1: raise libvirtError (‘virDomainBlockCommit() failed’, dom=self)
libvirtError: Requested operation is not valid: can’t keep relative backing relationship

問題使用libvirt virsh復現步驟:

$ cat build.sh 
#!/bin/bash

sudo qemu-img create -f qcow2 base.qcow2 10G
#sudo qemu-img create -f qcow2 sn1.qcow2 -o backing_file=base.qcow2 10G

sudo virsh define /opt/libvirt/vm1.xml 
sudo virsh start vm1

sudo virsh domblklist vm1

sudo virsh snapshot-create-as --domain vm1 snap1 \
    --diskspec vda,file=/opt/libvirt/sn1.qcow2 \
    --disk-only --atomic --no-metadata

sudo
virsh snapshot-create-as --domain vm1 snap2 \ --diskspec vda,file=/opt/libvirt/sn2.qcow2 \ --disk-only --atomic --no-metadata sudo virsh snapshot-create-as --domain vm1 snap3 \ --diskspec vda,file=/opt/libvirt/sn3.qcow2 \ --disk-only --atomic --no-metadata sudo virsh domblklist vm1 sudo
qemu-img info --backing-chain \ /opt/libvirt/sn3.qcow2 sudo virsh domblklist vm1 #sudo virsh blockcommit vm1 vda --verbose --pivot --active echo "-------merge" sudo virsh blockcommit --domain vm1 vda --base /opt/libvirt/sn1.qcow2 \ --top /opt/libvirt/sn2.qcow2 --keep-relative --wait --verbose sudo virsh domblklist vm1 sudo qemu-img info --backing-chain /opt/libvirt/vm1.xml $ cat unbuild.sh #!/bin/bash sudo virsh destroy vm1 sudo virsh undefine vm1 sudo rm ./*.qcow2 $ cat vm1.xml <domain type='kvm'> //如果是Xen,則type=‘xen’ <name>vm1</name> //虛擬機器名稱,同一物理機唯一 <uuid>fd3535db-2558-43e9-b067-314f48211343</uuid> //同一物理機唯一,可用uuidgen生成 <memory>524288</memory> <currentMemory>524288</currentMemory> //memory這兩個值最好設成一樣 <vcpu>2</vcpu> //虛擬機器可使用的cpu個數,檢視物理機可用CPU個數:cat /proc/cpuinfo |grep processor | wc -l <os> <type arch='x86_64' machine='pc-i440fx-vivid'>hvm</type> //arch指出系統架構型別,machine 則是機器型別,檢視機器型別:qemu-system-x86_64 -M ? <boot dev='hd'/> //啟動介質,第一次需要裝系統可以選擇cdrom光碟啟動 <bootmenu enable='yes'/> //表示啟動按F12進入啟動選單 </os> <features> <acpi/> //Advanced Configuration and Power Interface,高階配置與電源介面 <apic/> //Advanced Programmable Interrupt Controller,高階可程式設計中斷控制器 <pae/> //Physical Address Extension,實體地址擴充套件 </features> <clock offset='localtime'/> //虛擬機器時鐘設定,這裡表示本地本機時間 <on_poweroff>destroy</on_poweroff> //突發事件動作 <on_reboot>restart</on_reboot> <on_crash>restart</on_crash> <devices> //裝置配置 <emulator>/usr/bin/kvm</emulator> //如果是Xen則是/usr/lib/xen/binqemu-dm <disk type='file' device='disk'> //硬碟 <driver name='qemu' type='raw'/> <source file='/opt/libvirt/base.qcow2'/> <target dev='vda' bus='virtio'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> //域、匯流排、槽、功能號,slot值同一虛擬機器上唯一 </disk> <disk type='file' device='cdrom'>//光碟 <driver name='qemu' type='raw'/> <source file='/home/pencc/圖片/Linx-Node-201711-amd64.iso'/> <target dev='hdc' bus='ide'/> <readonly/> </disk> <graphics type='vnc' port='5900' autoport='yes' listen='0.0.0.0' keymap='en-us'> //配置vnc,windows下可以使用vncviewer登入,獲取vnc埠號:virsh vncdisplay vm0 <listen type='address' address='0.0.0.0'/> </graphics> </devices> </domain>

通過gdb除錯排查,發現問題在於建立快照後該快照結構體中的relPath為null,重啟虛擬機器後能得到該relPath,說明只有重啟後重構快照鏈時才會賦值,而真實的relPath儲存在dd->disk->src->relPath中,故在建立快照鏈流程中的qemuDomainSnapshotDiskDataCollect中新增VIR_STEAL_PTR即可。

修改後實測多次均ok。