1 # Copyright 2015-2016 Intel Corporation.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 """Automation of system configuration for DPDK use.
17 Parts of this based on ``tools/dpdk_nic_bind.py`` script from Intel(R)
21 from sys import platform as _platform
28 from tools import tasks
29 from conf import settings
30 from tools.module_manager import ModuleManager
32 _LOGGER = logging.getLogger(__name__)
33 RTE_PCI_TOOL = os.path.join(
34 settings.getValue('RTE_SDK'), 'tools', 'dpdk_nic_bind.py')
36 _DPDK_MODULE_MANAGER = ModuleManager()
43 """Setup system for DPDK.
46 _LOGGER.error('Not running on a compatible Linux version. Exiting...')
54 """Setup system for DPDK.
57 _LOGGER.error('Not running on a compatible Linux version. Exiting...')
65 # basic compatibility test
69 """Check if running on Linux.
71 Many of the functions in this file rely on features commonly found
72 only on Linux (i.e. ``/proc`` is not present on FreeBSD). Hence, this
73 check is important to ensure someone doesn't run this on an incompatible
76 return _platform.startswith('linux') and os.path.isdir('/proc')
82 def _insert_modules():
83 """Ensure required modules are inserted on system.
86 _DPDK_MODULE_MANAGER.insert_modules(settings.getValue('SYS_MODULES'))
88 mod_path_prefix = settings.getValue('OVS_DIR')
89 _DPDK_MODULE_MANAGER.insert_module_group(settings.getValue('OVS_MODULES'),
91 if 'vfio-pci' not in settings.getValue('DPDK_MODULES'):
92 mod_path_prefix = os.path.join(settings.getValue('RTE_SDK'),
93 settings.getValue('RTE_TARGET'))
94 _DPDK_MODULE_MANAGER.insert_module_group(settings.getValue('DPDK_MODULES'),
97 _DPDK_MODULE_MANAGER.insert_modules(settings.getValue('DPDK_MODULES'))
99 def _remove_modules():
100 """Ensure required modules are removed from system.
102 _DPDK_MODULE_MANAGER.remove_modules()
105 # vhost specific modules management
108 def insert_vhost_modules():
109 """Inserts VHOST related kernel modules
111 mod_path_prefix = os.path.join(settings.getValue('RTE_SDK'),
114 _DPDK_MODULE_MANAGER.insert_module_group(settings.getValue('VHOST_MODULE'), mod_path_prefix)
117 def remove_vhost_modules():
118 """Removes all VHOST related kernel modules
120 # all modules are removed automatically by _remove_modules() method
125 # 'vhost-net' module cleanup
128 def _remove_vhost_net():
129 """Remove vhost-net driver and file.
131 _DPDK_MODULE_MANAGER.remove_module('vhost-net')
133 tasks.run_task(['sudo', 'rm', '-f', '/dev/vhost-net'], _LOGGER,
134 'Removing \'/dev/vhost-net\' directory...', True)
135 except subprocess.CalledProcessError:
136 _LOGGER.error('Unable to remove directory \'/dev/vhost-net\'.')
142 def _vhost_user_cleanup():
143 """Remove files created by vhost-user tests.
145 for sock in settings.getValue('VHOST_USER_SOCKS'):
146 if os.path.exists(sock):
148 tasks.run_task(['sudo', 'rm', sock],
150 'Deleting vhost-user socket \'%s\'...' %
154 except subprocess.CalledProcessError:
155 _LOGGER.error('Unable to delete vhost-user socket \'%s\'.',
164 """Bind NICs using the Intel DPDK ``dpdk_nic_bind.py`` tool.
168 if 'vfio-pci' in settings.getValue('DPDK_MODULES'):
170 tasks.run_task(['sudo', 'chmod', 'a+x', '/dev/vfio'],
171 _LOGGER, 'Setting VFIO permissions .. a+x',
173 tasks.run_task(['sudo', 'chmod', '-R', '666', '/dev/vfio/'],
174 _LOGGER, 'Setting VFIO permissions .. 0666',
177 tasks.run_task(['sudo', RTE_PCI_TOOL, '--bind=' + _driver] +
178 settings.getValue('WHITELIST_NICS'), _LOGGER,
179 'Binding NICs %s...' %
180 settings.getValue('WHITELIST_NICS'),
182 except subprocess.CalledProcessError:
183 _LOGGER.error('Unable to bind NICs %s',
184 str(settings.getValue('WHITELIST_NICS')))
186 def _unbind_nics_get_driver():
187 """Check what driver the NICs should be bound to
188 after unbinding them from DPDK.
191 _output = subprocess.check_output([os.path.expanduser(RTE_PCI_TOOL), '--status'])
192 _my_encoding = locale.getdefaultlocale()[1]
193 for line in _output.decode(_my_encoding).split('\n'):
194 for nic in settings.getValue('WHITELIST_NICS'):
196 _driver_list.append((line.split("unused=", 1)[1]))
200 """Unbind NICs using the Intel DPDK ``dpdk_nic_bind.py`` tool.
202 nic_drivers = _unbind_nics_get_driver()
204 tasks.run_task(['sudo', RTE_PCI_TOOL, '--unbind'] +
205 settings.getValue('WHITELIST_NICS'), _LOGGER,
206 'Unbinding NICs %s...' %
207 str(settings.getValue('WHITELIST_NICS')),
209 except subprocess.CalledProcessError:
210 _LOGGER.error('Unable to unbind NICs %s',
211 str(settings.getValue('WHITELIST_NICS')))
212 # Rebind NICs to their original drivers
213 # using the Intel DPDK ``dpdk_nic_bind.py`` tool.
214 for i, nic in enumerate(settings.getValue('WHITELIST_NICS')):
216 if nic_drivers[i] != '':
217 tasks.run_task(['sudo', RTE_PCI_TOOL, '--bind',
218 nic_drivers[i], nic],
219 _LOGGER, 'Binding NIC %s...' %
222 except subprocess.CalledProcessError:
223 _LOGGER.error('Unable to bind NICs %s to drivers %s',
224 str(settings.getValue('WHITELIST_NICS')),
228 """A context manager for the system init/cleanup.
231 _LOGGER.info('Setting up DPDK')
235 def __exit__(self, type_, value, traceback):
236 _LOGGER.info('Cleaning up DPDK')