On 10/25/2012 11:18 AM, Peter Krempa wrote:
The network driver didn't care about config files when a network
was
destroyed, just when it was undefined leaving behind files for transient
networks.
This patch splits out the cleanup code to a helper function that handles
the cleanup if the inactive network object is being removed and re-uses
this code when getting rid of inactive networks.
---
src/network/bridge_driver.c | 133 +++++++++++++++++++++++++-------------------
1 file changed, 76 insertions(+), 57 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 976c132..45fca0e 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -155,6 +155,67 @@ networkRadvdConfigFileName(const char *netname)
return configfile;
}
+/* do needed cleanup steps and remove the network from the list */
+static int
+networkRemoveInactive(struct network_driver *driver,
+ virNetworkObjPtr net)
+{
+ char *leasefile = NULL;
+ char *radvdconfigfile = NULL;
+ char *radvdpidbase = NULL;
+ dnsmasqContext *dctx = NULL;
+ virNetworkIpDefPtr ipdef;
+ virNetworkDefPtr def = virNetworkObjGetPersistentDef(net);
+
+ int ret = -1;
+ int i;
+
+ /* we only support dhcp on one IPv4 address per defined network */
+ for (i = 0;
+ (ipdef = virNetworkDefGetIpByIndex(def, AF_UNSPEC, i));
+ i++) {
+ if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET) &&
+ (ipdef->nranges || ipdef->nhosts)) {
+ /* clean up files left over by dnsmasq */
+ if (!(dctx = dnsmasqContextNew(def->name, DNSMASQ_STATE_DIR)))
+ goto cleanup;
+
+ if (!(leasefile = networkDnsmasqLeaseFileName(def->name)))
+ goto cleanup;
+
+ dnsmasqDelete(dctx);
+ unlink(leasefile);
A couple of things about this:
1) I think it would be fine to do all of these deletes anytime a network
is destroyed, not just when it's undefined (although I guess it's
possible someone might rely on this behavior, it's not documented and
not part of the API (and I don't know why they would rely on it anyway).
2) Since we're not checking for errors anyway, I think we should just
always try the deletes/unlinks - it's possible that the configuration of
the network changed during its lifetime and the IP
addresses/ranges/hosts/whatever were deleted, so that now the network
isn't doing dhcp, but it was in the past and has stale files left around.
+
+ } else if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) {
+ /* clean up files left over by radvd */
+
+ if (!(radvdconfigfile = networkRadvdConfigFileName(def->name)))
+ goto no_memory;
+
+ if (!(radvdpidbase = networkRadvdPidfileBasename(def->name)))
+ goto no_memory;
+
+ unlink(radvdconfigfile);
+ virPidFileDelete(NETWORK_PID_DIR, radvdpidbase);
Same here. I think we should just always attempt these operations,
whether there are any ipv6 addresses or not. (anyway, the way it's
written now, if you had 5 IPv6 addresses on the network, you would be
attempting the same unlinks 5 times.)
+ }
+ }
+
+ virNetworkRemoveInactive(&driver->networks, net);
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(leasefile);
+ VIR_FREE(radvdconfigfile);
+ VIR_FREE(radvdpidbase);
+ dnsmasqContextFree(dctx);
+ return ret;
+
+no_memory:
+ virReportOOMError();
+ goto cleanup;
+}
+
static char *
networkBridgeDummyNicName(const char *brname)
{
@@ -2806,12 +2867,11 @@ cleanup:
return ret;
}
-static int networkUndefine(virNetworkPtr net) {
+static int
+networkUndefine(virNetworkPtr net) {
struct network_driver *driver = net->conn->networkPrivateData;
virNetworkObjPtr network;
- virNetworkIpDefPtr ipdef;
- bool dhcp_present = false, v6present = false;
- int ret = -1, ii;
+ int ret = -1;
networkDriverLock(driver);
@@ -2833,58 +2893,12 @@ static int networkUndefine(virNetworkPtr net) {
network) < 0)
goto cleanup;
- /* we only support dhcp on one IPv4 address per defined network */
- for (ii = 0;
- (ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii));
- ii++) {
- if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) {
- if (ipdef->nranges || ipdef->nhosts)
- dhcp_present = true;
- } else if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) {
- v6present = true;
- }
- }
-
- if (dhcp_present) {
- char *leasefile;
- dnsmasqContext *dctx = dnsmasqContextNew(network->def->name,
DNSMASQ_STATE_DIR);
- if (dctx == NULL)
- goto cleanup;
-
- dnsmasqDelete(dctx);
- dnsmasqContextFree(dctx);
-
- leasefile = networkDnsmasqLeaseFileName(network->def->name);
- if (!leasefile)
- goto cleanup;
- unlink(leasefile);
- VIR_FREE(leasefile);
- }
-
- if (v6present) {
- char *configfile = networkRadvdConfigFileName(network->def->name);
-
- if (!configfile) {
- virReportOOMError();
- goto cleanup;
- }
- unlink(configfile);
- VIR_FREE(configfile);
-
- char *radvdpidbase = networkRadvdPidfileBasename(network->def->name);
-
- if (!(radvdpidbase)) {
- virReportOOMError();
- goto cleanup;
- }
- virPidFileDelete(NETWORK_PID_DIR, radvdpidbase);
- VIR_FREE(radvdpidbase);
-
+ VIR_INFO("Undefining network '%s'", network->def->name);
+ if (networkRemoveInactive(driver, network) < 0) {
+ network = NULL;
+ goto cleanup;
}
- VIR_INFO("Undefining network '%s'", network->def->name);
- virNetworkRemoveInactive(&driver->networks,
- network);
network = NULL;
ret = 0;
@@ -3085,10 +3099,15 @@ static int networkDestroy(virNetworkPtr net) {
goto cleanup;
}
- ret = networkShutdownNetwork(driver, network);
+ if ((ret = networkShutdownNetwork(driver, network)) < 0)
+ goto cleanup;
+
if (!network->persistent) {
- virNetworkRemoveInactive(&driver->networks,
- network);
+ if (networkRemoveInactive(driver, network) < 0) {
+ network = NULL;
+ ret = -1;
+ goto cleanup;
+ }
network = NULL;
}
So, definitely you should do (2) above, and I think you should also do
(1), but if you want to do that separately/later, that's okay too.