Merge "linux_net: allow for creation of multiqueue taps"

This commit is contained in:
Jenkins 2016-11-28 12:35:07 +00:00 committed by Gerrit Code Review
commit 14073a360c
2 changed files with 83 additions and 3 deletions

View File

@ -1311,13 +1311,22 @@ def delete_ivs_vif_port(dev):
run_as_root=True)
def create_tap_dev(dev, mac_address=None):
def create_tap_dev(dev, mac_address=None, multiqueue=False):
if not device_exists(dev):
try:
# First, try with 'ip'
utils.execute('ip', 'tuntap', 'add', dev, 'mode', 'tap',
run_as_root=True, check_exit_code=[0, 2, 254])
cmd = ('ip', 'tuntap', 'add', dev, 'mode', 'tap')
if multiqueue:
cmd = cmd + ('multi_queue', )
utils.execute(*cmd, run_as_root=True, check_exit_code=[0, 2, 254])
except processutils.ProcessExecutionError:
if multiqueue:
LOG.warning(
_LW('Failed to create a tap device with ip tuntap. '
'tunctl does not support creation of multi-queue '
'enabled devices, skipping fallback.'))
raise
# Second option: tunctl
utils.execute('tunctl', '-b', '-t', dev, run_as_root=True)
if mac_address:

View File

@ -1418,3 +1418,74 @@ class LinuxNetworkTestCase(test.NoDBTestCase):
self.assertRaises(processutils.ProcessExecutionError,
linux_net.LinuxBridgeInterfaceDriver.remove_bridge,
'fake-bridge')
@mock.patch('nova.utils.execute')
def test_create_tap_dev(self, mock_execute):
linux_net.create_tap_dev('tap42')
mock_execute.assert_has_calls([
mock.call('ip', 'tuntap', 'add', 'tap42', 'mode', 'tap',
run_as_root=True, check_exit_code=[0, 2, 254]),
mock.call('ip', 'link', 'set', 'tap42', 'up',
run_as_root=True, check_exit_code=[0, 2, 254])
])
@mock.patch('os.path.exists', return_value=True)
@mock.patch('nova.utils.execute')
def test_create_tap_skipped_when_exists(self, mock_execute, mock_exists):
linux_net.create_tap_dev('tap42')
mock_exists.assert_called_once_with('/sys/class/net/tap42')
mock_execute.assert_not_called()
@mock.patch('nova.utils.execute')
def test_create_tap_dev_mac(self, mock_execute):
linux_net.create_tap_dev('tap42', '00:11:22:33:44:55')
mock_execute.assert_has_calls([
mock.call('ip', 'tuntap', 'add', 'tap42', 'mode', 'tap',
run_as_root=True, check_exit_code=[0, 2, 254]),
mock.call('ip', 'link', 'set', 'tap42',
'address', '00:11:22:33:44:55',
run_as_root=True, check_exit_code=[0, 2, 254]),
mock.call('ip', 'link', 'set', 'tap42', 'up',
run_as_root=True, check_exit_code=[0, 2, 254])
])
@mock.patch('nova.utils.execute')
def test_create_tap_dev_fallback_to_tunctl(self, mock_execute):
# ip failed, fall back to tunctl
mock_execute.side_effect = [processutils.ProcessExecutionError, 0, 0]
linux_net.create_tap_dev('tap42')
mock_execute.assert_has_calls([
mock.call('ip', 'tuntap', 'add', 'tap42', 'mode', 'tap',
run_as_root=True, check_exit_code=[0, 2, 254]),
mock.call('tunctl', '-b', '-t', 'tap42',
run_as_root=True),
mock.call('ip', 'link', 'set', 'tap42', 'up',
run_as_root=True, check_exit_code=[0, 2, 254])
])
@mock.patch('nova.utils.execute')
def test_create_tap_dev_multiqueue(self, mock_execute):
linux_net.create_tap_dev('tap42', multiqueue=True)
mock_execute.assert_has_calls([
mock.call('ip', 'tuntap', 'add', 'tap42', 'mode', 'tap',
'multi_queue',
run_as_root=True, check_exit_code=[0, 2, 254]),
mock.call('ip', 'link', 'set', 'tap42', 'up',
run_as_root=True, check_exit_code=[0, 2, 254])
])
@mock.patch('nova.utils.execute')
def test_create_tap_dev_multiqueue_tunctl_raises(self, mock_execute):
# if creation of a tap by the means of ip command fails,
# create_tap_dev() will try to do that by the means of tunctl
mock_execute.side_effect = processutils.ProcessExecutionError
# but tunctl can't create multiqueue taps, so the failure is expected
self.assertRaises(processutils.ProcessExecutionError,
linux_net.create_tap_dev,
'tap42', multiqueue=True)