2014-10-09 16:02:46 -07:00
|
|
|
#!/usr/bin/python
|
|
|
|
#
|
|
|
|
# Copyright 2014 Cumulus Networks, Inc. All rights reserved.
|
|
|
|
# Author: Roopa Prabhu, roopa@cumulusnetworks.com
|
|
|
|
#
|
|
|
|
|
|
|
|
import os
|
2014-12-28 07:07:47 -08:00
|
|
|
import re
|
2016-04-14 14:45:47 -07:00
|
|
|
import ifupdown.ifupdownflags as ifupdownflags
|
2016-05-13 19:52:57 +02:00
|
|
|
from ifupdown.utils import utils
|
2014-10-09 16:02:46 -07:00
|
|
|
from ifupdown.iface import *
|
|
|
|
from utilsbase import *
|
|
|
|
from iproute2 import *
|
|
|
|
from cache import *
|
|
|
|
|
2015-07-22 18:38:07 -04:00
|
|
|
class bondutil(utilsBase):
|
2014-10-09 16:02:46 -07:00
|
|
|
""" This class contains methods to interact with linux kernel bond
|
|
|
|
related interfaces """
|
|
|
|
|
|
|
|
_cache_fill_done = False
|
|
|
|
|
|
|
|
def __init__(self, *args, **kargs):
|
|
|
|
utilsBase.__init__(self, *args, **kargs)
|
2016-04-14 14:45:47 -07:00
|
|
|
if ifupdownflags.flags.CACHE and not self._cache_fill_done:
|
2014-10-09 16:02:46 -07:00
|
|
|
self._bond_linkinfo_fill_all()
|
|
|
|
self._cache_fill_done = True
|
|
|
|
|
|
|
|
def _bond_linkinfo_fill_attrs(self, bondname):
|
|
|
|
try:
|
|
|
|
linkCache.links[bondname]['linkinfo'] = {}
|
|
|
|
except:
|
|
|
|
linkCache.links[bondname] = {'linkinfo': {}}
|
|
|
|
|
|
|
|
try:
|
|
|
|
linkCache.set_attr([bondname, 'linkinfo', 'slaves'],
|
|
|
|
self.read_file_oneline('/sys/class/net/%s/bonding/slaves'
|
|
|
|
%bondname).split())
|
|
|
|
linkCache.set_attr([bondname, 'linkinfo', 'mode'],
|
|
|
|
self.read_file_oneline('/sys/class/net/%s/bonding/mode'
|
|
|
|
%bondname).split()[0])
|
|
|
|
linkCache.set_attr([bondname, 'linkinfo', 'xmit_hash_policy'],
|
|
|
|
self.read_file_oneline(
|
|
|
|
'/sys/class/net/%s/bonding/xmit_hash_policy'
|
|
|
|
%bondname).split()[0])
|
|
|
|
linkCache.set_attr([bondname, 'linkinfo', 'lacp_rate'],
|
|
|
|
self.read_file_oneline('/sys/class/net/%s/bonding/lacp_rate'
|
|
|
|
%bondname).split()[1])
|
2016-03-03 16:39:59 -08:00
|
|
|
linkCache.set_attr([bondname, 'linkinfo', 'ad_actor_sys_prio'],
|
|
|
|
self.read_file_oneline('/sys/class/net/%s/bonding/ad_actor_sys_prio'
|
2014-10-09 16:02:46 -07:00
|
|
|
%bondname))
|
2016-03-03 16:39:59 -08:00
|
|
|
linkCache.set_attr([bondname, 'linkinfo', 'ad_actor_system'],
|
|
|
|
self.read_file_oneline('/sys/class/net/%s/bonding/ad_actor_system'
|
2014-10-09 16:02:46 -07:00
|
|
|
%bondname))
|
2016-02-12 09:18:55 -08:00
|
|
|
linkCache.set_attr([bondname, 'linkinfo', 'lacp_bypass'],
|
|
|
|
self.read_file_oneline('/sys/class/net/%s/bonding/lacp_bypass'
|
|
|
|
%bondname).split()[1])
|
2014-10-09 16:02:46 -07:00
|
|
|
map(lambda x: linkCache.set_attr([bondname, 'linkinfo', x],
|
|
|
|
self.read_file_oneline('/sys/class/net/%s/bonding/%s'
|
|
|
|
%(bondname, x))),
|
|
|
|
['use_carrier', 'miimon', 'min_links', 'num_unsol_na',
|
2016-02-26 07:29:45 -08:00
|
|
|
'num_grat_arp'])
|
2014-10-09 16:02:46 -07:00
|
|
|
except Exception, e:
|
|
|
|
pass
|
|
|
|
|
|
|
|
def _bond_linkinfo_fill_all(self):
|
|
|
|
bondstr = self.read_file_oneline('/sys/class/net/bonding_masters')
|
|
|
|
if not bondstr:
|
|
|
|
return
|
|
|
|
[self._bond_linkinfo_fill_attrs(b) for b in bondstr.split()]
|
|
|
|
|
|
|
|
def _bond_linkinfo_fill(self, bondname, refresh=False):
|
ifupdown2: Allow lacp parameters to be set on 802.3ad bonds
Ticket: CM-10437
Reviewed By: CCR-4480
Testing Done: Created a bond and made sure it's lacp_rate could be set fast or
slow wioth or without specifying the mode.
The current code assumes that for a bond to be in 802.3ad mode the "bond-mode"
parameter has to be specified in the list of bond attributes being set. Only
then will ifupdown2 allow the lacp_rate and lacp_bypass attributes to be set.
But since we have changed the default mode to be 802.3ad, the mode attribute no
longer needs to be specified for a bond to be in 802.3ad mode.
So, instead of doing a check for the configuration attributes to determine the
mode, the linkinfo cache is checked. And the cache is refreshed, just in case
the mode attribute has been specified and just previously been set. The order in
which the attributes are set is fixed for bonds, and the mode is always set
prior to the lacp_rate and lacp_bypass attributes.
Also, while testing this I noticed another assumption about the default value of
an attribute: min_links. A warning is displayed when min_links is not specified
or set to 0, and the mode is set to 802.3ad. Well, now that the default for
min_links is 1 it doesn't have to be specified, even if the mode is set to
802.3ad. So ifupdown2 checks the current state of min_links if it is not
specified as one of the attibutes. If it is 0, either by being specified as an
attribute or not being specified but having that value, and the mode is set to
802.3ad, a warning is displayed.
And there was this other little problem where if a bond already existed in the
linkcache it wouldn't be refreshed, even if the refresh=True parameter was
specified in the _bond_linkinfo_fill function.
2016-04-14 16:03:06 -07:00
|
|
|
if not refresh:
|
|
|
|
try:
|
|
|
|
linkCache.get_attr([bondname, 'linkinfo', 'slaves'])
|
|
|
|
return
|
|
|
|
except:
|
|
|
|
pass
|
2014-10-09 16:02:46 -07:00
|
|
|
bondstr = self.read_file_oneline('/sys/class/net/bonding_masters')
|
|
|
|
if (not bondstr or bondname not in bondstr.split()):
|
|
|
|
raise Exception('bond %s not found' %bondname)
|
|
|
|
self._bond_linkinfo_fill_attrs(bondname)
|
|
|
|
|
|
|
|
def _cache_get(self, attrlist, refresh=False):
|
|
|
|
try:
|
2016-04-14 14:45:47 -07:00
|
|
|
if ifupdownflags.flags.DRYRUN:
|
2014-10-09 16:02:46 -07:00
|
|
|
return None
|
2016-04-14 14:45:47 -07:00
|
|
|
if ifupdownflags.flags.CACHE:
|
2015-07-22 18:38:07 -04:00
|
|
|
if not bondutil._cache_fill_done:
|
2014-10-09 16:02:46 -07:00
|
|
|
self._bond_linkinfo_fill_all()
|
2015-07-22 18:38:07 -04:00
|
|
|
bondutil._cache_fill_done = True
|
2014-10-09 16:02:46 -07:00
|
|
|
return linkCache.get_attr(attrlist)
|
|
|
|
if not refresh:
|
|
|
|
return linkCache.get_attr(attrlist)
|
|
|
|
self._bond_linkinfo_fill(attrlist[0], refresh)
|
|
|
|
return linkCache.get_attr(attrlist)
|
|
|
|
except Exception, e:
|
|
|
|
self.logger.debug('_cache_get(%s) : [%s]'
|
|
|
|
%(str(attrlist), str(e)))
|
|
|
|
pass
|
|
|
|
return None
|
|
|
|
|
|
|
|
def _cache_check(self, attrlist, value, refresh=False):
|
|
|
|
try:
|
|
|
|
attrvalue = self._cache_get(attrlist, refresh)
|
|
|
|
if attrvalue and attrvalue == value:
|
|
|
|
return True
|
|
|
|
except Exception, e:
|
|
|
|
self.logger.debug('_cache_check(%s) : [%s]'
|
|
|
|
%(str(attrlist), str(e)))
|
|
|
|
pass
|
|
|
|
return False
|
|
|
|
|
|
|
|
def _cache_update(self, attrlist, value):
|
2016-04-14 14:45:47 -07:00
|
|
|
if ifupdownflags.flags.DRYRUN: return
|
2014-10-09 16:02:46 -07:00
|
|
|
try:
|
|
|
|
if attrlist[-1] == 'slaves':
|
|
|
|
linkCache.add_to_attrlist(attrlist, value)
|
|
|
|
return
|
|
|
|
linkCache.add_attr(attrlist, value)
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
|
|
|
|
def _cache_delete(self, attrlist, value=None):
|
2016-04-14 14:45:47 -07:00
|
|
|
if ifupdownflags.flags.DRYRUN: return
|
2014-10-09 16:02:46 -07:00
|
|
|
try:
|
|
|
|
if attrlist[-1] == 'slaves':
|
|
|
|
linkCache.remove_from_attrlist(attrlist, value)
|
|
|
|
return
|
|
|
|
linkCache.del_attr(attrlist)
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
|
|
|
|
def _cache_invalidate(self):
|
2016-04-14 14:45:47 -07:00
|
|
|
if ifupdownflags.flags.DRYRUN: return
|
2014-10-09 16:02:46 -07:00
|
|
|
linkCache.invalidate()
|
|
|
|
|
|
|
|
def set_attrs(self, bondname, attrdict, prehook):
|
|
|
|
for attrname, attrval in attrdict.items():
|
|
|
|
if (self._cache_check([bondname, 'linkinfo',
|
|
|
|
attrname], attrval)):
|
|
|
|
continue
|
|
|
|
if (attrname == 'mode' or attrname == 'xmit_hash_policy' or
|
|
|
|
attrname == 'lacp_rate' or attrname == 'min_links'):
|
|
|
|
if prehook:
|
|
|
|
prehook(bondname)
|
|
|
|
try:
|
2015-08-10 14:17:46 -07:00
|
|
|
if ((attrname not in ['lacp_rate',
|
2016-02-12 09:18:55 -08:00
|
|
|
'lacp_bypass']) or
|
ifupdown2: Allow lacp parameters to be set on 802.3ad bonds
Ticket: CM-10437
Reviewed By: CCR-4480
Testing Done: Created a bond and made sure it's lacp_rate could be set fast or
slow wioth or without specifying the mode.
The current code assumes that for a bond to be in 802.3ad mode the "bond-mode"
parameter has to be specified in the list of bond attributes being set. Only
then will ifupdown2 allow the lacp_rate and lacp_bypass attributes to be set.
But since we have changed the default mode to be 802.3ad, the mode attribute no
longer needs to be specified for a bond to be in 802.3ad mode.
So, instead of doing a check for the configuration attributes to determine the
mode, the linkinfo cache is checked. And the cache is refreshed, just in case
the mode attribute has been specified and just previously been set. The order in
which the attributes are set is fixed for bonds, and the mode is always set
prior to the lacp_rate and lacp_bypass attributes.
Also, while testing this I noticed another assumption about the default value of
an attribute: min_links. A warning is displayed when min_links is not specified
or set to 0, and the mode is set to 802.3ad. Well, now that the default for
min_links is 1 it doesn't have to be specified, even if the mode is set to
802.3ad. So ifupdown2 checks the current state of min_links if it is not
specified as one of the attibutes. If it is 0, either by being specified as an
attribute or not being specified but having that value, and the mode is set to
802.3ad, a warning is displayed.
And there was this other little problem where if a bond already existed in the
linkcache it wouldn't be refreshed, even if the refresh=True parameter was
specified in the _bond_linkinfo_fill function.
2016-04-14 16:03:06 -07:00
|
|
|
self._cache_check([bondname, 'linkinfo', 'mode'], '802.3ad',
|
|
|
|
True)):
|
2015-08-10 14:17:46 -07:00
|
|
|
self.write_file('/sys/class/net/%s/bonding/%s'
|
|
|
|
%(bondname, attrname), attrval)
|
2014-10-09 16:02:46 -07:00
|
|
|
except Exception, e:
|
2016-04-14 14:45:47 -07:00
|
|
|
if ifupdownflags.flags.FORCE:
|
2014-10-09 16:02:46 -07:00
|
|
|
self.logger.warn(str(e))
|
|
|
|
pass
|
|
|
|
else:
|
|
|
|
raise
|
|
|
|
|
|
|
|
def set_use_carrier(self, bondname, use_carrier):
|
|
|
|
if not use_carrier or (use_carrier != '0' and use_carrier != '1'):
|
|
|
|
return
|
|
|
|
if (self._cache_check([bondname, 'linkinfo', 'use_carrier'],
|
|
|
|
use_carrier)):
|
|
|
|
return
|
|
|
|
self.write_file('/sys/class/net/%s' %bondname +
|
|
|
|
'/bonding/use_carrier', use_carrier)
|
|
|
|
self._cache_update([bondname, 'linkinfo',
|
|
|
|
'use_carrier'], use_carrier)
|
|
|
|
|
|
|
|
def get_use_carrier(self, bondname):
|
|
|
|
return self._cache_get([bondname, 'linkinfo', 'use_carrier'])
|
|
|
|
|
|
|
|
def set_xmit_hash_policy(self, bondname, hash_policy, prehook=None):
|
|
|
|
valid_values = ['layer2', 'layer3+4', 'layer2+3']
|
|
|
|
if not hash_policy:
|
|
|
|
return
|
|
|
|
if hash_policy not in valid_values:
|
|
|
|
raise Exception('invalid hash policy value %s' %hash_policy)
|
|
|
|
if (self._cache_check([bondname, 'linkinfo', 'xmit_hash_policy'],
|
|
|
|
hash_policy)):
|
|
|
|
return
|
|
|
|
if prehook:
|
|
|
|
prehook(bondname)
|
|
|
|
self.write_file('/sys/class/net/%s' %bondname +
|
|
|
|
'/bonding/xmit_hash_policy', hash_policy)
|
|
|
|
self._cache_update([bondname, 'linkinfo', 'xmit_hash_policy'],
|
|
|
|
hash_policy)
|
|
|
|
|
|
|
|
def get_xmit_hash_policy(self, bondname):
|
|
|
|
return self._cache_get([bondname, 'linkinfo', 'xmit_hash_policy'])
|
|
|
|
|
|
|
|
def set_miimon(self, bondname, miimon):
|
|
|
|
if (self._cache_check([bondname, 'linkinfo', 'miimon'],
|
|
|
|
miimon)):
|
|
|
|
return
|
|
|
|
self.write_file('/sys/class/net/%s' %bondname +
|
|
|
|
'/bonding/miimon', miimon)
|
|
|
|
self._cache_update([bondname, 'linkinfo', 'miimon'], miimon)
|
|
|
|
|
|
|
|
def get_miimon(self, bondname):
|
|
|
|
return self._cache_get([bondname, 'linkinfo', 'miimon'])
|
|
|
|
|
|
|
|
def set_mode(self, bondname, mode, prehook=None):
|
|
|
|
valid_modes = ['balance-rr', 'active-backup', 'balance-xor',
|
|
|
|
'broadcast', '802.3ad', 'balance-tlb', 'balance-alb']
|
|
|
|
if not mode:
|
|
|
|
return
|
|
|
|
if mode not in valid_modes:
|
|
|
|
raise Exception('invalid mode %s' %mode)
|
|
|
|
if (self._cache_check([bondname, 'linkinfo', 'mode'],
|
|
|
|
mode)):
|
|
|
|
return
|
|
|
|
if prehook:
|
|
|
|
prehook(bondname)
|
|
|
|
self.write_file('/sys/class/net/%s' %bondname + '/bonding/mode', mode)
|
|
|
|
self._cache_update([bondname, 'linkinfo', 'mode'], mode)
|
|
|
|
|
|
|
|
def get_mode(self, bondname):
|
|
|
|
return self._cache_get([bondname, 'linkinfo', 'mode'])
|
|
|
|
|
|
|
|
def set_lacp_rate(self, bondname, lacp_rate, prehook=None, posthook=None):
|
|
|
|
if not lacp_rate or (lacp_rate != '0' and lacp_rate != '1'):
|
|
|
|
return
|
|
|
|
if (self._cache_check([bondname, 'linkinfo', 'lacp_rate'],
|
|
|
|
lacp_rate)):
|
|
|
|
return
|
|
|
|
if prehook:
|
|
|
|
prehook(bondname)
|
|
|
|
try:
|
|
|
|
self.write_file('/sys/class/net/%s' %bondname +
|
|
|
|
'/bonding/lacp_rate', lacp_rate)
|
|
|
|
except:
|
|
|
|
raise
|
|
|
|
finally:
|
|
|
|
if posthook:
|
|
|
|
prehook(bondname)
|
|
|
|
self._cache_update([bondname, 'linkinfo',
|
|
|
|
'lacp_rate'], lacp_rate)
|
|
|
|
|
|
|
|
def get_lacp_rate(self, bondname):
|
|
|
|
return self._cache_get([bondname, 'linkinfo', 'lacp_rate'])
|
|
|
|
|
2016-02-26 07:29:45 -08:00
|
|
|
def set_lacp_bypass_allow(self, bondname, allow, prehook=None, posthook=None):
|
2016-05-12 16:00:41 +02:00
|
|
|
if (self._cache_check([bondname, 'linkinfo', 'lacp_bypass'], allow)):
|
2014-10-09 16:02:46 -07:00
|
|
|
return
|
|
|
|
if prehook:
|
|
|
|
prehook(bondname)
|
|
|
|
try:
|
|
|
|
self.write_file('/sys/class/net/%s' %bondname +
|
2016-02-26 07:29:45 -08:00
|
|
|
'/bonding/lacp_bypass', allow)
|
2014-10-09 16:02:46 -07:00
|
|
|
except:
|
|
|
|
raise
|
|
|
|
finally:
|
|
|
|
if posthook:
|
|
|
|
posthook(bondname)
|
|
|
|
self._cache_update([bondname, 'linkinfo',
|
2016-02-26 07:29:45 -08:00
|
|
|
'lacp_bypass'], allow)
|
2014-10-09 16:02:46 -07:00
|
|
|
|
2016-02-26 07:29:45 -08:00
|
|
|
def get_lacp_bypass_allow(self, bondname):
|
|
|
|
return self._cache_get([bondname, 'linkinfo', 'lacp_bypass'])
|
2014-10-09 16:02:46 -07:00
|
|
|
|
|
|
|
def set_min_links(self, bondname, min_links, prehook=None):
|
|
|
|
if (self._cache_check([bondname, 'linkinfo', 'min_links'],
|
|
|
|
min_links)):
|
|
|
|
return
|
|
|
|
if prehook:
|
|
|
|
prehook(bondname)
|
|
|
|
self.write_file('/sys/class/net/%s/bonding/min_links' %bondname,
|
|
|
|
min_links)
|
|
|
|
self._cache_update([bondname, 'linkinfo', 'min_links'], min_links)
|
|
|
|
|
|
|
|
def get_min_links(self, bondname):
|
|
|
|
return self._cache_get([bondname, 'linkinfo', 'min_links'])
|
|
|
|
|
2016-03-03 16:39:59 -08:00
|
|
|
def get_ad_actor_system(self, bondname):
|
|
|
|
return self._cache_get([bondname, 'linkinfo', 'ad_actor_system'])
|
2014-10-09 16:02:46 -07:00
|
|
|
|
2016-03-03 16:39:59 -08:00
|
|
|
def get_ad_actor_sys_prio(self, bondname):
|
|
|
|
return self._cache_get([bondname, 'linkinfo', 'ad_actor_sys_prio'])
|
|
|
|
|
|
|
|
def get_num_unsol_na(self, bondname):
|
|
|
|
return self._cache_get([bondname, 'linkinfo', 'num_unsol_na'])
|
|
|
|
|
|
|
|
def get_num_grat_arp(self, bondname):
|
|
|
|
return self._cache_get([bondname, 'linkinfo', 'num_grat_arp'])
|
2014-10-09 16:02:46 -07:00
|
|
|
|
|
|
|
def enslave_slave(self, bondname, slave, prehook=None, posthook=None):
|
|
|
|
slaves = self._cache_get([bondname, 'linkinfo', 'slaves'])
|
|
|
|
if slaves and slave in slaves: return
|
|
|
|
if prehook:
|
|
|
|
prehook(slave)
|
|
|
|
self.write_file('/sys/class/net/%s' %bondname +
|
|
|
|
'/bonding/slaves', '+' + slave)
|
|
|
|
if posthook:
|
|
|
|
posthook(slave)
|
|
|
|
self._cache_update([bondname, 'linkinfo', 'slaves'], slave)
|
|
|
|
|
|
|
|
def remove_slave(self, bondname, slave):
|
|
|
|
slaves = self._cache_get([bondname, 'linkinfo', 'slaves'])
|
|
|
|
if slave not in slaves:
|
|
|
|
return
|
|
|
|
sysfs_bond_path = ('/sys/class/net/%s' %bondname +
|
|
|
|
'/bonding/slaves')
|
|
|
|
if not os.path.exists(sysfs_bond_path):
|
|
|
|
return
|
|
|
|
self.write_file(sysfs_bond_path, '-' + slave)
|
|
|
|
self._cache_delete([bondname, 'linkinfo', 'slaves'], slave)
|
|
|
|
|
|
|
|
def remove_slaves_all(self, bondname):
|
2016-05-10 17:42:48 +02:00
|
|
|
if not self._cache_get([bondname, 'linkinfo', 'slaves']):
|
2014-10-09 16:02:46 -07:00
|
|
|
return
|
|
|
|
slaves = None
|
|
|
|
sysfs_bond_path = ('/sys/class/net/%s' %bondname +
|
|
|
|
'/bonding/slaves')
|
|
|
|
ipcmd = iproute2()
|
|
|
|
try:
|
2016-05-13 19:52:57 +02:00
|
|
|
with open(sysfs_bond_path, 'r') as f:
|
|
|
|
slaves = f.readline().strip().split()
|
2014-10-09 16:02:46 -07:00
|
|
|
except IOError, e:
|
|
|
|
raise Exception('error reading slaves of bond %s' %bondname
|
|
|
|
+ '(' + str(e) + ')')
|
|
|
|
for slave in slaves:
|
|
|
|
ipcmd.ip_link_down(slave)
|
|
|
|
try:
|
|
|
|
self.remove_slave(bondname, slave)
|
|
|
|
except Exception, e:
|
2016-04-14 14:45:47 -07:00
|
|
|
if not ifupdownflags.flags.FORCE:
|
2014-10-09 16:02:46 -07:00
|
|
|
raise Exception('error removing slave %s'
|
|
|
|
%slave + ' from bond %s' %bondname +
|
|
|
|
'(%s)' %str(e))
|
|
|
|
else:
|
|
|
|
pass
|
|
|
|
self._cache_del([bondname, 'linkinfo', 'slaves'])
|
|
|
|
|
|
|
|
def load_bonding_module(self):
|
2016-05-13 19:52:57 +02:00
|
|
|
return utils.exec_command('modprobe -q bonding')
|
2014-10-09 16:02:46 -07:00
|
|
|
|
|
|
|
def create_bond(self, bondname):
|
|
|
|
if self.bond_exists(bondname):
|
|
|
|
return
|
|
|
|
sysfs_net = '/sys/class/net/'
|
|
|
|
sysfs_bonding_masters = sysfs_net + 'bonding_masters'
|
|
|
|
if not os.path.exists(sysfs_bonding_masters):
|
|
|
|
self.logger.debug('loading bonding driver')
|
|
|
|
self.load_bonding_module()
|
|
|
|
self.write_file(sysfs_bonding_masters, '+' + bondname)
|
|
|
|
self._cache_update([bondname], {})
|
|
|
|
|
|
|
|
def delete_bond(self, bondname):
|
|
|
|
if not os.path.exists('/sys/class/net/%s' %bondname):
|
|
|
|
return
|
|
|
|
self.write_file('/sys/class/net/bonding_masters', '-' + bondname)
|
|
|
|
self._cache_delete([bondname])
|
|
|
|
|
|
|
|
def unset_master(self, bondname):
|
|
|
|
print 'Do nothing yet'
|
|
|
|
return 0
|
|
|
|
|
|
|
|
def get_slaves(self, bondname):
|
|
|
|
slaves = self._cache_get([bondname, 'linkinfo', 'slaves'])
|
|
|
|
if slaves:
|
|
|
|
return list(slaves)
|
|
|
|
slavefile = '/sys/class/net/%s/bonding/slaves' %bondname
|
|
|
|
if os.path.exists(slavefile):
|
|
|
|
buf = self.read_file_oneline(slavefile)
|
|
|
|
if buf:
|
|
|
|
slaves = buf.split()
|
|
|
|
if not slaves:
|
|
|
|
return slaves
|
|
|
|
self._cache_update([bondname, 'linkinfo', 'slaves'], slaves)
|
|
|
|
return list(slaves)
|
|
|
|
|
|
|
|
def bond_slave_exists(self, bond, slave):
|
|
|
|
slaves = self.get_slaves(bond)
|
|
|
|
if not slaves: return False
|
|
|
|
return slave in slaves
|
|
|
|
|
|
|
|
def bond_exists(self, bondname):
|
|
|
|
return os.path.exists('/sys/class/net/%s/bonding' %bondname)
|