Exemple #1
0
def autoconfig_dryrun(ask_questions=True):
    """
    Execute the dryrun function.

    :param ask_questions: When true ask the user for paraameters
    :type ask_questions: bool

    """

    acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE, clean=True)

    # Stop VPP on each node
    nodes = acfg.get_nodes()
    for i in nodes.items():
        node = i[1]
        VPPUtil.stop(node)

    # Discover
    acfg.discover()

    # Check the system resources
    nodes = acfg.get_nodes()
    for i in nodes.items():
        node = i[1]
        if not acfg.min_system_resources(node):
            return

    # Modify the devices
    if ask_questions:
        acfg.modify_devices()
    else:
        acfg.update_interfaces_config()

    # If there are no interfaces, just return
    for i in nodes.items():
        node = i[1]
        if not acfg.has_interfaces(node):
            print("\nThere are no VPP interfaces configured, please configure at least 1.")
            return

    # Modify CPU
    acfg.modify_cpu(ask_questions)

    # Calculate the cpu parameters
    acfg.calculate_cpu_parameters()

    # Acquire TCP stack parameters
    if ask_questions:
        acfg.acquire_tcp_params()

    # Apply the startup
    acfg.apply_vpp_startup()

    # Apply the grub configuration
    acfg.apply_grub_cmdline()

    # Huge Pages
    if ask_questions:
        acfg.modify_huge_pages()
    acfg.apply_huge_pages()
Exemple #2
0
def autoconfig_cp(node, src, dst):
    """
    Copies a file, saving the original if needed.

    :param node: Node dictionary with cpuinfo.
    :param src: Source File
    :param dst: Destination file
    :type node: dict
    :type src: string
    :type dst: string
    :raises RuntimeError: If command fails
    """

    # If the destination file exist, create a copy if one does not already
    # exist
    ofile = dst + '.orig'
    (ret, stdout, stderr) = VPPUtil.exec_command('ls {}'.format(dst))
    if ret == 0:
        cmd = 'cp {} {}'.format(dst, ofile)
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError('{} failed on node {} {} {}'.
                               format(cmd,
                                      node['host'],
                                      stdout,
                                      stderr))

    # Copy the source file
    cmd = 'cp {} {}'.format(src, os.path.dirname(dst))
    (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
    if ret != 0:
        raise RuntimeError('{} failed on node {} {}'.
                           format(cmd, node['host'], stderr))
Exemple #3
0
def autoconfig_setup(ask_questions=True):
    """
    The auto configuration setup function.

    We will copy the configuration files to the dryrun directory.

    """

    global rootdir

    distro = VPPUtil.get_linux_distro()
    if distro[0] == 'Ubuntu':
        rootdir = '/usr/local'
    else:
        rootdir = '/usr'

    # If there is a system configuration file use that, if not use the initial auto-config file
    filename = rootdir + VPP_AUTO_CONFIGURATION_FILE
    if os.path.isfile(filename) is True:
        acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
    else:
        raise RuntimeError('The Auto configuration file does not exist {}'.
                           format(filename))

    if ask_questions:
        print ("\nWelcome to the VPP system configuration utility")

        print ("\nThese are the files we will modify:")
        print ("    /etc/vpp/startup.conf")
        print ("    /etc/sysctl.d/80-vpp.conf")
        print ("    /etc/default/grub")

        print (
            "\nBefore we change them, we'll create working copies in "
            "{}".format(rootdir + VPP_DRYRUNDIR))
        print (
            "Please inspect them carefully before applying the actual "
            "configuration (option 3)!")

    nodes = acfg.get_nodes()
    for i in nodes.items():
        node = i[1]

        if (os.path.isfile(rootdir + VPP_STARTUP_FILE) is not True) and \
                (os.path.isfile(VPP_REAL_STARTUP_FILE) is True):
            autoconfig_cp(node, VPP_REAL_STARTUP_FILE, '{}'.format(rootdir + VPP_STARTUP_FILE))
        if (os.path.isfile(rootdir + VPP_HUGE_PAGE_FILE) is not True) and \
                (os.path.isfile(VPP_REAL_HUGE_PAGE_FILE) is True):
            autoconfig_cp(node, VPP_REAL_HUGE_PAGE_FILE, '{}'.format(rootdir + VPP_HUGE_PAGE_FILE))
        if (os.path.isfile(rootdir + VPP_GRUB_FILE) is not True) and \
                (os.path.isfile(VPP_REAL_GRUB_FILE) is True):
            autoconfig_cp(node, VPP_REAL_GRUB_FILE, '{}'.format(rootdir + VPP_GRUB_FILE))

        # Be sure the uio_pci_generic driver is installed
        cmd = 'modprobe uio_pci_generic'
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            logging.warning('{} failed on node {} {}'. format(cmd, node['host'], stderr))
Exemple #4
0
def autoconfig_grub_apply(node, ask_questions=True):
    """
    Apply the grub configuration.

    :param node: The node structure
    :type node: dict
    :param ask_questions: When True ask the user questions
    :type ask_questions: bool
    :returns: -1 if the caller should return, 0 if not
    :rtype: int

    """

    print ("\nThe configured grub cmdline looks like this:")
    configured_cmdline = node['grub']['default_cmdline']
    current_cmdline = node['grub']['current_cmdline']
    print (configured_cmdline)
    print ("\nThe current boot cmdline looks like this:")
    print (current_cmdline)
    if ask_questions:
        question = "\nDo you want to keep the current boot cmdline [Y/n]? "
        answer = autoconfig_yn(question, 'y')
        if answer == 'y':
            return

    node['grub']['keep_cmdline'] = False

    # Diff the file
    diffs = autoconfig_diff(node, VPP_REAL_GRUB_FILE, rootdir + VPP_GRUB_FILE)
    if diffs != '':
        print ("These are the changes we will apply to")
        print ("the GRUB file ({}).\n".format(VPP_REAL_GRUB_FILE))
        print (diffs)
        if ask_questions:
            answer = autoconfig_yn("\nAre you sure you want to apply these changes [y/N]? ", 'n')
            if answer == 'n':
                return -1

        # Copy and update grub
        autoconfig_cp(node, rootdir + VPP_GRUB_FILE, VPP_REAL_GRUB_FILE)
        distro = VPPUtil.get_linux_distro()
        if distro[0] == 'Ubuntu':
            cmd = "update-grub"
        else:
            cmd = "grub2-mkconfig -o /boot/grub2/grub.cfg"

        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError('{} failed on node {} {} {}'.
                               format(cmd, node['host'], stdout, stderr))

        print ("There have been changes to the GRUB config a", end=' ')
        print ("reboot will be required.")
        return -1
    else:
        print ('\nThere are no changes to the GRUB config.')

    return 0
Exemple #5
0
    def _get_default_cmdline(self):
        """
        Using /etc/default/grub return the default grub cmdline

        :returns: The default grub cmdline
        :rtype: string
        """

        # Get the default grub cmdline
        rootdir = self._node['rootdir']
        gfile = self._node['cpu']['grub_config_file']
        grubcmdline = self._node['cpu']['grubcmdline']
        cmd = 'cat {}'.format(rootdir + gfile)
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError('{} Executing failed on node {} {}'.
                               format(cmd, self._node['host'], stderr))

        # Get the Default Linux command line, ignoring commented lines
        lines = stdout.split('\n')
        for line in lines:
            if line == '' or line[0] == '#':
                continue
            ldefault = re.findall(r'{}=.+'.format(grubcmdline), line)
            if ldefault:
                self._default_cmdline = ldefault[0]
                break
Exemple #6
0
    def get_actual_huge_pages(self):
        """
        Get the current huge page configuration

        :returns the hugepage total, hugepage free, hugepage size,
        total memory, and total memory free
        :rtype: tuple
        """

        # Get the memory information using /proc/meminfo
        cmd = 'sudo cat /proc/meminfo'
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError(
                '{} failed on node {} {} {}'.format(
                    cmd, self._node['host'],
                    stdout, stderr))

        total = re.findall(r'HugePages_Total:\s+\w+', stdout)
        free = re.findall(r'HugePages_Free:\s+\w+', stdout)
        size = re.findall(r'Hugepagesize:\s+\w+\s+\w+', stdout)
        memtotal = re.findall(r'MemTotal:\s+\w+\s+\w+', stdout)
        memfree = re.findall(r'MemFree:\s+\w+\s+\w+', stdout)

        total = total[0].split(':')[1].lstrip()
        free = free[0].split(':')[1].lstrip()
        size = size[0].split(':')[1].lstrip()
        memtotal = memtotal[0].split(':')[1].lstrip()
        memfree = memfree[0].split(':')[1].lstrip()
        return total, free, size, memtotal, memfree
Exemple #7
0
def autoconfig_hugepage_apply(node, ask_questions=True):
    """
    Apply the huge page configuration.
    :param node: The node structure
    :type node: dict
    :param ask_questions: When True ask the user questions
    :type ask_questions: bool
    :returns: -1 if the caller should return, 0 if not
    :rtype: int

    """

    diffs = autoconfig_diff(node, VPP_REAL_HUGE_PAGE_FILE, rootdir + VPP_HUGE_PAGE_FILE)
    if diffs != '':
        print ("These are the changes we will apply to")
        print ("the huge page file ({}).\n".format(VPP_REAL_HUGE_PAGE_FILE))
        print (diffs)
        if ask_questions:
            answer = autoconfig_yn("\nAre you sure you want to apply these changes [Y/n]? ", 'y')
            if answer == 'n':
                return -1

        # Copy and sysctl
        autoconfig_cp(node, rootdir + VPP_HUGE_PAGE_FILE, VPP_REAL_HUGE_PAGE_FILE)
        cmd = "sysctl -p {}".format(VPP_REAL_HUGE_PAGE_FILE)
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError('{} failed on node {} {} {}'.
                               format(cmd, node['host'], stdout, stderr))
    else:
        print ('\nThere are no changes to the huge page configuration.')

    return 0
Exemple #8
0
def autoconfig_diff(node, src, dst):
    """
    Returns the diffs of 2 files.

    :param node: Node dictionary with cpuinfo.
    :param src: Source File
    :param dst: Destination file
    :type node: dict
    :type src: string
    :type dst: string
    :returns: The Answer
    :rtype: string
    :raises RuntimeError: If command fails
    """

    # Diff the files and return the output
    cmd = "diff {} {}".format(src, dst)
    (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
    if stderr != '':
        raise RuntimeError('{} failed on node {} {} {}'.
                           format(cmd,
                                  node['host'],
                                  ret,
                                  stderr))

    return stdout
Exemple #9
0
def autoconfig_apply(ask_questions=True):
    """
    Apply the configuration.

    Show the diff of the dryrun file and the actual configuration file
    Copy the files from the dryrun directory to the actual file.
    Peform the system function

    :param ask_questions: When true ask the user questions
    :type ask_questions: bool

    """

    vutil = VPPUtil()
    pkgs = vutil.get_installed_vpp_pkgs()
    if len(pkgs) == 0:
        print ("\nVPP is not installed, Install VPP with option 4.")
        return

    acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)

    if ask_questions:
        print ("\nWe are now going to configure your system(s).\n")
        answer = autoconfig_yn("Are you sure you want to do this [Y/n]? ", 'y')
        if answer == 'n':
            return

    nodes = acfg.get_nodes()
    for i in nodes.items():
        node = i[1]

        # Check the system resources
        if not acfg.min_system_resources(node):
            return

        # Stop VPP
        VPPUtil.stop(node)

        # Huge Pages
        ret = autoconfig_hugepage_apply(node, ask_questions)
        if ret != 0:
            return

        # VPP
        ret = autoconfig_vpp_apply(node, ask_questions)
        if ret != 0:
            return

        # Grub
        ret = autoconfig_grub_apply(node, ask_questions)
        if ret != 0:
            # We can still start VPP, even if we haven't configured grub
            VPPUtil.start(node)
            return

        # Everything is configured start vpp
        VPPUtil.start(node)
Exemple #10
0
    def __init__(self, node):
        distro = VPPUtil.get_linux_distro()
        if distro[0] == 'Ubuntu':
            node['cpu']['grubcmdline'] = 'GRUB_CMDLINE_LINUX_DEFAULT'
        else:
            node['cpu']['grubcmdline'] = 'GRUB_CMDLINE_LINUX'

        self._node = node
        self._current_cmdline = ""
        self._default_cmdline = ""
        self._get_current_cmdline()
        self._get_default_cmdline()
Exemple #11
0
def autoconfig_basic_test():
    """
    The auto configuration basic test menu

    """
    vutil = VPPUtil()
    pkgs = vutil.get_installed_vpp_pkgs()
    if len(pkgs) == 0:
        print ("\nVPP is not installed, install VPP with option 4.")
        return

    answer = ''
    while answer != 'q':
        answer = autoconfig_basic_test_menu()
        if answer == '1':
            autoconfig_ipv4_setup()
        elif answer == '2':
            autoconfig_create_iperf_vm()
        elif answer == '9' or answer == 'q':
            return
        else:
            autoconfig_not_implemented()
Exemple #12
0
    def get_cpu_info_per_node(node):
        """Return node related list of CPU numbers.

        :param node: Node dictionary with cpuinfo.
        :type node: dict
        :returns: Important CPU information.
        :rtype: dict
        """

        cmd = "lscpu"
        ret, stdout, stderr = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError("lscpu command failed on node {} {}."
                               .format(node['host'], stderr))

        cpuinfo = {}
        lines = stdout.split('\n')
        for line in lines:
            if line != '':
                linesplit = re.split(r':\s+', line)
                cpuinfo[linesplit[0]] = linesplit[1]

        cmd = "cat /proc/*/task/*/stat | awk '{print $1" "$2" "$39}'"
        ret, stdout, stderr = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError("cat command failed on node {} {}."
                               .format(node['host'], stderr))

        vpp_processes = {}
        vpp_lines = re.findall(r'\w+\(vpp_\w+\)\w+', stdout)
        for line in vpp_lines:
            linesplit = re.split(r'\w+\(', line)[1].split(')')
            vpp_processes[linesplit[0]] = linesplit[1]

        cpuinfo['vpp_processes'] = vpp_processes

        return cpuinfo
Exemple #13
0
    def get_cpu_info_per_node(node):
        """Return node related list of CPU numbers.

        :param node: Node dictionary with cpuinfo.
        :type node: dict
        :returns: Important CPU information.
        :rtype: dict
        """

        cmd = "lscpu"
        ret, stdout, stderr = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError("lscpu command failed on node {} {}.".format(
                node['host'], stderr))

        cpuinfo = {}
        lines = stdout.split('\n')
        for line in lines:
            if line != '':
                linesplit = re.split(r':\s+', line)
                cpuinfo[linesplit[0]] = linesplit[1]

        cmd = "cat /proc/*/task/*/stat | awk '{print $1" "$2" "$39}'"
        ret, stdout, stderr = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError("cat command failed on node {} {}.".format(
                node['host'], stderr))

        vpp_processes = {}
        vpp_lines = re.findall(r'\w+\(vpp_\w+\)\w+', stdout)
        for line in vpp_lines:
            linesplit = re.split(r'\w+\(', line)[1].split(')')
            vpp_processes[linesplit[0]] = linesplit[1]

        cpuinfo['vpp_processes'] = vpp_processes

        return cpuinfo
Exemple #14
0
def autoconfig_install():
    """
    Install or Uninstall VPP.

    """

    # Since these commands will take a while, we
    # want to see the progress
    logger = logging.getLogger()

    acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
    vutil = VPPUtil()

    nodes = acfg.get_nodes()
    for i in nodes.items():
        node = i[1]

        pkgs = vutil.get_installed_vpp_pkgs()

        if len(pkgs) > 0:
            print("\nThese packages are installed on node {}".format(
                node['host']))
            print("{:25} {}".format("Name", "Version"))
            for pkg in pkgs:
                try:
                    print("{:25} {}".format(pkg['name'], pkg['version']))
                except KeyError:
                    print("{}".format(pkg['name']))

            question = "\nDo you want to uninstall these "
            question += "packages [y/N]? "
            answer = autoconfig_yn(question, 'n')
            if answer == 'y':
                logger.setLevel(logging.INFO)
                vutil.uninstall_vpp(node)
        else:
            print("\nThere are no VPP packages on node {}.".format(
                node['host']))
            question = "Do you want to install VPP [Y/n]? "
            answer = autoconfig_yn(question, 'y')
            if answer == 'y':
                question = "Do you want to install the release version [Y/n]? "
                answer = autoconfig_yn(question, 'y')
                if answer == 'y':
                    branch = 'release'
                else:
                    branch = 'master'
                logger.setLevel(logging.INFO)
                vutil.install_vpp(node, branch)

    # Set the logging level back
    logger.setLevel(logging.ERROR)
Exemple #15
0
    def _get_current_cmdline(self):
        """
        Using /proc/cmdline return the current grub cmdline

        :returns: The current grub cmdline
        :rtype: string
        """

        # Get the memory information using /proc/meminfo
        cmd = "sudo cat /proc/cmdline"
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError("{} on node {} {} {}".format(
                cmd, self._node["host"], stdout, stderr))

        self._current_cmdline = stdout.strip("\n")
Exemple #16
0
    def unbind_vpp_device(node, device_id):
        """
        unbind the device specified

        :param node: Node dictionary with cpuinfo.
        :param device_id: The device id
        :type node: dict
        :type device_id: string
        """

        rootdir = node['rootdir']
        dpdk_script = rootdir + DPDK_SCRIPT
        cmd = dpdk_script + ' -u ' + ' ' + device_id
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError('{} failed on node {} {} {}'.format(
                cmd, node['host'], stdout, stderr))
Exemple #17
0
    def _get_current_cmdline(self):
        """
        Using /proc/cmdline return the current grub cmdline

        :returns: The current grub cmdline
        :rtype: string
        """

        # Get the memory information using /proc/meminfo
        cmd = 'sudo cat /proc/cmdline'
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError('{} on node {} {} {}'.
                               format(cmd, self._node['host'],
                                      stdout, stderr))

        self._current_cmdline = stdout.strip('\n')
Exemple #18
0
    def sys_info(self):
        """
        Print the system information

        """

        for i in self._nodes.items():
            print "\n=============================="
            name = i[0]
            node = i[1]

            print "NODE: {}\n".format(name)

            # CPU
            print "CPU:"
            self.cpu_info(node)

            # Grub
            print "\nGrub Command Line:"
            if 'grub' in node:
                print \
                    "  Current: {}".format(
                        node['grub']['current_cmdline'])
                print \
                    "  Configured: {}".format(
                        node['grub']['default_cmdline'])

            # Huge Pages
            print "\nHuge Pages:"
            self.hugepage_info(node)

            # Devices
            print "\nDevices:"
            self.device_info(node)

            # Status
            print "\nVPP Service Status:"
            state, errors = VPPUtil.status(node)
            print "  {}".format(state)
            for e in errors:
                print "  {}".format(e)

            # Minimum system resources
            self.min_system_resources(node)

            print "\n=============================="
Exemple #19
0
def autoconfig_install():
    """
    Install or Uninstall VPP.

    """

    # Since these commands will take a while, we
    # want to see the progress
    logger = logging.getLogger()

    acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
    vutil = VPPUtil()

    nodes = acfg.get_nodes()
    for i in nodes.items():
        node = i[1]

        pkgs = vutil.get_installed_vpp_pkgs()

        if len(pkgs) > 0:
            print ("\nThese packages are installed on node {}"
                   .format(node['host']))
            print ("{:25} {}".format("Name", "Version"))
            for pkg in pkgs:
                try:
                    print ("{:25} {}".format(
                        pkg['name'], pkg['version']))
                except KeyError:
                    print ("{}".format(pkg['name']))

            question = "\nDo you want to uninstall these "
            question += "packages [y/N]? "
            answer = autoconfig_yn(question, 'n')
            if answer == 'y':
                logger.setLevel(logging.INFO)
                vutil.uninstall_vpp(node)
        else:
            print ("\nThere are no VPP packages on node {}."
                   .format(node['host']))
            question = "Do you want to install VPP [Y/n]? "
            answer = autoconfig_yn(question, 'y')
            if answer == 'y':
                question = "Do you want to install the release version [Y/n]? "
                answer = autoconfig_yn(question, 'y')
                if answer == 'y':
                    branch = 'release'
                else:
                    branch = 'master'
                logger.setLevel(logging.INFO)
                vutil.install_vpp(node, branch)

    # Set the logging level back
    logger.setLevel(logging.ERROR)
Exemple #20
0
    def unbind_vpp_device(node, device_id):
        """
        unbind the device specified

        :param node: Node dictionary with cpuinfo.
        :param device_id: The device id
        :type node: dict
        :type device_id: string
        """

        rootdir = node['rootdir']
        dpdk_script = rootdir + DPDK_SCRIPT
        cmd = dpdk_script + ' -u ' + ' ' + device_id
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError('{} failed on node {} {} {}'.format(
                cmd, node['host'],
                stdout, stderr))
Exemple #21
0
    def hugepages_dryrun_apply(self):
        """
        Apply the huge page configuration

        """

        node = self._node
        hugepages = node['hugepages']

        vpp_hugepage_config = VPP_HUGEPAGE_CONFIG.format(
            nr_hugepages=hugepages['total'],
            max_map_count=hugepages['max_map_count'],
            shmmax=hugepages['shmax'])

        rootdir = node['rootdir']
        filename = rootdir + node['hugepages']['hugepage_config_file']

        cmd = 'echo "{0}" | sudo tee {1}'.\
            format(vpp_hugepage_config, filename)
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError('{} failed on node {} {} {}'.format(
                cmd, node['host'], stdout, stderr))
Exemple #22
0
def autoconfig_diff(node, src, dst):
    """
    Returns the diffs of 2 files.

    :param node: Node dictionary with cpuinfo.
    :param src: Source File
    :param dst: Destination file
    :type node: dict
    :type src: string
    :type dst: string
    :returns: The Answer
    :rtype: string
    :raises RuntimeError: If command fails
    """

    # Diff the files and return the output
    cmd = "diff {} {}".format(src, dst)
    (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
    if stderr != '':
        raise RuntimeError('{} failed on node {} {} {}'.format(
            cmd, node['host'], ret, stderr))

    return stdout
Exemple #23
0
    def bind_vpp_device(node, driver, device_id):
        """
        bind the device specified

        :param node: Node dictionary with cpuinfo.
        :param driver: The driver
        :param device_id: The device id
        :type node: dict
        :type driver: string
        :type device_id: string
        :returns ret: Command return code
        """

        rootdir = node['rootdir']
        dpdk_script = rootdir + DPDK_SCRIPT
        cmd = dpdk_script + ' -b ' + driver + ' ' + device_id
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            logging.error('{} failed on node {}'.format(
                cmd, node['host'], stdout, stderr))
            logging.error('{} {}'.format(stdout, stderr))

        return ret
Exemple #24
0
def autoconfig_hugepage_apply(node, ask_questions=True):
    """
    Apply the huge page configuration.
    :param node: The node structure
    :type node: dict
    :param ask_questions: When True ask the user questions
    :type ask_questions: bool
    :returns: -1 if the caller should return, 0 if not
    :rtype: int

    """

    diffs = autoconfig_diff(node, VPP_REAL_HUGE_PAGE_FILE, rootdir + VPP_HUGE_PAGE_FILE)
    if diffs != "":
        print("These are the changes we will apply to")
        print("the huge page file ({}).\n".format(VPP_REAL_HUGE_PAGE_FILE))
        print(diffs)
        if ask_questions:
            answer = autoconfig_yn(
                "\nAre you sure you want to apply these changes [Y/n]? ", "y"
            )
            if answer == "n":
                return -1

        # Copy and sysctl
        autoconfig_cp(node, rootdir + VPP_HUGE_PAGE_FILE, VPP_REAL_HUGE_PAGE_FILE)
        cmd = "sysctl -p {}".format(VPP_REAL_HUGE_PAGE_FILE)
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError(
                "{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr)
            )
    else:
        print("\nThere are no changes to the huge page configuration.")

    return 0
Exemple #25
0
    def hugepages_dryrun_apply(self):
        """
        Apply the huge page configuration

        """

        node = self._node
        hugepages = node["hugepages"]

        vpp_hugepage_config = VPP_HUGEPAGE_CONFIG.format(
            nr_hugepages=hugepages["total"],
            max_map_count=hugepages["max_map_count"],
            shmmax=hugepages["shmax"],
        )

        rootdir = node["rootdir"]
        filename = rootdir + node["hugepages"]["hugepage_config_file"]

        cmd = 'echo "{0}" | sudo tee {1}'.format(vpp_hugepage_config, filename)
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError(
                "{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr)
            )
Exemple #26
0
    def bind_vpp_device(node, driver, device_id):
        """
        bind the device specified

        :param node: Node dictionary with cpuinfo.
        :param driver: The driver
        :param device_id: The device id
        :type node: dict
        :type driver: string
        :type device_id: string
        :returns ret: Command return code
        """

        rootdir = node['rootdir']
        dpdk_script = rootdir + DPDK_SCRIPT
        cmd = dpdk_script + ' -b ' + driver + ' ' + device_id
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            logging.error('{} failed on node {}'.format(
                cmd, node['host'], stdout, stderr))
            logging.error('{} {}'.format(
                stdout, stderr))

        return ret
Exemple #27
0
    def get_cpu_layout_from_all_nodes(nodes):
        """Retrieve cpu layout from all nodes, assuming all nodes
           are Linux nodes.

        :param nodes: DICT__nodes from Topology.DICT__nodes.
        :type nodes: dict
        :raises RuntimeError: If the ssh command "lscpu -p" fails.
        """
        for node in nodes.values():
            cmd = "lscpu -p"
            ret, stdout, stderr = VPPUtil.exec_command(cmd)
            #           parsing of "lscpu -p" output:
            #           # CPU,Core,Socket,Node,,L1d,L1i,L2,L3
            #           0,0,0,0,,0,0,0,0
            #           1,1,0,0,,1,1,1,0
            if ret != 0:
                raise RuntimeError(
                    "Failed to execute ssh command, ret: {} err: {}".format(
                        ret, stderr))
            node['cpuinfo'] = list()
            for line in stdout.split("\n"):
                if line != '' and line[0] != "#":
                    node['cpuinfo'].append([CpuUtils.__str2int(x) for x in
                                            line.split(",")])
Exemple #28
0
    def hugepages_dryrun_apply(self):
        """
        Apply the huge page configuration

        """

        node = self._node
        hugepages = node['hugepages']

        vpp_hugepage_config = VPP_HUGEPAGE_CONFIG.format(
            nr_hugepages=hugepages['total'],
            max_map_count=hugepages['max_map_count'],
            shmmax=hugepages['shmax'])

        rootdir = node['rootdir']
        filename = rootdir + node['hugepages']['hugepage_config_file']

        cmd = 'echo "{0}" | sudo tee {1}'.\
            format(vpp_hugepage_config, filename)
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError('{} failed on node {} {} {}'.
                               format(cmd, node['host'],
                                      stdout, stderr))
Exemple #29
0
    def get_cpu_layout_from_all_nodes(nodes):
        """Retrieve cpu layout from all nodes, assuming all nodes
           are Linux nodes.

        :param nodes: DICT__nodes from Topology.DICT__nodes.
        :type nodes: dict
        :raises RuntimeError: If the ssh command "lscpu -p" fails.
        """
        for node in nodes.values():
            cmd = "lscpu -p"
            ret, stdout, stderr = VPPUtil.exec_command(cmd)
            #           parsing of "lscpu -p" output:
            #           # CPU,Core,Socket,Node,,L1d,L1i,L2,L3
            #           0,0,0,0,,0,0,0,0
            #           1,1,0,0,,1,1,1,0
            if ret != 0:
                raise RuntimeError(
                    "Failed to execute ssh command, ret: {} err: {}".format(
                        ret, stderr))
            node["cpuinfo"] = list()
            for line in stdout.split("\n"):
                if line != "" and line[0] != "#":
                    node["cpuinfo"].append(
                        [CpuUtils.__str2int(x) for x in line.split(",")])
Exemple #30
0
    def get_cpu_layout(node):
        """
        Get the cpu layout

        using lscpu -p get the cpu layout.
        Returns a list with each item representing a single cpu.

        :param node: Node dictionary.
        :type node: dict
        :returns: The cpu layout
        :rtype: list
        """

        cmd = 'lscpu -p'
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError('{} failed on node {} {}'.format(
                cmd, node['host'], stderr))

        pcpus = []
        lines = stdout.split('\n')
        for line in lines:
            if line == '' or line[0] == '#':
                continue
            linesplit = line.split(',')
            layout = {
                'cpu': linesplit[0],
                'core': linesplit[1],
                'socket': linesplit[2],
                'node': linesplit[3]
            }

            # cpu, core, socket, node
            pcpus.append(layout)

        return pcpus
Exemple #31
0
def autoconfig_grub_apply(node, ask_questions=True):
    """
    Apply the grub configuration.

    :param node: The node structure
    :type node: dict
    :param ask_questions: When True ask the user questions
    :type ask_questions: bool
    :returns: -1 if the caller should return, 0 if not
    :rtype: int

    """

    print("\nThe configured grub cmdline looks like this:")
    configured_cmdline = node["grub"]["default_cmdline"]
    current_cmdline = node["grub"]["current_cmdline"]
    print(configured_cmdline)
    print("\nThe current boot cmdline looks like this:")
    print(current_cmdline)
    if ask_questions:
        question = "\nDo you want to keep the current boot cmdline [Y/n]? "
        answer = autoconfig_yn(question, "y")
        if answer == "y":
            return

    node["grub"]["keep_cmdline"] = False

    # Diff the file
    diffs = autoconfig_diff(node, VPP_REAL_GRUB_FILE, rootdir + VPP_GRUB_FILE)
    if diffs != "":
        print("These are the changes we will apply to")
        print("the GRUB file ({}).\n".format(VPP_REAL_GRUB_FILE))
        print(diffs)
        if ask_questions:
            answer = autoconfig_yn(
                "\nAre you sure you want to apply these changes [y/N]? ", "n"
            )
            if answer == "n":
                return -1

        # Copy and update grub
        autoconfig_cp(node, rootdir + VPP_GRUB_FILE, VPP_REAL_GRUB_FILE)
        distro = VPPUtil.get_linux_distro()
        if distro[0] == "Ubuntu":
            cmd = "update-grub"
        else:
            cmd = "grub2-mkconfig -o /boot/grub2/grub.cfg"

        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError(
                "{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr)
            )

        print("There have been changes to the GRUB config a", end=" ")
        print("reboot will be required.")
        return -1
    else:
        print("\nThere are no changes to the GRUB config.")

    return 0
Exemple #32
0
def autoconfig_dryrun(ask_questions=True):
    """
    Execute the dryrun function.

    :param ask_questions: When true ask the user for paraameters
    :type ask_questions: bool

    """

    acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE, clean=True)

    # Stop VPP on each node
    nodes = acfg.get_nodes()
    for i in nodes.items():
        node = i[1]
        VPPUtil.stop(node)

    # Discover
    acfg.discover()

    # Check the system resources
    nodes = acfg.get_nodes()
    for i in nodes.items():
        node = i[1]
        if not acfg.min_system_resources(node):
            return

    # Modify the devices
    if ask_questions:
        acfg.modify_devices()
    else:
        acfg.update_interfaces_config()

    # If there are no interfaces, just return
    for i in nodes.items():
        node = i[1]
        if not acfg.has_interfaces(node):
            print(
                "\nThere are no VPP interfaces configured, please configure at least 1."
            )
            return

    # Modify CPU
    acfg.modify_cpu(ask_questions)

    # Calculate the cpu parameters
    acfg.calculate_cpu_parameters()

    # Acquire TCP stack parameters
    if ask_questions:
        acfg.acquire_tcp_params()

    # Apply the startup
    acfg.apply_vpp_startup()

    # Apply the grub configuration
    acfg.apply_grub_cmdline()

    # Huge Pages
    if ask_questions:
        acfg.modify_huge_pages()
    acfg.apply_huge_pages()
Exemple #33
0
def autoconfig_setup(ask_questions=True):
    """
    The auto configuration setup function.

    We will copy the configuration files to the dryrun directory.

    """

    global rootdir

    distro = VPPUtil.get_linux_distro()
    if distro[0] == "Ubuntu":
        rootdir = "/usr/local"
    else:
        rootdir = "/usr"

    # If there is a system configuration file use that, if not use the initial auto-config file
    filename = rootdir + VPP_AUTO_CONFIGURATION_FILE
    if os.path.isfile(filename) is True:
        acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
    else:
        raise RuntimeError(
            "The Auto configuration file does not exist {}".format(filename)
        )

    if ask_questions:
        print("\nWelcome to the VPP system configuration utility")

        print("\nThese are the files we will modify:")
        print("    /etc/vpp/startup.conf")
        print("    /etc/sysctl.d/80-vpp.conf")
        print("    /etc/default/grub")

        print(
            "\nBefore we change them, we'll create working copies in "
            "{}".format(rootdir + VPP_DRYRUNDIR)
        )
        print(
            "Please inspect them carefully before applying the actual "
            "configuration (option 3)!"
        )

    nodes = acfg.get_nodes()
    for i in nodes.items():
        node = i[1]

        if (os.path.isfile(rootdir + VPP_STARTUP_FILE) is not True) and (
            os.path.isfile(VPP_REAL_STARTUP_FILE) is True
        ):
            autoconfig_cp(
                node, VPP_REAL_STARTUP_FILE, "{}".format(rootdir + VPP_STARTUP_FILE)
            )
        if (os.path.isfile(rootdir + VPP_HUGE_PAGE_FILE) is not True) and (
            os.path.isfile(VPP_REAL_HUGE_PAGE_FILE) is True
        ):
            autoconfig_cp(
                node, VPP_REAL_HUGE_PAGE_FILE, "{}".format(rootdir + VPP_HUGE_PAGE_FILE)
            )
        if (os.path.isfile(rootdir + VPP_GRUB_FILE) is not True) and (
            os.path.isfile(VPP_REAL_GRUB_FILE) is True
        ):
            autoconfig_cp(
                node, VPP_REAL_GRUB_FILE, "{}".format(rootdir + VPP_GRUB_FILE)
            )

        # Be sure the uio_pci_generic driver is installed
        cmd = "modprobe uio_pci_generic"
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            logging.warning("{} failed on node {} {}".format(cmd, node["host"], stderr))
Exemple #34
0
    def apply_cmdline(self, node, isolated_cpus):
        """
        Apply cmdline to the default grub file

        :param node: Node dictionary with cpuinfo.
        :param isolated_cpus: The isolated cpu string
        :type node: dict
        :type isolated_cpus: string
        :return The vpp cmdline
        :rtype string
        """

        vpp_cmdline = self.create_cmdline(isolated_cpus)
        if vpp_cmdline == '':
            return vpp_cmdline

        # Update grub
        # Save the original file
        rootdir = node['rootdir']
        grubcmdline = node['cpu']['grubcmdline']
        ofilename = rootdir + node['cpu']['grub_config_file'] + '.orig'
        filename = rootdir + node['cpu']['grub_config_file']

        # Write the output file
        # Does a copy of the original file exist, if not create one
        (ret, stdout, stderr) = VPPUtil.exec_command('ls {}'.format(ofilename))
        if ret != 0:
            if stdout.strip('\n') != ofilename:
                cmd = 'sudo cp {} {}'.format(filename, ofilename)
                (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
                if ret != 0:
                    raise RuntimeError('{} failed on node {} {}'.
                                       format(cmd, self._node['host'], stderr))

        # Get the contents of the current grub config file
        cmd = 'cat {}'.format(filename)
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError('{} failed on node {} {}'.format(
                cmd,
                self._node['host'],
                stderr))

        # Write the new contents
        # Get the Default Linux command line, ignoring commented lines
        content = ""
        lines = stdout.split('\n')
        for line in lines:
            if line == '':
                content += line + '\n'
                continue
            if line[0] == '#':
                content += line + '\n'
                continue

            ldefault = re.findall(r'{}=.+'.format(grubcmdline), line)
            if ldefault:
                content += vpp_cmdline + '\n'
            else:
                content += line + '\n'

        content = content.replace(r"`", r"\`")
        content = content.rstrip('\n')
        cmd = "sudo cat > {0} << EOF\n{1}\n".format(filename, content)
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError('{} failed on node {} {}'.format(
                cmd,
                self._node['host'],
                stderr))

        return vpp_cmdline
Exemple #35
0
    def apply_cmdline(self, node, isolated_cpus):
        """
        Apply cmdline to the default grub file

        :param node: Node dictionary with cpuinfo.
        :param isolated_cpus: The isolated cpu string
        :type node: dict
        :type isolated_cpus: string
        :return The vpp cmdline
        :rtype string
        """

        vpp_cmdline = self.create_cmdline(isolated_cpus)
        if len(vpp_cmdline):
            # Update grub
            # Save the original file
            rootdir = node["rootdir"]
            grubcmdline = node["cpu"]["grubcmdline"]
            ofilename = rootdir + node["cpu"]["grub_config_file"] + ".orig"
            filename = rootdir + node["cpu"]["grub_config_file"]

            # Write the output file
            # Does a copy of the original file exist, if not create one
            (ret, stdout,
             stderr) = VPPUtil.exec_command("ls {}".format(ofilename))
            if ret != 0:
                if stdout.strip("\n") != ofilename:
                    cmd = "sudo cp {} {}".format(filename, ofilename)
                    (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
                    if ret != 0:
                        raise RuntimeError("{} failed on node {} {}".format(
                            cmd, self._node["host"], stderr))

            # Get the contents of the current grub config file
            cmd = "cat {}".format(filename)
            (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
            if ret != 0:
                raise RuntimeError("{} failed on node {} {}".format(
                    cmd, self._node["host"], stderr))

            # Write the new contents
            # Get the Default Linux command line, ignoring commented lines
            content = ""
            lines = stdout.split("\n")
            for line in lines:
                if line == "":
                    content += line + "\n"
                    continue
                if line[0] == "#":
                    content += line + "\n"
                    continue

                ldefault = re.findall(r"{}=.+".format(grubcmdline), line)
                if ldefault:
                    content += vpp_cmdline + "\n"
                else:
                    content += line + "\n"

            content = content.replace(r"`", r"\`")
            content = content.rstrip("\n")
            cmd = "sudo cat > {0} << EOF\n{1}\n".format(filename, content)
            (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
            if ret != 0:
                raise RuntimeError("{} failed on node {} {}".format(
                    cmd, self._node["host"], stderr))

        return vpp_cmdline
Exemple #36
0
    def get_all_devices(self):
        """
        Returns a list of all the devices

        """

        node = self._node
        rootdir = node['rootdir']
        dpdk_script = rootdir + DPDK_SCRIPT
        cmd = dpdk_script + ' --status'
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError('{} failed on node {} {}'.format(
                cmd,
                node['host'],
                stderr))

        # Get the network devices using the DPDK
        # First get everything after using DPDK
        stda = stdout.split('Network devices using DPDK-compatible driver')[1]
        # Then get everything before using kernel driver
        using_dpdk = stda.split('Network devices using kernel driver')[0]
        self._dpdk_devices = self._create_device_list(using_dpdk)

        # Get the network devices using the kernel
        stda = stdout.split('Network devices using kernel driver')[1]
        using_kernel = stda.split('Other network devices')[0]
        self._kernel_devices = self._create_device_list(using_kernel)

        # Get the other network devices
        stda = stdout.split('Other network devices')[1]
        other = stda.split('Crypto devices using DPDK-compatible driver')[0]
        self._other_devices = self._create_device_list(other)

        # Get the crypto devices using the DPDK
        stda = stdout.split('Crypto devices using DPDK-compatible driver')[1]
        crypto_using_dpdk = stda.split('Crypto devices using kernel driver')[0]
        self._crypto_dpdk_devices = self._create_device_list(
            crypto_using_dpdk)

        # Get the network devices using the kernel
        stda = stdout.split('Crypto devices using kernel driver')[1]
        crypto_using_kernel = stda.split('Other crypto devices')[0]
        self._crypto_kernel_devices = self._create_device_list(
            crypto_using_kernel)

        # Get the other network devices
        crypto_other = stdout.split('Other crypto devices')[1]
        self._crypto_other_devices = self._create_device_list(crypto_other)

        # Get the devices used by the kernel
        for devk in self._kernel_devices.items():
            dvid = devk[0]
            device = devk[1]
            for i in device['interfaces']:
                cmd = "ip addr show " + i
                (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
                if ret != 0:
                    raise RuntimeError('{} failed on node {} {}'.format(
                        cmd,
                        node['host'],
                        stderr))
                lstate = re.findall(r'state \w+', stdout)[0].split(' ')[1]

                # Take care of the links that are UP
                if lstate == 'UP':
                    device['linkup'] = True
                    self._link_up_devices[dvid] = device

        for devl in self._link_up_devices.items():
            dvid = devl[0]
            del self._kernel_devices[dvid]
Exemple #37
0
    def _create_device_list(device_string):
        """
        Returns a list of PCI devices

        :param device_string: The devices string from dpdk_devbind
        :returns: The device list
        :rtype: dictionary
        """

        devices = {}

        ids = re.findall(PCI_DEV_ID_REGEX, device_string)
        descriptions = re.findall(r'\'([\s\S]*?)\'', device_string)
        unused = re.findall(r'unused=\w+|unused=', device_string)

        for i, j in enumerate(ids):
            device = {'description': descriptions[i]}
            if unused:
                device['unused'] = unused[i].split('=')[1].split(',')

            cmd = 'ls /sys/bus/pci/devices/{}/driver/module/drivers'. \
                format(ids[i])
            (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
            if ret == 0:
                device['driver'] = stdout.split(':')[1].rstrip('\n')

            cmd = 'cat /sys/bus/pci/devices/{}/numa_node'.format(ids[i])
            (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
            if ret != 0:
                raise RuntimeError('{} failed {} {}'.
                                   format(cmd, stderr, stdout))
            numa_node = stdout.rstrip('\n')
            if numa_node == '-1':
                device['numa_node'] = '0'
            else:
                device['numa_node'] = numa_node

            interfaces = []
            device['interfaces'] = []
            cmd = 'ls /sys/bus/pci/devices/{}/net'.format(ids[i])
            (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
            if ret == 0:
                interfaces = stdout.rstrip('\n').split()
                device['interfaces'] = interfaces

            l2_addrs = []
            for intf in interfaces:
                cmd = 'cat /sys/bus/pci/devices/{}/net/{}/address'.format(
                    ids[i], intf)
                (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
                if ret != 0:
                    raise RuntimeError('{} failed {} {}'.
                                       format(cmd, stderr, stdout))

                l2_addrs.append(stdout.rstrip('\n'))

            device['l2addr'] = l2_addrs

            devices[ids[i]] = device

        return devices
Exemple #38
0
    def get_all_devices(self):
        """
        Returns a list of all the devices

        """

        node = self._node
        rootdir = node['rootdir']
        dpdk_script = rootdir + DPDK_SCRIPT
        cmd = dpdk_script + ' --status'
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError('{} failed on node {} {}'.format(
                cmd,
                node['host'],
                stderr))

        # Get the network devices using the DPDK
        # First get everything after using DPDK
        stda = stdout.split('Network devices using DPDK-compatible driver')[1]
        # Then get everything before using kernel driver
        using_dpdk = stda.split('Network devices using kernel driver')[0]
        self._dpdk_devices = self._create_device_list(using_dpdk)

        # Get the network devices using the kernel
        stda = stdout.split('Network devices using kernel driver')[1]
        using_kernel = stda.split('Other network devices')[0]
        self._kernel_devices = self._create_device_list(using_kernel)

        # Get the other network devices
        stda = stdout.split('Other network devices')[1]
        other = stda.split('Crypto devices using DPDK-compatible driver')[0]
        self._other_devices = self._create_device_list(other)

        # Get the crypto devices using the DPDK
        stda = stdout.split('Crypto devices using DPDK-compatible driver')[1]
        crypto_using_dpdk = stda.split('Crypto devices using kernel driver')[0]
        self._crypto_dpdk_devices = self._create_device_list(
            crypto_using_dpdk)

        # Get the network devices using the kernel
        stda = stdout.split('Crypto devices using kernel driver')[1]
        crypto_using_kernel = stda.split('Other crypto devices')[0]
        self._crypto_kernel_devices = self._create_device_list(
            crypto_using_kernel)

        # Get the other network devices
        crypto_other = stdout.split('Other crypto devices')[1]
        self._crypto_other_devices = self._create_device_list(crypto_other)

        # Get the devices used by the kernel
        for devk in self._kernel_devices.items():
            dvid = devk[0]
            device = devk[1]
            for i in device['interfaces']:
                cmd = "ip addr show " + i
                (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
                if ret != 0:
                    raise RuntimeError('{} failed on node {} {}'.format(
                        cmd,
                        node['host'],
                        stderr))
                lstate = re.findall(r'state \w+', stdout)[0].split(' ')[1]

                # Take care of the links that are UP
                if lstate == 'UP':
                    device['linkup'] = True
                    self._link_up_devices[dvid] = device

        for devl in self._link_up_devices.items():
            dvid = devl[0]
            del self._kernel_devices[dvid]
Exemple #39
0
    def _create_device_list(device_string):
        """
        Returns a list of PCI devices

        :param device_string: The devices string from dpdk_devbind
        :returns: The device list
        :rtype: dictionary
        """

        devices = {}

        ids = re.findall(PCI_DEV_ID_REGEX, device_string)
        descriptions = re.findall(r'\'([\s\S]*?)\'', device_string)
        unused = re.findall(r'unused=[\w,]+', device_string)

        for i, j in enumerate(ids):
            device = {'description': descriptions[i]}
            if unused:
                device['unused'] = unused[i].split('=')[1].split(',')

            cmd = 'ls /sys/bus/pci/devices/{}/driver/module/drivers'. \
                format(ids[i])
            (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
            if ret == 0:
                device['driver'] = stdout.split(':')[1].rstrip('\n')

            cmd = 'cat /sys/bus/pci/devices/{}/numa_node'.format(ids[i])
            (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
            if ret != 0:
                raise RuntimeError('{} failed {} {}'.
                                   format(cmd, stderr, stdout))
            numa_node = stdout.rstrip('\n')
            if numa_node == '-1':
                device['numa_node'] = '0'
            else:
                device['numa_node'] = numa_node

            interfaces = []
            device['interfaces'] = []
            cmd = 'ls /sys/bus/pci/devices/{}/net'.format(ids[i])
            (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
            if ret == 0:
                interfaces = stdout.rstrip('\n').split()
                device['interfaces'] = interfaces

            l2_addrs = []
            for intf in interfaces:
                cmd = 'cat /sys/bus/pci/devices/{}/net/{}/address'.format(
                    ids[i], intf)
                (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
                if ret != 0:
                    raise RuntimeError('{} failed {} {}'.
                                       format(cmd, stderr, stdout))

                l2_addrs.append(stdout.rstrip('\n'))

            device['l2addr'] = l2_addrs

            devices[ids[i]] = device

        return devices
Exemple #40
0
    def device_info(node):
        """
        Show the device information.

        """

        if 'cpu' in node and 'total_mbufs' in node['cpu']:
            total_mbufs = node['cpu']['total_mbufs']
            if total_mbufs is not 0:
                print "Total Number of Buffers: {}".format(total_mbufs)

        vpp = VppPCIUtil(node)
        vpp.get_all_devices()
        linkup_devs = vpp.get_link_up_devices()
        if len(linkup_devs):
            print("\nDevices with link up (can not be used with VPP):")
            vpp.show_vpp_devices(linkup_devs, show_header=False)
            # for dev in linkup_devs:
            #    print ("    " + dev)
        kernel_devs = vpp.get_kernel_devices()
        if len(kernel_devs):
            print("\nDevices bound to kernel drivers:")
            vpp.show_vpp_devices(kernel_devs, show_header=False)
        else:
            print("\nNo devices bound to kernel drivers")

        dpdk_devs = vpp.get_dpdk_devices()
        if len(dpdk_devs):
            print("\nDevices bound to DPDK drivers:")
            vpp.show_vpp_devices(dpdk_devs,
                                 show_interfaces=True,
                                 show_header=False)
        else:
            print("\nNo devices bound to DPDK drivers")

        vpputl = VPPUtil()
        interfaces = vpputl.get_hardware(node)
        if interfaces == {}:
            return

        print("\nDevices in use by VPP:")

        if len(interfaces.items()) < 2:
            print("None")
            return

        print "{:30} {:6} {:4} {:7} {:4} {:7}". \
            format('Name', 'Socket', 'RXQs',
                   'RXDescs', 'TXQs', 'TXDescs')
        for intf in sorted(interfaces.items()):
            name = intf[0]
            value = intf[1]
            if name == 'local0':
                continue
            socket = rx_qs = rx_ds = tx_qs = tx_ds = ''
            if 'cpu socket' in value:
                socket = int(value['cpu socket'])
            if 'rx queues' in value:
                rx_qs = int(value['rx queues'])
            if 'rx descs' in value:
                rx_ds = int(value['rx descs'])
            if 'tx queues' in value:
                tx_qs = int(value['tx queues'])
            if 'tx descs' in value:
                tx_ds = int(value['tx descs'])

            print("{:30} {:>6} {:>4} {:>7} {:>4} {:>7}".format(
                name, socket, rx_qs, rx_ds, tx_qs, tx_ds))