[libvirt] [PATCH 1/8] RNG updates, new xml parser/formatter code for interface type=hostdev-hybrid
Laine Stump
laine at laine.org
Thu Sep 13 15:51:59 UTC 2012
(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");
More information about the libvir-list
mailing list