conf: move virtPortProfile out of unions in virDomainNetDef

virtPortProfile is now used by 4 different types of network devices
(NETWORK, BRIDGE, DIRECT, and HOSTDEV), and it's getting cumbersome to
replicate so much code in 4 different places just because each type
has the virtPortProfile in a slightly different place. This patch puts
a single virtPortProfile in a common place (outside the type-specific
union) in both virDomainNetDef and virDomainActualNetDef, and adjusts
the parse and format code (and the few other places where it is used)
accordingly.

Note that when a <virtualport> element is found, the parse functions
verify that the interface is of a type that supports one, otherwise an
error is generated (CONFIG_UNSUPPORTED in the case of <interface>, and
INTERNAL in the case of <actual>, since the contents of <actual> are
always generated by libvirt itself).
This commit is contained in:
Laine Stump 2012-07-30 02:03:25 -04:00
parent 1c02ed1421
commit 1d1744285b
5 changed files with 63 additions and 109 deletions

View File

@ -1017,20 +1017,18 @@ virDomainActualNetDefFree(virDomainActualNetDefPtr def)
switch (def->type) { switch (def->type) {
case VIR_DOMAIN_NET_TYPE_BRIDGE: case VIR_DOMAIN_NET_TYPE_BRIDGE:
VIR_FREE(def->data.bridge.brname); VIR_FREE(def->data.bridge.brname);
VIR_FREE(def->data.bridge.virtPortProfile);
break; break;
case VIR_DOMAIN_NET_TYPE_DIRECT: case VIR_DOMAIN_NET_TYPE_DIRECT:
VIR_FREE(def->data.direct.linkdev); VIR_FREE(def->data.direct.linkdev);
VIR_FREE(def->data.direct.virtPortProfile);
break; break;
case VIR_DOMAIN_NET_TYPE_HOSTDEV: case VIR_DOMAIN_NET_TYPE_HOSTDEV:
virDomainHostdevDefClear(&def->data.hostdev.def); virDomainHostdevDefClear(&def->data.hostdev.def);
VIR_FREE(def->data.hostdev.virtPortProfile);
break; break;
default: default:
break; break;
} }
VIR_FREE(def->virtPortProfile);
virNetDevBandwidthFree(def->bandwidth); virNetDevBandwidthFree(def->bandwidth);
VIR_FREE(def); VIR_FREE(def);
@ -1058,14 +1056,12 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
case VIR_DOMAIN_NET_TYPE_NETWORK: case VIR_DOMAIN_NET_TYPE_NETWORK:
VIR_FREE(def->data.network.name); VIR_FREE(def->data.network.name);
VIR_FREE(def->data.network.portgroup); VIR_FREE(def->data.network.portgroup);
VIR_FREE(def->data.network.virtPortProfile);
virDomainActualNetDefFree(def->data.network.actual); virDomainActualNetDefFree(def->data.network.actual);
break; break;
case VIR_DOMAIN_NET_TYPE_BRIDGE: case VIR_DOMAIN_NET_TYPE_BRIDGE:
VIR_FREE(def->data.bridge.brname); VIR_FREE(def->data.bridge.brname);
VIR_FREE(def->data.bridge.ipaddr); VIR_FREE(def->data.bridge.ipaddr);
VIR_FREE(def->data.bridge.virtPortProfile);
break; break;
case VIR_DOMAIN_NET_TYPE_INTERNAL: case VIR_DOMAIN_NET_TYPE_INTERNAL:
@ -1074,12 +1070,10 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
case VIR_DOMAIN_NET_TYPE_DIRECT: case VIR_DOMAIN_NET_TYPE_DIRECT:
VIR_FREE(def->data.direct.linkdev); VIR_FREE(def->data.direct.linkdev);
VIR_FREE(def->data.direct.virtPortProfile);
break; break;
case VIR_DOMAIN_NET_TYPE_HOSTDEV: case VIR_DOMAIN_NET_TYPE_HOSTDEV:
virDomainHostdevDefClear(&def->data.hostdev.def); virDomainHostdevDefClear(&def->data.hostdev.def);
VIR_FREE(def->data.hostdev.virtPortProfile);
break; break;
case VIR_DOMAIN_NET_TYPE_USER: case VIR_DOMAIN_NET_TYPE_USER:
@ -1087,6 +1081,7 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
break; break;
} }
VIR_FREE(def->virtPortProfile);
VIR_FREE(def->script); VIR_FREE(def->script);
VIR_FREE(def->ifname); VIR_FREE(def->ifname);
@ -4370,6 +4365,7 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
int ret = -1; int ret = -1;
xmlNodePtr save_ctxt = ctxt->node; xmlNodePtr save_ctxt = ctxt->node;
xmlNodePtr bandwidth_node = NULL; xmlNodePtr bandwidth_node = NULL;
xmlNodePtr virtPortNode;
char *type = NULL; char *type = NULL;
char *mode = NULL; char *mode = NULL;
char *addrtype = NULL; char *addrtype = NULL;
@ -4402,15 +4398,24 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
goto error; goto error;
} }
if (actual->type == VIR_DOMAIN_NET_TYPE_BRIDGE) { virtPortNode = virXPathNode("./virtualport", ctxt);
xmlNodePtr virtPortNode = virXPathNode("./virtualport", ctxt); if (virtPortNode) {
if (virtPortNode && if (actual->type == VIR_DOMAIN_NET_TYPE_BRIDGE ||
(!(actual->data.bridge.virtPortProfile = actual->type == VIR_DOMAIN_NET_TYPE_DIRECT ||
virNetDevVPortProfileParse(virtPortNode)))) actual->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
if (!(actual->virtPortProfile
= virNetDevVPortProfileParse(virtPortNode))) {
goto error;
}
} else {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("<virtualport> element unsupported for type='%s'"
" in interface's <actual> element"), type);
goto error; goto error;
} else if (actual->type == VIR_DOMAIN_NET_TYPE_DIRECT) { }
xmlNodePtr virtPortNode; }
if (actual->type == VIR_DOMAIN_NET_TYPE_DIRECT) {
actual->data.direct.linkdev = virXPathString("string(./source[1]/@dev)", ctxt); actual->data.direct.linkdev = virXPathString("string(./source[1]/@dev)", ctxt);
mode = virXPathString("string(./source[1]/@mode)", ctxt); mode = virXPathString("string(./source[1]/@mode)", ctxt);
@ -4424,14 +4429,7 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
} }
actual->data.direct.mode = m; actual->data.direct.mode = m;
} }
virtPortNode = virXPathNode("./virtualport", ctxt);
if (virtPortNode &&
(!(actual->data.direct.virtPortProfile =
virNetDevVPortProfileParse(virtPortNode))))
goto error;
} else if (actual->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) { } else if (actual->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
xmlNodePtr virtPortNode = virXPathNode("./virtualport", ctxt);
virDomainHostdevDefPtr hostdev = &actual->data.hostdev.def; virDomainHostdevDefPtr hostdev = &actual->data.hostdev.def;
hostdev->parent.type = VIR_DOMAIN_DEVICE_NET; hostdev->parent.type = VIR_DOMAIN_DEVICE_NET;
@ -4452,12 +4450,6 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
hostdev, flags) < 0) { hostdev, flags) < 0) {
goto error; goto error;
} }
if (virtPortNode &&
(!(actual->data.hostdev.virtPortProfile =
virNetDevVPortProfileParse(virtPortNode)))) {
goto error;
}
} }
bandwidth_node = virXPathNode("./bandwidth", ctxt); bandwidth_node = virXPathNode("./bandwidth", ctxt);
@ -4517,7 +4509,6 @@ virDomainNetDefParseXML(virCapsPtr caps,
char *linkstate = NULL; char *linkstate = NULL;
char *addrtype = NULL; char *addrtype = NULL;
virNWFilterHashTablePtr filterparams = NULL; virNWFilterHashTablePtr filterparams = NULL;
virNetDevVPortProfilePtr virtPort = NULL;
virDomainActualNetDefPtr actual = NULL; virDomainActualNetDefPtr actual = NULL;
xmlNodePtr oldnode = ctxt->node; xmlNodePtr oldnode = ctxt->node;
int ret; int ret;
@ -4564,14 +4555,22 @@ virDomainNetDefParseXML(virCapsPtr caps,
xmlStrEqual(cur->name, BAD_CAST "source")) { xmlStrEqual(cur->name, BAD_CAST "source")) {
dev = virXMLPropString(cur, "dev"); dev = virXMLPropString(cur, "dev");
mode = virXMLPropString(cur, "mode"); mode = virXMLPropString(cur, "mode");
} else if (!virtPort && } else if (!def->virtPortProfile
(def->type == VIR_DOMAIN_NET_TYPE_DIRECT || && xmlStrEqual(cur->name, BAD_CAST "virtualport")) {
def->type == VIR_DOMAIN_NET_TYPE_NETWORK || if (def->type == VIR_DOMAIN_NET_TYPE_NETWORK ||
def->type == VIR_DOMAIN_NET_TYPE_BRIDGE || def->type == VIR_DOMAIN_NET_TYPE_BRIDGE ||
def->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) && def->type == VIR_DOMAIN_NET_TYPE_DIRECT ||
xmlStrEqual(cur->name, BAD_CAST "virtualport")) { def->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
if (!(virtPort = virNetDevVPortProfileParse(cur))) if (!(def->virtPortProfile
= virNetDevVPortProfileParse(cur))) {
goto error;
}
} else {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("<virtualport> element unsupported for"
" <interface type='%s'>"), type);
goto error; goto error;
}
} else if (!network && } else if (!network &&
(def->type == VIR_DOMAIN_NET_TYPE_SERVER || (def->type == VIR_DOMAIN_NET_TYPE_SERVER ||
def->type == VIR_DOMAIN_NET_TYPE_CLIENT || def->type == VIR_DOMAIN_NET_TYPE_CLIENT ||
@ -4688,8 +4687,6 @@ virDomainNetDefParseXML(virCapsPtr caps,
network = NULL; network = NULL;
def->data.network.portgroup = portgroup; def->data.network.portgroup = portgroup;
portgroup = NULL; portgroup = NULL;
def->data.network.virtPortProfile = virtPort;
virtPort = NULL;
def->data.network.actual = actual; def->data.network.actual = actual;
actual = NULL; actual = NULL;
break; break;
@ -4718,8 +4715,6 @@ virDomainNetDefParseXML(virCapsPtr caps,
def->data.bridge.ipaddr = address; def->data.bridge.ipaddr = address;
address = NULL; address = NULL;
} }
def->data.bridge.virtPortProfile = virtPort;
virtPort = NULL;
break; break;
case VIR_DOMAIN_NET_TYPE_CLIENT: case VIR_DOMAIN_NET_TYPE_CLIENT:
@ -4783,8 +4778,6 @@ virDomainNetDefParseXML(virCapsPtr caps,
def->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_VEPA; def->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_VEPA;
} }
def->data.direct.virtPortProfile = virtPort;
virtPort = NULL;
def->data.direct.linkdev = dev; def->data.direct.linkdev = dev;
dev = NULL; dev = NULL;
@ -4813,8 +4806,6 @@ virDomainNetDefParseXML(virCapsPtr caps,
hostdev, flags) < 0) { hostdev, flags) < 0) {
goto error; goto error;
} }
def->data.hostdev.virtPortProfile = virtPort;
virtPort = NULL;
break; break;
case VIR_DOMAIN_NET_TYPE_USER: case VIR_DOMAIN_NET_TYPE_USER:
@ -4937,7 +4928,6 @@ cleanup:
VIR_FREE(port); VIR_FREE(port);
VIR_FREE(ifname); VIR_FREE(ifname);
VIR_FREE(dev); VIR_FREE(dev);
VIR_FREE(virtPort);
virDomainActualNetDefFree(actual); virDomainActualNetDefFree(actual);
VIR_FREE(script); VIR_FREE(script);
VIR_FREE(bridge); VIR_FREE(bridge);
@ -11581,12 +11571,6 @@ virDomainActualNetDefFormat(virBufferPtr buf,
case VIR_DOMAIN_NET_TYPE_BRIDGE: case VIR_DOMAIN_NET_TYPE_BRIDGE:
virBufferEscapeString(buf, " <source bridge='%s'/>\n", virBufferEscapeString(buf, " <source bridge='%s'/>\n",
def->data.bridge.brname); def->data.bridge.brname);
if (def->data.bridge.virtPortProfile) {
virBufferAdjustIndent(buf, 6);
if (virNetDevVPortProfileFormat(def->data.bridge.virtPortProfile, buf) < 0)
return -1;
virBufferAdjustIndent(buf, -6);
}
break; break;
case VIR_DOMAIN_NET_TYPE_DIRECT: case VIR_DOMAIN_NET_TYPE_DIRECT:
@ -11603,10 +11587,6 @@ virDomainActualNetDefFormat(virBufferPtr buf,
return ret; return ret;
} }
virBufferAsprintf(buf, " mode='%s'/>\n", mode); virBufferAsprintf(buf, " mode='%s'/>\n", mode);
virBufferAdjustIndent(buf, 8);
if (virNetDevVPortProfileFormat(def->data.direct.virtPortProfile, buf) < 0)
goto error;
virBufferAdjustIndent(buf, -8);
break; break;
case VIR_DOMAIN_NET_TYPE_HOSTDEV: case VIR_DOMAIN_NET_TYPE_HOSTDEV:
@ -11615,10 +11595,6 @@ virDomainActualNetDefFormat(virBufferPtr buf,
flags, true) < 0) { flags, true) < 0) {
return -1; return -1;
} }
if (virNetDevVPortProfileFormat(def->data.hostdev.virtPortProfile,
buf) < 0) {
return -1;
}
virBufferAdjustIndent(buf, -8); virBufferAdjustIndent(buf, -8);
break; break;
@ -11631,6 +11607,8 @@ virDomainActualNetDefFormat(virBufferPtr buf,
} }
virBufferAdjustIndent(buf, 8); virBufferAdjustIndent(buf, 8);
if (virNetDevVPortProfileFormat(def->virtPortProfile, buf) < 0)
return -1;
if (virNetDevBandwidthFormat(def->bandwidth, buf) < 0) if (virNetDevBandwidthFormat(def->bandwidth, buf) < 0)
goto error; goto error;
virBufferAdjustIndent(buf, -8); virBufferAdjustIndent(buf, -8);
@ -11674,10 +11652,6 @@ virDomainNetDefFormat(virBufferPtr buf,
virBufferEscapeString(buf, " portgroup='%s'", virBufferEscapeString(buf, " portgroup='%s'",
def->data.network.portgroup); def->data.network.portgroup);
virBufferAddLit(buf, "/>\n"); virBufferAddLit(buf, "/>\n");
virBufferAdjustIndent(buf, 6);
if (virNetDevVPortProfileFormat(def->data.network.virtPortProfile, buf) < 0)
return -1;
virBufferAdjustIndent(buf, -6);
if ((flags & VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET) && if ((flags & VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET) &&
(virDomainActualNetDefFormat(buf, def->data.network.actual, flags) < 0)) (virDomainActualNetDefFormat(buf, def->data.network.actual, flags) < 0))
return -1; return -1;
@ -11697,12 +11671,6 @@ virDomainNetDefFormat(virBufferPtr buf,
if (def->data.bridge.ipaddr) if (def->data.bridge.ipaddr)
virBufferAsprintf(buf, " <ip address='%s'/>\n", virBufferAsprintf(buf, " <ip address='%s'/>\n",
def->data.bridge.ipaddr); def->data.bridge.ipaddr);
if (def->data.bridge.virtPortProfile) {
virBufferAdjustIndent(buf, 6);
if (virNetDevVPortProfileFormat(def->data.bridge.virtPortProfile, buf) < 0)
return -1;
virBufferAdjustIndent(buf, -6);
}
break; break;
case VIR_DOMAIN_NET_TYPE_SERVER: case VIR_DOMAIN_NET_TYPE_SERVER:
@ -11727,10 +11695,6 @@ virDomainNetDefFormat(virBufferPtr buf,
virBufferAsprintf(buf, " mode='%s'", virBufferAsprintf(buf, " mode='%s'",
virNetDevMacVLanModeTypeToString(def->data.direct.mode)); virNetDevMacVLanModeTypeToString(def->data.direct.mode));
virBufferAddLit(buf, "/>\n"); virBufferAddLit(buf, "/>\n");
virBufferAdjustIndent(buf, 6);
if (virNetDevVPortProfileFormat(def->data.direct.virtPortProfile, buf) < 0)
return -1;
virBufferAdjustIndent(buf, -6);
break; break;
case VIR_DOMAIN_NET_TYPE_HOSTDEV: case VIR_DOMAIN_NET_TYPE_HOSTDEV:
@ -11739,10 +11703,6 @@ virDomainNetDefFormat(virBufferPtr buf,
flags, true) < 0) { flags, true) < 0) {
return -1; return -1;
} }
if (virNetDevVPortProfileFormat(def->data.hostdev.virtPortProfile,
buf) < 0) {
return -1;
}
virBufferAdjustIndent(buf, -6); virBufferAdjustIndent(buf, -6);
break; break;
@ -11751,6 +11711,11 @@ virDomainNetDefFormat(virBufferPtr buf,
break; break;
} }
virBufferAdjustIndent(buf, 6);
if (virNetDevVPortProfileFormat(def->virtPortProfile, buf) < 0)
return -1;
virBufferAdjustIndent(buf, -6);
virBufferEscapeString(buf, " <script path='%s'/>\n", virBufferEscapeString(buf, " <script path='%s'/>\n",
def->script); def->script);
if (def->ifname && if (def->ifname &&
@ -15081,21 +15046,17 @@ virDomainNetGetActualVirtPortProfile(virDomainNetDefPtr iface)
{ {
switch (iface->type) { switch (iface->type) {
case VIR_DOMAIN_NET_TYPE_DIRECT: case VIR_DOMAIN_NET_TYPE_DIRECT:
return iface->data.direct.virtPortProfile;
case VIR_DOMAIN_NET_TYPE_BRIDGE: case VIR_DOMAIN_NET_TYPE_BRIDGE:
return iface->data.bridge.virtPortProfile;
case VIR_DOMAIN_NET_TYPE_HOSTDEV: case VIR_DOMAIN_NET_TYPE_HOSTDEV:
return iface->data.hostdev.virtPortProfile; return iface->virtPortProfile;
case VIR_DOMAIN_NET_TYPE_NETWORK: case VIR_DOMAIN_NET_TYPE_NETWORK:
if (!iface->data.network.actual) if (!iface->data.network.actual)
return NULL; return NULL;
switch (iface->data.network.actual->type) { switch (iface->data.network.actual->type) {
case VIR_DOMAIN_NET_TYPE_DIRECT: case VIR_DOMAIN_NET_TYPE_DIRECT:
return iface->data.network.actual->data.direct.virtPortProfile;
case VIR_DOMAIN_NET_TYPE_BRIDGE: case VIR_DOMAIN_NET_TYPE_BRIDGE:
return iface->data.network.actual->data.bridge.virtPortProfile;
case VIR_DOMAIN_NET_TYPE_HOSTDEV: case VIR_DOMAIN_NET_TYPE_HOSTDEV:
return iface->data.network.actual->data.hostdev.virtPortProfile; return iface->data.network.actual->virtPortProfile;
default: default:
return NULL; return NULL;
} }

View File

@ -770,18 +770,16 @@ struct _virDomainActualNetDef {
union { union {
struct { struct {
char *brname; char *brname;
virNetDevVPortProfilePtr virtPortProfile;
} bridge; } bridge;
struct { struct {
char *linkdev; char *linkdev;
int mode; /* enum virMacvtapMode from util/macvtap.h */ int mode; /* enum virMacvtapMode from util/macvtap.h */
virNetDevVPortProfilePtr virtPortProfile;
} direct; } direct;
struct { struct {
virDomainHostdevDef def; virDomainHostdevDef def;
virNetDevVPortProfilePtr virtPortProfile;
} hostdev; } hostdev;
} data; } data;
virNetDevVPortProfilePtr virtPortProfile;
virNetDevBandwidthPtr bandwidth; virNetDevBandwidthPtr bandwidth;
}; };
@ -810,7 +808,6 @@ struct _virDomainNetDef {
struct { struct {
char *name; char *name;
char *portgroup; char *portgroup;
virNetDevVPortProfilePtr virtPortProfile;
/* actual has info about the currently used physical /* actual has info about the currently used physical
* device (if the network is of type * device (if the network is of type
* bridge/private/vepa/passthrough). This is saved in the * bridge/private/vepa/passthrough). This is saved in the
@ -824,7 +821,6 @@ struct _virDomainNetDef {
struct { struct {
char *brname; char *brname;
char *ipaddr; char *ipaddr;
virNetDevVPortProfilePtr virtPortProfile;
} bridge; } bridge;
struct { struct {
char *name; char *name;
@ -832,13 +828,13 @@ struct _virDomainNetDef {
struct { struct {
char *linkdev; char *linkdev;
int mode; /* enum virMacvtapMode from util/macvtap.h */ int mode; /* enum virMacvtapMode from util/macvtap.h */
virNetDevVPortProfilePtr virtPortProfile;
} direct; } direct;
struct { struct {
virDomainHostdevDef def; virDomainHostdevDef def;
virNetDevVPortProfilePtr virtPortProfile;
} hostdev; } hostdev;
} data; } data;
/* virtPortProfile is used by network/bridge/direct/hostdev */
virNetDevVPortProfilePtr virtPortProfile;
struct { struct {
bool sndbuf_specified; bool sndbuf_specified;
unsigned long sndbuf; unsigned long sndbuf;

View File

@ -2854,8 +2854,8 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
} }
/* Find the most specific virtportprofile and copy it */ /* Find the most specific virtportprofile and copy it */
if (iface->data.network.virtPortProfile) { if (iface->virtPortProfile) {
virtport = iface->data.network.virtPortProfile; virtport = iface->virtPortProfile;
} else { } else {
if (portgroup) if (portgroup)
virtport = portgroup->virtPortProfile; virtport = portgroup->virtPortProfile;
@ -2863,14 +2863,14 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
virtport = netdef->virtPortProfile; virtport = netdef->virtPortProfile;
} }
if (virtport) { if (virtport) {
if (VIR_ALLOC(iface->data.network.actual->data.direct.virtPortProfile) < 0) { if (VIR_ALLOC(iface->data.network.actual->virtPortProfile) < 0) {
virReportOOMError(); virReportOOMError();
goto cleanup; goto cleanup;
} }
/* There are no pointers in a virtualPortProfile, so a shallow copy /* There are no pointers in a virtualPortProfile, so a shallow copy
* is sufficient * is sufficient
*/ */
*iface->data.network.actual->data.direct.virtPortProfile = *virtport; *iface->data.network.actual->virtPortProfile = *virtport;
} }
/* If there is only a single device, just return it (caller will detect /* If there is only a single device, just return it (caller will detect
@ -2935,8 +2935,8 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
} }
} }
} else if ((netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) && } else if ((netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) &&
iface->data.network.actual->data.direct.virtPortProfile && iface->data.network.actual->virtPortProfile &&
(iface->data.network.actual->data.direct.virtPortProfile->virtPortType (iface->data.network.actual->virtPortProfile->virtPortType
== VIR_NETDEV_VPORT_PROFILE_8021QBH)) { == VIR_NETDEV_VPORT_PROFILE_8021QBH)) {
/* pick first dev with 0 usageCount */ /* pick first dev with 0 usageCount */
@ -3068,8 +3068,8 @@ networkNotifyActualDevice(virDomainNetDefPtr iface)
if ((dev->usageCount > 0) && if ((dev->usageCount > 0) &&
((netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH) || ((netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH) ||
((netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) && ((netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) &&
iface->data.network.actual->data.direct.virtPortProfile && iface->data.network.actual->virtPortProfile &&
(iface->data.network.actual->data.direct.virtPortProfile->virtPortType (iface->data.network.actual->virtPortProfile->virtPortType
== VIR_NETDEV_VPORT_PROFILE_8021QBH)))) { == VIR_NETDEV_VPORT_PROFILE_8021QBH)))) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("network '%s' claims dev='%s' is already in use by a different domain"), _("network '%s' claims dev='%s' is already in use by a different domain"),

View File

@ -4762,7 +4762,6 @@ static char *qemuDomainXMLToNative(virConnectPtr conn,
} }
} else if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) { } else if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) {
VIR_FREE(net->data.direct.linkdev); VIR_FREE(net->data.direct.linkdev);
VIR_FREE(net->data.direct.virtPortProfile);
memset(net, 0, sizeof(*net)); memset(net, 0, sizeof(*net));
@ -4782,6 +4781,7 @@ static char *qemuDomainXMLToNative(virConnectPtr conn,
net->data.ethernet.dev = brname; net->data.ethernet.dev = brname;
net->data.ethernet.ipaddr = ipaddr; net->data.ethernet.ipaddr = ipaddr;
} }
VIR_FREE(net->virtPortProfile);
net->info.bootIndex = bootIndex; net->info.bootIndex = bootIndex;
} }
for (i = 0 ; i < def->ngraphics ; i++) { for (i = 0 ; i < def->ngraphics ; i++) {

View File

@ -1340,6 +1340,11 @@ int qemuDomainChangeNet(struct qemud_driver *driver,
return -1; return -1;
} }
if (!virNetDevVPortProfileEqual(olddev->virtPortProfile, dev->virtPortProfile)) {
virReportError(VIR_ERR_NO_SUPPORT, "%s",
_("cannot change <virtualport> settings"));
}
switch (olddev->type) { switch (olddev->type) {
case VIR_DOMAIN_NET_TYPE_USER: case VIR_DOMAIN_NET_TYPE_USER:
break; break;
@ -1367,8 +1372,7 @@ int qemuDomainChangeNet(struct qemud_driver *driver,
case VIR_DOMAIN_NET_TYPE_NETWORK: case VIR_DOMAIN_NET_TYPE_NETWORK:
if (STRNEQ_NULLABLE(olddev->data.network.name, dev->data.network.name) || if (STRNEQ_NULLABLE(olddev->data.network.name, dev->data.network.name) ||
STRNEQ_NULLABLE(olddev->data.network.portgroup, dev->data.network.portgroup) || STRNEQ_NULLABLE(olddev->data.network.portgroup, dev->data.network.portgroup)) {
!virNetDevVPortProfileEqual(olddev->data.network.virtPortProfile, dev->data.network.virtPortProfile)) {
virReportError(VIR_ERR_NO_SUPPORT, "%s", virReportError(VIR_ERR_NO_SUPPORT, "%s",
_("cannot modify network device configuration")); _("cannot modify network device configuration"));
return -1; return -1;
@ -1377,13 +1381,7 @@ int qemuDomainChangeNet(struct qemud_driver *driver,
break; break;
case VIR_DOMAIN_NET_TYPE_BRIDGE: case VIR_DOMAIN_NET_TYPE_BRIDGE:
/* allow changing brname, but not portprofile */ /* allow changing brname */
if (!virNetDevVPortProfileEqual(olddev->data.bridge.virtPortProfile,
dev->data.bridge.virtPortProfile)) {
virReportError(VIR_ERR_NO_SUPPORT, "%s",
_("cannot modify bridge network device configuration"));
return -1;
}
break; break;
case VIR_DOMAIN_NET_TYPE_INTERNAL: case VIR_DOMAIN_NET_TYPE_INTERNAL:
@ -1396,8 +1394,7 @@ int qemuDomainChangeNet(struct qemud_driver *driver,
case VIR_DOMAIN_NET_TYPE_DIRECT: case VIR_DOMAIN_NET_TYPE_DIRECT:
if (STRNEQ_NULLABLE(olddev->data.direct.linkdev, dev->data.direct.linkdev) || if (STRNEQ_NULLABLE(olddev->data.direct.linkdev, dev->data.direct.linkdev) ||
olddev->data.direct.mode != dev->data.direct.mode || olddev->data.direct.mode != dev->data.direct.mode) {
!virNetDevVPortProfileEqual(olddev->data.direct.virtPortProfile, dev->data.direct.virtPortProfile)) {
virReportError(VIR_ERR_NO_SUPPORT, "%s", virReportError(VIR_ERR_NO_SUPPORT, "%s",
_("cannot modify direct network device configuration")); _("cannot modify direct network device configuration"));
return -1; return -1;