Xen HVM guests with PV drivers end up with two network interfaces for
each configured interface. One of them being emulated by qemu and the
other one paravirtual. As this might not be desirable, the attached
patch provides a way for users to specify that only paravirtual network
interface should be presented to the guest.
The configuration was inspired by qemu/kvm driver, for which users can
specify model='virtio' to use paravirtual network interface.
The patch adds support for model='xenpv' which results in type=xenpv
instead of type=ioemu (or nothing for newer xen versions) in guests
native configuration. Xen's qemu ignores interfaces with type != ioemu
and only paravirtual network device will be seen in the guest.
A possible addition to this would be to force type=ioemu for all other
models which would result in only emulated network device to be provided
for an HVM guest on xen newer then XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU.
No type would be configured when model is missing in domains XML.
If you think this is a good idea, I'll prepare a second version of the
patch.
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
src/xen/xend_internal.c | 25 +++++++++++++++++--------
src/xen/xm_internal.c | 19 ++++++++++++++-----
2 files changed, 31 insertions(+), 13 deletions(-)
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
index e370eb8..9ea59c7 100644
--- a/src/xen/xend_internal.c
+++ b/src/xen/xend_internal.c
@@ -5427,6 +5427,7 @@ xenDaemonFormatSxprNet(virConnectPtr conn,
int isAttach)
{
const char *script = DEFAULT_VIF_SCRIPT;
+ int pv_only = 0;
if (def->type != VIR_DOMAIN_NET_TYPE_BRIDGE &&
def->type != VIR_DOMAIN_NET_TYPE_NETWORK &&
@@ -5495,15 +5496,23 @@ xenDaemonFormatSxprNet(virConnectPtr conn,
!STRPREFIX(def->ifname, "vif"))
virBufferVSprintf(buf, "(vifname '%s')", def->ifname);
- if (def->model != NULL)
- virBufferVSprintf(buf, "(model '%s')", def->model);
+ if (def->model != NULL) {
+ if (hvm && STREQ(def->model, "xenpv"))
+ pv_only = 1;
+ else
+ virBufferVSprintf(buf, "(model '%s')", def->model);
+ }
- /*
- * apparently (type ioemu) breaks paravirt drivers on HVM so skip this
- * from Xen 3.1.0
- */
- if (hvm && xendConfigVersion <= XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU)
- virBufferAddLit(buf, "(type ioemu)");
+ if (pv_only)
+ virBufferAddLit(buf, "(type xenpv)");
+ else {
+ /*
+ * apparently (type ioemu) breaks paravirt drivers on HVM so skip this
+ * from Xen 3.1.0
+ */
+ if (hvm && xendConfigVersion <= XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU)
+ virBufferAddLit(buf, "(type ioemu)");
+ }
if (!isAttach)
virBufferAddLit(buf, ")");
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
index 40c1996..fe4bcbd 100644
--- a/src/xen/xm_internal.c
+++ b/src/xen/xm_internal.c
@@ -2041,6 +2041,7 @@ static int xenXMDomainConfigFormatNet(virConnectPtr conn,
virConfValuePtr val, tmp;
char *str;
xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData;
+ int pv_only = 0;
virBufferVSprintf(&buf, "mac=%02x:%02x:%02x:%02x:%02x:%02x",
net->mac[0], net->mac[1],
@@ -2092,12 +2093,20 @@ static int xenXMDomainConfigFormatNet(virConnectPtr conn,
goto cleanup;
}
- if (hvm && priv->xendConfigVersion <=
XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU)
- virBufferAddLit(&buf, ",type=ioemu");
+ if (net->model) {
+ if (hvm && STREQ(net->model, "xenpv"))
+ pv_only = 1;
+ else
+ virBufferVSprintf(&buf, ",model=%s",
+ net->model);
+ }
- if (net->model)
- virBufferVSprintf(&buf, ",model=%s",
- net->model);
+ if (pv_only)
+ virBufferAddLit(&buf, ",type=xenpv");
+ else {
+ if (hvm && priv->xendConfigVersion <=
XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU)
+ virBufferAddLit(&buf, ",type=ioemu");
+ }
if (net->ifname)
virBufferVSprintf(&buf, ",vifname=%s",
--
1.6.5.3