libvirt q35 报错

13 篇文章 0 订阅

如果是Q35,PCIeRoot 默认就是 true。


修改machine=q35    <type arch='x86_64' machine='pc-q35-2.6'>hvm</type>

报如下错:

error: XML error: The PCI controller with index='0' must be model='pcie-root' for this machine type, but model='pci-root' was found instead


于是查看代码:


查找Controller,从def里的controllers里查找出符合 type和idx 的Controller的位置
int
virDomainControllerFind(const virDomainDef *def,
                        int type,
                        int idx)
{
    size_t i;

    for (i = 0; i < def->ncontrollers; i++) {
        if ((def->controllers[i]->type == type) &&
            (def->controllers[i]->idx == idx)) {
            return i;
        }
    }

    return -1;
}


    pciRoot = virDomainControllerFind(def, VIR_DOMAIN_CONTROLLER_TYPE_PCI, 0);     查找VIR_DOMAIN_CONTROLLER_TYPE_PCI,索引是0的Controller


    /* NB: any machine that sets addPCIRoot to true must also return
     * true from the function qemuDomainSupportsPCI().
     */
    if (addPCIRoot) {
        if (pciRoot >= 0) {
            if (def->controllers[pciRoot]->model != VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) {
                virReportError(VIR_ERR_XML_ERROR,
                               _("The PCI controller with index='0' must be "
                                 "model='pci-root' for this machine type, "
                                 "but model='%s' was found instead"),
                               virDomainControllerModelPCITypeToString(def->controllers[pciRoot]->model));
                goto cleanup;
            }
        } else if (!virDomainDefAddController(def, VIR_DOMAIN_CONTROLLER_TYPE_PCI, 0,
                                              VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT)) {
            goto cleanup;
        }
    }

    /* When a machine has a pcie-root, make sure that there is always
     * a dmi-to-pci-bridge controller added as bus 1, and a pci-bridge
     * as bus 2, so that standard PCI devices can be connected
     *
     * NB: any machine that sets addPCIeRoot to true must also return
     * true from the function qemuDomainSupportsPCI().
     */
    if (addPCIeRoot) {                      #从这里就有bug了,如果是PCIeRoot,结果用的是pciRoot的索引去查找控制器,这样肯定查找到的就不是真正的PCIE控制器

        if (pciRoot >= 0) {
            if (def->controllers[pciRoot]->model != VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT) {    大致判断在这里,如果这里pci的controller的model如果不是PCIE_ROOT 就会报错
                virReportError(VIR_ERR_XML_ERROR,
                               _("The PCI controller with index='0' must be "
                                 "model='pcie-root' for this machine type, "
                                 "but model='%s' was found instead"),
                               virDomainControllerModelPCITypeToString(def->controllers[pciRoot]->model));
                goto cleanup;
            }
        } else if (!virDomainDefAddController(def, VIR_DOMAIN_CONTROLLER_TYPE_PCI, 0,
                                             VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT)) {
            goto cleanup;
        }
        /* Add a dmi-to-pci-bridge bridge if there are no PCI controllers
         * other than the pcie-root. This is so that there will be hot-pluggable
         * PCI slots available.
         *
         * We skip this step for aarch64 mach-virt guests, where we want to
         * be able to have a pure virtio-mmio topology
         */
        if (virDomainControllerFind(def, VIR_DOMAIN_CONTROLLER_TYPE_PCI, 1) < 0 &&
            !qemuDomainMachineIsVirt(def) &&
            !virDomainDefAddController(def, VIR_DOMAIN_CONTROLLER_TYPE_PCI, 1,
                                       VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE))
            goto cleanup;
    }


从以上代码分析,于是修改xml文件, 把pci的controller修改为 pcie-root

<controller type='pci' index='0' model='pci-root'/>   改为 <controller type='pci' index='0' model='pcie-root'/>


保存后,还是报错,不过这次报错和上次不同,报如下错:

error: internal error: Bus 0 must be PCI for integrated PIIX3 USB or IDE controllers

    if (device->type == VIR_DOMAIN_DEVICE_CONTROLLER && addr->domain == 0 &&
        addr->bus == 0 && addr->slot == 1) {
        virDomainControllerDefPtr cont = device->data.controller;

        if ((cont->type == VIR_DOMAIN_CONTROLLER_TYPE_IDE && cont->idx == 0 &&
             addr->function == 1) ||
            (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_USB && cont->idx == 0 &&            USB类型的controoler
             (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI ||                如果是PIIX3_UHCI就会进入下面的判断
              cont->model == -1) && addr->function == 2)) {                               从以上条件可以看出如果是 PIIX3_UHCI 的USB基本会进入下面的代码
            /* Note the check for nbuses > 0 - if there are no PCI
             * buses, we skip this check. This is a quirk required for
             * some machinetypes such as s390, which pretend to have a
             * PCI bus for long enough to generate the "-usb" on the
             * commandline, but that don't really care if a PCI bus
             * actually exists. */
            if (addrs->nbuses > 0 &&                                            总线
                !(addrs->buses[0].flags & VIR_PCI_CONNECT_TYPE_PCI_DEVICE)) {   总线类型, 基本就是如果不是PIC的设置,基本就会进入报错
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("Bus 0 must be PCI for integrated PIIX3 "
                                 "USB or IDE controllers"));
                return -1;
            } else {
                return 0;
            }
        }
    }

从以上代码可以得出结论:

如果是PIIX3的必须是PCI设置,这个就很奇怪了,所以把 usb controller改成其它的,比如PIIX4、 ICH9就可以了


PIIX3_UHCI,
PIIX4_UHCI,
EHCI,
ICH9_EHCI1,
ICH9_UHCI1,
ICH9_UHCI2,
ICH9_UHCI3,
VT82C686B_UHCI,
PCI_OHCI,
NEC_XHCI,
NONE,


<controller type='usb' index='0' model='piix4-uhci'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
    </controller>


感觉是个bug, 难道PIIX3就只能是 PCI ,不能是PCIE?


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值