added login and permission fix
This commit is contained in:
parent
6172d9e2aa
commit
3579924883
BIN
bin/usb-client
BIN
bin/usb-client
Binary file not shown.
BIN
bin/usb-relay
BIN
bin/usb-relay
Binary file not shown.
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
|
@ -35,48 +36,58 @@ func fdToFile(fd int, name string) *os.File {
|
||||||
// VHCI-created devices don't get normal udev rules applied, so they
|
// VHCI-created devices don't get normal udev rules applied, so they
|
||||||
// default to root-only access.
|
// default to root-only access.
|
||||||
func fixVHCIDevicePermissions(port int) {
|
func fixVHCIDevicePermissions(port int) {
|
||||||
// Wait for the device to finish enumerating and create device nodes
|
// Wait for the device to finish enumerating and create device nodes.
|
||||||
// The kernel needs time to enumerate descriptors and bind drivers
|
// The kernel needs time to enumerate descriptors and bind drivers.
|
||||||
for attempt := 0; attempt < 10; attempt++ {
|
for attempt := 0; attempt < 15; attempt++ {
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
|
|
||||||
// Find device nodes created by this VHCI port
|
found := false
|
||||||
// VHCI creates devices under /sys/devices/platform/vhci_hcd.0/usbN/
|
|
||||||
// We look for video4linux devices
|
// Walk the VHCI sysfs tree to find device nodes at any depth.
|
||||||
matches, _ := filepath.Glob("/sys/devices/platform/vhci_hcd.0/usb*/*/video4linux/video*")
|
// Paths look like: vhci_hcd.0/usb3/3-1/3-1:1.0/video4linux/video0
|
||||||
for _, m := range matches {
|
filepath.WalkDir("/sys/devices/platform/vhci_hcd.0", func(path string, d os.DirEntry, err error) error {
|
||||||
devName := filepath.Base(m)
|
if err != nil {
|
||||||
devPath := "/dev/" + devName
|
return nil
|
||||||
if _, err := os.Stat(devPath); err == nil {
|
}
|
||||||
|
|
||||||
|
dir := filepath.Dir(path)
|
||||||
|
parent := filepath.Base(dir)
|
||||||
|
|
||||||
|
// video4linux devices → /dev/videoN
|
||||||
|
if parent == "video4linux" && strings.HasPrefix(d.Name(), "video") {
|
||||||
|
devPath := "/dev/" + d.Name()
|
||||||
|
if err := os.Chmod(devPath, 0666); err == nil {
|
||||||
|
log.Printf("[use] set permissions 0666 on %s", devPath)
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sound devices → /dev/snd/*
|
||||||
|
if parent == "sound" && strings.HasPrefix(d.Name(), "card") {
|
||||||
|
// For sound cards, chmod all related device nodes
|
||||||
|
sndDir := filepath.Join(path, "device")
|
||||||
|
if _, err := os.Stat(sndDir); err == nil {
|
||||||
|
filepath.WalkDir("/dev/snd", func(sndPath string, sd os.DirEntry, err error) error {
|
||||||
|
if err == nil && !sd.IsDir() {
|
||||||
|
os.Chmod(sndPath, 0666)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// input devices → /dev/input/eventN
|
||||||
|
if strings.HasPrefix(d.Name(), "event") && strings.Contains(path, "/input/input") {
|
||||||
|
devPath := "/dev/input/" + d.Name()
|
||||||
if err := os.Chmod(devPath, 0666); err == nil {
|
if err := os.Chmod(devPath, 0666); err == nil {
|
||||||
log.Printf("[use] set permissions 0666 on %s", devPath)
|
log.Printf("[use] set permissions 0666 on %s", devPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Also check for other common device types (input, sound, etc.)
|
return nil
|
||||||
for _, subsys := range []string{"sound/card*", "input/input*/event*"} {
|
})
|
||||||
sysMatches, _ := filepath.Glob("/sys/devices/platform/vhci_hcd.0/usb*/*/" + subsys)
|
|
||||||
for _, m := range sysMatches {
|
|
||||||
devName := filepath.Base(m)
|
|
||||||
devPath := "/dev/" + devName
|
|
||||||
// For sound devices, also check /dev/snd/
|
|
||||||
if _, err := os.Stat(devPath); err == nil {
|
|
||||||
os.Chmod(devPath, 0666)
|
|
||||||
}
|
|
||||||
devPath = "/dev/snd/" + devName
|
|
||||||
if _, err := os.Stat(devPath); err == nil {
|
|
||||||
os.Chmod(devPath, 0666)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if attempt == 0 {
|
if attempt >= 2 && found {
|
||||||
continue // first iteration: always wait more
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if we found any video devices
|
|
||||||
if len(matches) > 0 {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -272,6 +272,7 @@ func (um *UseManager) tunnelReadLoop(tunnel *useTunnel) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := um.client.SendTunnelData(tunnel.id, buf[:n]); err != nil {
|
if err := um.client.SendTunnelData(tunnel.id, buf[:n]); err != nil {
|
||||||
|
log.Printf("[use] tunnel send error: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -326,11 +327,17 @@ func (um *UseManager) handleTunnelData(tunnelID string, data []byte) {
|
||||||
um.mu.RUnlock()
|
um.mu.RUnlock()
|
||||||
|
|
||||||
if !exists {
|
if !exists {
|
||||||
|
log.Printf("[use] tunnel data for unknown tunnel %s (%d bytes)", tunnelID[:8], len(data))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write to the tunnel socket (relay -> VHCI)
|
// Write to the tunnel socket (relay -> VHCI)
|
||||||
tunnel.conn.Write(data)
|
n, err := tunnel.conn.Write(data)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[use] tunnel write error: %v", err)
|
||||||
|
} else if n != len(data) {
|
||||||
|
log.Printf("[use] tunnel short write: %d/%d", n, len(data))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (um *UseManager) handleClientLeft(msg *protocol.ClientLeft) {
|
func (um *UseManager) handleClientLeft(msg *protocol.ClientLeft) {
|
||||||
|
|
|
||||||
|
|
@ -421,10 +421,15 @@ func (s *Server) handleCmdSubmit(r io.Reader, hdr *URBHeader, retChan chan<- []b
|
||||||
5000, buf,
|
5000, buf,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Printf("[usbip-server] CTRL OUT seq=%d failed: %v", hdr.SeqNum, err)
|
||||||
status = -32 // -EPIPE
|
status = -32 // -EPIPE
|
||||||
|
} else {
|
||||||
|
log.Printf("[usbip-server] CTRL OUT seq=%d OK (bmReqType=0x%02x bReq=0x%02x wVal=0x%04x)",
|
||||||
|
hdr.SeqNum, bmRequestType, bRequest, wValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Printf("[usbip-server] CTRL OUT seq=%d → response status=%d", hdr.SeqNum, status)
|
||||||
resp, err := BuildRetSubmit(hdr.SeqNum, hdr.DevID, hdr.Direction, hdr.Endpoint, status, nil)
|
resp, err := BuildRetSubmit(hdr.SeqNum, hdr.DevID, hdr.Direction, hdr.Endpoint, status, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -559,6 +564,8 @@ func (s *Server) handleCmdUnlink(r io.Reader, hdr *URBHeader, retChan chan<- []b
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Printf("[usbip-server] UNLINK seq=%d target_seq=%d", hdr.SeqNum, body.UnlinkSeqNum)
|
||||||
|
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
pending, exists := s.pendingURBs[body.UnlinkSeqNum]
|
pending, exists := s.pendingURBs[body.UnlinkSeqNum]
|
||||||
if exists {
|
if exists {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue