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 <osvob...@redhat.com> Reviewed-on: https://gerrit.ovirt.org/46430 Continuous-Integration: Jenkins CI Reviewed-by: Ido Barkan <ibar...@redhat.com> Reviewed-by: Dan Kenigsberg <dan...@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 <osvob...@redhat.com> Gerrit-Reviewer: Dan Kenigsberg <dan...@redhat.com> Gerrit-Reviewer: Ido Barkan <ibar...@redhat.com> _______________________________________________ vdsm-patches mailing list vdsm-patches@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches