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