[lxc-devel] [lxd/master] Add USBAddress and more PICAddress to resources API

stgraber on Github lxc-bot at linuxcontainers.org
Mon Dec 7 23:52:33 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20201207/b7f3e646/attachment.bin>
-------------- next part --------------
From efabc7ee81743706ac3134d17da55e05cdd8c8ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 7 Dec 2020 18:26:59 -0500
Subject: [PATCH 1/3] api: Add resources_network_usb and resources_disk_address
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 doc/api-extensions.md | 10 ++++++++--
 shared/version/api.go |  2 ++
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/doc/api-extensions.md b/doc/api-extensions.md
index 5fdc480d10..12c78e6eb5 100644
--- a/doc/api-extensions.md
+++ b/doc/api-extensions.md
@@ -1225,7 +1225,13 @@ send/receive on top of that.
 
 ## gpu\_mdev
 This adds support for virtual GPUs. It introduces the `mdev` config key for GPU devices which takes
-a supported mdev type, e.g. i915-GVTg_V5_4.
+a supported mdev type, e.g. i915-GVTg\_V5\_4.
 
 ## resources\_pci\_iommu
-This adds the IOMMUGroup field for PCI entries in the resources API.
\ No newline at end of file
+This adds the IOMMUGroup field for PCI entries in the resources API.
+
+## resources\_network\_usb
+Adds the usb\_address field to the network card entries in the resources API.
+
+## resources\_disk\_address
+Adds the usb\_address and pci\_address fields to the disk entries in the resources API.
diff --git a/shared/version/api.go b/shared/version/api.go
index 12ae55eb2d..427249d08b 100644
--- a/shared/version/api.go
+++ b/shared/version/api.go
@@ -237,6 +237,8 @@ var APIExtensions = []string{
 	"storage_zfs_clone_copy_rebase",
 	"gpu_mdev",
 	"resources_pci_iommu",
+	"resources_network_usb",
+	"resources_disk_address",
 }
 
 // APIExtensionsCount returns the number of available API extensions.

From 89a5672ef40061d1bbcab952cba241deccc0fb97 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 7 Dec 2020 18:27:41 -0500
Subject: [PATCH 2/3] lxd/resources: Add PCIAddress/USBAddress for networks and
 disks
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Closes #8215

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/resources/network.go |  6 ++++++
 lxd/resources/storage.go | 31 +++++++++++++++++++++++++++++
 lxd/resources/usb.go     | 42 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 79 insertions(+)

diff --git a/lxd/resources/network.go b/lxd/resources/network.go
index 034e5b8190..b6bf773e71 100644
--- a/lxd/resources/network.go
+++ b/lxd/resources/network.go
@@ -59,6 +59,12 @@ func networkAddDeviceInfo(devicePath string, pciDB *pcidb.PCIDB, uname unix.Utsn
 		}
 	}
 
+	// USB address
+	usbAddr, err := parseUSBAddress(devicePath)
+	if err == nil {
+		card.USBAddress = usbAddr
+	}
+
 	// Vendor and product
 	deviceVendorPath := filepath.Join(devicePath, "vendor")
 	if sysfsExists(deviceVendorPath) {
diff --git a/lxd/resources/storage.go b/lxd/resources/storage.go
index b051957f76..8a07c1c2a0 100644
--- a/lxd/resources/storage.go
+++ b/lxd/resources/storage.go
@@ -160,6 +160,37 @@ func GetStorage() (*api.ResourcesStorage, error) {
 			}
 			disk.Device = strings.TrimSpace(string(diskDev))
 
+			// PCI address
+			deviceDevicePath := filepath.Join(devicePath, "device")
+			if sysfsExists(deviceDevicePath) {
+				linkTarget, err := filepath.EvalSymlinks(deviceDevicePath)
+				if err != nil {
+					return nil, errors.Wrapf(err, "Failed to track down \"%s\"", deviceDevicePath)
+				}
+
+				if strings.Contains(linkTarget, "/pci") && sysfsExists(filepath.Join(deviceDevicePath, "subsystem")) {
+					virtio := strings.HasPrefix(filepath.Base(linkTarget), "virtio")
+					if virtio {
+						linkTarget = filepath.Dir(linkTarget)
+					}
+
+					subsystem, err := filepath.EvalSymlinks(filepath.Join(deviceDevicePath, "subsystem"))
+					if err != nil {
+						return nil, errors.Wrapf(err, "Failed to track down \"%s\"", filepath.Join(deviceDevicePath, "subsystem"))
+					}
+
+					if filepath.Base(subsystem) == "pci" || virtio {
+						disk.PCIAddress = filepath.Base(linkTarget)
+					}
+				}
+			}
+
+			// USB address
+			usbAddr, err := parseUSBAddress(devicePath)
+			if err == nil {
+				disk.USBAddress = usbAddr
+			}
+
 			// NUMA node
 			if sysfsExists(filepath.Join(devicePath, "numa_node")) {
 				numaNode, err := readInt(filepath.Join(devicePath, "numa_node"))
diff --git a/lxd/resources/usb.go b/lxd/resources/usb.go
index fc88c459dc..3d38c2b8ff 100644
--- a/lxd/resources/usb.go
+++ b/lxd/resources/usb.go
@@ -1,6 +1,7 @@
 package resources
 
 import (
+	"fmt"
 	"io/ioutil"
 	"path/filepath"
 	"strconv"
@@ -15,6 +16,47 @@ import (
 
 var sysBusUSB = "/sys/bus/usb/devices"
 
+// parseUSBAddress returns the suspected USB address (bus:dev) for the device.
+func parseUSBAddress(devicePath string) (string, error) {
+	// Resolve symlink.
+	devicePath, err := filepath.EvalSymlinks(devicePath)
+	if err != nil {
+		return "", errors.Wrap(err, "Failed to resolve device symlink")
+	}
+
+	// Parse the path looking for a usb address.
+	baseIndex := -1
+	parts := strings.Split(devicePath, "/")
+	for i, name := range parts {
+		if strings.HasPrefix(name, "usb") {
+			baseIndex = i
+			break
+		}
+	}
+
+	// Check that we have found an entry starting with "usb" and we have at least 2 sub-entries.
+	if baseIndex < 0 || len(parts) < baseIndex+2 {
+		return "", fmt.Errorf("No match")
+	}
+
+	// Device path for the USB device.
+	usbPath := strings.Join(parts[0:baseIndex+2], "/")
+
+	// Bus address.
+	bus, err := readUint(filepath.Join(usbPath, "busnum"))
+	if err != nil {
+		return "", errors.Wrap(err, "Unable to parse USB bus addr")
+	}
+
+	// Device address.
+	dev, err := readUint(filepath.Join(usbPath, "devnum"))
+	if err != nil {
+		return "", errors.Wrap(err, "Unable to parse USB device addr")
+	}
+
+	return fmt.Sprintf("%d:%d", bus, dev), nil
+}
+
 // GetUSB returns a filled api.ResourcesUSB struct ready for use by LXD
 func GetUSB() (*api.ResourcesUSB, error) {
 	// Load the USB database.

From ffc46a2278eb072403c62f148443cf864de1fd2a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 7 Dec 2020 18:49:49 -0500
Subject: [PATCH 3/3] shared/api: Add PCIAddress/USBAddress on network and
 storage
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 shared/api/resource.go | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/shared/api/resource.go b/shared/api/resource.go
index d9fd419542..adaf241026 100644
--- a/shared/api/resource.go
+++ b/shared/api/resource.go
@@ -184,6 +184,9 @@ type ResourcesNetworkCard struct {
 
 	// API extension: resources_network_firmware
 	FirmwareVersion string `json:"firmware_version,omitempty" yaml:"firmware_version,omitempty"`
+
+	// API extension: resources_network_usb
+	USBAddress string `json:"usb_address,omitempty" yaml:"usb_address,omitempty"`
 }
 
 // ResourcesNetworkCardPort represents a network port on the system
@@ -263,6 +266,10 @@ type ResourcesStorageDisk struct {
 	DeviceID string `json:"device_id" yaml:"device_id"`
 
 	Partitions []ResourcesStorageDiskPartition `json:"partitions" yaml:"partitions"`
+
+	// API extension: resources_disk_address
+	PCIAddress string `json:"pci_address,omitempty" yaml:"pci_address,omitempty"`
+	USBAddress string `json:"usb_address,omitempty" yaml:"usb_address,omitempty"`
 }
 
 // ResourcesStorageDiskPartition represents a partition on a disk


More information about the lxc-devel mailing list