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()
44 """Setup system for DPDK.
47 _LOGGER.error('Not running on a compatible Linux version. Exiting...')
56 """Setup system for DPDK.
59 _LOGGER.error('Not running on a compatible Linux version. Exiting...')
68 # vhost specific modules management
72 def insert_vhost_modules():
73 """Inserts VHOST related kernel modules
75 mod_path_prefix = os.path.join(settings.getValue('RTE_SDK'),
78 _insert_module_group('VHOST_MODULE', mod_path_prefix)
81 def remove_vhost_modules():
82 """Removes all VHOST related kernel modules
84 _remove_module_group('VHOST_MODULE')
87 # basic compatibility test
92 """Check if running on Linux.
94 Many of the functions in this file rely on features commonly found
95 only on Linux (i.e. ``/proc`` is not present on FreeBSD). Hence, this
96 check is important to ensure someone doesn't run this on an incompatible
99 return _platform.startswith('linux') and os.path.isdir('/proc')
106 def _is_module_inserted(module):
107 """Check if a module is inserted on system.
109 with open('/proc/modules') as mod_file:
110 loaded_mods = mod_file.readlines()
112 # first check if module is loaded
113 for line in loaded_mods:
114 if line.startswith(module):
119 def _insert_modules():
120 """Ensure required modules are inserted on system.
123 _DPDK_MODULE_MANAGER.insert_modules(settings.getValue('SYS_MODULES'))
125 mod_path_prefix = settings.getValue('OVS_DIR')
126 _insert_module_group('OVS_MODULES', mod_path_prefix)
127 mod_path_prefix = os.path.join(settings.getValue('RTE_SDK'),
128 settings.getValue('RTE_TARGET'))
129 _insert_module_group('DPDK_MODULES', mod_path_prefix)
132 def _insert_module_group(module_group, group_path_prefix):
133 """Ensure all modules in a group are inserted into the system.
135 :param module_group: A name of configuration item containing a list
138 for module in settings.getValue(module_group):
139 # first check if module is loaded
140 if _is_module_inserted(module[1]):
144 mod_path = os.path.join(group_path_prefix, module[0],
146 tasks.run_task(['sudo', 'insmod', mod_path], _LOGGER,
147 'Inserting module \'%s\'...' % module[1], True)
148 except subprocess.CalledProcessError:
149 _LOGGER.error('Unable to insert module \'%s\'.', module[1])
150 raise # fail catastrophically
153 def _remove_modules():
154 """Ensure required modules are removed from system.
156 _remove_module_group('OVS_MODULES')
157 _remove_module_group('DPDK_MODULES')
159 _DPDK_MODULE_MANAGER.remove_modules()
161 def _remove_module_group(module_group):
162 """Ensure all modules in a group are removed from the system.
164 :param module_group: A name of configuration item containing a list
167 for module in settings.getValue(module_group):
168 # first check if module is loaded
169 if not _is_module_inserted(module[1]):
173 tasks.run_task(['sudo', 'rmmod', module[1]], _LOGGER,
174 'Removing module \'%s\'...' % module[1], True)
175 except subprocess.CalledProcessError:
176 _LOGGER.error('Unable to remove module \'%s\'.', module[1])
181 # 'vhost-net' module management
184 def _remove_vhost_net():
185 """Remove vhost-net driver and file.
187 if _is_module_inserted('vhost_net'):
189 tasks.run_task(['sudo', 'rmmod', 'vhost_net'], _LOGGER,
190 'Removing \'/dev/vhost-net\' directory...', True)
191 except subprocess.CalledProcessError:
192 _LOGGER.error('Unable to remove module \'vhost_net\'.')
195 tasks.run_task(['sudo', 'rm', '-f', '/dev/vhost-net'], _LOGGER,
196 'Removing \'/dev/vhost-net\' directory...', True)
197 except subprocess.CalledProcessError:
198 _LOGGER.error('Unable to remove directory \'/dev/vhost-net\'.')
206 """Bind NICs using the Intel DPDK ``dpdk_nic_bind.py`` tool.
209 tasks.run_task(['sudo', RTE_PCI_TOOL, '--bind', 'igb_uio'] +
210 settings.getValue('WHITELIST_NICS'), _LOGGER,
211 'Binding NICs %s...' %
212 settings.getValue('WHITELIST_NICS'),
214 except subprocess.CalledProcessError:
215 _LOGGER.error('Unable to bind NICs %s',
216 str(settings.getValue('WHITELIST_NICS')))
218 def _unbind_nics_get_driver():
219 """Check what driver the NICs should be bound to
220 after unbinding them from DPDK.
223 _output = subprocess.check_output([os.path.expanduser(RTE_PCI_TOOL), '--status'])
224 _my_encoding = locale.getdefaultlocale()[1]
225 for line in _output.decode(_my_encoding).split('\n'):
226 for nic in settings.getValue('WHITELIST_NICS'):
228 _driver_list.append((line.split("unused=", 1)[1]))
232 """Unbind NICs using the Intel DPDK ``dpdk_nic_bind.py`` tool.
234 nic_drivers = _unbind_nics_get_driver()
236 tasks.run_task(['sudo', RTE_PCI_TOOL, '--unbind'] +
237 settings.getValue('WHITELIST_NICS'), _LOGGER,
238 'Unbinding NICs %s...' %
239 str(settings.getValue('WHITELIST_NICS')),
241 except subprocess.CalledProcessError:
242 _LOGGER.error('Unable to unbind NICs %s',
243 str(settings.getValue('WHITELIST_NICS')))
244 # Rebind NICs to their original drivers
245 # using the Intel DPDK ``dpdk_nic_bind.py`` tool.
246 for i, nic in enumerate(settings.getValue('WHITELIST_NICS')):
248 if nic_drivers[i] != '':
249 tasks.run_task(['sudo', RTE_PCI_TOOL, '--bind',
250 nic_drivers[i], nic],
251 _LOGGER, 'Binding NIC %s...' %
254 except subprocess.CalledProcessError:
255 _LOGGER.error('Unable to bind NICs %s to drivers %s',
256 str(settings.getValue('WHITELIST_NICS')),
265 def _vhost_user_cleanup():
266 """Remove files created by vhost-user tests.
268 for sock in settings.getValue('VHOST_USER_SOCKS'):
269 if os.path.exists(sock):
271 tasks.run_task(['sudo', 'rm', sock],
273 'Deleting vhost-user socket \'%s\'...' %
277 except subprocess.CalledProcessError:
278 _LOGGER.error('Unable to delete vhost-user socket \'%s\'.',
284 """A context manager for the system init/cleanup.
287 _LOGGER.info('Setting up DPDK')
291 def __exit__(self, type_, value, traceback):
292 _LOGGER.info('Cleaning up DPDK')