network: convert networkReleaseActualDevice to virNetworkPortDef

Convert the virDomainNetDef object into a virNetworkPortDef object
at the start of networkReleaseActualDevice. This largely decouples
the method impl from the domain object type.

Reviewed-by: Laine Stump <laine@laine.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2018-11-12 16:32:31 +00:00
parent 116f87e98c
commit 04ada2f841

View File

@ -4939,10 +4939,10 @@ networkReleaseActualDevice(virNetworkPtr net,
virDomainNetDefPtr iface) virDomainNetDefPtr iface)
{ {
virNetworkDriverStatePtr driver = networkGetDriver(); virNetworkDriverStatePtr driver = networkGetDriver();
virDomainNetType actualType = virDomainNetGetActualType(iface);
virNetworkObjPtr obj; virNetworkObjPtr obj;
virNetworkDefPtr netdef; virNetworkDefPtr netdef;
virNetworkForwardIfDefPtr dev = NULL; virNetworkForwardIfDefPtr dev = NULL;
virNetworkPortDefPtr port = NULL;
size_t i; size_t i;
int ret = -1; int ret = -1;
@ -4951,77 +4951,50 @@ networkReleaseActualDevice(virNetworkPtr net,
virReportError(VIR_ERR_NO_NETWORK, virReportError(VIR_ERR_NO_NETWORK,
_("no network with matching name '%s'"), _("no network with matching name '%s'"),
net->name); net->name);
goto error; goto cleanup;
} }
if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK) { if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Expected an interface for a virtual network")); _("Expected an interface for a virtual network"));
goto error; goto cleanup;
} }
if (iface->data.network.actual == NULL) {
ret = 0;
goto cleanup;
}
if (!(port = virDomainNetDefActualToNetworkPort(dom, iface)))
goto cleanup;
netdef = virNetworkObjGetDef(obj); netdef = virNetworkObjGetDef(obj);
switch ((virNetworkForwardType) netdef->forward.type) { switch ((virNetworkPortPlugType)port->plugtype) {
case VIR_NETWORK_FORWARD_NONE: case VIR_NETWORK_PORT_PLUG_TYPE_NONE:
case VIR_NETWORK_FORWARD_NAT: VIR_DEBUG("Releasing network device with no plug type");
case VIR_NETWORK_FORWARD_ROUTE:
case VIR_NETWORK_FORWARD_OPEN:
if (iface->data.network.actual &&
networkUnplugBandwidth(obj, iface->bandwidth,
&iface->data.network.actual->class_id) < 0)
goto error;
break; break;
case VIR_NETWORK_FORWARD_BRIDGE: case VIR_NETWORK_PORT_PLUG_TYPE_NETWORK:
if (iface->data.network.actual && case VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE:
actualType == VIR_DOMAIN_NET_TYPE_BRIDGE && if (networkUnplugBandwidth(obj, port->bandwidth,
networkUnplugBandwidth(obj, iface->bandwidth, &port->class_id) < 0)
&iface->data.network.actual->class_id) < 0) goto cleanup;
goto error;
break;
case VIR_NETWORK_FORWARD_PRIVATE:
case VIR_NETWORK_FORWARD_VEPA:
case VIR_NETWORK_FORWARD_PASSTHROUGH:
case VIR_NETWORK_FORWARD_HOSTDEV:
break; break;
case VIR_NETWORK_FORWARD_LAST: case VIR_NETWORK_PORT_PLUG_TYPE_DIRECT:
default: if (netdef->forward.nifs == 0) {
virReportEnumRangeError(virNetworkForwardType, netdef->forward.type); virReportError(VIR_ERR_INTERNAL_ERROR,
goto error; _("network '%s' uses a direct mode, but "
} "has no forward dev and no interface pool"),
netdef->name);
if ((!iface->data.network.actual) || goto cleanup;
((actualType != VIR_DOMAIN_NET_TYPE_DIRECT) &&
(actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV))) {
VIR_DEBUG("Nothing to release to network %s", iface->data.network.name);
goto success;
}
if (netdef->forward.nifs == 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("network '%s' uses a direct/hostdev mode, but "
"has no forward dev and no interface pool"),
netdef->name);
goto error;
}
if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
const char *actualDev;
actualDev = virDomainNetGetActualDirectDev(iface);
if (!actualDev) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("the interface uses a direct mode, "
"but has no source dev"));
goto error;
} }
for (i = 0; i < netdef->forward.nifs; i++) { for (i = 0; i < netdef->forward.nifs; i++) {
if (netdef->forward.ifs[i].type if (netdef->forward.ifs[i].type
== VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV && == VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV &&
STREQ(actualDev, netdef->forward.ifs[i].device.dev)) { STREQ(port->plug.direct.linkdev, netdef->forward.ifs[i].device.dev)) {
dev = &netdef->forward.ifs[i]; dev = &netdef->forward.ifs[i];
break; break;
} }
@ -5031,23 +5004,24 @@ networkReleaseActualDevice(virNetworkPtr net,
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("network '%s' doesn't have dev='%s' " _("network '%s' doesn't have dev='%s' "
"in use by domain"), "in use by domain"),
netdef->name, actualDev); netdef->name, port->plug.direct.linkdev);
goto error; goto cleanup;
} }
} else /* if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) */ { break;
virDomainHostdevDefPtr hostdev;
hostdev = virDomainNetGetActualHostdev(iface); case VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI:
if (!hostdev) { if (netdef->forward.nifs == 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("the interface uses a hostdev mode, but has no hostdev")); _("network '%s' uses a hostdev mode, but "
goto error; "has no forward dev and no interface pool"),
netdef->name);
goto cleanup;
} }
for (i = 0; i < netdef->forward.nifs; i++) { for (i = 0; i < netdef->forward.nifs; i++) {
if (netdef->forward.ifs[i].type if (netdef->forward.ifs[i].type
== VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_PCI && == VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_PCI &&
virPCIDeviceAddressEqual(&hostdev->source.subsys.u.pci.addr, virPCIDeviceAddressEqual(&port->plug.hostdevpci.addr,
&netdef->forward.ifs[i].device.pci)) { &netdef->forward.ifs[i].device.pci)) {
dev = &netdef->forward.ifs[i]; dev = &netdef->forward.ifs[i];
break; break;
@ -5059,26 +5033,30 @@ networkReleaseActualDevice(virNetworkPtr net,
_("network '%s' doesn't have " _("network '%s' doesn't have "
"PCI device %04x:%02x:%02x.%x in use by domain"), "PCI device %04x:%02x:%02x.%x in use by domain"),
netdef->name, netdef->name,
hostdev->source.subsys.u.pci.addr.domain, port->plug.hostdevpci.addr.domain,
hostdev->source.subsys.u.pci.addr.bus, port->plug.hostdevpci.addr.bus,
hostdev->source.subsys.u.pci.addr.slot, port->plug.hostdevpci.addr.slot,
hostdev->source.subsys.u.pci.addr.function); port->plug.hostdevpci.addr.function);
goto error; goto cleanup;
} }
break;
case VIR_NETWORK_PORT_PLUG_TYPE_LAST:
default:
virReportEnumRangeError(virNetworkPortPlugType, port->plugtype);
goto cleanup;
} }
success: virNetworkObjMacMgrDel(obj, driver->dnsmasqStateDir, dom->name, &port->mac);
virNetworkObjMacMgrDel(obj, driver->dnsmasqStateDir, dom->name, &iface->mac);
netdef->connections--;
if (dev)
dev->connections--;
/* finally we can call the 'unplugged' hook script if any */
networkRunHook(obj, dom, iface, VIR_HOOK_NETWORK_OP_IFACE_UNPLUGGED,
VIR_HOOK_SUBOP_BEGIN);
networkLogAllocation(netdef, dev, &port->mac, false);
if (iface->data.network.actual) {
netdef->connections--;
if (dev)
dev->connections--;
/* finally we can call the 'unplugged' hook script if any */
networkRunHook(obj, dom, iface, VIR_HOOK_NETWORK_OP_IFACE_UNPLUGGED,
VIR_HOOK_SUBOP_BEGIN);
networkLogAllocation(netdef, dev, &iface->mac, false);
}
ret = 0; ret = 0;
cleanup: cleanup:
virNetworkObjEndAPI(&obj); virNetworkObjEndAPI(&obj);
@ -5086,10 +5064,8 @@ networkReleaseActualDevice(virNetworkPtr net,
virDomainActualNetDefFree(iface->data.network.actual); virDomainActualNetDefFree(iface->data.network.actual);
iface->data.network.actual = NULL; iface->data.network.actual = NULL;
} }
virNetworkPortDefFree(port);
return ret; return ret;
error:
goto cleanup;
} }