Skip to content

Commit

Permalink
Merge pull request #12281 from skatsaounis/fix-wwan-devices-info
Browse files Browse the repository at this point in the history
Fix info --resources for wwan devices
  • Loading branch information
tomponline authored Sep 29, 2023
2 parents e4b244c + 10f6cd4 commit cfda2b7
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 22 deletions.
39 changes: 22 additions & 17 deletions lxd/resources/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,13 @@ var netProtocols = map[uint64]string{
}

func networkAddDeviceInfo(devicePath string, pciDB *pcidb.PCIDB, uname unix.Utsname, card *api.ResourcesNetworkCard) error {
deviceDeviceDir, err := getDeviceDir(devicePath)
if err != nil {
return fmt.Errorf("Failed to read %q: %w", devicePath, err)
}

// VDPA
vDPAMatches, err := filepath.Glob(filepath.Join(devicePath, "vdpa*"))
vDPAMatches, err := filepath.Glob(filepath.Join(deviceDeviceDir, "vdpa*"))
if err != nil {
return fmt.Errorf("Malformed VDPA device name search pattern: %w", err)
}
Expand All @@ -53,18 +58,18 @@ func networkAddDeviceInfo(devicePath string, pciDB *pcidb.PCIDB, uname unix.Utsn
}

// SRIOV
if sysfsExists(filepath.Join(devicePath, "sriov_numvfs")) {
if sysfsExists(filepath.Join(deviceDeviceDir, "sriov_numvfs")) {
sriov := api.ResourcesNetworkCardSRIOV{}

// Get maximum and current VF count
vfMaximum, err := readUint(filepath.Join(devicePath, "sriov_totalvfs"))
vfMaximum, err := readUint(filepath.Join(deviceDeviceDir, "sriov_totalvfs"))
if err != nil {
return fmt.Errorf("Failed to read %q: %w", filepath.Join(devicePath, "sriov_totalvfs"), err)
return fmt.Errorf("Failed to read %q: %w", filepath.Join(deviceDeviceDir, "sriov_totalvfs"), err)
}

vfCurrent, err := readUint(filepath.Join(devicePath, "sriov_numvfs"))
vfCurrent, err := readUint(filepath.Join(deviceDeviceDir, "sriov_numvfs"))
if err != nil {
return fmt.Errorf("Failed to read %q: %w", filepath.Join(devicePath, "sriov_numvfs"), err)
return fmt.Errorf("Failed to read %q: %w", filepath.Join(deviceDeviceDir, "sriov_numvfs"), err)
}

sriov.MaximumVFs = vfMaximum
Expand All @@ -75,10 +80,10 @@ func networkAddDeviceInfo(devicePath string, pciDB *pcidb.PCIDB, uname unix.Utsn
}

// NUMA node
if sysfsExists(filepath.Join(devicePath, "numa_node")) {
numaNode, err := readInt(filepath.Join(devicePath, "numa_node"))
if sysfsExists(filepath.Join(deviceDeviceDir, "numa_node")) {
numaNode, err := readInt(filepath.Join(deviceDeviceDir, "numa_node"))
if err != nil {
return fmt.Errorf("Failed to read %q: %w", filepath.Join(devicePath, "numa_node"), err)
return fmt.Errorf("Failed to read %q: %w", filepath.Join(deviceDeviceDir, "numa_node"), err)
}

if numaNode > 0 {
Expand All @@ -87,17 +92,17 @@ func networkAddDeviceInfo(devicePath string, pciDB *pcidb.PCIDB, uname unix.Utsn
}

// USB address
usbAddr, err := usbAddress(devicePath)
usbAddr, err := usbAddress(deviceDeviceDir)
if err != nil {
return fmt.Errorf("Failed to find USB address for %q: %w", devicePath, err)
return fmt.Errorf("Failed to find USB address for %q: %w", deviceDeviceDir, err)
}

if usbAddr != "" {
card.USBAddress = usbAddr
}

// Vendor and product
deviceVendorPath := filepath.Join(devicePath, "vendor")
deviceVendorPath := filepath.Join(deviceDeviceDir, "vendor")
if sysfsExists(deviceVendorPath) {
id, err := os.ReadFile(deviceVendorPath)
if err != nil {
Expand All @@ -107,7 +112,7 @@ func networkAddDeviceInfo(devicePath string, pciDB *pcidb.PCIDB, uname unix.Utsn
card.VendorID = strings.TrimPrefix(strings.TrimSpace(string(id)), "0x")
}

deviceDevicePath := filepath.Join(devicePath, "device")
deviceDevicePath := filepath.Join(deviceDeviceDir, "device")
if sysfsExists(deviceDevicePath) {
id, err := os.ReadFile(deviceDevicePath)
if err != nil {
Expand All @@ -133,11 +138,11 @@ func networkAddDeviceInfo(devicePath string, pciDB *pcidb.PCIDB, uname unix.Utsn
}

// Driver information
driverPath := filepath.Join(devicePath, "driver")
driverPath := filepath.Join(deviceDeviceDir, "driver")
if sysfsExists(driverPath) {
linkTarget, err := filepath.EvalSymlinks(driverPath)
if err != nil {
return fmt.Errorf("Failed to find %q: %w", driverPath, err)
return fmt.Errorf("Failed to find device directory %q: %w", driverPath, err)
}

// Set the driver name
Expand Down Expand Up @@ -179,9 +184,9 @@ func networkAddDeviceInfo(devicePath string, pciDB *pcidb.PCIDB, uname unix.Utsn
protocol, ok := netProtocols[devType]
if !ok {
info.Protocol = "unknown"
} else {
info.Protocol = protocol
}

info.Protocol = protocol
}

// Add MAC address
Expand Down
36 changes: 31 additions & 5 deletions lxd/resources/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,21 +113,26 @@ func udevDecode(s string) (string, error) {
}

func pciAddress(devicePath string) (string, error) {
deviceDeviceDir, err := getDeviceDir(devicePath)
if err != nil {
return "", err
}

// Check if we have a subsystem listed at all.
if !sysfsExists(filepath.Join(devicePath, "subsystem")) {
if !sysfsExists(filepath.Join(deviceDeviceDir, "subsystem")) {
return "", nil
}

// Track down the device.
linkTarget, err := filepath.EvalSymlinks(devicePath)
linkTarget, err := filepath.EvalSymlinks(deviceDeviceDir)
if err != nil {
return "", fmt.Errorf("Failed to find %q: %w", devicePath, err)
return "", fmt.Errorf("Failed to find %q: %w", deviceDeviceDir, err)
}

// Extract the subsystem.
subsystemTarget, err := filepath.EvalSymlinks(filepath.Join(linkTarget, "subsystem"))
if err != nil {
return "", fmt.Errorf("Failed to find %q: %w", filepath.Join(devicePath, "subsystem"), err)
return "", fmt.Errorf("Failed to find %q: %w", filepath.Join(deviceDeviceDir, "subsystem"), err)
}

subsystem := filepath.Base(subsystemTarget)
Expand All @@ -137,7 +142,7 @@ func pciAddress(devicePath string) (string, error) {
linkTarget = filepath.Dir(linkTarget)
subsystemTarget, err := filepath.EvalSymlinks(filepath.Join(linkTarget, "subsystem"))
if err != nil {
return "", fmt.Errorf("Failed to find %q: %w", filepath.Join(devicePath, "subsystem"), err)
return "", fmt.Errorf("Failed to find %q: %w", filepath.Join(deviceDeviceDir, "subsystem"), err)
}

subsystem = filepath.Base(subsystemTarget)
Expand Down Expand Up @@ -192,3 +197,24 @@ func usbAddress(devicePath string) (string, error) {
return fmt.Sprintf("%d:%d", bus, dev), nil
}
}

// getDeviceDir returns the directory which contains device information needed for a device.
// It appends /device to the path until it ends up to a child /device which is a regular file.
// This function is needed for devices which include sub-devices like wwan.
func getDeviceDir(devicePath string) (string, error) {
for {
deviceDir := filepath.Join(devicePath, "device")
fileInfo, err := os.Stat(deviceDir)
if os.IsNotExist(err) {
break
} else if err != nil {
return "", fmt.Errorf("Unable to get file info for %q: %w", deviceDir, err)
} else if fileInfo.Mode().IsRegular() {
break
}

devicePath = deviceDir
}

return devicePath, nil
}

0 comments on commit cfda2b7

Please sign in to comment.