[libvirt] [PATCH 4/6] net: Remove dnsmasq and radvd files also when destroying transient nets

Laine Stump laine at laine.org
Thu Oct 25 20:56:53 UTC 2012


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.




More information about the libvir-list mailing list