提交 ddd31fd7 编写于 作者: J Ján Tomko

Reserve existing USB addresses

Check if they fit on the USB controllers the domain has,
and error out if two devices try to use the same address.
上级 2f081351
......@@ -1562,3 +1562,45 @@ virDomainUSBAddressSetAddControllers(virDomainUSBAddressSetPtr addrs,
}
return 0;
}
int
virDomainUSBAddressReserve(virDomainDeviceInfoPtr info,
void *data)
{
virDomainUSBAddressSetPtr addrs = data;
virDomainUSBAddressHubPtr targetHub = NULL;
char *portStr = NULL;
int ret = -1;
int targetPort;
if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB)
return 0;
if (!virDomainUSBAddressPortIsValid(info->addr.usb.port))
return 0;
portStr = virDomainUSBAddressPortFormat(info->addr.usb.port);
if (!portStr)
goto cleanup;
VIR_DEBUG("Reserving USB address bus=%u port=%s", info->addr.usb.bus, portStr);
if (!(targetHub = virDomainUSBAddressFindPort(addrs, info, &targetPort,
portStr)))
goto cleanup;
if (virBitmapIsBitSet(targetHub->portmap, targetPort)) {
virReportError(VIR_ERR_XML_ERROR,
_("Duplicate USB address bus %u port %s"),
info->addr.usb.bus, portStr);
goto cleanup;
}
ignore_value(virBitmapSetBit(targetHub->portmap, targetPort));
ret = 0;
cleanup:
VIR_FREE(portStr);
return ret;
}
......@@ -275,4 +275,8 @@ int virDomainUSBAddressSetAddControllers(virDomainUSBAddressSetPtr addrs,
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
void virDomainUSBAddressSetFree(virDomainUSBAddressSetPtr addrs);
int
virDomainUSBAddressReserve(virDomainDeviceInfoPtr info,
void *data)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
#endif /* __DOMAIN_ADDR_H__ */
......@@ -110,6 +110,7 @@ virDomainPCIControllerModelToConnectType;
virDomainUSBAddressPortFormat;
virDomainUSBAddressPortFormatBuf;
virDomainUSBAddressPortIsValid;
virDomainUSBAddressReserve;
virDomainUSBAddressSetAddControllers;
virDomainUSBAddressSetCreate;
virDomainUSBAddressSetFree;
......
......@@ -1330,6 +1330,7 @@ qemuDomainObjPrivateFree(void *data)
virDomainPCIAddressSetFree(priv->pciaddrs);
virDomainCCWAddressSetFree(priv->ccwaddrs);
virDomainVirtioSerialAddrSetFree(priv->vioserialaddrs);
virDomainUSBAddressSetFree(priv->usbaddrs);
virDomainChrSourceDefFree(priv->monConfig);
qemuDomainObjFreeJob(priv);
VIR_FREE(priv->lockState);
......
......@@ -187,6 +187,7 @@ struct _qemuDomainObjPrivate {
virDomainPCIAddressSetPtr pciaddrs;
virDomainCCWAddressSetPtr ccwaddrs;
virDomainVirtioSerialAddrSetPtr vioserialaddrs;
virDomainUSBAddressSetPtr usbaddrs;
virQEMUCapsPtr qemuCaps;
char *lockState;
......
......@@ -1622,11 +1622,44 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
}
static int
qemuDomainAssignUSBAddresses(virDomainDefPtr def,
virDomainObjPtr obj)
{
int ret = -1;
virDomainUSBAddressSetPtr addrs = NULL;
qemuDomainObjPrivatePtr priv = NULL;
if (!(addrs = virDomainUSBAddressSetCreate()))
goto cleanup;
if (virDomainUSBAddressSetAddControllers(addrs, def) < 0)
goto cleanup;
if (virDomainUSBDeviceDefForeach(def, virDomainUSBAddressReserve, addrs,
true) < 0)
goto cleanup;
VIR_DEBUG("Existing USB addresses have been reserved");
if (obj && obj->privateData) {
priv = obj->privateData;
priv->usbaddrs = addrs;
addrs = NULL;
}
ret = 0;
cleanup:
virDomainUSBAddressSetFree(addrs);
return ret;
}
int
qemuDomainAssignAddresses(virDomainDefPtr def,
virQEMUCapsPtr qemuCaps,
virDomainObjPtr obj,
bool newDomain ATTRIBUTE_UNUSED)
bool newDomain)
{
if (qemuDomainAssignVirtioSerialAddresses(def, obj) < 0)
return -1;
......@@ -1642,6 +1675,9 @@ qemuDomainAssignAddresses(virDomainDefPtr def,
if (qemuDomainAssignPCIAddresses(def, qemuCaps, obj) < 0)
return -1;
if (newDomain && qemuDomainAssignUSBAddresses(def, obj) < 0)
return -1;
return 0;
}
......
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory unit='KiB'>219136</memory>
<currentMemory unit='KiB'>219136</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<devices>
<emulator>/usr/bin/qemu</emulator>
<controller type='usb' index='0'/>
<memballoon model='virtio'/>
<hub type='usb'>
<address type='usb' bus='0' port='1'/>
</hub>
<input type='mouse' bus='usb'>
<address type='usb' bus='0' port='1'/>
</input>
</devices>
</domain>
......@@ -1180,6 +1180,9 @@ mymain(void)
DO_TEST("usb-hub",
QEMU_CAPS_CHARDEV, QEMU_CAPS_USB_HUB,
QEMU_CAPS_NODEFCONFIG);
DO_TEST_PARSE_ERROR("usb-hub-conflict",
QEMU_CAPS_CHARDEV, QEMU_CAPS_USB_HUB,
QEMU_CAPS_NODEFCONFIG);
DO_TEST("usb-port-missing",
QEMU_CAPS_CHARDEV, QEMU_CAPS_USB_HUB,
QEMU_CAPS_NODEFCONFIG);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册