目录
前言:
近期频繁遇到虚拟机迁移出现check不匹配以及cpu feature内容与启动时的配置内容增加的的问题,为此针对性的调研了libvirt在虚拟机启动时是如何组织cpu check信息以及如何扩展cpu feature信息的问题。根据自身以往经验自适应模式出现问题较多(check不匹配、feather不匹配),因此本文章调试的配置为cpu自适应模式,来分析check模式不相同的原因以及feather内容是如何添加到libvirt中的。
调研发现,cpu check值与cpu mode配置相关,并且保存配置文件内check信息到originCPU中,更新cpu信息到vm->def->cpu中,其次libvirt会获取qemu关于cpu feature的配置信息,并扩充到libvirt中的def->cpu->feature中,即libvirt中扩展的feature信息都是从qemu中获取的。
1 cpu check配置
cpu check问题在计算迁移或者整机迁移中出现情况较多,报错信息类似与“Target CPU ckeck full does not match source none“分析一下是什么原因导致源配置与目标配置不同的。
图1 cpu自适应模式启动配置
当虚拟机以该配置启动时,在启动cpu之前libvirt会对cpu进行更新配置:
图2 libvirt扩充cpu模式逻辑
调用逻辑为:qemuDomainCreateXML->qemuProcessStart->qemuProcessLaunch->qemuProcessUpdateAndVerifyCPU->qemuProcessUpdateLiveGuestCPU
由代码逻辑可以确定当cpu模式为custom时会强制设置check值为full,由资料解释因为自适应模式比较灵活,为了迁移安全需要进行全量检测。由于我们启动时的cpu为默认配置因此check值为none并把该值保存在origCPU中,这样就导致libvirt dumpxml的cpu内容与origCPU中的内容有区别。
反向证明:
1:当cpu mode为直通模式时,virsh dumpxml出check的内容跟配置文件设置的可以保持一致,若cpu mode为custom模式 ,无论配置文件设置ckeck为何值,dumpxml出check的内容均为full;
2 扩充CPU features
libvirt通过启动后的qemu进程获取vcpu的支持属性以及cpu_map配置文件中的属性进行匹配cpuid值,其次是虚拟机启动时的feature配置与cpu_map进行匹配,如果相同则为扩展的属性信息。
2.1获取扩展feature属性内容
在libvirt启动完qemu进程还未启动vcpu时,libvirt会通过qmp指令”qom-list /machine/unattached/device[0]”获取vcpu所支持的特性,其中machine/unattached/device[0]为qemu64-x86_64-cpu,接着使用qom-get获取该属性值。
图3 使用info qom-tree获取qom对象信息
图4 通过qom-list获取vcpu可支持的属性
图5 通过qom-get获取vcpu是否开启该属性
libvirt根据该属性的值来扩充cpu features信息;
图6 获取填充feature信息逻辑
2.1获取cpu_map配置文件中的属性值
配置文件中的属性信息被读取到全局变量cpumap中根据cpu model值获取对应具体的cpu_map;
图7 cpu_map/x86_qemu64.xml信息
图8 获取cpumap逻辑
通过cpuid匹配来确认最终需要扩展那些cpu feature信息
图9 libvirt扩展feature信息逻辑
遍历全局变量cpu_map: 如果启动时的配置文件中cpu有该属性则设置expected为require,但是在qemu进程的vcpu中该属性设置为假,因此需要添加该feature并设置该属性值为disable,如果该属性在启动是的配置文件中没有,但是在qmeu进程的vcpu中该配置为真,因此需要添加该feature并设置该属性值为require;
总结
本文章回答了两个问题:
1:为什么虚拟机迁移的时候会出现check不匹配的情况?
答:由于该cpu mode为custom在libvirt逻辑中会强制设置ckeck属性值为full以保证迁移的安全性,并保存启动时的配置在originCPU中,而启动的配置文件中cpu check值为默认值none.
2:libvirt dumpxml信息中的feature属性值从哪来的:
答:来源为两个地方,1:虚拟机启动时的feature值;2:从qemu进程中获取的cpu 属性值;虚拟机启动时的feature没有该值,但在qemu进程中有该属性为真,并且在cpumap中也有该属性则设置该属性为require,如果启动时的feature中有该属性,并且在cpumap中也有该属性但qemu进程中没有该属性则设置为disable.