[libvirt] [PATCHv2 3/4] network: set macvtap/hostdev networks active if their state file exists
John Ferlan
jferlan at redhat.com
Wed Apr 23 19:00:53 UTC 2014
On 04/17/2014 07:43 AM, Laine Stump wrote:
> libvirt attempts to determine at startup time which networks are
> already active, and set their active flags. Previously it has done
> this by assuming that all networks are inactive, then setting the
> active flag if the network has a bridge device associated with it and
> that bridge device exists. This is not useful for macvtap and hostdev
> based networks, since they do not use a bridge device.
>
> Of course the reason that such a check had to be done was that the
> presence of a status file in the network "stateDir" couldn't be
> trusted as an indicator of whether or not a network was active. This
> was due to the network driver mistakenly using
> /var/lib/libvirt/network to store the status files, rather than
> /var/run/libvirt/network (similar to what is done by every other
> libvirt driver that stores status xml for its objects). The difference
> is that /var/run is cleared out when the host reboots, so you can be
> assured that the state file you are seeing isn't just left over from a
> previous boot of the host.
>
> Now that the network driver has been switched to using
> /var/run/libvirt/network for status, we can also modify it to assume
> that any network with an existing status file is by definition active
> - we do this when reading the status file. To fine tune the results,
> networkFindActiveConfigs() is changed to networkUpdateAllState(),
> and only sets active = 0 if the conditions for particular network
> types are *not* met.
>
> The result is that during the first run of libvirtd after the host
> boots, there are no status files, so no networks are active. Any time
> libvirtd is restarted, any network with a status file will be marked
> as active (unless the network uses a bridge device and that device for
> some reason doesn't exist).
> ---
> Changes from V1:
>
> * rename networkFindActiveConfigs() to networkUpdateAllState() (rather
> than networkFindInactiveConfigs()
>
> * undo the change in order of calling the above function
> vs. virNetworkReadAllConfigs(), just in case that would cause some
> undetected regression.
>
> * extricate the reading of pidfiles from the switch statement that
> behaves differently for different types of networks - those networks
> that don't use dnsmasq/radvd will not have any pidfiles for them
> anyway, so it becomes a NOP (and if a new network type that *does*
> use one of those processes is created, it will automatically work
> correctly here.)
>
>
> src/conf/network_conf.c | 1 +
> src/network/bridge_driver.c | 69 ++++++++++++++++++++++++++++++++-------------
> 2 files changed, 51 insertions(+), 19 deletions(-)
>
> diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
> index 56c4a09..69ad929 100644
> --- a/src/conf/network_conf.c
> +++ b/src/conf/network_conf.c
> @@ -3060,6 +3060,7 @@ virNetworkLoadState(virNetworkObjListPtr nets,
> net->floor_sum = floor_sum_val;
>
> net->taint = taint;
> + net->active = 1; /* any network with a state file is by definition active */
Typing and thinking - it's a dangerous combination... Since the driver
initialization now "moves" files from /lib/ to /pid/ without regard to
whether they were active previously in /lib/ - is it possible that other
code will erroneously mark something active?
The prior code would look through the state files to mark active... This
code says, I found a state file thus I must be active. Of course only
true for migration case - so hmm.... does the previous patch need a tweak?
>
> cleanup:
> VIR_FREE(configFile);
> diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
> index 57dfb2d..0c879b9 100644
> --- a/src/network/bridge_driver.c
> +++ b/src/network/bridge_driver.c
> @@ -328,38 +328,69 @@ networkBridgeDummyNicName(const char *brname)
> return nicname;
> }
>
> +/* Update the internal status of all allegedly active networks
> + * according to external conditions on the host (i.e. anything that
> + * isn't stored directly in each network's state file). */
> static void
> -networkFindActiveConfigs(virNetworkDriverStatePtr driver)
> +networkUpdateAllState(virNetworkDriverStatePtr driver)
> {
> size_t i;
>
> for (i = 0; i < driver->networks.count; i++) {
> virNetworkObjPtr obj = driver->networks.objs[i];
>
> + if (!obj->active)
> + continue;
> +
> virNetworkObjLock(obj);
>
> - /* If bridge exists, then mark it active */
> - if (obj->def->bridge &&
> - virNetDevExists(obj->def->bridge) == 1) {
> - obj->active = 1;
> + switch (obj->def->forward.type) {
> + case VIR_NETWORK_FORWARD_NONE:
> + case VIR_NETWORK_FORWARD_NAT:
> + case VIR_NETWORK_FORWARD_ROUTE:
> + /* If bridge exists, then mark it active */
> + if (!(obj->def->bridge && virNetDevExists(obj->def->bridge) == 1))
> + obj->active = 0;
> + break;
Comment is still misleading...
ACK with that change
John
>
> - /* Try and read dnsmasq/radvd pids if any */
> - if (obj->def->ips && (obj->def->nips > 0)) {
> - char *radvdpidbase;
> + case VIR_NETWORK_FORWARD_BRIDGE:
> + if (obj->def->bridge) {
> + if (virNetDevExists(obj->def->bridge) != 1)
> + obj->active = 0;
> + break;
> + }
> + /* intentionally drop through to common case for all
> + * macvtap networks (forward='bridge' with no bridge
> + * device defined is macvtap using its 'bridge' mode)
> + */
> + case VIR_NETWORK_FORWARD_PRIVATE:
> + case VIR_NETWORK_FORWARD_VEPA:
> + case VIR_NETWORK_FORWARD_PASSTHROUGH:
> + /* so far no extra checks */
> + break;
>
> - ignore_value(virPidFileReadIfAlive(driverState->pidDir, obj->def->name,
> - &obj->dnsmasqPid,
> - dnsmasqCapsGetBinaryPath(driver->dnsmasqCaps)));
> + case VIR_NETWORK_FORWARD_HOSTDEV:
> + /* so far no extra checks */
> + break;
> + }
>
> - if (!(radvdpidbase = networkRadvdPidfileBasename(obj->def->name)))
> - goto cleanup;
> - ignore_value(virPidFileReadIfAlive(driverState->pidDir, radvdpidbase,
> - &obj->radvdPid, RADVD));
> - VIR_FREE(radvdpidbase);
> - }
> + /* Try and read dnsmasq/radvd pids of active networks */
> + if (obj->active && obj->def->ips && (obj->def->nips > 0)) {
> + char *radvdpidbase;
> +
> + ignore_value(virPidFileReadIfAlive(driverState->pidDir,
> + obj->def->name,
> + &obj->dnsmasqPid,
> + dnsmasqCapsGetBinaryPath(driver->dnsmasqCaps)));
> + radvdpidbase = networkRadvdPidfileBasename(obj->def->name);
> + if (!radvdpidbase)
> + break;
> + ignore_value(virPidFileReadIfAlive(driverState->pidDir,
> + radvdpidbase,
> + &obj->radvdPid, RADVD));
> + VIR_FREE(radvdpidbase);
> }
>
> - cleanup:
> virNetworkObjUnlock(obj);
> }
>
> @@ -591,7 +622,7 @@ networkStateInitialize(bool privileged,
> driverState->networkAutostartDir) < 0)
> goto error;
>
> - networkFindActiveConfigs(driverState);
> + networkUpdateAllState(driverState);
> networkReloadFirewallRules(driverState);
> networkRefreshDaemons(driverState);
>
>
More information about the libvir-list
mailing list