Currently, an interface's vlan number corresponds to its index in
the table of network interfaces. That is no longer true when we
allow devices to be removed.
To fix this, we store the vlan number in the domain's state XML
so that it survives libvirtd restarts.
* src/domain_conf.h: add vlan number to virDomainNetDef
* src/domain_conf.c: store it in XML as <state vlan='N'/>, defaulting
to -1 if this is state saved by a previous version of libvirt
* src/qemu_conf.c: assign vlan numbers before starting qemu
---
src/domain_conf.c | 12 ++++++++++++
src/domain_conf.h | 1 +
src/qemu_conf.c | 7 +++++--
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/src/domain_conf.c b/src/domain_conf.c
index 2b4fe90..cce863c 100644
--- a/src/domain_conf.c
+++ b/src/domain_conf.c
@@ -954,6 +954,7 @@ virDomainNetDefParseXML(virConnectPtr conn,
char *internal = NULL;
char *nic_name = NULL;
char *hostnet_name = NULL;
+ char *vlan = NULL;
if (VIR_ALLOC(def) < 0) {
virReportOOMError(conn);
@@ -1023,6 +1024,7 @@ virDomainNetDefParseXML(virConnectPtr conn,
xmlStrEqual(cur->name, BAD_CAST "state")) {
nic_name = virXMLPropString(cur, "nic");
hostnet_name = virXMLPropString(cur, "hostnet");
+ vlan = virXMLPropString(cur, "vlan");
}
}
cur = cur->next;
@@ -1038,6 +1040,13 @@ virDomainNetDefParseXML(virConnectPtr conn,
def->hostnet_name = hostnet_name;
nic_name = hostnet_name = NULL;
+ def->vlan = -1;
+ if (vlan && virStrToLong_i(vlan, NULL, 10, &def->vlan) < 0) {
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Cannot parse <state> 'vlan'
attribute"));
+ goto error;
+ }
+
switch (def->type) {
case VIR_DOMAIN_NET_TYPE_NETWORK:
if (network == NULL) {
@@ -1159,6 +1168,7 @@ cleanup:
VIR_FREE(internal);
VIR_FREE(nic_name);
VIR_FREE(hostnet_name);
+ VIR_FREE(vlan);
return def;
@@ -3614,6 +3624,8 @@ virDomainNetDefFormat(virConnectPtr conn,
virBufferEscapeString(buf, " nic='%s'", def->nic_name);
if (def->hostnet_name)
virBufferEscapeString(buf, " hostnet='%s'",
def->hostnet_name);
+ if (def->vlan > 0)
+ virBufferVSprintf(buf, " vlan='%d'", def->vlan);
virBufferAddLit(buf, "/>\n");
}
diff --git a/src/domain_conf.h b/src/domain_conf.h
index 1e30107..8fa384a 100644
--- a/src/domain_conf.h
+++ b/src/domain_conf.h
@@ -177,6 +177,7 @@ struct _virDomainNetDef {
char *ifname;
char *nic_name;
char *hostnet_name;
+ int vlan;
};
enum virDomainChrSrcType {
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index 0362d76..6d876cb 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -1535,11 +1535,13 @@ int qemudBuildCommandLine(virConnectPtr conn,
char *nic, *host;
int tapfd = -1;
+ net->vlan = i;
+
if ((qemuCmdFlags & QEMUD_CMD_FLAG_NET_NAME) &&
qemuAssignNetNames(def, net) < 0)
goto no_memory;
- if (qemuBuildNicStr(conn, net, NULL, ',', i, &nic) < 0)
+ if (qemuBuildNicStr(conn, net, NULL, ',', net->vlan, &nic)
< 0)
goto error;
ADD_ARG_LIT("-net");
@@ -1565,7 +1567,8 @@ int qemudBuildCommandLine(virConnectPtr conn,
(*tapfds)[(*ntapfds)++] = tapfd;
}
- if (qemuBuildHostNetStr(conn, net, NULL, ',', i, tapfd, &host)
< 0)
+ if (qemuBuildHostNetStr(conn, net, NULL, ',',
+ net->vlan, tapfd, &host) < 0)
goto error;
ADD_ARG_LIT("-net");
--
1.6.2.5