自动化编译dpdk

dpdk版本、网卡驱动版本、网卡固件版本、网卡型号之间有着强依赖的关系。特别是一些新网卡,容易出现一些版本不匹配的问题。我们可以先通过ethtool -i eth0命令和lspci -vvv -s [bus-info] | grep -i product命令来查看网卡的型号和固件版本。然后到mlx官网查看ofed各版本支持的网卡型号,如ofed-5.0只支持较低版本的cx6 dx固件。在这里插入图片描述
对于cx6 dx网卡,建议还是使用ofed-5.4版本,不然可能会出现各种各样的问题。确定好ofed版本之后,再去dpdk官网确定dpdk版本即可。特别需要注意的是dpdk-19.11开始支持cx6 dx网卡,所以如果用小于19.11的版本部署在cx6网卡上,dpdk将无法接管网卡。在这里插入图片描述
所以理论上,cx6 dx网卡搭配ofed-5.4和dpdk19.11就可以了,但是实际上咨询过mlx官方人员,建议ofed-5.4搭配dpdk-20.11使用,可能是19.11有一些bug吧。dpdk-20.11编译方式跟之前的版本差别挺大的,20.11编译需要使用meson和ninja,meson需要python3.5以上的版本,3.7当然也可以,我准备使用python3.7,由于线上环境复杂,我想实现一个自动化脚本,可以从python3开始自动化编译dpdk,实现过程中遇到了很多坑,在这里记录一下。

  1. 编译python3.7.8之后,使用pip3会报pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available,原因是python3.7和低版本的openssl不兼容,需要更新openssl到1.1以上
  2. 安装新版本的openssl后,执行openssl version报version `OPENSSL_1_1_1’ not found (required by openssl),原因是openssl动态库找不到了,需要将LD_LIBRARY_PATH重新指向新编译的openssl库。
  3. 编译python3.7之前,需要安装apt-get install libffi-dev,否则python3后面使用的时候会报No module named ‘_ctypes’ when using Value from module multiprocessing
#! /bin/bash
set -x

DPDK_VERSION=20.11.1

HOME_DIR=/root/
DPDK_XZ=dpdk-${DPDK_VERSION}.tar.xz
DPDK_TAR=dpdk-${DPDK_VERSION}.tar
DPDK_DIR=dpdk-stable-${DPDK_VERSION}

OPENSSL_TAR=OpenSSL_1_1_1d.tar.gz
OPENSSL_DIR=openssl-OpenSSL_1_1_1d

PY3_VERSION=3.7.8
PY3_XZ=Python-${PY3_VERSION}.tar.xz
PY3_TAR=Python-${PY3_VERSION}.tar
PY3_DIR=Python-${PY3_VERSION}

log_path="/var/log/build.log"

function logger() {
    local msg=$1
    local DATE=`date +"%F %T"`
    echo -e "[DPDK] ${DATE}: ${msg}" >> ${log_path}
    echo "[DPDK] ${DATE}: ${msg}"
}

function download_pkg() {
	# 可以把安装包上传到公司内部的存储服务器上
}

function install_openssl() {
    download_pkg ${OPENSSL_TAR}

    cd ${HOME_DIR}
    yes | rm -f ${OPENSSL_DIR}
    tar zxvf ${OPENSSL_TAR}
    cd ${OPENSSL_DIR}

    ./config --prefix=/usr/local/openssl
    make && make install

    yes | mv /usr/bin/openssl /usr/bin/openssl.old
    yes | mv /usr/lib64/openssl /usr/lib64/openssl.old
    yes | mv /usr/lib64/libssl.so /usr/lib64/libssl.so.old
    ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl
    ln -s /usr/local/openssl/include/openssl /usr/include/openssl
    ln -s /usr/local/openssl/lib/libssl.so /usr/lib64/libssl.so
    echo "/usr/local/openssl/lib" >> /etc/ld.so.conf
    ldconfig -v
    echo "export LD_LIBRARY_PATH=/usr/local/openssl/lib:$LD_LIBRARY_PATH" >> ~/.bashrc
    export LD_LIBRARY_PATH=/usr/local/openssl/lib:$LD_LIBRARY_PATH

    openssl_v=`openssl version | grep OpenSSL | awk '{print $2}'`

    if [[ ${openssl_v} != "1.1.1d" ]]; then
        logger "install openssl failed"
        exit 1
    fi
}

function install_py3() {
    openssl_v=`openssl version | grep OpenSSL | awk '{print $2}'`

    if [[ ${openssl_v} < "1.1.1d" ]]; then
        logger "openssl is older than 1.1.1d"
        install_openssl
    else
        logger "openssl is newer than 1.1.1d"
    fi
    
    download_pkg ${PY3_XZ}

    apt-get install -y libffi-dev

    cd ${HOME_DIR}
    xz -d ${PY3_XZ}
    tar -xf ${PY3_TAR}
    cd ${PY3_DIR}
    yes | mv /usr/local/bin/python3 /usr/local/bin/python3.bak
    yes | mv /usr/local/bin/pip3 /usr/local/bin/pip3.bak
    ./configure --prefix=/usr/local/python3.7 --with-openssl=/usr/local/openssl
    make && make install
    ln -s /usr/local/python3.7/bin/python3 /usr/local/bin/python3
    ln -s /usr/local/python3.7/bin/pip3 /usr/local/bin/pip3
    pip3 install pyelftools

    py3_version=`/usr/local/python3.7/bin/python3 -V | grep 'Python' | awk '{print $2}'`

    if [[ ${py3_version} == "3.7.8" ]]; then
        logger "install py3 success"
    else
        logger "install py3 fail"
        exit 1
    fi
}

function install_ninja_meson() {
    pip3 install meson
    yes | mv /usr/local/bin/meson /usr/local/bin/meson.bak
    ln -s /usr/local/python3.7/bin/meson /usr/local/bin/meson

    pip3 install ninja
    yes | mv /usr/local/bin/ninja /usr/local/bin/ninja.bak
    ln -s /usr/local/python3.7/bin/ninja /usr/local/bin/ninja
}

function install_dpdk() {
    cd ${HOME_DIR}
    
    download_pkg ${DPDK_XZ}

    cd ${HOME_DIR}
    yes | rm -rf ${DPDK_DIR}
    xz -d ${DPDK_XZ}
    tar -xf ${DPDK_TAR}
    cd ${DPDK_DIR}
    
    meson build --prefix=/root/dpdk-stable-20.11.1/mydpdk -Denable_kmods=true

    ninja -C build install
    echo "/root/dpdk-stable-20.11.1/mydpdk/lib/x86_64-linux-gnu/" >> /etc/ld.so.conf

    /sbin/ldconfig


}

function main() {

    py3_version=`/usr/local/bin/python3 -V | grep 'Python' | awk '{print $2}'`

    if [[ ${py3_version} < "3.7.0" ]]; then
        logger "py3 version older than 3.7.0"
        install_py3
    fi

    apt-get install -y libnuma-dev build-essential

    install_ninja_meson
    install_dpdk
}

main

遇到的很多坑其实还是python3.7的环境问题,估计使用python3.5的话问题会少很多。秉承着用新不用旧的原则,本来还想编译dpdk-22-11的,但是遇到了更负责的环境问题,只好作罢。果然,在使用开源软件方面,还是要用老的稳定版本,这样坑就少一些。事实上cx6 dx网卡使用dpdk-19.11也可以,19版本可以使用make编译,在我的环境上会简单很多。只需要解压后,修改config/common_base,打开mlx5编译开关:CONFIG_RTE_LIBRTE_MLX5_PMD=y,执行make install T=x86_64-native-linuxapp-gcc -j16编译dpdk就可以了。
编译dpdk前其实还有些前置步骤,就是安装ofed和配置大页内存,在我的debian操作系统中我也实现了自动化,安装ofed就不谈了,主要是在安装完后需要执行rm -rf /lib/udev/rules.d/82-net-setup-link.rules再重启,不然网卡名会变;配置大业内存的脚本如下,仅供参考,不建议使用。

function update_grub() {
    MEM=$(cat /proc/meminfo |grep MemTotal |awk '{print $2}')
    mem=$((${MEM} / 1024 / 1024))
    threshold=$((${mem} / 2))
    
    if [ ${threshold} -gt "64" ]; then
        hugepages=64
    else
        hugepages=${threshold}
    fi

    GRUB_LINE=`grep '^GRUB_CMDLINE_LINUX_DEFAULT'  /etc/default/grub`
    grub_line=`echo ${GRUB_LINE} | awk -F '"' '{print $2}'`
    logger "grub_line: ${grub_line}"
    g_default_hugepagesz=`echo ${grub_line} | awk -F 'default_hugepagesz=' '{print $2}' | awk '{print $1}'`

    if [ -n ${g_default_hugepagesz} ]; then
        sed -i "s/default_hugepagesz=${g_default_hugepagesz}//" /etc/default/grub
    fi

    g_hugepagesz=`echo ${grub_line} | awk -F 'hugepagesz=' '{print $2}' | awk '{print $1}'`

    if [ -n ${g_hugepagesz} ]; then
        sed -i "s/hugepagesz=${g_hugepagesz}//" /etc/default/grub
    fi

    g_hugepages=`echo ${grub_line} | awk -F 'hugepages=' '{print $2}' | awk '{print $1}'`

    if [ -n ${g_hugepages} ]; then
        sed -i "s/hugepages=${g_hugepages}//" /etc/default/grub
    fi

    grub_line=`grep '^GRUB_CMDLINE_LINUX_DEFAULT'  /etc/default/grub | awk -F '"' '{print $2}'`
    new_line="default_hugepagesz=1G hugepagesz=1G hugepages=${hugepages}G"

    sed -i "s/${grub_line}/${grub_line} ${new_line}/g" /etc/default/grub
    /usr/sbin/update-grub
}

由于安装ofed后配置大页内存之后,需要重启机器,所以建议使用ansible playbook来实现完整的自动化部署,playbook脚本中可以通过notify handler wait_for_connection来控制机器重启,具体就不赘述了,谷歌即可。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值