Linux NVMe Commands
列出controller
# 列出主控制器
nvme id-ctrl /dev/nvme0
# 列出secondary controller
nvme list-secondary /dev/nvme0
创建namespace
# 创建50GB的ns
nvme create-ns /dev/nvme0 -nsze=97656250 --ncap=97656250 --flbas=0 -dps=0
返回的是ns的id
Attach namespace 到 controller
# attach 到主控制器
nvme attach-ns /dev/nvme0 -n $NSID -c 65
nvme ns-rescan /dev/nvme0
# attach 到secondary controller
nvme attach-ns /dev/nvme0 -c $VIRT_CNTLID -n $NSID
Detach
nvme detach-ns /dev/nvme0 -n $NSID -c 65
完整脚本
使用普通NVMe设备的流程
NVME_DEV=/dev/nvme0
SIZE_GB=512
BLOCK_SIZE=4096
VFNID=0
# Get the ID of the primary (host) controller
HOST_CNTLID=$(nvme id-ctrl $NVME_DEV -o json | jq .cntlid)
# Get the ID of the secondary (virtual function) controller
VIRT_CNTLID=$(nvme list-secondary $NVME_DEV -o json | jq '."secondary-controllers"[]|select(."virtual-function-number"=='$((VFNID + 1))')."secondary-controller-identifier"')
SIZE_BLOCKS=$((SIZE_GB * 1000000000 / BLOCK_SIZE))
echo "Primary controller ID: $HOST_CNTLID"
echo "Secondary controller ID: $VIRT_CNTLID"
echo "Creating namespace with $SIZE_BLOCKS $BLOCK_SIZE-byte blocks..."
# Create the new namespace, and capture the output, which should be "create-ns: Success, created nsid:32"
out=$(nvme create-ns $NVME_DEV --nsze=$SIZE_BLOCKS --ncap=$SIZE_BLOCKS --block-size $BLOCK_SIZE)
NSID=${out#*created nsid:}
echo "Created namespace $NSID"
# Attach the namespace to the host
nvme attach-ns $NVME_DEV -n $NSID -c $HOST_CNTLID
# Wait for the namespace to populate
while true; do
NSDEV=$(nvme list -o json | jq -r ".Devices[]|select(.NameSpace==$NSID).DevicePath")
if [ -n "$NSDEV" ]; then
break
fi
sleep 1
nvme ns-rescan $NVME_DEV
done
# Partition/format/image the new namespace
(...)
# Detach the new namespace from the primary controller
nvme detach-ns $NVME_DEV -c $HOST_CNTLID -n $NSID
# Attach it to the secondary controller
nvme attach-ns $NVME_DEV -c $VIRT_CNTLID -n $NSID
启用支持SR-IOV的NVMe设备的virtual function
#!/bin/bash # find device if [ $# -ne 2 ]; then echo "Usage: $0 <nvme_device> <vf_number>" echo "Example: $0 nvme2 4" exit 1 fi nvme_dev=$1 vf_num=$2 bdf=$(basename $(readlink /sys/class/nvme/$nvme_dev/device)) if [ $vf_num -gt 32 ]; then echo "VF number should be less than 32" exit 1 fi if [ -z "$bdf" ]; then echo "Cannot find device $nvme_dev. Exit!" exit 1 fi echo "NVMe dev : $nvme_dev" echo "BDF : $bdf" echo "VF number : $vf_num" # enable VF sudo nvme virt-mgmt /dev/$nvme_dev -c 65 -r 0 -a 1 -n 0 # Deallocate VQ sudo nvme virt-mgmt /dev/$nvme_dev -c 65 -r 1 -a 1 -n 0 # Dealoocate VI sudo nvme reset /dev/$nvme_dev for (( i=1; i<=$vf_num; i++ )) do sudo nvme virt-mgmt /dev/$nvme_dev -c $i -r 0 -n 4 -a 8 # Allocate VQ sudo nvme virt-mgmt /dev/$nvme_dev -c $i -r 1 -n 4 -a 8 # Aloocate VI done sudo bash -c "sudo echo 0 > /sys/bus/pci/devices/$bdf/sriov_drivers_autoprobe" # no autoprobe sudo bash -c "sudo echo $vf_num > /sys/class/nvme/$nvme_dev/device/sriov_numvfs" # enable VF # check for (( i=1; i<=$vf_num; i++ )) do sudo nvme virt-mgmt /dev/$nvme_dev -c $i -a 9 done sudo nvme list-secondary /dev/$nvme_dev | grep SC | head -n $(($vf_num*3))
为NVMe vf绑定vfio驱动
#!/bin/bash sudo modprobe vfio-pci # find device if [ $# -ne 3 ]; then echo "Usage: $0 <nvme_device> <vf_number> <is_vfio>" echo "Example: $0 nvme2 4 1" exit 1 fi nvme_dev=$1 vf_num=$2 is_vfio=$3 bdf=$(basename $(readlink /sys/class/nvme/$nvme_dev/device)) if [ $vf_num -gt 32 ]; then echo "VF number should be less than 32" exit 1 fi if [ -z "$bdf" ]; then echo "Cannot find device $nvme_dev. Exit!" exit 1 fi echo "NVMe dev : $nvme_dev" echo "BDF : $bdf" echo "VF number : $vf_num" echo "is_vfio : $is_vfio" for (( i=1; i<=$vf_num; i++ )) do vfbdf=$(basename $(readlink /sys/class/nvme/$nvme_dev/device/virtfn$(($i-1)))) if [ $is_vfio -eq 1 ]; then echo "Binding $vfbdf to vfio-pci" bash -c "echo $vfbdf > /sys/bus/pci/drivers/nvme/unbind" &> /dev/null echo vfio-pci > /sys/bus/pci/devices/$vfbdf/driver_override echo $vfbdf > /sys/bus/pci/drivers_probe else echo "Binding $vfbdf to nvme" bash -c "echo $vfbdf > /sys/bus/pci/drivers/vfio-pci/unbind" &> /dev/null echo nvme > /sys/bus/pci/devices/$vfbdf/driver_override echo $vfbdf > /sys/bus/pci/drivers_probe fi done