fix USBDEVFS_DISCONNECT_CLAIM

This commit is contained in:
2026-02-18 22:24:54 +01:00
parent 88564d9837
commit 170f5dabcc
4 changed files with 90 additions and 25 deletions
+27 -10
View File
@@ -51,19 +51,36 @@ func (s *Server) Attach() error {
}
s.handle = handle
// Disconnect kernel drivers from all interfaces
// For each interface: disconnect kernel driver and claim it
for _, iface := range s.device.Interfaces {
if iface.Driver != "" && iface.Driver != "(none)" {
// Try to disconnect - ignore errors for already-disconnected interfaces
handle.DisconnectDriver()
}
}
ifnum := uint32(iface.Number)
// Claim all interfaces
for _, iface := range s.device.Interfaces {
if err := handle.ClaimInterface(uint32(iface.Number)); err != nil {
log.Printf("[usbip-server] warning: could not claim interface %d: %v", iface.Number, err)
// Try atomic disconnect+claim first (USBDEVFS_DISCONNECT_CLAIM, Linux 3.7+)
err := handle.DisconnectClaimInterface(ifnum)
if err == nil {
log.Printf("[usbip-server] interface %d: disconnect+claim OK", ifnum)
continue
}
// Fallback: disconnect driver per interface, then claim
if disconnErr := handle.DisconnectDriverForInterface(ifnum); disconnErr != nil {
log.Printf("[usbip-server] interface %d: disconnect warning: %v", ifnum, disconnErr)
}
if claimErr := handle.ClaimInterface(ifnum); claimErr != nil {
log.Printf("[usbip-server] error: could not claim interface %d: %v", ifnum, claimErr)
// This is a critical error - clean up and fail
for _, prev := range s.device.Interfaces {
if uint32(prev.Number) < ifnum {
handle.ReleaseInterface(uint32(prev.Number))
}
}
handle.ConnectDriver()
handle.Close()
s.handle = nil
return fmt.Errorf("claiming interface %d: %w", ifnum, claimErr)
}
log.Printf("[usbip-server] interface %d: fallback disconnect+claim OK", ifnum)
}
return nil