问题描述:
在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。