2

I successfully shared a device from a USB port of my Raspberry Pi (running Raspbian) to a Ubuntu virtual machine on a local server, using usbip.

Here's a list of the commands I'm running:

On the server side (Raspberry Pi):

modprobe usb-core
modprobe usb-host
sudo usbipd -D
sudo usbip --debug bind -b 1-1.2

On the client side (Ubuntu server):

modprobe vici-hcd
sudo usbip attach 192.168.100.100 1-1.2

It's working well but every time the local network has a problem, I need to do all the process again on both sides. This makes it really hard to use in a production mode because I'd like this system to be reliable and resilient.

I added the modules to /etc/modules to have them start when booting (not sure if it's working), but in that case, the problem is happening without any reboot.

I'm writing two scripts to run these commands periodically on both sides but it still won't be an ideal solution considering that the server has to bind before the client can attach.

Am I doing it wrong? Is there anyone that found a reliable way to make usbip working, which doesn't require to reconfigure everything all the time?

Pierre
  • 121
  • Welcome to Ask Ubuntu! :-) You can use udev rules to automate these commands every time the net but as I don't have your hardware I can;t test ift for you and tell you what to do exactly. – Fabby Aug 18 '17 at 16:43

1 Answers1

2

There two steps on the usbip server, and two steps on the usbip client. It's the same process on each, just the names are a bit different.

Step #1 on both the server and client: Load load modules at boot.

This replaces the sudo modprobe lines.

See Run modprobe on startup for detailed explanation and alternatives.

Edit /etc/modules (using sudo, of course), and add the names of the modules for that machine.

Example:

$ sudo nano /etc/modules

usb-core
usb-host

Now those modules will be added (modprobe) at boot.

Step #2 on both the server and client: Create a systemd service file for easy control, reset, and start-on-boot on the usbip client and server.

This one is a bit more involved. It requires an understanding of systemd and basic shell commands.

Here's an example systemd etc/systemd/system/usbipd.service file for the usbip server that you must create:

[Unit]
Description=usbip host daemon
After=network.target

[Service]
Type=forking
ExecStart=/usr/sbin/usbipd -D
ExecStartPost=/bin/sh -c "/usr/sbin/usbip bind --$(/usr/sbin/usbip list -p -l | grep '#usbid=10c4:8a2a#' | cut '-d#' -f1)"  // Edit this line to match your USB device
ExecStop=/bin/sh -c "/usr/lib/linux-tools/$(uname -r)/usbip detach --port=$(/usr/lib/linux-tools/$(uname -r)/usbip port | grep '<Port in Use>' | sed -E 's/^Port ([0-9][0-9]).*/\1/')"

[Install]
WantedBy=multi-user.target

You can see that the .service file runs usbip in server (daemon) mode when started, and terminates the server when stopped. This means that you can use normal systemctl commands to run and query the server:

systemctl status usbipd.service          // status and troubleshooting
sudo systemctl start usbipd.service      // start
sudo systemctl stop usbipd.service       // stop
sudo systemctl restart usbipd.service    // stop, then start again
sudo systemctl enable usbipd.service     // start at boot forever from now on
sudo systemctl enable usbipd.service     // leave dormant at boot forever from now on

Now I can have usbipd start automatically whenever my server boots, and I can query it's status using plain old ssh.

The rather similar systemd file for the client is left as an exercise for the student.

user535733
  • 62,253