我希望有一个主机启动并运行 usbip
[Unit]
Description=USB-IP Binding
After=network-online.target
[Service]
ExecStartPre=/usr/sbin/usbipd -D
ExecStart=/usr/sbin/usbip bind --busid 1-1.5
ExecStop=/usr/sbin/usbip unbind --busid 1-1.5
Restart=on-failure
[Install]
WantedBy=default.target
它似乎正确启动,没有错误,但是当我转到客户端并列出服务器时,它没有显示 usbip 正在运行。
还有人知道通过 USBIP 共享所有 USB 设备的脚本吗?
感谢您的帮助。
答案1
基于评论中发布的链接OP,问题似乎就在这里:
ExecStartPre=/usr/sbin/usbipd -D
ExecStart=/usr/sbin/usbip bind --busid 1-1.5
如果您没有Type=
为 systemd 服务指定选项,它会假定该服务是Type=simple
.在这种情况下,ExecStart=
如果一切顺利,systemd 将假设使用该选项启动的进程将永远运行。但该usbip bind
命令只是告诉usbipd
进程接管服务,然后退出。然后 systemd 会认为“哦不,服务崩溃了!”,并且由于它也有Restart=on-failure
,它会一遍又一遍地不断重新启动服务。
为了使其工作,您可以指定Type=forking
并使实际usbipd
流程成为一条ExecStart=
线,并usbip bind
成为一条ExecStartPost=
线,如您发布的链接中所建议的那样。但该解决方案存在一个对于 systemd 新用户来说很常见的错误:您假设usbipd
需要自己成为守护进程,而 systemd 可以轻松地为您完成此操作。
-D
最好的解决方案是从命令行中删除该选项usbipd
,并省略Type=forking
(或Type=simple
显式使用)。这样,systemd 将为您处理守护进程,并且还能够监视和停止服务进程,而无需求助于 PID 文件或随意的killall usbipd
ExecPost=
命令。
所以,我的建议是:
[Unit]
Description=USB-IP Binding
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/sbin/usbipd
ExecStartPost=/usr/sbin/usbip bind --busid 1-1.5
ExecStop=/usr/sbin/usbip unbind --busid 1-1.5
[Install]
WantedBy=multi-user.target
通过这些设置,systemd 将期望该usbipd
进程将永远运行,并且如果该进程意外终止,实际上会将服务标记为失败。Restart=on-failure
如果您希望 systemd 在这种情况下自动重新启动服务,您可以添加, 。
当关闭服务时,该ExecStop
命令将告诉usbipd
您从 USB 设备上彻底解除绑定,一旦成功完成,systemd 将看到服务器进程仍在运行,并将在没有任何显式命令的情况下杀死它。
每当您使用 时After=network-online.target
,您应该始终也使用Wants=network-online.target
,否则它可能无法按预期工作。看网络上线后运行服务在 systemd 文档中,涵盖 systemd 特殊目标的手册页中也提到了systemd.special(7)
.
答案2
我采取的方法是将其分成两个服务,一个用于守护程序,一个用于绑定模板。
因此对于守护进程 - /etc/systemd/system/usbipd.service
[Unit]
Description=usbip host daemon
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
Restart=always
ExecStartPre=/usr/sbin/modprobe usbip-core
ExecStartPre=/usr/sbin/modprobe usbip-host
ExecStart=/usr/sbin/usbipd
ExecStopPost=/usr/sbin/rmmod usbip-host
ExecStopPost=/usr/sbin/rmmod usbip-core
[Install]
WantedBy=multi-user.target
以及绑定的模板 - /etc/systemd/system/[电子邮件受保护]
[Unit]
Description=Bind USB device to usbipd
After=network-online.target usbipd.service
Wants=network-online.target usbipd.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/usbip bind --busid %i
ExecStop=/usr/sbin/usbip unbind --busid %i
[Install]
WantedBy=multi-user.target
启用并启动守护进程:
systemctl enable usbipd
systemctl start usbuipd
然后添加绑定:
systemctl enable [email protected]
systemctl start [email protected]
将 1-1.2.3 替换为您要共享的 USB 设备的绑定 ID。您可以使用任意数量的设备来共享,然后您可以单独绑定和取消绑定每个设备,然后在计算机启动时绑定(或不绑定)。
使用以下命令查找绑定 ID:
usbip list -l
请注意,如果在大约 10 分钟内未通过远程计算机连接,usbip 绑定似乎就会过期 - 不是很有帮助!
我还没有决定如何处理客户端附加,可能不是使用 systemd。如果 usbip 具有更多的智能,那将非常有帮助......