]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
nodedev: add USB port to nodedev XML
authorMaximilian Martin <maximilian_martin@gmx.de>
Mon, 18 Aug 2025 14:34:16 +0000 (16:34 +0200)
committerDaniel P. Berrangé <berrange@redhat.com>
Wed, 11 Feb 2026 18:26:39 +0000 (18:26 +0000)
This adds the physical USB port to the capabilities of a
USB device in nodedev XML.
example: <port>1.4</port>

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Maximilian Martin <maximilian_martin@gmx.de>
src/conf/node_device_conf.c
src/conf/node_device_conf.h
src/conf/schemas/basictypes.rng
src/conf/schemas/domaincommon.rng
src/conf/schemas/nodedev.rng
src/node_device/node_device_udev.c
tests/nodedevschemadata/usb_device_1d6b_1_0000_00_1d_0.xml

index 9c7982c68001070e1cb102920926eae324d2d543..ed0d340aa2ed9d3af490011ae628341f3ba000dc 100644 (file)
@@ -432,6 +432,9 @@ virNodeDeviceCapUSBDevDefFormat(virBuffer *buf,
     virBufferAsprintf(buf, "<bus>%d</bus>\n", data->usb_dev.bus);
     virBufferAsprintf(buf, "<device>%d</device>\n",
                       data->usb_dev.device);
+    if (data->usb_dev.port)
+        virBufferEscapeString(buf, "<port>%s</port>\n",
+                              data->usb_dev.port);
     virBufferAsprintf(buf, "<product id='0x%04x'",
                       data->usb_dev.product);
     if (data->usb_dev.product_name)
@@ -2083,6 +2086,7 @@ virNodeDevCapUSBDevParseXML(xmlXPathContextPtr ctxt,
                                     _("invalid USB product ID supplied for '%1$s'")) < 0)
         return -1;
 
+    usb_dev->port  = virXPathString("string(./port[1])", ctxt);
     usb_dev->vendor_name  = virXPathString("string(./vendor[1])", ctxt);
     usb_dev->product_name = virXPathString("string(./product[1])", ctxt);
 
@@ -2802,6 +2806,7 @@ virNodeDevCapsDefFree(virNodeDevCapsDef *caps)
     case VIR_NODE_DEV_CAP_USB_DEV:
         g_free(data->usb_dev.product_name);
         g_free(data->usb_dev.vendor_name);
+        g_free(data->usb_dev.port);
         break;
     case VIR_NODE_DEV_CAP_USB_INTERFACE:
         g_free(data->usb_if.description);
index b98fb750ce75686889772a301949445fb23c759d..d6d20812782b4a038333d15027cccc773bf1ae87 100644 (file)
@@ -211,6 +211,7 @@ typedef struct _virNodeDevCapUSBDev virNodeDevCapUSBDev;
 struct _virNodeDevCapUSBDev {
    unsigned int bus;
    unsigned int device;
+   char *port;
    unsigned int product;
    unsigned int vendor;
    char *product_name;
index 381e0ac24ffdf1c860046bacda857332fcaf24d0..a2ecfd3514d8b17f83cec98c667ca632b2451fcb 100644 (file)
     </choice>
   </define>
 
+  <define name="usbIdDefault">
+    <data type="string">
+      <param name="pattern">-1</param>
+    </data>
+  </define>
+  <define name="usbId">
+    <data type="string">
+      <param name="pattern">(0x)?[0-9a-fA-F]{1,4}</param>
+    </data>
+  </define>
+  <define name="usbVersion">
+    <data type="string">
+      <param name="pattern">[0-9]{1,2}.[0-9]{1,2}</param>
+    </data>
+  </define>
+  <define name="usbAddr">
+    <data type="string">
+      <param name="pattern">(0x)?[0-9a-fA-F]{1,3}</param>
+    </data>
+  </define>
+  <define name="usbClass">
+    <data type="string">
+      <param name="pattern">(0x)?[0-9a-fA-F]{1,2}</param>
+    </data>
+  </define>
+  <define name="usbPort">
+    <data type="string">
+      <param name="pattern">((0x)?[0-9a-fA-F]{1,3}\.){0,3}(0x)?[0-9a-fA-F]{1,3}</param>
+    </data>
+  </define>
+
   <define name="wwn">
     <data type="string">
       <param name="pattern">(0x)?[0-9a-fA-F]{16}</param>
index bd6b88b429f0c4b6e52ca263d5f6f61558b241d7..bf37c5332c7f35159a2e644b5c2c7bbfac2c2053 100644 (file)
       <ref name="dnsName"/>
     </choice>
   </define>
-  <define name="usbIdDefault">
-    <data type="string">
-      <param name="pattern">-1</param>
-    </data>
-  </define>
-  <define name="usbId">
-    <data type="string">
-      <param name="pattern">(0x)?[0-9a-fA-F]{1,4}</param>
-    </data>
-  </define>
-  <define name="usbVersion">
-    <data type="string">
-      <param name="pattern">[0-9]{1,2}.[0-9]{1,2}</param>
-    </data>
-  </define>
-  <define name="usbAddr">
-    <data type="string">
-      <param name="pattern">(0x)?[0-9a-fA-F]{1,3}</param>
-    </data>
-  </define>
-  <define name="usbClass">
-    <data type="string">
-      <param name="pattern">(0x)?[0-9a-fA-F]{1,2}</param>
-    </data>
-  </define>
-  <define name="usbPort">
-    <data type="string">
-      <param name="pattern">((0x)?[0-9a-fA-F]{1,3}\.){0,3}(0x)?[0-9a-fA-F]{1,3}</param>
-    </data>
-  </define>
   <define name="driveController">
     <data type="string">
       <param name="pattern">[0-9]{1,2}</param>
index 31ce517e4d562d20033051288a708c5d64b21fd5..3b5d1391c5bfce49c9929621d28d4c668b10015c 100644 (file)
     <element name="device">
       <ref name="unsignedLong"/>
     </element>
+    <element name="port">
+      <ref name="unsignedLong"/>
+    </element>
 
     <element name="product">
       <attribute name="id">
index 20a525bcec79e273190ac80642eb2ebf6e4da739..89aca2d4d623e110090dddcb9498d4c994fbf6fa 100644 (file)
@@ -595,6 +595,10 @@ udevProcessUSBDevice(struct udev_device *device,
         return -1;
     if (udevGetUintProperty(device, "ID_VENDOR_ID", &usb_dev->vendor, 16) < 0)
         return -1;
+    if (!usb_dev->port) {
+        udevGetStringSysfsAttr(device, "devpath",
+                               &usb_dev->port);
+    }
 
     udevGetStringProperty(device,
                           "ID_VENDOR_FROM_DATABASE",
index 29533e769b3dd8717ab87e2a95655e93f5b5a290..089821353229d92ea1609150cd88f49a828afd99 100644 (file)
@@ -4,6 +4,7 @@
   <capability type='usb_device'>
     <bus>2</bus>
     <device>1</device>
+    <port>3</port>
     <product id='0x0001'>1.1 root hub</product>
     <vendor id='0x1d6b'>Linux Foundation</vendor>
   </capability>