1
0
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:
Julien Fortin
2016-05-13 19:52:57 +02:00
parent afe5125163
commit a193d8d1c0
18 changed files with 343 additions and 464 deletions

View File

@@ -10,6 +10,7 @@ try:
from ipaddr import IPNetwork
from sets import Set
from ifupdown.iface import *
from ifupdown.utils import utils
from ifupdownaddons.utilsbase import *
from ifupdownaddons.modulebase import moduleBase
from ifupdownaddons.iproute2 import iproute2
@@ -114,7 +115,7 @@ class ethtool(moduleBase,utilsBase):
# something. this prevents unconfigured ifaces from resetting to default
self.ifaceobjs_modified_configs.append(ifaceobj.name)
cmd = 'ethtool -s %s %s' %(ifaceobj.name, cmd)
self.exec_command(cmd)
utils.exec_command(cmd)
except Exception, e:
self.log_error('%s: %s' %(ifaceobj.name, str(e)), ifaceobj)
else:
@@ -188,16 +189,16 @@ class ethtool(moduleBase,utilsBase):
running_attr = None
try:
if attr == 'autoneg':
output=self.exec_commandl(['ethtool', ifaceobj.name])
output = utils.exec_commandl(['ethtool', ifaceobj.name])
running_attr = self.get_autoneg(ethtool_output=output)
else:
running_attr = self.read_file_oneline('/sys/class/net/%s/%s' % \
(ifaceobj.name, attr))
except:
except Exception as e:
# for nonexistent interfaces, we get an error (rc = 256 or 19200)
self.logger.debug('ethtool: problems calling ethtool or reading'
' /sys/class on iface %s for attr %s' % \
(ifaceobj.name,attr))
' /sys/class on iface %s for attr %s: %s' %
(ifaceobj.name, attr, str(e)))
return running_attr