一句话总结
背景介绍
自己编译libvirt源码包:libvirt:1.2.12
创建虚拟机的时候报错
虚拟机的xml没有指定controller
No PCI buses available
原因分析
通过搜索源码发现No PCI buses available错误在domain_addr.c
开启gdb调试(具体看本人相关博文:gdb debug libvirt)
在virDomainPCIAddressGetNextSlot处打断电
触发断点
可见确实是由于addrs->nbuses == 0导致的错误
gdb下bt一下,查看函数调用栈
根据错误原因我们知道是addr->nbuses导致的错误
通过函数栈,分析代码知道,addr是这里生成的
此处打断点,进入看就会发现addrs->nbuses就是函数的nbuses值
在qemuDomainAssignPCIAddresses中nbuses来源于max_idx
nbuses = max_idx + 1;
从代码上分析,应该是没有进这里
导致max_idx是默认值-1,断点调试之
11q
7是VIR_DOMAIN_CONTROLLER_TYPE_PCI
此外def->ncontrollers等于1说明只有一个usd控制器
也就是说def中没有pci的控制器导致的错误
接下来分享def->controllers的来源
在回到刚才的bt结果的函数栈
猜测def来源于qemuDomainCreateXML
进入qemuDomainCreateXML经过层层调用,最终生成def是这里
我们找到controller相关地方
如果虚拟机xml中指定了controller
然并卵,我们这里没有指定controller,应该是哪里会生成默认的
通过打断点不停调试,发现是在这里指定的controller
看下方法virDomainDefPostParse源码
通过调试知道,这里调用到qemu/qemu_domain.c:919
看下源码
根据虚拟机的arch机器machine类型决定添加那种controller设备
可见,这里machine的类型是ubuntu,因此没有添加
有些朋友可能会说,machine类型的就是引用的pc-i440fx-utopic
如,用virsh capabilities查得
虽然后期os.machine最终会用qemuCanonicalizeMachine替换为pc-i440fx-utopic
但是controller此时已经设定好了,也就是书已经决定么有pci-root这个controller了
问题解决
在上述代码中补充”ubuntu”
如下,在ubuntu的libvirt-1.2.12的包中已经做了这个patch