USBIP на CentOS 7 (USB через сеть)

Серверная

Репозиторий:

# rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
# rpm -ivh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm

Установка:

# yum install kmod-usbip
# yum install usbip-utils

Загрузить модули:

# modprobe usbip-core
# modprobe usbip-host
# modprobe vhci-hcd

Проверить загруженные модули:

# lsmod | grep usbip

Запустить сервер:

# usbipd -D

Открыть порт в фаерволе:

# firewall-cmd --zone=public --add-port=3240/tcp --permanent
# firewall-cmd --reload

Для просмотра USB устройств нужно выполнить команду:

# usbip list -l
 - busid 1-1.1.1 (0a89:0025)
   Aktiv : Rutoken lite (0a89:0025)

 - busid 1-1.1.2 (0a89:0025)
   Aktiv : Rutoken lite (0a89:0025)

 - busid 1-1.1.3 (0a89:0025)
   Aktiv : Rutoken lite (0a89:0025)

 - busid 1-1.1.4 (0a89:0025)
   Aktiv : Rutoken lite (0a89:0025)

Необходимые устройства расшарить командой:

# usbip bind -b 1-1.1.1

Подключиться к устройству на сервере и отключиться (это делается из-за бага. иначе клиент видит расшариное устройство, но не может подключиться, ошибка: «usbip err: usbip_windows.c: 829 (attach_device) cannot find device«):

# usbip attach -r 192.168.2.24 -b 1-1.1.1
# usbip detach -p 0

Клиент Windows 10

Скачать клиент для Windows

В архиве присутствует исправленный usbip.exe и оригинальный (usbip.orig.exe).

В архиве присутствует драйвер USBIPEnum.inf.

Для установки драйвера нужно открыть диспетчер устройств, выделить текущий ПК

В верхнем меню Действие -> Установить старое устройство

выбрать Установить оборудования, выбранного из списка и Далее

выбрать Показать все устройства и Далее

нажать Установить с диска…

выбрать USBIPEnum.inf и нажать Открыть

выбрать USB/IP Enumerator и нажать Далее

 

Посмотреть список доступных устройств:

C:\usbip> usbip -l %server-ip%

Пример результата:

C:\usbip>usbip.exe -l 192.168.2.24
- 192.168.2.24
   1-1.2: SanDisk Corp. : unknown product (0781:5597)
        : /sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2
        : (Defined at Interface level) (00/00/00)

 1-1.1.4: unknown vendor : unknown product (0a89:0025)
        : /sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1.4
        : (Defined at Interface level) (00/00/00)

 1-1.1.3: unknown vendor : unknown product (0a89:0025)
        : /sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1.3
        : (Defined at Interface level) (00/00/00)

 1-1.1.2: unknown vendor : unknown product (0a89:0025)
        : /sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1.2
        : (Defined at Interface level) (00/00/00)

 1-1.1.1: unknown vendor : unknown product (0a89:0025)
        : /sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1.1
        : (Defined at Interface level) (00/00/00)

Подключить устройство:

C:\usbip>usbip.exe -a 192.168.2.24 1-1.2

При успешном подключении:

C:\usbip> usbip -a %server-ip% 1-1.2
new usb device attached to usbvbus port 1

 

Создание авто-запуска USBIP

Создать файл /usr/bin/usbip_auto и заполнить его:

#!/bin/bash

fn_usbip_start()
{
	echo "param 2:"$1
	
	for usb_name in ${usb}; do
		if [[ $1 == service ]]
		then
			usbip bind -b ${usb_name} >> /var/log/usbip_auto.log
			echo "test"
		else
			usbip bind -b ${usb_name}
		fi
		
		sleep 1
	done

	sleep 1

	for usb_name in ${usb}; do
		if [[ $1 == service ]]
		then
			usbip attach -r ${ip} -b ${usb_name} >> /var/log/usbip_auto.log
		else
			usbip attach -r ${ip} -b ${usb_name}
		fi
		
		sleep 1
		
		if [[ $1 == service ]]
		then
			usbip detach -p 00 >> /var/log/usbip_auto.log
		else
			usbip detach -p 00
		fi
		
		sleep 2
	done
	
	if [[ $1 == service ]]
	then
		usbip port >> /var/log/usbip_auto.log
	else
		usbip port
	fi
	
	sleep 2

	if [[ $1 == service ]]
	then
		usbip list -r ${ip} >> /var/log/usbip_auto.log
	else
		usbip list -r ${ip}
	fi
}

fn_usbip_stop()
{
	for usb_name in ${usb}; do
		if [[ $1 == service ]]
		then
			usbip unbind -b ${usb_name} >> /var/log/usbip_auto.log
		else
			usbip unbind -b ${usb_name}
		fi
		sleep 1
	done

	sleep 1
}

while IFS= read -r line
do
	if [[ $line == ip* ]]
	then
		ip=${line:3}
	elif [[ $line == usb* ]]
	then
		usb=${line:4}
	fi
done < /etc/usbip_auto/usbip.conf

if [[ $1 == start ]]
then
	
	if [[ $2 == service ]]
	then
		echo $(date +\%Y-\%m-\%d-\%H-\%M-\%S)" - Запуск" >> /var/log/usbip_auto.log
		
		modprobe usbip-core >> /var/log/usbip_auto.log
		sleep 1
		modprobe usbip-host >> /var/log/usbip_auto.log
		sleep 1
		modprobe vhci-hcd >> /var/log/usbip_auto.log
		sleep 1
		usbipd -D >> /var/log/usbip_auto.log
	else
		echo $(date +\%Y-\%m-\%d-\%H-\%M-\%S)" - Запуск"
		
		modprobe usbip-core
		sleep 1
		modprobe usbip-host
		sleep 1
		modprobe vhci-hcd
		sleep 1
		usbipd -D
	fi
	sleep 1
	
	fn_usbip_start $2
	
	if [[ $2 == service ]]
	then
		echo $(date +\%Y-\%m-\%d-\%H-\%M-\%S)" - Успешно запушено" >> /var/log/usbip_auto.log
	else
		echo $(date +\%Y-\%m-\%d-\%H-\%M-\%S)" - Успешно запушено"
	fi
	
elif [[ $1 == restart ]]
then
	
	if [[ $2 == service ]]
	then
		echo $(date +\%Y-\%m-\%d-\%H-\%M-\%S)" - Перезапуск" >> /var/log/usbip_auto.log
	else
		echo $(date +\%Y-\%m-\%d-\%H-\%M-\%S)" - Перезапуск"
	fi
	
	fn_usbip_stop $2
	fn_usbip_start $2
	
	if [[ $2 == service ]]
	then
		echo $(date +\%Y-\%m-\%d-\%H-\%M-\%S)" - Успешно перезапущено" >> /var/log/usbip_auto.log
	else
		echo $(date +\%Y-\%m-\%d-\%H-\%M-\%S)" - Успешно перезапущено"
	fi
	
elif [[ $1 == stop ]]
then
	
	if [[ $2 == service ]]
	then
		echo $(date +\%Y-\%m-\%d-\%H-\%M-\%S)" - Остановка" >> /var/log/usbip_auto.log
	else
		echo $(date +\%Y-\%m-\%d-\%H-\%M-\%S)" - Остановка"
	fi
	
	fn_usbip_stop $2
	
	if [[ $2 == service ]]
	then
		echo $(date +\%Y-\%m-\%d-\%H-\%M-\%S)" - Успешно остановлено" >> /var/log/usbip_auto.log
	else
		echo $(date +\%Y-\%m-\%d-\%H-\%M-\%S)" - Успешно остановлено"
	fi
	
fi

Дать ему права на выполнение:

chmod 755 /usr/bin/usbip_auto

Создать директорию /etc/usbip_auto:

mkdir /etc/usbip_auto

Создать файл настроек /etc/usbip_auto/usbip.conf с содержимым:

ip 192.168.2.52
usb 3-3.1 3-3.2 3-3.4

Параметр ip — это адрес на котором находятся USB устройства, usb — через пробел указать адреса USB устройст которые подключать автоматически

Создать файл /etc/systemd/system/usbip-auto.service с содержимым:

[Unit]
Description=USBIP auto-start
After=syslog.target

[Service]
Type=forking
ExecStart=/usr/bin/usbip_auto start service >> /dev/null
ExecStop=/usr/bin/usbip_auto stop service >> /dev/null

[Install]
WantedBy=multi-user.target

Выполнить команду для обновления списка сервисов:

systemctl daemon-reload

Добавить сервис в автозапуск:

systemctl enable usbip-auto

После выполнения данных манипуляций появится возможность еще перезапускать порты при необходимости выполнив команду:

usbip_auto restart

 

Ошибки

Ошибка 1:

C:\usbip> usbip -a %server-ip% 1-1
usbip err: usbip_network.c: 121 (usbip_recv_op_common) recv op_common, -1
usbip err: usbip_windows.c: 756 (query_interface0) recv op_common
usbip err: usbip_windows.c: 829 (attach_device) cannot find device

Найти в фале usbip.exe 0х00000106, заменить на 0х00000111

[usbip.exe]
00000CBC: 06 11
00000E0A: 06 11

 

Ошибка 2:

C:\usbip>usbip.exe -a 192.168.2.24 1-1.1
usbip err: usbip_windows.c: 829 (attach_device) cannot find device

На серверу нужно подключить устройство и отключить:

# usbip attach -r 192.168.2.24 -b 1-1.1
# usbip detach -p 0

 

Ошибка 3:

usbip err: usbip_windows.c:  62 (usbip_vbus_dev_node_name) usbvbus interface is not registered

usbip err: usbip_windows.c: 654 (import_device) open vbus driver
usbip err: usbip_windows.c: 840 (attach_device) query

Ошибка появляется если не установлен драйвер USB/IP Enumerator

Инструкция по установке драйвера