Avoid unnecessary use of rootwrap for some network commands

Every time we run something as root with rootwrap, it takes about
ten times longer (setup-wise anyway). For things that don't need
to be run as root, we should avoid this hit. Nova network does
this a lot and is also slow enough to cause trouble, so this
patch attempts to address that for a few situations.

Related-bug: #1257626

Change-Id: Idc26776bf96ccfd9f50383e9d40aa47397d4e2cf
This commit is contained in:
Dan Smith 2014-01-09 09:24:08 -08:00
parent 8b9f924306
commit 831da3df61
3 changed files with 22 additions and 16 deletions

View File

@ -809,12 +809,19 @@ def clean_conntrack(fixed_ip):
LOG.exception(_('Error deleting conntrack entries for %s'), fixed_ip)
def _enable_ipv4_forwarding():
sysctl_key = 'net.ipv4.ip_forward'
stdout, stderr = _execute('sysctl', '-n', sysctl_key)
if stdout.strip() is not '1':
_execute('sysctl', '-w', '%s=1' % sysctl_key, run_as_root=True)
@utils.synchronized('lock_gateway', external=True)
def initialize_gateway_device(dev, network_ref):
if not network_ref:
return
_execute('sysctl', '-w', 'net.ipv4.ip_forward=1', run_as_root=True)
_enable_ipv4_forwarding()
# NOTE(vish): The ip for dnsmasq has to be the first address on the
# bridge for it to respond to reqests properly
@ -823,7 +830,7 @@ def initialize_gateway_device(dev, network_ref):
new_ip_params = [[full_ip, 'brd', network_ref['broadcast']]]
old_ip_params = []
out, err = _execute('ip', 'addr', 'show', 'dev', dev,
'scope', 'global', run_as_root=True)
'scope', 'global')
for line in out.split('\n'):
fields = line.split()
if fields and fields[0] == 'inet':
@ -833,8 +840,7 @@ def initialize_gateway_device(dev, network_ref):
new_ip_params.append(ip_params)
if not old_ip_params or old_ip_params[0][0] != full_ip:
old_routes = []
result = _execute('ip', 'route', 'show', 'dev', dev,
run_as_root=True)
result = _execute('ip', 'route', 'show', 'dev', dev)
if result:
out, err = result
for line in out.split('\n'):
@ -1197,11 +1203,7 @@ def _execute(*cmd, **kwargs):
def device_exists(device):
"""Check if ethernet device exists."""
try:
_execute('ip', 'link', 'show', 'dev', device, run_as_root=True)
except processutils.ProcessExecutionError:
return False
return True
return os.path.exists('/sys/class/net/%s' % device)
def _dhcp_file(dev, kind):
@ -1534,7 +1536,7 @@ class LinuxBridgeInterfaceDriver(LinuxNetInterfaceDriver):
_execute('ip', 'route', 'del', *fields,
run_as_root=True)
out, err = _execute('ip', 'addr', 'show', 'dev', interface,
'scope', 'global', run_as_root=True)
'scope', 'global')
for line in out.split('\n'):
fields = line.split()
if fields and fields[0] == 'inet':

View File

@ -782,6 +782,8 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
return existing, ""
if args[0] == 'ip' and args[1] == 'route' and args[2] == 'show':
return routes, ""
if args[0] == 'sysctl':
return '1\n', ''
self.stubs.Set(utils, 'execute', fake_execute)
network = {'dhcp_server': '192.168.1.1',
'cidr': '192.168.1.0/24',
@ -798,7 +800,7 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
" inet6 dead::beef:dead:beef:dead/64 scope link\n"
" valid_lft forever preferred_lft forever\n")
expected = [
('sysctl', '-w', 'net.ipv4.ip_forward=1'),
('sysctl', '-n', 'net.ipv4.ip_forward'),
('ip', 'addr', 'show', 'dev', 'eth0', 'scope', 'global'),
('ip', 'route', 'show', 'dev', 'eth0'),
('ip', 'addr', 'del', '192.168.0.1/24',
@ -822,7 +824,7 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
" inet6 dead::beef:dead:beef:dead/64 scope link\n"
" valid_lft forever preferred_lft forever\n")
expected = [
('sysctl', '-w', 'net.ipv4.ip_forward=1'),
('sysctl', '-n', 'net.ipv4.ip_forward'),
('ip', 'addr', 'show', 'dev', 'eth0', 'scope', 'global'),
('ip', 'route', 'show', 'dev', 'eth0'),
('ip', 'route', 'del', 'default', 'dev', 'eth0'),
@ -851,7 +853,7 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
" inet6 dead::beef:dead:beef:dead/64 scope link\n"
" valid_lft forever preferred_lft forever\n")
expected = [
('sysctl', '-w', 'net.ipv4.ip_forward=1'),
('sysctl', '-n', 'net.ipv4.ip_forward'),
('ip', 'addr', 'show', 'dev', 'eth0', 'scope', 'global'),
('ip', '-f', 'inet6', 'addr', 'change',
'2001:db8::/64', 'dev', 'eth0'),
@ -865,7 +867,7 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
" inet6 dead::beef:dead:beef:dead/64 scope link\n"
" valid_lft forever preferred_lft forever\n")
expected = [
('sysctl', '-w', 'net.ipv4.ip_forward=1'),
('sysctl', '-n', 'net.ipv4.ip_forward'),
('ip', 'addr', 'show', 'dev', 'eth0', 'scope', 'global'),
('ip', 'route', 'show', 'dev', 'eth0'),
('ip', 'addr', 'add', '192.168.1.1/24',
@ -968,7 +970,7 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
run_as_root=True, check_exit_code=False),
mock.call('ip', 'route', 'show', 'dev', 'eth0'),
mock.call('ip', 'addr', 'show', 'dev', 'eth0', 'scope',
'global', run_as_root=True),
'global'),
]
}
with contextlib.nested(

View File

@ -550,7 +550,9 @@ class LibvirtVifTestCase(test.TestCase):
network=mynetwork)
d.unplug_iovisor(None, myvif)
def test_plug_iovisor(self):
@mock.patch('nova.network.linux_net.device_exists')
def test_plug_iovisor(self, device_exists):
device_exists.return_value = True
d = vif.LibvirtGenericVIFDriver(self._get_conn(ver=9010))
with mock.patch.object(utils, 'execute') as execute:
execute.side_effect = processutils.ProcessExecutionError