Change in vdsm[ovirt-3.5]: netinfo: rework reporting of DHCPv4/6 on network devices

osvoboda at redhat.com osvoboda at redhat.com
Tue Nov 10 22:56:01 UTC 2015


Hello Ido Barkan, Dan Kenigsberg,

I'd like you to do a code review.  Please visit

    https://gerrit.ovirt.org/48399

to review the following change.

Change subject: netinfo: rework reporting of DHCPv4/6 on network devices
......................................................................

netinfo: rework reporting of DHCPv4/6 on network devices

This is a minimal backport of upstream patches aiming to fix a bug
described as:

DHCP is still reported for hours after a network got static IP
configuration.

This is because reporting is based on dhclient's leases.

Change-Id: Iaffdc836f8f64ecdc0a7e37ef50c228032f99696
Bug-Url: https://bugzilla.redhat.com/1184497
Signed-off-by: Ondřej Svoboda <osvoboda at redhat.com>
Reviewed-on: https://gerrit.ovirt.org/46430
Continuous-Integration: Jenkins CI
Reviewed-by: Ido Barkan <ibarkan at redhat.com>
Reviewed-by: Dan Kenigsberg <danken at redhat.com>
---
M lib/vdsm/netinfo.py
1 file changed, 54 insertions(+), 18 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/99/48399/1

diff --git a/lib/vdsm/netinfo.py b/lib/vdsm/netinfo.py
index 01f25c7..f0a83d1 100644
--- a/lib/vdsm/netinfo.py
+++ b/lib/vdsm/netinfo.py
@@ -540,7 +540,15 @@
                      in sorted(opts.iteritems())))
 
 
-def _getNetInfo(iface, dhcp4, bridged, gateways, ipv6routes, ipaddrs):
+def _dhcp_used(iface, ifaces_with_active_leases, net_attrs):
+    if net_attrs is None:
+        return iface in ifaces_with_active_leases
+    else:
+        return net_attrs.get('bootproto') == 'dhcp'
+
+
+def _getNetInfo(iface, dhcp4, bridged, gateways, ipv6routes, ipaddrs,
+                net_attrs):
     '''Returns a dictionary of properties about the network's interface status.
     Raises a KeyError if the iface does not exist.'''
     data = {}
@@ -557,7 +565,8 @@
         ipv4addr, ipv4netmask, ipv4addrs, ipv6addrs = getIpInfo(iface, ipaddrs)
         data.update({'iface': iface, 'bridged': bridged,
                      'addr': ipv4addr, 'netmask': ipv4netmask,
-                     'bootproto4': 'dhcp' if iface in dhcp4 else 'none',
+                     'bootproto4': 'dhcp' if _dhcp_used(
+                         iface, dhcp4, net_attrs) else 'none',
                      'gateway': getgateway(gateways, iface),
                      'ipv4addrs': ipv4addrs,
                      'ipv6addrs': ipv6addrs,
@@ -618,6 +627,41 @@
             'ipv6addrs': ipv6addrs,
             'mtu': str(link.mtu),
             'netmask': ipv4netmask}
+
+
+def _propose_updates_to_reported_dhcp(network_info, networking):
+    """
+    Report DHCPv4 state of a network's topmost device based on the network's
+    configuration, to fix bug #1184497 (DHCP still being reported for hours
+    after a network got static IP configuration, as reporting is based on
+    dhclient leases).
+    """
+    updated_networking = dict(bondings={}, bridges={}, nics={}, vlans={})
+    network_device = network_info['iface']
+
+    for devices in ('bridges', 'vlans', 'bondings', 'nics'):
+        dev_info = networking[devices].get(network_device)
+        if dev_info:
+            updated_networking[devices][network_device] = {
+                'bootproto4': network_info['bootproto4'],
+                'cfg': {'BOOTPROTO': network_info['bootproto4']},
+            }
+            break
+
+    return updated_networking
+
+
+def _update_reported_dhcp(replacement, networking):
+    """
+    For each network device (representing a network), apply updates to reported
+    DHCP-related fields, as prepared by _propose_updates_to_reported_dhcp.
+    """
+    for device_type, devices in replacement.iteritems():
+        for device_name, replacement_device_info in devices.iteritems():
+            device_info = networking[device_type][device_name]
+            device_info['bootproto4'] = replacement_device_info['bootproto4']
+            if replacement_device_info['cfg']:
+                device_info['cfg'].update(replacement_device_info['cfg'])
 
 
 def _parseExpiryTime(expiryTime):
@@ -700,6 +744,7 @@
 
 def _libvirtNets2vdsm(nets, gateways=None, ipv6routes=None,
                       ipAddrs=None):
+    running_config = RunningConfig()
     dhcp4 = getDhclientIfaces(_DHCLIENT_LEASES_GLOBS)
     if gateways is None:
         gateways = getRoutes()
@@ -713,24 +758,11 @@
             d[net] = _getNetInfo(netAttr.get('iface', net),
                                  dhcp4,
                                  netAttr['bridged'], gateways,
-                                 ipv6routes, ipAddrs)
+                                 ipv6routes, ipAddrs,
+                                 running_config.networks.get(net, None))
         except KeyError:
             continue  # Do not report missing libvirt networks.
     return d
-
-
-def _cfgBootprotoCompat(netsAndDevices):
-    """Set network 'cfg' 'BOOTPROTO' for backwards engine compatibility."""
-    for netAttrs in netsAndDevices['networks'].itervalues():
-        if netAttrs['bridged'] and 'BOOTPROTO' not in netAttrs['cfg']:
-            netAttrs['cfg']['BOOTPROTO'] = netAttrs['bootproto4']
-
-        for devType in ('bondings', 'bridges', 'nics', 'vlans'):
-            dev = netsAndDevices[devType].get(netAttrs['iface'])
-
-            if dev and 'BOOTPROTO' not in dev['cfg']:
-                dev['cfg']['BOOTPROTO'] = netAttrs['bootproto4']
-                break
 
 
 def get(vdsmnets=None):
@@ -758,7 +790,11 @@
         elif dev.isVLAN():
             d['vlans'][dev.name] = _vlaninfo(dev, ipaddrs)
 
-    _cfgBootprotoCompat(d)
+    for network_info in d['networks'].itervalues():
+        if network_info['bridged']:
+            network_info['cfg']['BOOTPROTO'] = network_info['bootproto4']
+        updates = _propose_updates_to_reported_dhcp(network_info, d)
+        _update_reported_dhcp(updates, d)
 
     return d
 


-- 
To view, visit https://gerrit.ovirt.org/48399
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iaffdc836f8f64ecdc0a7e37ef50c228032f99696
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Ondřej Svoboda <osvoboda at redhat.com>
Gerrit-Reviewer: Dan Kenigsberg <danken at redhat.com>
Gerrit-Reviewer: Ido Barkan <ibarkan at redhat.com>


More information about the vdsm-patches mailing list