Skip to content

Commit

Permalink
domainmgr: handle usb devices correctly
Browse files Browse the repository at this point in the history
in cases PCI devices, that had a network usb dongle connected,
blacklisted other usb devices for pass-through

Signed-off-by: Christoph Ostarek <[email protected]>
  • Loading branch information
christoph-zededa committed Oct 18, 2023
1 parent 6949ccf commit 683fe7d
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 14 deletions.
6 changes: 5 additions & 1 deletion pkg/pillar/cmd/domainmgr/domainmgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -2939,6 +2939,10 @@ func updatePortAndPciBackIoBundle(ctx *domainContext, ib *types.IoBundle) (chang
ib.Type, ib.Phylabel, ib.AssignmentGroup, isPort, keepInHost, len(list))
anyChanged := false
for _, ib := range list {
if ib.UsbAddr != "" {
// this is usb device forwarding, so usbmanager cares for not passing through network devices
continue
}
changed, err := updatePortAndPciBackIoMember(ctx, ib, isPort, keepInHost)
anyChanged = anyChanged || changed
if err != nil {
Expand Down Expand Up @@ -3011,7 +3015,7 @@ func updatePortAndPciBackIoMember(ctx *domainContext, ib *types.IoBundle, isPort
ib.IsPCIBack = false
// Verify that it has been returned from pciback
_, err = types.IoBundleToPci(log, ib)
if err != nil {
if err != nil || ib.UsbAddr != "" {
err = fmt.Errorf("adapter %s (group %s type %d) PCI ID %s not found: %v",
ib.Phylabel, ib.AssignmentGroup, ib.Type,
ib.PciLong, err)
Expand Down
16 changes: 16 additions & 0 deletions pkg/pillar/types/assignableadapters.go
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,19 @@ func (aa *AssignableAdapters) CheckBadAssignmentGroups(log *base.LogObject, PCIS
if ib.AssignmentGroup == "" || ib2.AssignmentGroup == ib.AssignmentGroup {
continue
}
if ib.UsbAddr != "" || ib2.UsbAddr != "" {
usbAddr1 := strings.TrimLeft(ib.UsbAddr, "0")
usbAddr2 := strings.TrimLeft(ib2.UsbAddr, "0")
if usbAddr1 == usbAddr2 {
err := fmt.Errorf("CheckBadAssignmentGroup: %s same USB address as %s; UsbAddr %s vs %s",
ib2.Ifname, ib.Ifname, usbAddr1, usbAddr2)
log.Error(err)
ib.Error = err.Error()
ib.ErrorTime = time.Now()
changed = true
}
continue
}
if PCISameController != nil && PCISameController(ib.PciLong, ib2.PciLong) {
err := fmt.Errorf("CheckBadAssignmentGroup: %s same PCI controller as %s; pci long %s vs %s",
ib2.Ifname, ib.Ifname, ib2.PciLong, ib.PciLong)
Expand Down Expand Up @@ -481,6 +494,9 @@ func (aa *AssignableAdapters) ExpandControllers(log *base.LogObject, list []*IoB
ib2.Phylabel, ib2.PciLong)
continue
}
if ib.UsbAddr != "" || ib2.UsbAddr != "" {
continue
}
if PCISameController != nil && PCISameController(ib.PciLong, ib2.PciLong) {
log.Warnf("ExpandController found %s matching %s; long %s long %s",
ib2.Phylabel, ib.Phylabel, ib2.PciLong, ib.PciLong)
Expand Down
54 changes: 41 additions & 13 deletions pkg/pillar/types/ifnametopci.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"os"
"path"
"regexp"
"strconv"
"strings"

"github.com/lf-edge/eve/pkg/pillar/base"
Expand All @@ -22,10 +23,32 @@ import (
const basePath = "/sys/class/net"
const pciPath = "/sys/bus/pci/devices"

// ExtractUSBBusnumPort extracts busnum and port number out of a sysfs device path
func ExtractUSBBusnumPort(path string) (uint16, string, error) {
var busnum uint16

re := regexp.MustCompile(`\/usb\d+(\/\d+\-[\d\.]+)*(\/(\d+)\-([\d\.]+))\/`)

matches := re.FindStringSubmatch(path)
if len(matches) < 3 {
return busnum, "", fmt.Errorf("could not extract usb portnum from %s", path)
}
port := matches[len(matches)-1]
busnumString := matches[len(matches)-2]
busnum64, err := strconv.ParseUint(busnumString, 10, 16)
if err != nil {
return 0, port, fmt.Errorf("could not extract usb busnum from %s", path)
}
busnum = uint16(busnum64)

return busnum, port, nil
}

// Returns the long PCI IDs
func ifNameToPci(log *base.LogObject, ifName string) (string, error) {
func ifNameToPciAndUsbAddr(log *base.LogObject, ifName string) (string, string, error) {
// Match for PCI IDs
re := regexp.MustCompile("([0-9a-f]){4}:([0-9a-f]){2}:([0-9a-f]){2}.[ls0-9a-f]")
var usbAddr string
ifPath := basePath + "/" + ifName
devPath := ifPath + "/device"
info, err := os.Lstat(devPath)
Expand All @@ -34,7 +57,7 @@ func ifNameToPci(log *base.LogObject, ifName string) (string, error) {
if !os.IsNotExist(err) {
log.Errorln(err)
}
return "", err
return "", usbAddr, err
}
// Try alternate since the PCI device can be kethN
// if ifName is ethN
Expand All @@ -46,47 +69,52 @@ func ifNameToPci(log *base.LogObject, ifName string) (string, error) {
if !os.IsNotExist(err) {
log.Errorln(err)
}
return "", err
return "", usbAddr, err
}
log.Noticef("ifNameToPci using alternate %s", ifName)
}
if (info.Mode() & os.ModeSymlink) == 0 {
log.Errorf("Skipping non-symlink %s\n", devPath)
return "", fmt.Errorf("Not a symlink %s", devPath)
return "", usbAddr, fmt.Errorf("Not a symlink %s", devPath)
}
link, err := os.Readlink(devPath)
if err != nil {
return "", err
return "", usbAddr, err
}

busnum, portnum, err := ExtractUSBBusnumPort(link)
if err == nil {
usbAddr = fmt.Sprintf("%d:%s", busnum, portnum)
}
target := path.Base(link)
if re.MatchString(target) {
return target, nil
return target, usbAddr, nil
}
log.Noticef("Not PCI %s - try fallback for %s", target, ifName)
// Try fallback to handle nested virtualization
info, err = os.Lstat(ifPath)
if err != nil {
log.Noticef("Fallback failed: %s", err)
return target, fmt.Errorf("Not PCI %s", target)
return target, usbAddr, fmt.Errorf("Not PCI %s", target)
}
if (info.Mode() & os.ModeSymlink) == 0 {
log.Noticef("Fallback not symlink")
return target, fmt.Errorf("Not PCI %s", target)
return target, usbAddr, fmt.Errorf("Not PCI %s", target)
}
link, err = os.Readlink(ifPath)
if err != nil {
log.Noticef("Fallback readlink failed: %s", err)
return target, fmt.Errorf("Not PCI %s", target)
return target, usbAddr, fmt.Errorf("Not PCI %s", target)
}
link = path.Clean(link)
components := strings.Split(link, "/")
for _, c := range components {
if re.MatchString(c) {
log.Noticef("Fallback found %s", c)
return c, nil
return c, usbAddr, nil
}
}
return target, fmt.Errorf("Not PCI %s", target)
return target, usbAddr, fmt.Errorf("Not PCI %s", target)
}

// Returns the long PCI IDs for Virtual function
Expand Down Expand Up @@ -210,7 +238,7 @@ func IoBundleToPci(log *base.LogObject, ib *IoBundle) (string, error) { //nolint
if ib.Type == IoNetEthVF {
l, err = vfIfNameToPci(ib.Ifname)
} else {
l, err = ifNameToPci(log, ib.Ifname)
l, ib.UsbAddr, err = ifNameToPciAndUsbAddr(log, ib.Ifname)
}
rename := false
if err == nil {
Expand Down Expand Up @@ -239,7 +267,7 @@ func IoBundleToPci(log *base.LogObject, ib *IoBundle) (string, error) { //nolint
return long, err
}
} else {
long, err = ifNameToPci(log, ib.Ifname)
long, ib.UsbAddr, err = ifNameToPciAndUsbAddr(log, ib.Ifname)
if err != nil {
return long, err
}
Expand Down

0 comments on commit 683fe7d

Please sign in to comment.