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>
+ </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;
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;
+
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;
+ }
}
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;
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");
--
1.7.4.4