Вот как мне удалось заставить Proxmox работать с Infiniband и SR-IOV. В качестве железа использовался коммутатор Mellanox (sx6036) и сетевая карта Mellanox Cx-4 100Gbps EDR с двумя (или одним) портами. Убедитесь, что у вас стоит последняя версия прошивки. НАСКОЛЬКО МНЕ ИЗВЕСТНО, ЭТО НЕ РАБОТАЕТ С OPENSM И ДЛЯ SR-IOV НУЖЕН КОММУТАТОР MELLANOX.
На вашем коммутаторе включите SM и виртуализацию, затем перезапустите службу SM, включив или выключив её, либо перезагрузив коммутатор:
- ib sm enable
- ib sm virt enable
- configuration write
Когда это настроено, нужно включить IOMMU и активировать SR-IOV на железе. Этот процесс зависит от конкретного оборудования, поэтому он не рассматривается в этом руководстве. Конфигурацию IOMMU в Proxmox можно сделать, следуя инструкции:
После этого установите следующие пакеты:
apt install -y infiniband-diags ibutils rdma-core rdmacm-utils mstflint
Проверьте линк, узлы и запустите диагностику:
ibstat — ОБРАТИТЕ ВНИМАНИЕ НА НАЗВАНИЕ HCA
ibnodes
ibdiagnet
Определяем шину карты Mellanox и делаем запрос:
lspci | grep -i mellanox
mstflint -d <здесь bus id>
Включаем SR-IOV и 4 виртуальных функции (или сколько вам нужно):
mstconfig -d <здесь bus id> set SRIOV_EN=1 NUM_OF_VFS=4
Дальше — спасибо Jose-d:
vim /etc/systemd/system/mellanox_initvf.service
Вставьте следующее, ОБЯЗАТЕЛЬНО ОБНОВИТЕ HCA:
[Unit]
After=network.target
[Service]
Type=oneshot
# примечание: меняйте под своё железо:
ExecStart=/bin/bash -c "/usr/bin/echo 4 > /sys/class/infiniband/<HCA ЗДЕСЬ>/device/sriov_numvfs"
ExecStart=/usr/local/bin/initIbGuids.sh
StandardOutput=journal
TimeoutStartSec=60
RestartSec=60
[Install]
WantedBy=multi-user.target
Теперь включаем сервис:
systemctl enable mellanox_initvf.service
Создаём скрипт:
vim /usr/local/bin/initIbGuids.sh
Вставьте следующее:
#!/bin/bash
first_dev=$(ibstat --list_of_cas | head -n 1)
node_guid=$(ibstat ${first_dev} | grep "Node GUID" | cut -d ':' -f 2 | xargs | cut -d 'x' -f 2)
port_guid=$(ibstat ${first_dev} | grep "Port GUID" | cut -d ':' -f 2 | xargs | cut -d 'x' -f 2)
echo "first dev: $first_dev"
echo "node guid: $node_guid"
echo "port_guid: $port_guid"
if ip link show $first_dev &> /dev/null ; then
for vf in {0..3}; do
vf_guid=$(echo "${port_guid::-5}cafe$((vf+1))" | sed 's/..\B/&:/g')
echo "vf_guid для vf $vf — $vf_guid"
ip link set dev ${first_dev} vf $vf port_guid ${vf_guid}
ip link set dev ${first_dev} vf $vf node_guid ${vf_guid}
ip link set dev ${first_dev} vf $vf state auto
done
fi
Не забудьте выставить права для файла:
chmod 777 /usr/local/bin/initIbGuids.sh
Теперь SR-IOV настроен и готов к подключению к виртуальной машине.
Из ВМ мы видим полный линк на устройстве SR-IOV, и оно находится в активном состоянии.
На вашем коммутаторе включите SM и виртуализацию, затем перезапустите службу SM, включив или выключив её, либо перезагрузив коммутатор:
- ib sm enable
- ib sm virt enable
- configuration write
Когда это настроено, нужно включить IOMMU и активировать SR-IOV на железе. Этот процесс зависит от конкретного оборудования, поэтому он не рассматривается в этом руководстве. Конфигурацию IOMMU в Proxmox можно сделать, следуя инструкции:
После этого установите следующие пакеты:
apt install -y infiniband-diags ibutils rdma-core rdmacm-utils mstflint
Проверьте линк, узлы и запустите диагностику:
ibstat — ОБРАТИТЕ ВНИМАНИЕ НА НАЗВАНИЕ HCA
ibnodes
ibdiagnet
Определяем шину карты Mellanox и делаем запрос:
lspci | grep -i mellanox
mstflint -d <здесь bus id>
Включаем SR-IOV и 4 виртуальных функции (или сколько вам нужно):
mstconfig -d <здесь bus id> set SRIOV_EN=1 NUM_OF_VFS=4
Дальше — спасибо Jose-d:
vim /etc/systemd/system/mellanox_initvf.service
Вставьте следующее, ОБЯЗАТЕЛЬНО ОБНОВИТЕ HCA:
[Unit]
After=network.target
[Service]
Type=oneshot
# примечание: меняйте под своё железо:
ExecStart=/bin/bash -c "/usr/bin/echo 4 > /sys/class/infiniband/<HCA ЗДЕСЬ>/device/sriov_numvfs"
ExecStart=/usr/local/bin/initIbGuids.sh
StandardOutput=journal
TimeoutStartSec=60
RestartSec=60
[Install]
WantedBy=multi-user.target
Теперь включаем сервис:
systemctl enable mellanox_initvf.service
Создаём скрипт:
vim /usr/local/bin/initIbGuids.sh
Вставьте следующее:
#!/bin/bash
first_dev=$(ibstat --list_of_cas | head -n 1)
node_guid=$(ibstat ${first_dev} | grep "Node GUID" | cut -d ':' -f 2 | xargs | cut -d 'x' -f 2)
port_guid=$(ibstat ${first_dev} | grep "Port GUID" | cut -d ':' -f 2 | xargs | cut -d 'x' -f 2)
echo "first dev: $first_dev"
echo "node guid: $node_guid"
echo "port_guid: $port_guid"
if ip link show $first_dev &> /dev/null ; then
for vf in {0..3}; do
vf_guid=$(echo "${port_guid::-5}cafe$((vf+1))" | sed 's/..\B/&:/g')
echo "vf_guid для vf $vf — $vf_guid"
ip link set dev ${first_dev} vf $vf port_guid ${vf_guid}
ip link set dev ${first_dev} vf $vf node_guid ${vf_guid}
ip link set dev ${first_dev} vf $vf state auto
done
fi
Не забудьте выставить права для файла:
chmod 777 /usr/local/bin/initIbGuids.sh
Теперь SR-IOV настроен и готов к подключению к виртуальной машине.
Из ВМ мы видим полный линк на устройстве SR-IOV, и оно находится в активном состоянии.

. Я использую службу, а не запускаю её при поднятии интерфейса, потому что с таким способом были проблемы со стабильностью — примерно каждый четвертый перезапуск просто не срабатывал. А когда сделал её службой, всё всегда работает без сбоев.