#!/bin/bash # # Initialize SRIOV virtual devices # # This is usually run automatically by systemd after a hardware activation # event in udev has triggered a start of the rdma.service unit port=1 function __get_parent_pci_dev() { pushd /sys/bus/pci/devices/$pci_dev >/dev/null 2>&1 ppci_dev=`ls -l physfn | cut -f 2 -d '/'` popd >/dev/null 2>&1 } function __get_parent_ib_dev() { ib_dev=`ls -l | awk '/'$ppci_dev'/ { print $9 }'` } function __get_parent_net_dev() { for netdev in /sys/bus/pci/devices/$ppci_dev/net/* ; do if [ "$port" -eq `cat $netdev/dev_port` ]; then netdev=`basename $netdev` break fi done } function __get_vf_num() { pushd /sys/bus/pci/devices/$ppci_dev >/dev/null 2>&1 vf=`ls -l virtfn* | awk '/'$pci_dev'/ { print $9 }' | sed -e 's/virtfn//'` popd >/dev/null 2>&1 } function __en_sriov_set_vf() { pci_dev=$1 shift [ "$1" = "port" ] && port=$2 && shift 2 # We find our parent device by the netdev registered port number, # however, the netdev port numbers start at 0 while the port # numbers on the card start at 1, so we subtract 1 from our # configured port number to get the netdev number let port-- # Now we need to fill in the necessary information to pass to the ip # command __get_parent_pci_dev __get_parent_net_dev __get_vf_num # The rest is easy. Either the user passed valid arguments as options # or they didn't ip link set dev $netdev vf $vf $* } function __ib_sriov_set_vf() { pci_dev=$1 shift [ "$1" = "port" ] && port=$2 && shift 2 guid="" __get_parent_pci_dev __get_parent_ib_dev [ -f $ib_dev/iov/$pci_dev/ports/$port/gid_idx/0 ] || return while [ -n "$1" ]; do case $1 in guid) guid=$2 shift 2 ;; pkey) shift 1 break ;; *) echo "Unknown option in $src" shift ;; esac done if [ -n "$guid" ]; then guid_idx=`cat "$ib_dev/iov/$pci_dev/ports/$port/gid_idx/0"` echo "$guid" > "$ib_dev/iov/ports/$port/admin_guids/$guid_idx" fi i=0 while [ -n "$1" ]; do for pkey in $ib_dev/iov/ports/$port/pkeys/*; do if [ `cat $pkey` = "$1" ]; then echo `basename $pkey` > $ib_dev/iov/$pci_dev/ports/$port/pkey_idx/$i let i++ break fi done shift done } [ -d /sys/class/infiniband ] || return pushd /sys/class/infiniband >/dev/null 2>&1 if [ -z "$*" ]; then src=/etc/rdma/sriov-vfs [ -f "$src" ] || return grep -v "^#" $src | while read -a args; do # When we use read -a to read into an array, the index starts at # 0, unlike below where the arg count starts at 1 port=1 next_arg=1 [ "${args[$next_arg]}" = "port" ] && next_arg=3 case ${args[$next_arg]} in guid|pkey) __ib_sriov_set_vf ${args[*]} ;; mac|vlan|rate|spoofchk|enable) __en_sriov_set_vf ${args[*]} ;; *) ;; esac done else [ "$2" = "port" ] && next_arg=$4 || next_arg=$2 case $next_arg in guid|pkey) __ib_sriov_set_vf $* ;; mac|vlan|rate|spoofchk|enable) __en_sriov_set_vf $* ;; *) ;; esac fi popd >/dev/null 2>&1