1 # Copyright (c) 2018 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
6 # http://www.apache.org/licenses/LICENSE-2.0
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
14 """DUT setup library."""
16 from robot.api import logger
18 from resources.libraries.python.Constants import Constants
19 from resources.libraries.python.ssh import SSH, exec_cmd_no_error
20 from resources.libraries.python.topology import NodeType, Topology
23 class DUTSetup(object):
24 """Contains methods for setting up DUTs."""
27 def get_service_logs(node, service):
28 """Get specific service unit logs from node.
30 :param node: Node in the topology.
31 :param service: Service unit name.
35 if DUTSetup.running_in_container(node):
36 command = ('echo $(< /var/log/supervisord.log);'
37 'echo $(< /tmp/*supervisor*.log)')
39 command = ('journalctl --no-pager --unit={name} '
40 '--since="$(echo `systemctl show -p '
41 'ActiveEnterTimestamp {name}` | '
42 'awk \'{{print $2 $3}}\')"'.
44 message = 'Node {host} failed to get logs from unit {name}'.\
45 format(host=node['host'], name=service)
47 exec_cmd_no_error(node, command, timeout=30, sudo=True,
51 def get_service_logs_on_all_duts(nodes, service):
52 """Get specific service unit logs from all DUTs.
54 :param nodes: Nodes in the topology.
55 :param service: Service unit name.
59 for node in nodes.values():
60 if node['type'] == NodeType.DUT:
61 DUTSetup.get_service_logs(node, service)
64 def restart_service(node, service):
65 """Restart the named service on node.
67 :param node: Node in the topology.
68 :param service: Service unit name.
72 if DUTSetup.running_in_container(node):
73 command = 'supervisorctl restart {name}'.format(name=service)
75 command = 'service {name} restart'.format(name=service)
76 message = 'Node {host} failed to restart service {name}'.\
77 format(host=node['host'], name=service)
80 node, command, timeout=180, sudo=True, message=message)
82 DUTSetup.get_service_logs(node, service)
85 def restart_service_on_all_duts(nodes, service):
86 """Restart the named service on all DUTs.
88 :param node: Nodes in the topology.
89 :param service: Service unit name.
93 for node in nodes.values():
94 if node['type'] == NodeType.DUT:
95 DUTSetup.restart_service(node, service)
98 def start_service(node, service):
99 """Start up the named service on node.
101 :param node: Node in the topology.
102 :param service: Service unit name.
106 # TODO: change command to start once all parent function updated.
107 if DUTSetup.running_in_container(node):
108 command = 'supervisorctl restart {name}'.format(name=service)
110 command = 'service {name} restart'.format(name=service)
111 message = 'Node {host} failed to start service {name}'.\
112 format(host=node['host'], name=service)
115 node, command, timeout=180, sudo=True, message=message)
117 DUTSetup.get_service_logs(node, service)
120 def start_service_on_all_duts(nodes, service):
121 """Start up the named service on all DUTs.
123 :param node: Nodes in the topology.
124 :param service: Service unit name.
128 for node in nodes.values():
129 if node['type'] == NodeType.DUT:
130 DUTSetup.start_service(node, service)
133 def stop_service(node, service):
134 """Stop the named service on node.
136 :param node: Node in the topology.
137 :param service: Service unit name.
141 if DUTSetup.running_in_container(node):
142 command = 'supervisorctl stop {name}'.format(name=service)
144 command = 'service {name} stop'.format(name=service)
145 message = 'Node {host} failed to stop service {name}'.\
146 format(host=node['host'], name=service)
149 node, command, timeout=180, sudo=True, message=message)
151 DUTSetup.get_service_logs(node, service)
154 def stop_service_on_all_duts(nodes, service):
155 """Stop the named service on all DUTs.
157 :param node: Nodes in the topology.
158 :param service: Service unit name.
162 for node in nodes.values():
163 if node['type'] == NodeType.DUT:
164 DUTSetup.stop_service(node, service)
167 def get_vpp_pid(node):
168 """Get PID of running VPP process.
170 :param node: DUT node.
174 :raises RuntimeError: If it is not possible to get the PID.
180 logger.trace('Try {}: Get VPP PID'.format(i))
181 ret_code, stdout, stderr = ssh.exec_command('pidof vpp')
184 raise RuntimeError('Not possible to get PID of VPP process '
185 'on node: {0}\n {1}'.
186 format(node['host'], stdout + stderr))
188 pid_list = stdout.split()
189 if len(pid_list) == 1:
192 logger.debug("No VPP PID found on node {0}".
193 format(node['host']))
196 logger.debug("More then one VPP PID found on node {0}".
197 format(node['host']))
198 return [int(pid) for pid in pid_list]
203 def get_vpp_pids(nodes):
204 """Get PID of running VPP process on all DUTs.
206 :param nodes: DUT nodes.
212 for node in nodes.values():
213 if node['type'] == NodeType.DUT:
214 pids[node['host']] = DUTSetup.get_vpp_pid(node)
218 def crypto_device_verify(node, crypto_type, numvfs, force_init=False):
219 """Verify if Crypto QAT device virtual functions are initialized on all
220 DUTs. If parameter force initialization is set to True, then try to
221 initialize or remove VFs on QAT.
223 :param node: DUT node.
224 :crypto_type: Crypto device type - HW_DH895xcc or HW_C3xxx.
225 :param numvfs: Number of VFs to initialize, 0 - disable the VFs.
226 :param force_init: If True then try to initialize to specific value.
228 :type crypto_type: string
230 :type force_init: bool
232 :raises RuntimeError: If QAT VFs are not created and force init is set
235 pci_addr = Topology.get_cryptodev(node)
236 sriov_numvfs = DUTSetup.get_sriov_numvfs(node, pci_addr)
238 if sriov_numvfs != numvfs:
240 # QAT is not initialized and we want to initialize with numvfs
241 DUTSetup.crypto_device_init(node, crypto_type, numvfs)
243 raise RuntimeError('QAT device failed to create VFs on {host}'.
244 format(host=node['host']))
247 def crypto_device_init(node, crypto_type, numvfs):
248 """Init Crypto QAT device virtual functions on DUT.
250 :param node: DUT node.
251 :crypto_type: Crypto device type - HW_DH895xcc or HW_C3xxx.
252 :param numvfs: Number of VFs to initialize, 0 - disable the VFs.
254 :type crypto_type: string
257 :raises RuntimeError: If failed to stop VPP or QAT failed to initialize.
259 if crypto_type == "HW_DH895xcc":
260 kernel_mod = "qat_dh895xcc"
261 kernel_drv = "dh895xcc"
262 elif crypto_type == "HW_C3xxx":
263 kernel_mod = "qat_c3xxx"
266 raise RuntimeError('Unsupported crypto device type on {host}'.
267 format(host=node['host']))
269 pci_addr = Topology.get_cryptodev(node)
271 # QAT device must be re-bound to kernel driver before initialization.
272 DUTSetup.verify_kernel_module(node, kernel_mod, force_load=True)
274 # Stop VPP to prevent deadlock.
275 DUTSetup.stop_service(node, Constants.VPP_UNIT)
277 current_driver = DUTSetup.get_pci_dev_driver(
278 node, pci_addr.replace(':', r'\:'))
279 if current_driver is not None:
280 DUTSetup.pci_driver_unbind(node, pci_addr)
282 # Bind to kernel driver.
283 DUTSetup.pci_driver_bind(node, pci_addr, kernel_drv)
285 # Initialize QAT VFs.
287 DUTSetup.set_sriov_numvfs(node, pci_addr, numvfs)
290 def get_virtfn_pci_addr(node, pf_pci_addr, vf_id):
291 """Get PCI address of Virtual Function.
293 :param node: DUT node.
294 :param pf_pci_addr: Physical Function PCI address.
295 :param vf_id: Virtual Function number.
297 :type pf_pci_addr: str
299 :returns: Virtual Function PCI address.
301 :raises RuntimeError: If failed to get Virtual Function PCI address.
304 "'basename $(readlink /sys/bus/pci/devices/{pci}/virtfn{vf_id})'".\
305 format(pci=pf_pci_addr, vf_id=vf_id)
306 message = 'Failed to get virtual function PCI address.'
308 stdout, _ = exec_cmd_no_error(node, command, timeout=30, sudo=True,
311 return stdout.strip()
314 def get_sriov_numvfs(node, pf_pci_addr):
315 """Get number of SR-IOV VFs.
317 :param node: DUT node.
318 :param pf_pci_addr: Physical Function PCI device address.
320 :type pf_pci_addr: str
321 :returns: Number of VFs.
323 :raises RuntimeError: If PCI device is not SR-IOV capable.
325 command = 'cat /sys/bus/pci/devices/{pci}/sriov_numvfs'.\
326 format(pci=pf_pci_addr.replace(':', r'\:'))
327 message = 'PCI device {pci} is not a SR-IOV device.'.\
328 format(pci=pf_pci_addr)
331 stdout, _ = exec_cmd_no_error(node, command, timeout=30, sudo=True,
334 sriov_numvfs = int(stdout)
336 logger.trace('Reading sriov_numvfs info failed on {host}'.
337 format(host=node['host']))
342 def set_sriov_numvfs(node, pf_pci_addr, numvfs=0):
343 """Init or reset SR-IOV virtual functions by setting its number on PCI
344 device on DUT. Setting to zero removes all VFs.
346 :param node: DUT node.
347 :param pf_pci_addr: Physical Function PCI device address.
348 :param numvfs: Number of VFs to initialize, 0 - removes the VFs.
350 :type pf_pci_addr: str
352 :raises RuntimeError: Failed to create VFs on PCI.
355 "'echo {num} | tee /sys/bus/pci/devices/{pci}/sriov_numvfs'".\
356 format(num=numvfs, pci=pf_pci_addr.replace(':', r'\:'))
357 message = 'Failed to create {num} VFs on {pci} device on {host}'.\
358 format(num=numvfs, pci=pf_pci_addr, host=node['host'])
360 exec_cmd_no_error(node, command, timeout=120, sudo=True,
364 def pci_driver_unbind(node, pci_addr):
365 """Unbind PCI device from current driver on node.
367 :param node: DUT node.
368 :param pci_addr: PCI device address.
371 :raises RuntimeError: If PCI device unbind failed.
374 "'echo {pci} | tee /sys/bus/pci/devices/{pcie}/driver/unbind'".\
375 format(pci=pci_addr, pcie=pci_addr.replace(':', r'\:'))
376 message = 'Failed to unbind PCI device {pci} on {host}'.\
377 format(pci=pci_addr, host=node['host'])
379 exec_cmd_no_error(node, command, timeout=120, sudo=True,
383 def pci_driver_bind(node, pci_addr, driver):
384 """Bind PCI device to driver on node.
386 :param node: DUT node.
387 :param pci_addr: PCI device address.
388 :param driver: Driver to bind.
392 :raises RuntimeError: If PCI device bind failed.
394 message = 'Failed to bind PCI device {pci} to {driver} on host {host}'.\
395 format(pci=pci_addr, driver=driver, host=node['host'])
398 "'echo {driver} | tee /sys/bus/pci/devices/{pci}/driver_override'".\
399 format(driver=driver, pci=pci_addr.replace(':', r'\:'))
401 exec_cmd_no_error(node, command, timeout=120, sudo=True,
405 "'echo {pci} | tee /sys/bus/pci/drivers/{driver}/bind'".\
406 format(pci=pci_addr, driver=driver)
408 exec_cmd_no_error(node, command, timeout=120, sudo=True,
412 "'echo | tee /sys/bus/pci/devices/{pci}/driver_override'".\
413 format(pci=pci_addr.replace(':', r'\:'))
415 exec_cmd_no_error(node, command, timeout=120, sudo=True,
419 def pci_vf_driver_unbind(node, pf_pci_addr, vf_id):
420 """Unbind Virtual Function from driver on node.
422 :param node: DUT node.
423 :param pf_pci_addr: PCI device address.
424 :param vf_id: Virtual Function ID.
426 :type pf_pci_addr: str
428 :raises RuntimeError: If Virtual Function unbind failed.
430 vf_pci_addr = DUTSetup.get_virtfn_pci_addr(node, pf_pci_addr, vf_id)
431 vf_path = "/sys/bus/pci/devices/{pf_pci_addr}/virtfn{vf_id}".\
432 format(pf_pci_addr=pf_pci_addr.replace(':', r'\:'), vf_id=vf_id)
435 "'echo {vf_pci_addr} | tee {vf_path}/driver/unbind'".\
436 format(vf_pci_addr=vf_pci_addr, vf_path=vf_path)
438 message = 'Failed to unbind VF {vf_pci_addr} to on {host}'.\
439 format(vf_pci_addr=vf_pci_addr, host=node['host'])
441 exec_cmd_no_error(node, command, timeout=120, sudo=True,
445 def pci_vf_driver_bind(node, pf_pci_addr, vf_id, driver):
446 """Bind Virtual Function to driver on node.
448 :param node: DUT node.
449 :param pf_pci_addr: PCI device address.
450 :param vf_id: Virtual Function ID.
451 :param driver: Driver to bind.
453 :type pf_pci_addr: str
456 :raises RuntimeError: If PCI device bind failed.
458 vf_pci_addr = DUTSetup.get_virtfn_pci_addr(node, pf_pci_addr, vf_id)
459 vf_path = "/sys/bus/pci/devices/{pf_pci_addr}/virtfn{vf_id}".\
460 format(pf_pci_addr=pf_pci_addr.replace(':', r'\:'), vf_id=vf_id)
462 message = 'Failed to bind VF {vf_pci_addr} to {driver} on {host}'.\
463 format(vf_pci_addr=vf_pci_addr, driver=driver, host=node['host'])
466 "'echo {driver} | tee {vf_path}/driver_override'".\
467 format(driver=driver, vf_path=vf_path)
469 exec_cmd_no_error(node, command, timeout=120, sudo=True,
473 "'echo {vf_pci_addr} | tee /sys/bus/pci/drivers/{driver}/bind'".\
474 format(vf_pci_addr=vf_pci_addr, driver=driver)
476 exec_cmd_no_error(node, command, timeout=120, sudo=True,
480 "'echo | tee {vf_path}/driver_override'".\
481 format(vf_path=vf_path)
483 exec_cmd_no_error(node, command, timeout=120, sudo=True,
487 def get_pci_dev_driver(node, pci_addr):
488 """Get current PCI device driver on node.
491 # lspci -vmmks 0000:00:05.0
493 Class: Ethernet controller
495 Device: Virtio network device
496 SVendor: Red Hat, Inc
501 :param node: DUT node.
502 :param pci_addr: PCI device address.
505 :returns: Driver or None
506 :raises RuntimeError: If PCI rescan or lspci command execution failed.
507 :raises RuntimeError: If it is not possible to get the interface driver
508 information from the node.
514 logger.trace('Try number {0}: Get PCI device driver'.format(i))
516 cmd = 'lspci -vmmks {0}'.format(pci_addr)
517 ret_code, stdout, _ = ssh.exec_command(cmd)
519 raise RuntimeError("'{0}' failed on '{1}'"
520 .format(cmd, node['host']))
522 for line in stdout.splitlines():
528 name, value = line.split("\t", 1)
530 if name == "Driver:":
532 if name == 'Driver:':
536 logger.trace('Driver for PCI device {} not found, executing '
537 'pci rescan and retrying'.format(pci_addr))
538 cmd = 'sh -c "echo 1 > /sys/bus/pci/rescan"'
539 ret_code, _, _ = ssh.exec_command_sudo(cmd)
540 if int(ret_code) != 0:
541 raise RuntimeError("'{0}' failed on '{1}'"
542 .format(cmd, node['host']))
547 def verify_kernel_module(node, module, force_load=False):
548 """Verify if kernel module is loaded on node. If parameter force
549 load is set to True, then try to load the modules.
552 :param module: Module to verify.
553 :param force_load: If True then try to load module.
556 :type force_load: bool
557 :raises RuntimeError: If module is not loaded or failed to load.
559 command = 'grep -w {module} /proc/modules'.format(module=module)
560 message = 'Kernel module {module} is not loaded on host {host}'.\
561 format(module=module, host=node['host'])
564 exec_cmd_no_error(node, command, timeout=30, sudo=False,
568 # Module is not loaded and we want to load it
569 DUTSetup.load_kernel_module(node, module)
574 def verify_kernel_module_on_all_duts(nodes, module, force_load=False):
575 """Verify if kernel module is loaded on all DUTs. If parameter force
576 load is set to True, then try to load the modules.
578 :param node: DUT nodes.
579 :param module: Module to verify.
580 :param force_load: If True then try to load module.
583 :type force_load: bool
585 for node in nodes.values():
586 if node['type'] == NodeType.DUT:
587 DUTSetup.verify_kernel_module(node, module, force_load)
590 def verify_uio_driver_on_all_duts(nodes):
591 """Verify if uio driver kernel module is loaded on all DUTs. If module
592 is not present it will try to load it.
594 :param node: DUT nodes.
597 for node in nodes.values():
598 if node['type'] == NodeType.DUT:
599 uio_driver = Topology.get_uio_driver(node)
600 DUTSetup.verify_kernel_module(node, uio_driver, force_load=True)
603 def load_kernel_module(node, module):
604 """Load kernel module on node.
606 :param node: DUT node.
607 :param module: Module to load.
611 :raises RuntimeError: If loading failed.
613 command = 'modprobe {module}'.format(module=module)
614 message = 'Failed to load {module} on host {host}'.\
615 format(module=module, host=node['host'])
617 exec_cmd_no_error(node, command, timeout=30, sudo=True, message=message)
620 def install_vpp_on_all_duts(nodes, vpp_pkg_dir):
621 """Install VPP on all DUT nodes. Start the VPP service in case of
622 systemd is not available or does not support autostart.
624 :param nodes: Nodes in the topology.
625 :param vpp_pkg_dir: Path to directory where VPP packages are stored.
627 :type vpp_pkg_dir: str
628 :raises RuntimeError: If failed to remove or install VPP.
630 for node in nodes.values():
631 message = 'Failed to install VPP on host {host}!'.\
632 format(host=node['host'])
633 if node['type'] == NodeType.DUT:
634 command = 'ln -s /dev/null /etc/sysctl.d/80-vpp.conf || true'
635 exec_cmd_no_error(node, command, sudo=True)
637 command = '. /etc/lsb-release; echo "${DISTRIB_ID}"'
638 stdout, _ = exec_cmd_no_error(node, command)
640 if stdout.strip() == 'Ubuntu':
641 exec_cmd_no_error(node, 'apt-get purge -y "*vpp*" || true',
642 timeout=120, sudo=True)
643 exec_cmd_no_error(node, 'dpkg -i --force-all {dir}*.deb'.
644 format(dir=vpp_pkg_dir), timeout=120,
645 sudo=True, message=message)
646 exec_cmd_no_error(node, 'dpkg -l | grep vpp', sudo=True)
647 if DUTSetup.running_in_container(node):
648 DUTSetup.restart_service(node, Constants.VPP_UNIT)
650 exec_cmd_no_error(node, 'yum -y remove "*vpp*" || true',
651 timeout=120, sudo=True)
652 exec_cmd_no_error(node, 'rpm -ivh {dir}*.rpm'.
653 format(dir=vpp_pkg_dir), timeout=120,
654 sudo=True, message=message)
655 exec_cmd_no_error(node, 'rpm -qai *vpp*', sudo=True)
656 DUTSetup.restart_service(node, Constants.VPP_UNIT)
659 def running_in_container(node):
660 """This method tests if topology node is running inside container.
662 :param node: Topology node.
664 :returns: True if running in docker container, false if not or failed
668 command = "fgrep docker /proc/1/cgroup"
669 message = 'Failed to get cgroup settings.'
671 exec_cmd_no_error(node, command, timeout=30, sudo=False,
678 def get_docker_mergeddir(node, uuid):
679 """Get Docker overlay for MergedDir diff.
681 :param node: DUT node.
682 :param uuid: Docker UUID.
685 :returns: Docker container MergedDir.
687 :raises RuntimeError: If getting output failed.
689 command = "docker inspect --format='"\
690 "{{{{.GraphDriver.Data.MergedDir}}}}' {uuid}".format(uuid=uuid)
691 message = 'Failed to get directory of {uuid} on host {host}'.\
692 format(uuid=uuid, host=node['host'])
694 stdout, _ = exec_cmd_no_error(node, command, sudo=True, message=message)
695 return stdout.strip()
698 def get_huge_page_size(node):
699 """Get default size of huge pages in system.
701 :param node: Node in the topology.
703 :returns: Default size of free huge pages in system.
705 :raises RuntimeError: If reading failed for three times.
711 ret_code, stdout, _ = ssh.exec_command_sudo(
712 "grep Hugepagesize /proc/meminfo | awk '{ print $2 }'")
715 huge_size = int(stdout)
717 logger.trace('Reading huge page size information failed')
721 raise RuntimeError('Getting huge page size information failed.')
725 def get_huge_page_free(node, huge_size):
726 """Get number of free huge pages in system.
728 :param node: Node in the topology.
729 :param huge_size: Size of hugepages.
732 :returns: Number of free huge pages in system.
734 :raises RuntimeError: If reading failed for three times.
736 # TODO: add numa aware option
741 ret_code, stdout, _ = ssh.exec_command_sudo(
742 'cat /sys/kernel/mm/hugepages/hugepages-{0}kB/free_hugepages'.
746 huge_free = int(stdout)
748 logger.trace('Reading free huge pages information failed')
752 raise RuntimeError('Getting free huge pages information failed.')
756 def get_huge_page_total(node, huge_size):
757 """Get total number of huge pages in system.
759 :param node: Node in the topology.
760 :param huge_size: Size of hugepages.
764 :returns: Total number of huge pages in system.
766 :raises RuntimeError: If reading failed for three times.
768 # TODO: add numa aware option
773 ret_code, stdout, _ = ssh.exec_command_sudo(
774 'cat /sys/kernel/mm/hugepages/hugepages-{0}kB/nr_hugepages'.
778 huge_total = int(stdout)
780 logger.trace('Reading total huge pages information failed')
784 raise RuntimeError('Getting total huge pages information failed.')
788 def check_huge_page(node, huge_mnt, mem_size, allocate=False):
789 """Check if there is enough HugePages in system. If allocate is set to
790 true, try to allocate more HugePages.
792 :param node: Node in the topology.
793 :param huge_mnt: HugePage mount point.
794 :param mem_size: Requested memory in MB.
795 :param allocate: Whether to allocate more memory if not enough.
801 :raises RuntimeError: Mounting hugetlbfs failed or not enough HugePages
802 or increasing map count failed.
804 # TODO: split function into smaller parts.
808 # Get huge pages information
809 huge_size = DUTSetup.get_huge_page_size(node)
810 huge_free = DUTSetup.get_huge_page_free(node, huge_size)
811 huge_total = DUTSetup.get_huge_page_total(node, huge_size)
813 # Check if memory reqested is available on host
814 if (mem_size * 1024) > (huge_free * huge_size):
815 # If we want to allocate hugepage dynamically
817 mem_needed = (mem_size * 1024) - (huge_free * huge_size)
818 huge_to_allocate = ((mem_needed / huge_size) * 2) + huge_total
819 max_map_count = huge_to_allocate*4
820 # Increase maximum number of memory map areas a process may have
821 ret_code, _, _ = ssh.exec_command_sudo(
822 'echo "{0}" | sudo tee /proc/sys/vm/max_map_count'.
823 format(max_map_count))
824 if int(ret_code) != 0:
825 raise RuntimeError('Increase map count failed on {host}'.
826 format(host=node['host']))
827 # Increase hugepage count
828 ret_code, _, _ = ssh.exec_command_sudo(
829 'echo "{0}" | sudo tee /proc/sys/vm/nr_hugepages'.
830 format(huge_to_allocate))
831 if int(ret_code) != 0:
832 raise RuntimeError('Mount huge pages failed on {host}'.
833 format(host=node['host']))
834 # If we do not want to allocate dynamicaly end with error
836 raise RuntimeError('Not enough free huge pages: {0}, {1} MB'.
837 format(huge_free, huge_free * huge_size))
838 # Check if huge pages mount point exist
840 ret_code, stdout, _ = ssh.exec_command('cat /proc/mounts')
841 if int(ret_code) == 0:
842 for line in stdout.splitlines():
843 # Try to find something like:
844 # none /mnt/huge hugetlbfs rw,relatime,pagesize=2048k 0 0
846 if mount[2] == 'hugetlbfs' and mount[1] == huge_mnt:
849 # If huge page mount point not exist create one
851 ret_code, _, _ = ssh.exec_command_sudo(
852 'mkdir -p {mnt}'.format(mnt=huge_mnt))
853 if int(ret_code) != 0:
854 raise RuntimeError('Create mount dir failed on {host}'.
855 format(host=node['host']))
856 ret_code, _, _ = ssh.exec_command_sudo(
857 'mount -t hugetlbfs -o pagesize=2048k none {mnt}'.
858 format(mnt=huge_mnt))
859 if int(ret_code) != 0:
860 raise RuntimeError('Mount huge pages failed on {host}'.
861 format(host=node['host']))