提交 dddad4bc 编写于 作者: J Jiri Denemark 提交者: Daniel Veillard

Support for interface model='netfront'

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='netfront' which results in
type=netfront 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.

Four possible configuration scenarios follow:

- no model specified in domain's XML
    - libvirt will behave like before this change; it will set
      type=ioemu for HVM guests on xen host which is not newer than
      XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU
    - covered by existing tests

- PV guest, any model
    - no functional change, model is passed as is (and ignored by the
      hypervisor)
    - covered by existing tests (e.g., *-net-e1000.*)
- HVM guest, model=netfront
    - type is set to "netfront", model is not specified
    - covered by new *-net-netfront.* tests

- HVM guest, model != netfront
    - type is set to "ioemu", model is passed as is
    - covered by new *-net-ioemu.* tests

The fourth scenario feels like a regression for xen newer than
XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU as users who had a model specified
in their guest's configuration won't see a paravirtual interface in
their guests any more. On the other hand, the reason for specifying a
model is most likely the fact that they want to use such model which
implies emulated interface. Users of older xen won't be affected at all
as their xen provides paravirtual interface regardless of the type used.

- src/xen/xend_internal.c: add netfront support for the xend backend
- src/xen/xm_internal.c: add netfront support for the XM serialization too
上级 834d6547
...@@ -1770,11 +1770,12 @@ xenDaemonParseSxprNets(virConnectPtr conn, ...@@ -1770,11 +1770,12 @@ xenDaemonParseSxprNets(virConnectPtr conn,
for (cur = root; cur->kind == SEXPR_CONS; cur = cur->u.s.cdr) { for (cur = root; cur->kind == SEXPR_CONS; cur = cur->u.s.cdr) {
node = cur->u.s.car; node = cur->u.s.car;
if (sexpr_lookup(node, "device/vif")) { if (sexpr_lookup(node, "device/vif")) {
const char *tmp2, *model; const char *tmp2, *model, *type;
char buf[50]; char buf[50];
tmp2 = sexpr_node(node, "device/vif/script"); tmp2 = sexpr_node(node, "device/vif/script");
tmp = sexpr_node(node, "device/vif/bridge"); tmp = sexpr_node(node, "device/vif/bridge");
model = sexpr_node(node, "device/vif/model"); model = sexpr_node(node, "device/vif/model");
type = sexpr_node(node, "device/vif/type");
if (VIR_ALLOC(net) < 0) if (VIR_ALLOC(net) < 0)
goto no_memory; goto no_memory;
...@@ -1841,6 +1842,11 @@ xenDaemonParseSxprNets(virConnectPtr conn, ...@@ -1841,6 +1842,11 @@ xenDaemonParseSxprNets(virConnectPtr conn,
!(net->model = strdup(model))) !(net->model = strdup(model)))
goto no_memory; goto no_memory;
if (!model && type &&
STREQ(type, "netfront") &&
!(net->model = strdup("netfront")))
goto no_memory;
if (VIR_REALLOC_N(def->nets, def->nnets + 1) < 0) if (VIR_REALLOC_N(def->nets, def->nnets + 1) < 0)
goto no_memory; goto no_memory;
...@@ -5500,15 +5506,25 @@ xenDaemonFormatSxprNet(virConnectPtr conn, ...@@ -5500,15 +5506,25 @@ xenDaemonFormatSxprNet(virConnectPtr conn,
!STRPREFIX(def->ifname, "vif")) !STRPREFIX(def->ifname, "vif"))
virBufferVSprintf(buf, "(vifname '%s')", def->ifname); virBufferVSprintf(buf, "(vifname '%s')", def->ifname);
if (def->model != NULL) if (!hvm) {
if (def->model != NULL)
virBufferVSprintf(buf, "(model '%s')", def->model);
}
else if (def->model == NULL) {
/*
* apparently (type ioemu) breaks paravirt drivers on HVM so skip
* this from XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU
*/
if (xendConfigVersion <= XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU)
virBufferAddLit(buf, "(type ioemu)");
}
else if (STREQ(def->model, "netfront")) {
virBufferAddLit(buf, "(type netfront)");
}
else {
virBufferVSprintf(buf, "(model '%s')", def->model); 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)"); virBufferAddLit(buf, "(type ioemu)");
}
if (!isAttach) if (!isAttach)
virBufferAddLit(buf, ")"); virBufferAddLit(buf, ")");
......
...@@ -1020,6 +1020,7 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) { ...@@ -1020,6 +1020,7 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
while (list) { while (list) {
char script[PATH_MAX]; char script[PATH_MAX];
char model[10]; char model[10];
char type[10];
char ip[16]; char ip[16];
char mac[18]; char mac[18];
char bridge[50]; char bridge[50];
...@@ -1031,6 +1032,7 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) { ...@@ -1031,6 +1032,7 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
script[0] = '\0'; script[0] = '\0';
ip[0] = '\0'; ip[0] = '\0';
model[0] = '\0'; model[0] = '\0';
type[0] = '\0';
vifname[0] = '\0'; vifname[0] = '\0';
if ((list->type != VIR_CONF_STRING) || (list->str == NULL)) if ((list->type != VIR_CONF_STRING) || (list->str == NULL))
...@@ -1076,6 +1078,13 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) { ...@@ -1076,6 +1078,13 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
_("Model %s too big for destination"), data); _("Model %s too big for destination"), data);
goto skipnic; goto skipnic;
} }
} else if (STRPREFIX(key, "type=")) {
int len = nextkey ? (nextkey - data) : sizeof(type) - 1;
if (virStrncpy(type, data, len, sizeof(type)) == NULL) {
xenXMError(conn, VIR_ERR_INTERNAL_ERROR,
_("Type %s too big for destination"), data);
goto skipnic;
}
} else if (STRPREFIX(key, "vifname=")) { } else if (STRPREFIX(key, "vifname=")) {
int len = nextkey ? (nextkey - data) : sizeof(vifname) - 1; int len = nextkey ? (nextkey - data) : sizeof(vifname) - 1;
if (virStrncpy(vifname, data, len, sizeof(vifname)) == NULL) { if (virStrncpy(vifname, data, len, sizeof(vifname)) == NULL) {
...@@ -1145,10 +1154,16 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) { ...@@ -1145,10 +1154,16 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
!(net->data.ethernet.ipaddr = strdup(ip))) !(net->data.ethernet.ipaddr = strdup(ip)))
goto no_memory; goto no_memory;
} }
if (model[0] && if (model[0] &&
!(net->model = strdup(model))) !(net->model = strdup(model)))
goto no_memory; goto no_memory;
if (!model[0] && type[0] &&
STREQ(type, "netfront") &&
!(net->model = strdup("netfront")))
goto no_memory;
if (vifname[0] && if (vifname[0] &&
!(net->ifname = strdup(vifname))) !(net->ifname = strdup(vifname)))
goto no_memory; goto no_memory;
...@@ -2092,12 +2107,25 @@ static int xenXMDomainConfigFormatNet(virConnectPtr conn, ...@@ -2092,12 +2107,25 @@ static int xenXMDomainConfigFormatNet(virConnectPtr conn,
goto cleanup; goto cleanup;
} }
if (hvm && priv->xendConfigVersion <= XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU) if (!hvm) {
if (net->model != NULL)
virBufferVSprintf(&buf, ",model=%s", net->model);
}
else if (net->model == NULL) {
/*
* apparently type ioemu breaks paravirt drivers on HVM so skip this
* from XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU
*/
if (priv->xendConfigVersion <= XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU)
virBufferAddLit(&buf, ",type=ioemu");
}
else if (STREQ(net->model, "netfront")) {
virBufferAddLit(&buf, ",type=netfront");
}
else {
virBufferVSprintf(&buf, ",model=%s", net->model);
virBufferAddLit(&buf, ",type=ioemu"); virBufferAddLit(&buf, ",type=ioemu");
}
if (net->model)
virBufferVSprintf(&buf, ",model=%s",
net->model);
if (net->ifname) if (net->ifname)
virBufferVSprintf(&buf, ",vifname=%s", virBufferVSprintf(&buf, ",vifname=%s",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册