• SRIOV 分离 VF 网口


    SRIOV.sh

    #!/bin/bash
    
    __FileName__=""
    __Author__="ShiWei"
    __Time__="/2021/05/08"
    __Version__="V1"
    
    # 打印命令  并且  执行命令  函数
    execute_and_pirnt_cmd() {
        # 第二个 参数 所执行命令 的注释
    #    echo -e "
     $2 "
        printf "
    %12s %-s
    " " " $2
        echo  "[root@shiwei ~]# ${1}"
        res=-1  # 无 特殊字符命令的 输出状态
        result=0  # 有特殊字符命令的 输出结果
        echo $1 | grep -E  ['!'@#$%^&*()><|_+] &> /dev/zero
        # 0 : 有 特殊字符 ;  1 : 无 特殊字符
        if [ $? -ne 0 ];then
            $1
            res=$?
        else
            # 命令之后包含 管道符
            echo $1 > cmd_script
            chmod 777 cmd_script
            bash cmd_script
    #        ./cmd_script > result_file
    #        result=`cat result_file`
    #        rm -rf result_file
            rm -rf cmd_script
    #        return ${result}
    #        res=$?   # 此种方式 获取命令 执行结果 失败
        fi
    
        return ${res}
    }
    
    
    # 自动判断 该参数是否 配置,
    read_or_config () {
        # 必须保证两个参数
        # 先判断 该参数是否已 配置
        if [ -z `eval 'echo $'"${2}"` ]; then
            read -p "$1" "$2"
        fi
    }
    
    # 优化网口
    optim_net_card () {
        # 优化 物理网口
        ip link set ${1// /} mtu 9000
        combined=`ethtool  -l  ${1} | grep "Combined" | head -1 | awk -F ":" '{print $2}'`
        ethtool -L ${1} combined  ${combined// /}
            # 设置网卡最大缓存
        rx_num=`ethtool -g ${1} | grep -i rx:  | sed -n  '1p' | cut -d: -f2`
        tx_num=`ethtool -g ${1} | grep -i tx:  | sed -n  '1p' | cut -d: -f2`
        ethtool -G ${1} rx  ${rx_num// /}  tx  ${tx_num// }
    } &> /dev/zero
    
    
    bus () {
        echo '[root@Num_eigth_46 ~]# lspci -vvv | grep -i  ether'
        lspci -vvv | grep -i ether
    
        printf "%-15s %-8s %-15s %-15s %-20s %-32s %18s
    "  "网口名"  "  状态"  "      Bus 号"  "   驱动名"  "     驱动版本" "             固件版本"  "  槽位号"
        for i in `cat /proc/net/dev | egrep -iv 'lo:|virbr|vnet|face|inter' | cut -d: -f1 | sort`
        do
    
            printf "%-15s" $i
            state=`ip addr  show $i | sed '1p' -n  | awk -F state '{print $2}' | awk '{print $1}'`
            printf "%-8s" $state
            bus=`ethtool -i $i | grep -i bus | awk -F info: '{print $2}'`
            printf "%-15s" $bus
            driver_name=`ethtool -i $i | sed '1p' -n | awk -F river: '{print $2}'`
            printf "%-15s" $driver_name
            driver_ver=`ethtool -i $i | sed '2p' -n | awk -F sion: '{print $2}'`
            printf "%-20s" $driver_ver
            fw_version=`ethtool -i $i | sed '3p' -n | cut -d: -f2`
            printf "%-32s" "$fw_version"
            slots=`lspci -v -s ${bus} | grep 'Physical Slot' | cut -d ':' -f2 | grep -v 'Input/output'`
            printf "%-6s
    " $slots
        done
    }
    
    
    # [[ ${arr[@]/ens4f0/} != ${arr[@]} ]] && echo "Yes" || echo "No"
    echo "#############################################################################################"
    echo "#####################             SRIOV  自动化脚本                  ########################"
    echo "#############################################################################################"
    echo
    printf "******  若当前为 SSH 链接机器, 则链接 IP 不可为当前所要配置SRIOV的网卡的IP   ******** 
    "
    printf "******  若该卡的是1G 电口卡,且驱动为 igb, 则SRIOV 的配置方法为 modprobe igb max_vfs=2,2,2,2 
     当同时存在多个驱动为 igb 的1G电口卡时, 默认优先分离板载的,  ****
    "
    printf "******  到当前为止 , 对 intel , mellanox, wangxun 卡 均有效   *****
    "
    printf "******  需要打 VF 驱动的网卡请自行先把 VF  驱动打好,否则即使分离 VF 口成功了, 
     由于不存在 VF 驱动的拉起, 你是看不到 VF 网口名的,但是各个 VF 口的 PCI 设备是存在的 
    "
    echo "#############################################################################################"
    echo
    
    
    
    
    PLATFORM='intel'
    VIRT_BIOS='yes'
    int_name=""
    BUS=""
    VF_NUM="0"
    CURR_VF_NUM="0"
    VF_ROOT=""
    MAX_VF=""
    TP_1G_SPEED="0"
    
    echo
    echo
    # <1. 判断 CPU 平台
    lscpu | sed '19p' -n | grep -i "VT-x"      # intel
    if [ $? -eq 0 ]; then
        echo "该系统 CPU 为 Intel 平台"
    else
        lscpu | sed '19p' -n | grep -i "amd-v" # amd
        if [ $? -eq 0 ]; then
            PLATFORM="amd"
            echo "*********** 该系统 CPU 为 AMD 平台"
        else
            PLATFORM="other"
            echo "*********** 该系统 CPU 为未知 平台"
            exit
        fi
    fi
    
    
    # <2.  判断 系统是否 开启 IOMMU, Intel 平台 在 /etc/default/grub 文件中添加 "intel_iommu=on iommu=pt",
        # Intel 平台 开启 IOMMU
        # 判断 Intel 平台 是否开启 IOMMU
    if [ "$PLATFORM" == "intel" ]; then
        virt-host-validate | grep -i warn
        if [ $? -eq 0 ]; then
            grubby --update-kernel=`grubby --default-kernel` --args="intel_iommu=on iommu=pt"
            grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg
            echo "*********** 该 Intel 平台系统内核已配置 IOMMU, 请重启就好 ......."
        fi
    fi
    
        # 提示 要重启, 使其新添加的内核 参数 生效
        # AMD  平台 无需开启 IOMMU, 自动开启
    
    # <3. 判断 系统 BIOS 是否开启 SRIOV 虚拟化开关
        # Intel 平台在 Bios 下开启 VT-D 虚拟化开关
        # AMD 平台需要在 Bios 下开启 SRIOV 和 SVM 两个 开关
    virt-host-validate | grep "/dev/kvm exists" | grep -i "fail"
    if [ $? -eq 0 ]; then
        VIRT_BIOS="no"
    fi
    
    if [ "$VIRT_BIOS" == "no" ];then
        if [ "$PLATFORM" == "amd" ]; then
            modprobe kvm
            modprobe ccp
            modprode kvm_amd
            echo "*********** 该 AMD 平台系统在 BIOS 下 未 开启虚拟化 SRIOV 和 SVM 开关, 请开启........."
            exit
        elif [ "$PLATFORM" == "intel" ]; then
            modprobe kvm
            mobprobe kvm_intel
            echo "*********** 该 Intel 平台系统在 BIOS 下 未 开启虚拟化 VT-D 开关, 请开启........."
            exit
        fi
    else
        echo "*********** 该 ${PLATFORM} 平台系统在 BIOS 下已开启虚拟化开关。"
    fi
    
    echo
    # 展示 SRIOV  vF 信息
    bus
    echo
    
    
    # 输入待测网口名
    while :
    do
        read_or_config "请输入本机待测网口名:" int_name
    
        cat /proc/net/dev | egrep -iv 'lo:|virbr|vnet|face|inter' | cut -d: -f1 | grep ${int_name// /} &> /dev/zero
        if [ $? -eq 0 ];then
            break
        else
            echo "Sorry !本机无此网口,  请重新输入.........."
            int_name=""
        fi
    done
    echo
    # 获取网卡 品牌 信息
    bus_str=`ethtool -i ${int_name} | grep 'bus-info' | awk '{print $2}' | sed 's# ##g'`
    driver_name=`ethtool -i ${int_name} | grep 'driver:' | awk '{print $2}' | sed 's# ##g'`
    type_str=`lspci -vvv | grep 'Ethernet controller' | grep "${bus_str#*:}" | awk '{print $4,$5}' | tr A-Z a-z `
    # 获取网卡是电口还是 光口(TP: 电口;  FIBRE: 光口)
    cable_type=`ethtool ${int_name} | grep 'Supported ports:' | sed -r  's#.*[(.*)]$#1#g' | sed 's/ //g'`
    # 获取网卡当前速率
    net_curr_speed=`ethtool ${int_name} | grep 'Speed:' | awk '{print $2}'`
    # 判断该网卡是 几 P 的(几个接口的)
    net_port_total=`ls -al "/sys/bus/pci/drivers/${driver_name}/" | grep ${bus_str%.*} | wc -l`
    # 判断当前 网口是 该网卡的 第几个 接口
    net_port_num=${bus_str##*.}
    # 当前 该网卡所有 网口的 vf 数量
    declare -a every_curr_vfs
    
    for num in $(seq 0 $(echo $((4-1))))
    do
        every_curr_vfs[${num}]=`cd  /sys/bus/pci/drivers/${driver_name} && cat ${bus_str%.*}.${num}/sriov_numvfs`
    done
    
    
    if [ "${cable_type}" == "TP" -a "${driver_name}" == "igb" ]; then
        echo "******** 该网卡接口为电口, 且速率为 ${net_curr_speed}"
        TP_1G_SPEED="1"
    
    elif [ "${cable_type}" == "FIBRE" ]; then
        echo "******** 该网卡接口为光口 "
    fi
    
    
    #*	表示任意字符串。
    #[abc]	表示 a、b、c 三个字符中的任意一个。比如,[15ZH] 表示 1、5、Z、H 四个字符中的任意一个。
    #[m-n]	表示从 m 到 n 的任意一个字符。比如,[0-9] 表示任意一个数字,[0-9a-zA-Z] 表示字母或数字。
    #|	表示多重选择,类似逻辑运算中的或运算。比如,abc | xyz 表示匹配字符串 "abc" 或者 "xyz"。
    
    case ${type_str} in
        *intel*)
            brand="intel"
        ;;
        *mellanox*)
            brand="mellanox"
        ;;
        *wangxun*)
            brand="wangxun"
        ;;
        *)
            brand="no"
        ;;
    esac
    
    echo "******** 网卡品牌为: ${brand}"
    
    
    cd "/sys/bus/pci/devices/"
    	# 等价地址
    #	/sys/class/net/<网口名>/device
    
    # 获取 Bus 号
    BUS=`ethtool -i ${int_name} | grep -i bus | awk -F info: '{print $2}'`
    BUS=${BUS// /}
    echo "*********** ${int_name} 网口的 BUS 号为: $BUS"
    #VF_ROOT="/sys/bus/pci/devices/${BUS}"
    #cd VF_ROOT
    # 展示 可分离的 最大 VF 口数量
    MAX_VF=`cat   ${BUS// /}/sriov_totalvfs`
    CURR_VF_NUM=`cat   ${BUS// /}/sriov_numvfs`
    echo "*********** ${int_name} 网口可分离的最大 VF 数量为: ${MAX_VF}"
    echo "*********** ${int_name} 网口当前已分离的 VF 口数量为: ${CURR_VF_NUM}"
    echo
    
    # 设置 VF
    while :
    do
        read -p "请输入${int_name} 网口要分离的 VF 口数量:" VF_NUM
            # 判断输入得是否有效
        if [[ ${VF_NUM// /} -gt $MAX_VF || ${VF_NUM// /} -lt 0 ]];then
            echo "              可分离 VF 口有效范围为: (0 <= VF <= ${MAX_VF})"
        else
            # 判断是否不为 1G 电口卡
            if [ "${TP_1G_SPEED}" == "0" ]; then
                echo ${VF_NUM} > ${BUS// /}/sriov_numvfs
            else
                modprobe -r igb
                sleep 1
                # 给该网卡所有网口
                every_curr_vfs[${net_port_num}]=${VF_NUM}
                config_str="${every_curr_vfs[0]},${every_curr_vfs[1]},${every_curr_vfs[2]},${every_curr_vfs[3]}"
                modprobe igb max_vfs=${config_str}
    #            modprobe igb max_vfs=2,2,2,2
                echo
            fi
            echo "*********** VF 口分离完成。"
            wait
            sleep 1
            break
        fi
    done
    
    sleep 7
    # 展示 所有 创建的 VF 口
    if [[ "${VF_NUM}" -ne "0" ]]; then
        #bus | grep "${int_name}v"
        echo "在 ${int_name} 物理网口上所创建的所有 VF 口如下:"
        all_vf=($(cat /proc/net/dev | egrep -iv 'lo:|virbr|vnet|face|inter' | cut -d: -f1 | egrep -i "${int_name}.{1,}" | sort --field-separator=" " --key=3))
        for vf in $(seq $(echo $((${VF_NUM// /} - 1 ))) -1  0)
        do
            if [ `expr ${vf} % 5` == "0" ]; then
                printf "
    "
            fi
            printf "   ${all_vf[${vf}]}   "
        done
        echo "   ${all_vf[0]}   "
        # 设置物理口的 mtu 为 9000
        optim_net_card ${int_name}
        # 设置 所有 VF 口 的 mtu 为 9000
        for vf_dev in `cat /proc/net/dev | egrep -iv 'lo:|virbr|vnet|face|inter' | cut -d: -f1 | egrep -i "${int_name}[a-z]{1,}" | sort --field-separator=" " --key=3 | awk '{print $1}'`
        do
    #        ip link set ${vf_dev// /} mtu 9000
            optim_net_card ${vf_dev}
        done
    fi
    echo
    echo
    
    # 优化 物理网口
        # 设置最大队列
    #combined=`ethtool  -l  ${int_name} | grep "Combined" | head -1 | awk -F ":" '{print $2}'`
    #ethtool -L ${int_name} combined  ${combined}
    #    # 设置网卡最大缓存
    #rx_num=`ethtool -g ${int_name} | grep -i rx  | sed -n  '1p' | cut -d: -f2`
    #tx_num=`ethtool -g ${int_name} | grep -i tx  | sed -n  '1p' | cut -d: -f2`
    #ethtool -G ${int_name} rx  ${rx_num}  tx  ${tx_num}
    
    # DHCP  获取 IP
    dhclient -r
    dhclient &> /dev/zero
    
    # 善意的提醒
    # 1. 测试 SRIOV bond 时 , 别忘记安装  python3 了
    
    
    
    
    
    
    
  • 相关阅读:
    Java学习之Java历史版本
    小数的二进制转换
    cpp反汇编调试一
    理解 typedef 定义的函数指针
    mov 与 lea 区别
    asmlinkage的用法
    秒的换算:ms(毫秒),μs(微秒),ns(纳秒),ps(皮秒)
    Java字节码例子解析
    Go程序的一生是怎样的?
    Linux内核 hlist_head/hlist_node结构解析
  • 原文地址:https://www.cnblogs.com/shiwei1930/p/14920144.html
Copyright © 2020-2023  润新知