Change in vdsm[ovirt-3.6]: Advertise aggregator ID in bonding interfaces

sshnaidm at redhat.com sshnaidm at redhat.com
Thu Mar 10 13:04:37 UTC 2016


Sagi Shnaidman has uploaded a new change for review.

Change subject: Advertise aggregator ID in bonding interfaces
......................................................................

Advertise aggregator ID in bonding interfaces

If interface or bond itself has an aggregator ID, then
advertise it to engine in getCaps
Bug-Url: https://bugzilla.redhat.com/1281666
Change-Id: I85267967c9cb1b0a626d91cb1953361ed4de727a
Signed-off-by: Sagi Shnaidman <sshnaidm at redhat.com>
---
M lib/vdsm/netinfo.py
M tests/functional/networkTests.py
M vdsm/caps.py
3 files changed, 85 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/88/54588/1

diff --git a/lib/vdsm/netinfo.py b/lib/vdsm/netinfo.py
index bfd7546..6a496e1 100644
--- a/lib/vdsm/netinfo.py
+++ b/lib/vdsm/netinfo.py
@@ -64,6 +64,7 @@
 NET_PATH = '/sys/class/net'
 BONDING_MASTERS = '/sys/class/net/bonding_masters'
 BONDING_SLAVES = '/sys/class/net/%s/bonding/slaves'
+BONDING_SLAVE_OPT = '/sys/class/net/%s/bonding_slave/%s'
 BONDING_ACTIVE_SLAVE = '/sys/class/net/%s/bonding/active_slave'
 BONDING_OPT = '/sys/class/net/%s/bonding/%s'
 BONDING_DEFAULTS = constants.P_VDSM_LIB + 'bonding-defaults.json'
@@ -129,6 +130,27 @@
 def slaves(bonding):
     with open(BONDING_SLAVES % bonding) as f:
         return f.readline().split()
+
+def _file_value(path):
+    if os.path.exists(path):
+        with open(path, 'r') as f:
+            return f.read().replace('N/A', '').strip()
+
+
+def get_bond_slave_agg_info(nic_name):
+    agg_id_path = BONDING_SLAVE_OPT % (nic_name, 'ad_aggregator_id')
+    agg_id = _file_value(agg_id_path)
+    return {'ad_aggregator_id': agg_id} if agg_id else {}
+
+
+def get_bond_agg_info(bond_name):
+    agg_id_path = BONDING_OPT % (bond_name, 'ad_aggregator')
+    ad_mac_path = BONDING_OPT % (bond_name, 'ad_partner_mac')
+    agg_id = _file_value(agg_id_path)
+    agg_mac = _file_value(ad_mac_path)
+    return {
+        'ad_aggregator_id': agg_id, 'ad_partner_mac': agg_mac
+    } if agg_id and agg_mac else {}
 
 
 def active_slave(bonding):
@@ -796,8 +818,10 @@
             devinfo = networking['bridges'][dev.name] = _bridgeinfo(dev)
         elif dev.isNICLike():
             devinfo = networking['nics'][dev.name] = _nicinfo(dev, paddr)
+            devinfo.update(get_bond_slave_agg_info(dev.name))
         elif dev.isBOND():
             devinfo = networking['bondings'][dev.name] = _bondinfo(dev)
+            devinfo.update(get_bond_agg_info(dev.name))
         elif dev.isVLAN():
             devinfo = networking['vlans'][dev.name] = _vlaninfo(dev)
         else:
diff --git a/tests/functional/networkTests.py b/tests/functional/networkTests.py
index f7beebc..ca7ef48 100644
--- a/tests/functional/networkTests.py
+++ b/tests/functional/networkTests.py
@@ -22,6 +22,7 @@
 import re
 import netaddr
 import os.path
+import six
 
 from nose import with_setup
 from nose.plugins.skip import SkipTest
@@ -2787,3 +2788,62 @@
                 {}, {BONDING_NAME: {'remove': True}}, NOCHK)
             self.assertEqual(status, SUCCESS, msg)
             self.assertBondDoesntExist(BONDING_NAME, nics)
+
+    @contextmanager
+    def setup_bonds_with_veth_pair(self, bond_options):
+        with veth.pair() as (n1, n2), veth.pair() as (n3, n4):
+            nics = [n1, n2, n3, n4]
+            bonds = {BONDING_NAME: (n1, n3), BONDING_NAME + "0": (n2, n4)}
+            for bond, pair in six.iteritems(bonds):
+                bonding = {'nics': pair}
+                bonding.update({'options': bond_options})
+                status, msg = self.setupNetworks(
+                    {},
+                    {bond: bonding},
+                    NOCHK)
+                self.assertEqual(status, SUCCESS, msg)
+                self.assertBondExists(bond, pair)
+            status, msg, info = self.vdsm_net.getVdsCapabilities()
+            bond_caps, nic_caps = info['bondings'], info['nics']
+            try:
+                yield bonds, nics, bond_caps, nic_caps
+            finally:
+                for bond in bonds:
+                    status, msg = self.setupNetworks(
+                        {}, {bond: {'remove': True}}, NOCHK)
+                    self.assertEqual(status, SUCCESS, msg)
+                    self.assertBondDoesntExist(bond, bonds[bond])
+
+    @cleanupNet
+    @ValidateRunningAsRoot
+    def test_bond_mode4_caps_aggregator_id(self):
+        with self.setup_bonds_with_veth_pair(
+                'mode=4 lacp_rate=1 miimon=100'
+        ) as (bonds, nics, bond_caps, nic_caps):
+            for bond in bonds:
+                self.assertIn('ad_aggregator_id', bond_caps[bond])
+                self.assertIn('ad_partner_mac', bond_caps[bond])
+            bond1, bond2 = bonds
+            self.assertEqual(
+                bond_caps[bond1]['ad_partner_mac'],
+                bond_caps[bond2]['hwaddr']
+            )
+            self.assertEqual(
+                bond_caps[bond2]['ad_partner_mac'],
+                bond_caps[bond1]['hwaddr']
+            )
+            for nic in nics:
+                self.assertIn('ad_aggregator_id', nic_caps[nic])
+                self.assertNotEqual(nic_caps[nic]['ad_aggregator_id'], None)
+
+    @cleanupNet
+    @ValidateRunningAsRoot
+    def test_bond_mode0_caps_aggregator_id(self):
+        with self.setup_bonds_with_veth_pair(
+                'mode=0'
+        ) as (bonds, nics, bond_caps, nic_caps):
+            for bond in bonds:
+                self.assertNotIn('ad_aggregator_id', bond_caps[bond])
+                self.assertNotIn('ad_partner_mac', bond_caps[bond])
+            for nic in nics:
+                self.assertNotIn('ad_aggregator_id', nic_caps[nic])
\ No newline at end of file
diff --git a/vdsm/caps.py b/vdsm/caps.py
index ae038a7..07d6e18 100644
--- a/vdsm/caps.py
+++ b/vdsm/caps.py
@@ -719,7 +719,7 @@
     caps['kdumpStatus'] = _getKdumpStatus()
 
     caps['hostdevPassthrough'] = str(_getHostdevPassthorughSupport()).lower()
-    caps['additionalFeatures'] = []
+    caps['additionalFeatures'] = ['partner_mac']
     if _glusterEnabled:
         caps['additionalFeatures'].extend(glusterAdditionalFeatures())
     return caps


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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I85267967c9cb1b0a626d91cb1953361ed4de727a
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.6
Gerrit-Owner: Sagi Shnaidman <sshnaidm at redhat.com>


More information about the vdsm-patches mailing list