On Fri, Aug 26, 2011 at 01:44:22AM +0300, Marc-André Lureau wrote: > --- > docs/schemas/domain.rng | 14 +++++ > src/conf/domain_conf.c | 62 +++++++++++++++++++- > src/conf/domain_conf.h | 10 +++ > src/qemu/qemu_command.c | 40 ++++++++++--- > src/qemu/qemu_command.h | 6 +- > src/qemu/qemu_hotplug.c | 2 +- > .../qemuxml2argv-input-usbmouse-addr.args | 1 + > .../qemuxml2argv-input-usbmouse-addr.xml | 27 +++++++++ > tests/qemuxml2argvtest.c | 2 + > 9 files changed, 149 insertions(+), 15 deletions(-) > create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse-addr.args > create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse-addr.xml > > diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng > index 82a4339..632e029 100644 > --- a/docs/schemas/domain.rng > +++ b/docs/schemas/domain.rng > @@ -2029,6 +2029,14 @@ > </attribute> > </element> > </define> > + <define name="usbportaddress"> > + <attribute name="bus"> > + <ref name="usbAddr"/> > + </attribute> > + <attribute name="port"> > + <ref name="usbAddr"/> > + </attribute> > + </define> > <define name="pciaddress"> > <optional> > <attribute name="domain"> > @@ -2360,6 +2368,12 @@ > </attribute> > <ref name="ccidaddress"/> > </group> > + <group> > + <attribute name="type"> > + <value>usb</value> > + </attribute> > + <ref name="usbportaddress"/> > + </group> > </choice> > </element> > </define> > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > index 10bc130..5487e0e 100644 > --- a/src/conf/domain_conf.c > +++ b/src/conf/domain_conf.c > @@ -133,7 +133,8 @@ VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST, > "pci", > "drive", > "virtio-serial", > - "ccid") > + "ccid", > + "usb") > > VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST, > "block", > @@ -1398,6 +1399,9 @@ int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info, > > case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE: > return virDomainDeviceDriveAddressIsValid(&info->addr.drive); > + > + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB: > + return virDomainDeviceUSBAddressIsValid(&info->addr.usb); > } > > return 0; > @@ -1419,6 +1423,13 @@ int virDomainDeviceDriveAddressIsValid(virDomainDeviceDriveAddressPtr addr ATTRI > return 1; /* 0 is valid for all fields, so any successfully parsed addr is valid */ > } > > +int virDomainDeviceUSBAddressIsValid(virDomainDeviceUSBAddressPtr addr) > +{ > + if (addr->port >= 128) /* FIXME: is this correct */ > + return 0; > + > + return 1; > +} > > int virDomainDeviceVirtioSerialAddressIsValid( > virDomainDeviceVirtioSerialAddressPtr addr ATTRIBUTE_UNUSED) > @@ -1787,6 +1798,40 @@ cleanup: > return ret; > } > > +static int > +virDomainDeviceUSBAddressParseXML(xmlNodePtr node, > + virDomainDeviceUSBAddressPtr addr) > +{ > + char *port, *bus; > + int ret = -1; > + > + memset(addr, 0, sizeof(*addr)); > + > + port = virXMLPropString(node, "port"); > + bus = virXMLPropString(node, "bus"); > + > + if (port && > + virStrToLong_ui(port, NULL, 10, &addr->port) < 0) { > + virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("Cannot parse <address> 'port' attribute")); > + goto cleanup; > + } > + > + if (bus && > + virStrToLong_ui(bus, NULL, 10, &addr->bus) < 0) { > + virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("Cannot parse <address> 'bus' attribute")); > + goto cleanup; > + } > + > + ret = 0; > + > +cleanup: > + VIR_FREE(bus); > + VIR_FREE(port); > + return ret; > +} > + > /* Parse the XML definition for a device address > * @param node XML nodeset to parse for device address definition > */ > @@ -1860,6 +1905,11 @@ virDomainDeviceInfoParseXML(xmlNodePtr node, > goto cleanup; > break; > > + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB: > + if (virDomainDeviceUSBAddressParseXML(address, &info->addr.usb) < 0) > + goto cleanup; > + break; > + > default: > /* Should not happen */ > virDomainReportError(VIR_ERR_INTERNAL_ERROR, > @@ -3806,7 +3856,7 @@ error: > goto cleanup; > } > > -/* Parse the XML definition for a network interface */ > +/* Parse the XML definition for an input device */ > static virDomainInputDefPtr > virDomainInputDefParseXML(const char *ostype, > xmlNodePtr node, > @@ -3884,6 +3934,14 @@ virDomainInputDefParseXML(const char *ostype, > if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) > goto error; > > + if (def->bus == VIR_DOMAIN_INPUT_BUS_USB && > + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && > + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) { > + virDomainReportError(VIR_ERR_XML_ERROR, "%s", > + _("Invalid address for a USB device")); > + goto error; > + } > + > cleanup: > VIR_FREE(type); > VIR_FREE(bus); > diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h > index 0f5e974..1ad8071 100644 > --- a/src/conf/domain_conf.h > +++ b/src/conf/domain_conf.h > @@ -69,6 +69,7 @@ enum virDomainDeviceAddressType { > VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE, > VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL, > VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID, > + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB, > > VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST > }; > @@ -105,6 +106,13 @@ struct _virDomainDeviceCcidAddress { > unsigned int slot; > }; > > +typedef struct _virDomainDeviceUSBAddress virDomainDeviceUSBAddress; > +typedef virDomainDeviceUSBAddress *virDomainDeviceUSBAddressPtr; > +struct _virDomainDeviceUSBAddress { > + unsigned int bus; > + unsigned int port; > +}; > + > typedef struct _virDomainDeviceInfo virDomainDeviceInfo; > typedef virDomainDeviceInfo *virDomainDeviceInfoPtr; > struct _virDomainDeviceInfo { > @@ -115,6 +123,7 @@ struct _virDomainDeviceInfo { > virDomainDeviceDriveAddress drive; > virDomainDeviceVirtioSerialAddress vioserial; > virDomainDeviceCcidAddress ccid; > + virDomainDeviceUSBAddress usb; > } addr; > }; > > @@ -1437,6 +1446,7 @@ int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info, > int virDomainDevicePCIAddressIsValid(virDomainDevicePCIAddressPtr addr); > int virDomainDeviceDriveAddressIsValid(virDomainDeviceDriveAddressPtr addr); > int virDomainDeviceVirtioSerialAddressIsValid(virDomainDeviceVirtioSerialAddressPtr addr); > +int virDomainDeviceUSBAddressIsValid(virDomainDeviceUSBAddressPtr addr); > void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info); > void virDomainDefClearPCIAddresses(virDomainDefPtr def); > void virDomainDefClearDeviceAliases(virDomainDefPtr def); > diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c > index 2f32e37..91d8124 100644 > --- a/src/qemu/qemu_command.c > +++ b/src/qemu/qemu_command.c > @@ -1327,7 +1327,11 @@ qemuBuildDeviceAddressStr(virBufferPtr buf, > info->addr.pci.slot, info->addr.pci.function); > else > virBufferAsprintf(buf, ",addr=0x%x", info->addr.pci.slot); > + } else if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) { > + virBufferAsprintf(buf, ",bus=usb%d.0", info->addr.usb.bus); > + virBufferAsprintf(buf, ",port=%d", info->addr.usb.port); > } > + > return 0; > } > > @@ -2089,7 +2093,8 @@ error: > > > char * > -qemuBuildUSBInputDevStr(virDomainInputDefPtr dev) > +qemuBuildUSBInputDevStr(virDomainInputDefPtr dev, > + virBitmapPtr qemuCaps) > { > virBuffer buf = VIR_BUFFER_INITIALIZER; > > @@ -2097,6 +2102,9 @@ qemuBuildUSBInputDevStr(virDomainInputDefPtr dev) > dev->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ? > "usb-mouse" : "usb-tablet", dev->info.alias); > > + if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0) > + goto error; > + > if (virBufferError(&buf)) { > virReportOOMError(); > goto error; > @@ -2285,9 +2293,10 @@ qemuBuildPCIHostdevPCIDevStr(virDomainHostdevDefPtr dev) > > > char * > -qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev) > +qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev, > + virBitmapPtr qemuCaps) > { > - char *ret = NULL; > + virBuffer buf = VIR_BUFFER_INITIALIZER; > > if (!dev->source.subsys.u.usb.bus && > !dev->source.subsys.u.usb.device) { > @@ -2296,13 +2305,24 @@ qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev) > return NULL; > } > > - if (virAsprintf(&ret, "usb-host,hostbus=%d,hostaddr=%d,id=%s", > - dev->source.subsys.u.usb.bus, > - dev->source.subsys.u.usb.device, > - dev->info.alias) < 0) > + virBufferAsprintf(&buf, "usb-host,hostbus=%d,hostaddr=%d,id=%s", > + dev->source.subsys.u.usb.bus, > + dev->source.subsys.u.usb.device, > + dev->info.alias); > + > + if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0) > + goto error; > + > + if (virBufferError(&buf)) { > virReportOOMError(); > + goto error; > + } > > - return ret; > + return virBufferContentAndReset(&buf); > + > +error: > + virBufferFreeAndReset(&buf); > + return NULL; > } > > > @@ -4223,7 +4243,7 @@ qemuBuildCommandLine(virConnectPtr conn, > if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { > char *optstr; > virCommandAddArg(cmd, "-device"); > - if (!(optstr = qemuBuildUSBInputDevStr(input))) > + if (!(optstr = qemuBuildUSBInputDevStr(input, qemuCaps))) > goto error; > virCommandAddArg(cmd, optstr); > VIR_FREE(optstr); > @@ -4741,7 +4761,7 @@ qemuBuildCommandLine(virConnectPtr conn, > > if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { > virCommandAddArg(cmd, "-device"); > - if (!(devstr = qemuBuildUSBHostdevDevStr(hostdev))) > + if (!(devstr = qemuBuildUSBHostdevDevStr(hostdev, qemuCaps))) > goto error; > virCommandAddArg(cmd, devstr); > VIR_FREE(devstr); > diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h > index 099d683..de09577 100644 > --- a/src/qemu/qemu_command.h > +++ b/src/qemu/qemu_command.h > @@ -98,7 +98,8 @@ char * qemuBuildWatchdogDevStr(virDomainWatchdogDefPtr dev, > char * qemuBuildMemballoonDevStr(virDomainMemballoonDefPtr dev, > virBitmapPtr qemuCaps); > > -char * qemuBuildUSBInputDevStr(virDomainInputDefPtr dev); > +char * qemuBuildUSBInputDevStr(virDomainInputDefPtr dev, > + virBitmapPtr qemuCaps); > > char * qemuBuildSoundDevStr(virDomainSoundDefPtr sound, > virBitmapPtr qemuCaps); > @@ -115,7 +116,8 @@ int qemuOpenPCIConfig(virDomainHostdevDefPtr dev); > /* Legacy, pre device support */ > char * qemuBuildUSBHostdevUsbDevStr(virDomainHostdevDefPtr dev); > /* Current, best practice */ > -char * qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev); > +char * qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev, > + virBitmapPtr qemuCaps); > > > > diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c > index b2da6d0..60cd241 100644 > --- a/src/qemu/qemu_hotplug.c > +++ b/src/qemu/qemu_hotplug.c > @@ -922,7 +922,7 @@ int qemuDomainAttachHostUsbDevice(struct qemud_driver *driver, > if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { > if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0) > goto error; > - if (!(devstr = qemuBuildUSBHostdevDevStr(hostdev))) > + if (!(devstr = qemuBuildUSBHostdevDevStr(hostdev, priv->qemuCaps))) > goto error; > } > > diff --git a/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse-addr.args b/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse-addr.args > new file mode 100644 > index 0000000..b6dc0d3 > --- /dev/null > +++ b/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse-addr.args > @@ -0,0 +1 @@ > +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -device usb-mouse,id=input0,bus=usb.0,port=4 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 > diff --git a/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse-addr.xml b/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse-addr.xml > new file mode 100644 > index 0000000..a2fa8e3 > --- /dev/null > +++ b/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse-addr.xml > @@ -0,0 +1,27 @@ > +<domain type='qemu'> > + <name>QEMUGuest1</name> > + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> > + <memory>219136</memory> > + <currentMemory>219136</currentMemory> > + <vcpu>1</vcpu> > + <os> > + <type arch='i686' machine='pc'>hvm</type> > + <boot dev='hd'/> > + </os> > + <clock offset='utc'/> > + <on_poweroff>destroy</on_poweroff> > + <on_reboot>restart</on_reboot> > + <on_crash>destroy</on_crash> > + <devices> > + <emulator>/usr/bin/qemu</emulator> > + <disk type='block' device='disk'> > + <source dev='/dev/HostVG/QEMUGuest1'/> > + <target dev='hda' bus='ide'/> > + <address type='drive' controller='0' bus='0' unit='0'/> > + </disk> > + <controller type='ide' index='0'/> > + <input type='mouse' bus='usb'> > + <address type='usb' bus='0' port='4'/> > + </input> > + </devices> > +</domain> > diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c > index f3abc24..b573380 100644 > --- a/tests/qemuxml2argvtest.c > +++ b/tests/qemuxml2argvtest.c > @@ -493,6 +493,8 @@ mymain(void) > DO_TEST("usb-ich9-ehci-addr", false, > QEMU_CAPS_CHARDEV, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, > QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1); > + DO_TEST("input-usbmouse-addr", false, > + QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG); > > DO_TEST("smbios", false, QEMU_CAPS_SMBIOS_TYPE); > ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list