mirror of
https://github.com/CumulusNetworks/ifupdown2.git
synced 2024-05-06 15:54:50 +00:00
performance fix: better handling fd to allow subprocess.close_fds=False and code re-organisation
Ticket: None Reviewed By: CCR-4692 Testing Done: smoke + scale tests If called with close_fds=True the subprocess module will try to close every fd from 3 to MAXFD before executing the specified command. This is done in Python not even with a C-implementation which truly affecting performances. This patch aims to better handle the file descriptor used by ifupdown2. Either by closing them after use or by setting the close-on-exec flag for the file descriptor, which causes the file descriptor to be automatically (and atomically) closed when any of the exec-family functions succeed. With the actual patch all tests are passing, I can't think of any future issue but if any a possible future modification might be to use the parameter 'preexec_fn', which allows us to set function which will be executed in the child process before executing the command line. We can always manually close any remaining open file descriptors with something like: >>> os.listdir('/proc/self/fd/') ['0', '1', '2', ‘3’, etc..] >>> for fd in os.listdir('/proc/self/fd/') >>> if int(fd) > 2: >>> os.close(fd) This patch is also totally re-organising the use of subprocesses. By removing all subprocess code redundancy.
This commit is contained in:
@@ -9,6 +9,7 @@ from utilsbase import *
|
||||
import os
|
||||
import re
|
||||
import logging
|
||||
from ifupdown.utils import utils
|
||||
import ifupdown.ifupdownflags as ifupdownflags
|
||||
from cache import *
|
||||
|
||||
@@ -63,7 +64,7 @@ class brctl(utilsBase):
|
||||
battrs = {}
|
||||
bports = {}
|
||||
|
||||
brout = self.exec_command('/sbin/brctl showstp %s' %bridgename)
|
||||
brout = utils.exec_command('/sbin/brctl showstp %s' % bridgename)
|
||||
chunks = re.split(r'\n\n', brout, maxsplit=0, flags=re.MULTILINE)
|
||||
|
||||
try:
|
||||
@@ -133,9 +134,9 @@ class brctl(utilsBase):
|
||||
except:
|
||||
pass
|
||||
if not bridgename:
|
||||
brctlout = self.exec_command('/sbin/brctl show')
|
||||
brctlout = utils.exec_command('/sbin/brctl show')
|
||||
else:
|
||||
brctlout = self.exec_command('/sbin/brctl show ' + bridgename)
|
||||
brctlout = utils.exec_command('/sbin/brctl show %s' % bridgename)
|
||||
if not brctlout:
|
||||
return
|
||||
|
||||
@@ -202,13 +203,13 @@ class brctl(utilsBase):
|
||||
def create_bridge(self, bridgename):
|
||||
if self.bridge_exists(bridgename):
|
||||
return
|
||||
self.exec_command('/sbin/brctl addbr %s' %bridgename)
|
||||
utils.exec_command('/sbin/brctl addbr %s' % bridgename)
|
||||
self._cache_update([bridgename], {})
|
||||
|
||||
def delete_bridge(self, bridgename):
|
||||
if not self.bridge_exists(bridgename):
|
||||
return
|
||||
self.exec_command('/sbin/brctl delbr %s' %bridgename)
|
||||
utils.exec_command('/sbin/brctl delbr %s' % bridgename)
|
||||
self._cache_invalidate()
|
||||
|
||||
def add_bridge_port(self, bridgename, bridgeportname):
|
||||
@@ -216,8 +217,8 @@ class brctl(utilsBase):
|
||||
ports = self._cache_get([bridgename, 'linkinfo', 'ports'])
|
||||
if ports and ports.get(bridgeportname):
|
||||
return
|
||||
self.exec_command('/sbin/brctl addif ' + bridgename + ' ' +
|
||||
bridgeportname)
|
||||
utils.exec_command('/sbin/brctl addif %s %s' %
|
||||
(bridgename, bridgeportname))
|
||||
self._cache_update([bridgename, 'linkinfo', 'ports',
|
||||
bridgeportname], {})
|
||||
|
||||
@@ -226,8 +227,8 @@ class brctl(utilsBase):
|
||||
ports = self._cache_get([bridgename, 'linkinfo', 'ports'])
|
||||
if not ports or not ports.get(bridgeportname):
|
||||
return
|
||||
self.exec_command('/sbin/brctl delif ' + bridgename + ' ' +
|
||||
bridgeportname)
|
||||
utils.exec_command('/sbin/brctl delif %s %s' %
|
||||
(bridgename, bridgeportname))
|
||||
self._cache_delete([bridgename, 'linkinfo', 'ports',
|
||||
'bridgeportname'])
|
||||
|
||||
@@ -240,16 +241,19 @@ class brctl(utilsBase):
|
||||
curval = portattrs.get(k)
|
||||
if curval and curval == v:
|
||||
continue
|
||||
self.exec_command('/sbin/brctl set%s %s %s %s'
|
||||
%(k, bridgename, bridgeportname, v))
|
||||
utils.exec_command('/sbin/brctl set%s %s %s %s' %
|
||||
(k, bridgename, bridgeportname, v))
|
||||
|
||||
def set_bridgeport_attr(self, bridgename, bridgeportname,
|
||||
attrname, attrval):
|
||||
if self._cache_check([bridgename, 'linkinfo', 'ports',
|
||||
bridgeportname, attrname], attrval):
|
||||
return
|
||||
self.exec_command('/sbin/brctl set%s %s %s %s' %(attrname, bridgename,
|
||||
bridgeportname, attrval))
|
||||
utils.exec_command('/sbin/brctl set%s %s %s %s' %
|
||||
(attrname,
|
||||
bridgename,
|
||||
bridgeportname,
|
||||
attrval))
|
||||
|
||||
def set_bridge_attrs(self, bridgename, attrdict):
|
||||
for k, v in attrdict.iteritems():
|
||||
@@ -258,8 +262,8 @@ class brctl(utilsBase):
|
||||
if self._cache_check([bridgename, 'linkinfo', k], v):
|
||||
continue
|
||||
try:
|
||||
self.exec_command('/sbin/brctl set%s %s %s'
|
||||
%(k, bridgename, v))
|
||||
cmd = '/sbin/brctl set%s %s %s' % (k, bridgename, v)
|
||||
utils.exec_command(cmd)
|
||||
except Exception, e:
|
||||
self.logger.warn('%s: %s' %(bridgename, str(e)))
|
||||
pass
|
||||
@@ -267,8 +271,8 @@ class brctl(utilsBase):
|
||||
def set_bridge_attr(self, bridgename, attrname, attrval):
|
||||
if self._cache_check([bridgename, 'linkinfo', attrname], attrval):
|
||||
return
|
||||
self.exec_command('/sbin/brctl set%s %s %s'
|
||||
%(attrname, bridgename, attrval))
|
||||
utils.exec_command('/sbin/brctl set%s %s %s' %
|
||||
(attrname, bridgename, attrval))
|
||||
|
||||
def get_bridge_attrs(self, bridgename):
|
||||
return self._cache_get([bridgename, 'linkinfo'])
|
||||
@@ -282,7 +286,7 @@ class brctl(utilsBase):
|
||||
bridgeportname, attrname])
|
||||
|
||||
def set_stp(self, bridge, stp_state):
|
||||
self.exec_command('/sbin/brctl stp ' + bridge + ' ' + stp_state)
|
||||
utils.exec_command('/sbin/brctl stp %s %s' % (bridge, stp_state))
|
||||
|
||||
def get_stp(self, bridge):
|
||||
sysfs_stpstate = '/sys/class/net/%s/bridge/stp_state' %bridge
|
||||
@@ -314,22 +318,21 @@ class brctl(utilsBase):
|
||||
return preprocess_func(value)
|
||||
|
||||
def set_ageing(self, bridge, ageing):
|
||||
self.exec_command('/sbin/brctl setageing ' + bridge + ' ' + ageing)
|
||||
utils.exec_command('/sbin/brctl setageing %s %s' % (bridge, ageing))
|
||||
|
||||
def get_ageing(self, bridge):
|
||||
return self.read_value_from_sysfs('/sys/class/net/%s/bridge/ageing_time'
|
||||
%bridge, self.conv_value_to_user)
|
||||
|
||||
def set_bridgeprio(self, bridge, bridgeprio):
|
||||
self.exec_command('/sbin/brctl setbridgeprio ' + bridge + ' ' +
|
||||
bridgeprio)
|
||||
def set_bridgeprio(self, bridge, prio):
|
||||
utils.exec_command('/sbin/brctl setbridgeprio %s %s' % (bridge, prio))
|
||||
|
||||
def get_bridgeprio(self, bridge):
|
||||
return self.read_file_oneline(
|
||||
'/sys/class/net/%s/bridge/priority' %bridge)
|
||||
|
||||
def set_fd(self, bridge, fd):
|
||||
self.exec_command('/sbin/brctl setfd ' + bridge + ' ' + fd)
|
||||
utils.exec_command('/sbin/brctl setfd %s %s' % (bridge, fd))
|
||||
|
||||
def get_fd(self, bridge):
|
||||
return self.read_value_from_sysfs(
|
||||
@@ -341,51 +344,51 @@ class brctl(utilsBase):
|
||||
raise Exception('set_gcint not implemented')
|
||||
|
||||
def set_hello(self, bridge, hello):
|
||||
self.exec_command('/sbin/brctl sethello ' + bridge + ' ' + hello)
|
||||
utils.exec_command('/sbin/brctl sethello %s %s' % (bridge, hello))
|
||||
|
||||
def get_hello(self, bridge):
|
||||
return self.read_value_from_sysfs('/sys/class/net/%s/bridge/hello_time'
|
||||
%bridge, self.conv_value_to_user)
|
||||
|
||||
def set_maxage(self, bridge, maxage):
|
||||
self.exec_command('/sbin/brctl setmaxage ' + bridge + ' ' + maxage)
|
||||
utils.exec_command('/sbin/brctl setmaxage %s %s' % (bridge, maxage))
|
||||
|
||||
def get_maxage(self, bridge):
|
||||
return self.read_value_from_sysfs('/sys/class/net/%s/bridge/max_age'
|
||||
%bridge, self.conv_value_to_user)
|
||||
|
||||
def set_pathcost(self, bridge, port, pathcost):
|
||||
self.exec_command('/sbin/brctl setpathcost %s' %bridge + ' %s' %port +
|
||||
' %s' %pathcost)
|
||||
utils.exec_command('/sbin/brctl setpathcost %s %s %s' %
|
||||
(bridge, port, pathcost))
|
||||
|
||||
def get_pathcost(self, bridge, port):
|
||||
return self.read_file_oneline('/sys/class/net/%s/brport/path_cost'
|
||||
%port)
|
||||
|
||||
def set_portprio(self, bridge, port, prio):
|
||||
self.exec_command('/sbin/brctl setportprio %s' %bridge + ' %s' %port +
|
||||
' %s' %prio)
|
||||
utils.exec_command('/sbin/brctl setportprio %s %s %s' %
|
||||
(bridge, port, prio))
|
||||
|
||||
def get_portprio(self, bridge, port):
|
||||
return self.read_file_oneline('/sys/class/net/%s/brport/priority'
|
||||
%port)
|
||||
|
||||
def set_hashmax(self, bridge, hashmax):
|
||||
self.exec_command('/sbin/brctl sethashmax %s' %bridge + ' %s' %hashmax)
|
||||
utils.exec_command('/sbin/brctl sethashmax %s %s' % (bridge, hashmax))
|
||||
|
||||
def get_hashmax(self, bridge):
|
||||
return self.read_file_oneline('/sys/class/net/%s/bridge/hash_max'
|
||||
%bridge)
|
||||
|
||||
def set_hashel(self, bridge, hashel):
|
||||
self.exec_command('/sbin/brctl sethashel %s' %bridge + ' %s' %hashel)
|
||||
utils.exec_command('/sbin/brctl sethashel %s %s' % (bridge, hashel))
|
||||
|
||||
def get_hashel(self, bridge):
|
||||
return self.read_file_oneline('/sys/class/net/%s/bridge/hash_elasticity'
|
||||
%bridge)
|
||||
|
||||
def set_mclmc(self, bridge, mclmc):
|
||||
self.exec_command('/sbin/brctl setmclmc %s' %bridge + ' %s' %mclmc)
|
||||
utils.exec_command('/sbin/brctl setmclmc %s %s' % (bridge, mclmc))
|
||||
|
||||
def get_mclmc(self, bridge):
|
||||
return self.read_file_oneline(
|
||||
@@ -393,24 +396,21 @@ class brctl(utilsBase):
|
||||
%bridge)
|
||||
|
||||
def set_mcrouter(self, bridge, mcrouter):
|
||||
self.exec_command('/sbin/brctl setmcrouter %s' %bridge +
|
||||
' %s' %mcrouter)
|
||||
utils.exec_command('/sbin/brctl setmcrouter %s %s' % (bridge, mcrouter))
|
||||
|
||||
def get_mcrouter(self, bridge):
|
||||
return self.read_file_oneline(
|
||||
'/sys/class/net/%s/bridge/multicast_router' %bridge)
|
||||
|
||||
def set_mcsnoop(self, bridge, mcsnoop):
|
||||
self.exec_command('/sbin/brctl setmcsnoop %s' %bridge +
|
||||
' %s' %mcsnoop)
|
||||
utils.exec_command('/sbin/brctl setmcsnoop %s %s' % (bridge, mcsnoop))
|
||||
|
||||
def get_mcsnoop(self, bridge):
|
||||
return self.read_file_oneline(
|
||||
'/sys/class/net/%s/bridge/multicast_snooping' %bridge)
|
||||
|
||||
def set_mcsqc(self, bridge, mcsqc):
|
||||
self.exec_command('/sbin/brctl setmcsqc %s' %bridge +
|
||||
' %s' %mcsqc)
|
||||
utils.exec_command('/sbin/brctl setmcsqc %s %s' % (bridge, mcsqc))
|
||||
|
||||
def get_mcsqc(self, bridge):
|
||||
return self.read_file_oneline(
|
||||
@@ -418,8 +418,8 @@ class brctl(utilsBase):
|
||||
%bridge)
|
||||
|
||||
def set_mcqifaddr(self, bridge, mcqifaddr):
|
||||
self.exec_command('/sbin/brctl setmcqifaddr %s' %bridge +
|
||||
' %s' %mcqifaddr)
|
||||
utils.exec_command('/sbin/brctl setmcqifaddr %s %s' %
|
||||
(bridge, mcqifaddr))
|
||||
|
||||
def get_mcqifaddr(self, bridge):
|
||||
return self.read_file_oneline(
|
||||
@@ -427,8 +427,8 @@ class brctl(utilsBase):
|
||||
%bridge)
|
||||
|
||||
def set_mcquerier(self, bridge, mcquerier):
|
||||
self.exec_command('/sbin/brctl setmcquerier %s' %bridge +
|
||||
' %s' %mcquerier)
|
||||
utils.exec_command('/sbin/brctl setmcquerier %s %s' %
|
||||
(bridge, mcquerier))
|
||||
|
||||
def get_mcquerier(self, bridge):
|
||||
return self.read_file_oneline(
|
||||
@@ -448,15 +448,15 @@ class brctl(utilsBase):
|
||||
self.logger.warn('mcqv4src \'%s\' invalid IPv4 address' %mcquerier)
|
||||
return
|
||||
|
||||
self.exec_command('/sbin/brctl setmcqv4src %s' %bridge +
|
||||
' %d %s' %(vlan, mcquerier))
|
||||
utils.exec_command('/sbin/brctl setmcqv4src %s %d %s' %
|
||||
(bridge, vlan, mcquerier))
|
||||
|
||||
def del_mcqv4src(self, bridge, vlan):
|
||||
self.exec_command('/sbin/brctl delmcqv4src %s %d' %(bridge, vlan))
|
||||
utils.exec_command('/sbin/brctl delmcqv4src %s %d' % (bridge, vlan))
|
||||
|
||||
def get_mcqv4src(self, bridge, vlan=None):
|
||||
mcqv4src = {}
|
||||
mcqout = self.exec_command('/sbin/brctl showmcqv4src %s' %bridge)
|
||||
mcqout = utils.exec_command('/sbin/brctl showmcqv4src %s' % bridge)
|
||||
if not mcqout: return None
|
||||
mcqlines = mcqout.splitlines()
|
||||
for l in mcqlines[1:]:
|
||||
@@ -470,8 +470,7 @@ class brctl(utilsBase):
|
||||
return mcqv4src
|
||||
|
||||
def set_mclmi(self, bridge, mclmi):
|
||||
self.exec_command('/sbin/brctl setmclmi %s' %bridge +
|
||||
' %s' %mclmi)
|
||||
utils.exec_command('/sbin/brctl setmclmi %s %s' % (bridge, mclmi))
|
||||
|
||||
def get_mclmi(self, bridge):
|
||||
return self.read_file_oneline(
|
||||
@@ -479,8 +478,7 @@ class brctl(utilsBase):
|
||||
%bridge)
|
||||
|
||||
def set_mcmi(self, bridge, mcmi):
|
||||
self.exec_command('/sbin/brctl setmcmi %s' %bridge +
|
||||
' %s' %mcmi)
|
||||
utils.exec_command('/sbin/brctl setmcmi %s %s' % (bridge, mcmi))
|
||||
|
||||
def get_mcmi(self, bridge):
|
||||
return self.read_file_oneline(
|
||||
|
Reference in New Issue
Block a user