(a couple of things I noticed in passing, which are useful general info whether or not we take these patches in their current form) On 09/07/2012 12:14 PM, Shradha Shah wrote: > This patch introduces the new interface type='hostdev-hybrid' along with > attribute managed > Includes updates to the domain RNG and new xml parser/formatter code. > Also introduces a ephemeral tag for hybrid hostdevs. > The ephemeral tag for hybrid hostdevs will be useful for live migration > support at a later stage. > --- > docs/formatdomain.html.in | 29 ++++++ > docs/schemas/domaincommon.rng | 50 ++++++++++ > src/conf/domain_conf.c | 96 +++++++++++++++++--- > src/conf/domain_conf.h | 2 + > src/uml/uml_conf.c | 5 + > src/xenxs/xen_sxpr.c | 1 + > .../qemuxml2argv-net-hostdevhybrid.args | 8 ++ > .../qemuxml2argv-net-hostdevhybrid.xml | 35 +++++++ > tests/qemuxml2argvtest.c | 2 + > .../qemuxml2xmlout-net-hostdevhybrid.xml | 40 ++++++++ > tests/qemuxml2xmltest.c | 1 + > 11 files changed, 256 insertions(+), 13 deletions(-) > > diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in > index 503685f..70cf362 100644 > --- a/docs/formatdomain.html.in > +++ b/docs/formatdomain.html.in > @@ -2659,6 +2659,20 @@ > guest instead of <interface type='hostdev'/>. > </p> > > + <p> > + Libvirt later than 0.10.0 also supports "intelligent passthrough" > + of VF in the hybrid mode. This is done by using the <interface > + type='hostdev-hybrid'/> functionality. Similar to <interface > + type='hostdev'/> the device's MAC address is first optionally > + configured and the device is optionally associated with an 802.1Qbh > + capable switch using an optionally specified <virtualport> > + element (see the examples of virtualport given above for > + type='direct' network devices). The Vf is passed into the guest as > + a PCI device and at the same time a virtual interface with > + type='direct' mode='bridge' is created in the guest. This hybrid mode > + of intelligent passthrough makes Live migration possible. > + </p> > + > <pre> > ... > <devices> > @@ -2674,6 +2688,21 @@ > </devices> > ...</pre> > > +<pre> > + ... > + <devices> > + <interface type='hostdev-hybrid'> > + <source> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> > + </source> > + <mac address='52:54:00:6d:90:02'> > + <virtualport type='802.1Qbh'> > + <parameters profileid='finance'/> > + </virtualport> > + </interface> > + </devices> > + ...</pre> > + > > <h5><a name="elementsNICSMulticast">Multicast tunnel</a></h5> > > diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng > index c2c6184..eedc255 100644 > --- a/docs/schemas/domaincommon.rng > +++ b/docs/schemas/domaincommon.rng > @@ -1677,6 +1677,56 @@ > <ref name="interface-options"/> > </interleave> > </group> > + <group> > + <attribute name="type"> > + <value>hostdev-hybrid</value> I noticed that the <group> for hostdev-hybrid is exactly the same as for hostdev. In this case, you can just change this line in the hostdev group: <value>hostdev></value> into the following 4 lines: <choice> <value>hostdev</value> <value>hostdev-hybrid</value> </choice> and avoid adding the new <group> altogether. > + </attribute> > + <optional> > + <attribute name="managed"> > + <choice> > + <value>yes</value> > + <value>no</value> > + </choice> > + </attribute> > + </optional> > + <interleave> > + <element name="source"> > + <choice> > + <group> > + <ref name="usbproduct"/> > + <optional> > + <ref name="usbaddress"/> > + </optional> > + </group> > + <element name="address"> > + <choice> > + <group> > + <attribute name="type"> > + <value>pci</value> > + </attribute> > + <ref name="pciaddress"/> > + </group> > + <group> > + <attribute name="type"> > + <value>usb</value> > + </attribute> > + <attribute name="bus"> > + <ref name="usbAddr"/> > + </attribute> > + <attribute name="device"> > + <ref name="usbPort"/> > + </attribute> > + </group> > + </choice> > + </element> > + </choice> > + </element> > + <optional> > + <ref name="virtualPortProfile"/> > + </optional> > + <ref name="interface-options"/> > + </interleave> > + </group> > </choice> > </element> > </define> > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > index 8952b69..d8ab40c 100644 > --- a/src/conf/domain_conf.c > +++ b/src/conf/domain_conf.c > @@ -293,7 +293,8 @@ VIR_ENUM_IMPL(virDomainNet, VIR_DOMAIN_NET_TYPE_LAST, > "bridge", > "internal", > "direct", > - "hostdev") > + "hostdev", > + "hostdev-hybrid") > > VIR_ENUM_IMPL(virDomainNetBackend, VIR_DOMAIN_NET_BACKEND_TYPE_LAST, > "default", > @@ -1020,6 +1021,9 @@ virDomainActualNetDefFree(virDomainActualNetDefPtr def) > case VIR_DOMAIN_NET_TYPE_HOSTDEV: > virDomainHostdevDefClear(&def->data.hostdev.def); > break; > + case VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID: > + virDomainHostdevDefClear(&def->data.hostdev.def); > + break; might as well combine the above two cases. > default: > break; > } > @@ -1072,6 +1076,10 @@ void virDomainNetDefFree(virDomainNetDefPtr def) > virDomainHostdevDefClear(&def->data.hostdev.def); > break; > > + case VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID: > + virDomainHostdevDefClear(&def->data.hostdev.def); > + break; > + Same here I think (can't see all of the context) > case VIR_DOMAIN_NET_TYPE_USER: > case VIR_DOMAIN_NET_TYPE_LAST: > break; > @@ -1563,8 +1571,10 @@ void virDomainDefFree(virDomainDefPtr def) > * so the original object must still be available during the call > * to virDomainHostdevDefFree(). > */ > - for (i = 0 ; i < def->nhostdevs ; i++) > - virDomainHostdevDefFree(def->hostdevs[i]); > + for (i = 0 ; i < def->nhostdevs ; i++) { > + if (def->hostdevs[i]->ephemeral == 0) > + virDomainHostdevDefFree(def->hostdevs[i]); > + } > VIR_FREE(def->hostdevs); > > for (i = 0 ; i < def->nleases ; i++) > @@ -4525,6 +4535,7 @@ virDomainActualNetDefParseXML(xmlNodePtr node, > if (actual->type != VIR_DOMAIN_NET_TYPE_BRIDGE && > actual->type != VIR_DOMAIN_NET_TYPE_DIRECT && > actual->type != VIR_DOMAIN_NET_TYPE_HOSTDEV && > + actual->type != VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID && > actual->type != VIR_DOMAIN_NET_TYPE_NETWORK) { > virReportError(VIR_ERR_INTERNAL_ERROR, > _("unsupported type '%s' in interface's <actual> element"), > @@ -4536,7 +4547,8 @@ virDomainActualNetDefParseXML(xmlNodePtr node, > if (virtPortNode) { > if (actual->type == VIR_DOMAIN_NET_TYPE_BRIDGE || > actual->type == VIR_DOMAIN_NET_TYPE_DIRECT || > - actual->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) { > + actual->type == VIR_DOMAIN_NET_TYPE_HOSTDEV || > + actual->type == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID) { > /* the virtualport in <actual> should always already > * have an instanceid/interfaceid if its required, > * so don't let the parser generate one */ > @@ -4589,6 +4601,30 @@ virDomainActualNetDefParseXML(xmlNodePtr node, > hostdev, flags) < 0) { > goto error; > } > + } else if (actual->type == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID) { > + virDomainHostdevDefPtr hostdev = &actual->data.hostdev.def; > + > + hostdev->parent.type = VIR_DOMAIN_DEVICE_NONE; > + if (VIR_ALLOC(hostdev->info) < 0) { > + virReportOOMError(); > + goto error; > + } > + hostdev->ephemeral = 1; > + /* The helper function expects type to already be found and > + * passed in as a string, since it is in a different place in > + * NetDef vs HostdevDef. > + */ > + addrtype = virXPathString("string(./source/address/@type)", ctxt); > + /* if not explicitly stated, source/vendor implies usb device */ > + if (!addrtype && virXPathNode("./source/vendor", ctxt) && > + (addrtype = strdup("usb")) == NULL) { > + virReportOOMError(); > + goto error; > + } > + if (virDomainHostdevPartsParse(node, ctxt, NULL, addrtype, > + hostdev, flags) < 0) { > + goto error; > + } I've got a feeling a lot of this is common code with hostdev. Maybe you could refactor it to avoid duplicated code. > } > > bandwidth_node = virXPathNode("./bandwidth", ctxt); > @@ -4708,7 +4744,8 @@ virDomainNetDefParseXML(virCapsPtr caps, > } > } else if (def->type == VIR_DOMAIN_NET_TYPE_BRIDGE || > def->type == VIR_DOMAIN_NET_TYPE_DIRECT || > - def->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) { > + def->type == VIR_DOMAIN_NET_TYPE_HOSTDEV || > + def->type == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID) { > if (!(def->virtPortProfile > = virNetDevVPortProfileParse(cur, > VIR_VPORT_XML_GENERATE_MISSING_DEFAULTS| > @@ -4968,6 +5005,27 @@ virDomainNetDefParseXML(virCapsPtr caps, > } > break; > > + case VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID: > + hostdev = &def->data.hostdev.def; > + hostdev->parent.type = VIR_DOMAIN_DEVICE_NONE; > + if (VIR_ALLOC(hostdev->info) < 0) { > + virReportOOMError(); > + goto error; > + } > + hostdev->ephemeral = 1; > + addrtype = virXPathString("string(./source/address/@type)", ctxt); > + /* if not explicitly stated, source/vendor implies usb device */ > + if (!addrtype && virXPathNode("./source/vendor", ctxt) && > + ((addrtype = strdup("usb")) == NULL)) { > + virReportOOMError(); > + goto error; > + } > + if (virDomainHostdevPartsParse(node, ctxt, NULL, addrtype, > + hostdev, flags) < 0) { > + goto error; > + } > + break; > + > case VIR_DOMAIN_NET_TYPE_USER: > case VIR_DOMAIN_NET_TYPE_LAST: > break; > @@ -7609,7 +7667,8 @@ int virDomainNetInsert(virDomainDefPtr def, virDomainNetDefPtr net) > return -1; > def->nets[def->nnets] = net; > def->nnets++; > - if (net->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) { > + if ((net->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) || > + (net->type == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID)) { > /* hostdev net devices must also exist in the hostdevs array */ > return virDomainHostdevInsert(def, &net->data.hostdev.def); > } > @@ -7631,7 +7690,8 @@ virDomainNetRemove(virDomainDefPtr def, size_t i) > { > virDomainNetDefPtr net = def->nets[i]; > > - if (net->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) { > + if ((net->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) || > + (net->type == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID)) { > /* hostdev net devices are normally also be in the hostdevs > * array, but might have already been removed by the time we > * get here. > @@ -8995,8 +9055,10 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, > > def->nets[def->nnets++] = net; > > - /* <interface type='hostdev'> must also be in the hostdevs array */ > - if (net->type == VIR_DOMAIN_NET_TYPE_HOSTDEV && > + /* <interface type='hostdev' and 'hostdev-hybrid'> must also be in > + the hostdevs array */ > + if (((net->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) || > + (net->type == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID)) && > virDomainHostdevInsert(def, &net->data.hostdev.def) < 0) { > goto no_memory; > } > @@ -11941,7 +12003,8 @@ virDomainActualNetDefFormat(virBufferPtr buf, > } > > virBufferAsprintf(buf, "<actual type='%s'", type); > - if (def->type == VIR_DOMAIN_NET_TYPE_HOSTDEV && > + if ((def->type == VIR_DOMAIN_NET_TYPE_HOSTDEV || > + def->type == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID) && > def->data.hostdev.def.managed) { > virBufferAddLit(buf, " managed='yes'"); > } > @@ -11971,6 +12034,7 @@ virDomainActualNetDefFormat(virBufferPtr buf, > break; > > case VIR_DOMAIN_NET_TYPE_HOSTDEV: > + case VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID: > if (virDomainHostdevSourceFormat(buf, &def->data.hostdev.def, > flags, true) < 0) { > return -1; > @@ -12011,7 +12075,8 @@ virDomainNetDefFormat(virBufferPtr buf, > } > > virBufferAsprintf(buf, " <interface type='%s'", type); > - if (def->type == VIR_DOMAIN_NET_TYPE_HOSTDEV && > + if (((def->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) || > + (def->type == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID)) && > def->data.hostdev.def.managed) { > virBufferAddLit(buf, " managed='yes'"); > } > @@ -12078,6 +12143,7 @@ virDomainNetDefFormat(virBufferPtr buf, > break; > > case VIR_DOMAIN_NET_TYPE_HOSTDEV: > + case VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID: > if (virDomainHostdevSourceFormat(buf, &def->data.hostdev.def, > flags, true) < 0) { > return -1; > @@ -14620,10 +14686,12 @@ virDomainNetGetActualDirectMode(virDomainNetDefPtr iface) > virDomainHostdevDefPtr > virDomainNetGetActualHostdev(virDomainNetDefPtr iface) > { > - if (iface->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) > + if ((iface->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) || > + (iface->type == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID)) > return &iface->data.hostdev.def; > if (iface->type == VIR_DOMAIN_NET_TYPE_NETWORK && > - iface->data.network.actual->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) { > + (iface->data.network.actual->type == VIR_DOMAIN_NET_TYPE_HOSTDEV || > + iface->data.network.actual->type == VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID)){ > return &iface->data.network.actual->data.hostdev.def; > } > return NULL; > @@ -14636,6 +14704,7 @@ virDomainNetGetActualVirtPortProfile(virDomainNetDefPtr iface) > case VIR_DOMAIN_NET_TYPE_DIRECT: > case VIR_DOMAIN_NET_TYPE_BRIDGE: > case VIR_DOMAIN_NET_TYPE_HOSTDEV: > + case VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID: > return iface->virtPortProfile; > case VIR_DOMAIN_NET_TYPE_NETWORK: > if (!iface->data.network.actual) > @@ -14644,6 +14713,7 @@ virDomainNetGetActualVirtPortProfile(virDomainNetDefPtr iface) > case VIR_DOMAIN_NET_TYPE_DIRECT: > case VIR_DOMAIN_NET_TYPE_BRIDGE: > case VIR_DOMAIN_NET_TYPE_HOSTDEV: > + case VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID: > return iface->data.network.actual->virtPortProfile; > default: > return NULL; > diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h > index 3995c2d..156eb32 100644 > --- a/src/conf/domain_conf.h > +++ b/src/conf/domain_conf.h > @@ -378,6 +378,7 @@ struct _virDomainHostdevDef { > virDomainDeviceDef parent; /* higher level Def containing this */ > int mode; /* enum virDomainHostdevMode */ > unsigned int managed : 1; > + unsigned int ephemeral : 1; I'm not sure why managed was defined as a bitfield, but these days we're more inclined to use bool > union { > virDomainHostdevSubsys subsys; > struct { > @@ -727,6 +728,7 @@ enum virDomainNetType { > VIR_DOMAIN_NET_TYPE_INTERNAL, > VIR_DOMAIN_NET_TYPE_DIRECT, > VIR_DOMAIN_NET_TYPE_HOSTDEV, > + VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID, > > VIR_DOMAIN_NET_TYPE_LAST, > }; > diff --git a/src/uml/uml_conf.c b/src/uml/uml_conf.c > index 410f3e2..edea034 100644 > --- a/src/uml/uml_conf.c > +++ b/src/uml/uml_conf.c > @@ -261,6 +261,11 @@ umlBuildCommandLineNet(virConnectPtr conn, > _("hostdev networking type not supported")); > goto error; > > + case VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID: > + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("hostdev-hybrid networking type not supported")); > + goto error; > + > case VIR_DOMAIN_NET_TYPE_LAST: > break; > } > diff --git a/src/xenxs/xen_sxpr.c b/src/xenxs/xen_sxpr.c > index 8bb3849..c94b787 100644 > --- a/src/xenxs/xen_sxpr.c > +++ b/src/xenxs/xen_sxpr.c > @@ -1987,6 +1987,7 @@ xenFormatSxprNet(virConnectPtr conn, > case VIR_DOMAIN_NET_TYPE_INTERNAL: > case VIR_DOMAIN_NET_TYPE_DIRECT: > case VIR_DOMAIN_NET_TYPE_HOSTDEV: > + case VIR_DOMAIN_NET_TYPE_HOSTDEV_HYBRID: > case VIR_DOMAIN_NET_TYPE_LAST: > break; > } > diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-hostdevhybrid.args b/tests/qemuxml2argvdata/qemuxml2argv-net-hostdevhybrid.args > new file mode 100644 > index 0000000..a4c50d1 > --- /dev/null > +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-hostdevhybrid.args > @@ -0,0 +1,8 @@ > +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 \ > +-device rtl8139,vlan=0,id=net0,mac=00:11:22:33:44:55,bus=pci.0,addr=0x3 \ > +-net user,vlan=0,name=hostnet0 -usb \ > +-device pci-assign,host=03:07.1,id=hostdev0,bus=pci.0,addr=0x4 \ > +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5 > diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-hostdevhybrid.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-hostdevhybrid.xml > new file mode 100644 > index 0000000..dcf3fd1 > --- /dev/null > +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-hostdevhybrid.xml > @@ -0,0 +1,35 @@ > +<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> > + <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' target='0' unit='0'/> > + </disk> > + <controller type='usb' index='0'/> > + <controller type='ide' index='0'/> > + <interface type='hostdev-hybrid' managed='yes'> > + <mac address='00:11:22:33:44:55'/> > + <source> > + <address type='pci' domain='0x0002' bus='0x03' slot='0x07' function='0x1'/> > + </source> > + <virtualport type='802.1Qbg'> > + <parameters managerid='11' typeid='1193047' typeidversion='2' instanceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/> > + </virtualport> > + </interface> > + <memballoon model='virtio'/> > + </devices> > +</domain> > diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c > index 47c3f6c..4155352 100644 > --- a/tests/qemuxml2argvtest.c > +++ b/tests/qemuxml2argvtest.c > @@ -576,6 +576,8 @@ mymain(void) > DO_TEST("net-mcast", NONE); > DO_TEST("net-hostdev", > QEMU_CAPS_PCIDEVICE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG); > + DO_TEST("net-hostdevhybrid", > + QEMU_CAPS_PCIDEVICE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG); > > DO_TEST("serial-vc", NONE); > DO_TEST("serial-pty", NONE); > diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-hostdevhybrid.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-hostdevhybrid.xml > new file mode 100644 > index 0000000..5ab9ed3 > --- /dev/null > +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-net-hostdevhybrid.xml > @@ -0,0 +1,40 @@ > +<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> > + <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' target='0' unit='0'/> > + </disk> > + <controller type='usb' index='0'/> > + <controller type='ide' index='0'/> > + <interface type='hostdev-hybrid' managed='yes'> > + <mac address='00:11:22:33:44:55'/> > + <source> > + <address type='pci' domain='0x0002' bus='0x03' slot='0x07' function='0x1'/> > + </source> > + <virtualport type='802.1Qbg'> > + <parameters managerid='11' typeid='1193047' typeidversion='2' instanceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/> > + </virtualport> > + </interface> > + <hostdev mode='subsystem' type='pci' managed='yes'> > + <source> > + <address domain='0x0002' bus='0x03' slot='0x07' function='0x1'/> > + </source> > + </hostdev> > + <memballoon model='virtio'/> > + </devices> > +</domain> > diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c > index 87d9e77..73846e2 100644 > --- a/tests/qemuxml2xmltest.c > +++ b/tests/qemuxml2xmltest.c > @@ -181,6 +181,7 @@ mymain(void) > DO_TEST("net-eth-ifname"); > DO_TEST("net-virtio-network-portgroup"); > DO_TEST("net-hostdev"); > + DO_TEST_DIFFERENT("net-hostdevhybrid"); > DO_TEST("net-openvswitch"); > DO_TEST("sound"); > DO_TEST("sound-device"); -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list