Also extend the XML schema and add a test for XML parsing.
---
docs/schemas/nodedev.rng | 9 +++++++++
src/conf/node_device_conf.c | 4 ++++
src/conf/node_device_conf.h | 1 +
src/node_device/node_device_hal.c | 1 +
src/node_device/node_device_udev.c | 6 ++++++
tests/nodedevschemadata/usb_1_1_5_3.xml | 11 +++++++++++
tests/nodedevxml2xmltest.c | 1 +
7 files changed, 33 insertions(+)
create mode 100644 tests/nodedevschemadata/usb_1_1_5_3.xml
diff --git a/docs/schemas/nodedev.rng b/docs/schemas/nodedev.rng
index 81ab4d4..6e3da6c 100644
--- a/docs/schemas/nodedev.rng
+++ b/docs/schemas/nodedev.rng
@@ -193,6 +193,15 @@
<empty/>
</choice>
</element>
+
+ <optional>
+ <element name='serial'>
+ <choice>
+ <text/>
+ <empty/>
+ </choice>
+ </element>
+ </optional>
</define>
<define name='capusbinterface'>
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
index e65b5e4..7926e60 100644
--- a/src/conf/node_device_conf.c
+++ b/src/conf/node_device_conf.c
@@ -365,6 +365,8 @@ char *virNodeDeviceDefFormat(const virNodeDeviceDef *def)
data->usb_dev.vendor_name);
else
virBufferAddLit(&buf, " />\n");
+ virBufferEscapeString(&buf,
"<serial>%s</serial>\n",
+ data->usb_dev.serial);
break;
case VIR_NODE_DEV_CAP_USB_INTERFACE:
virBufferAsprintf(&buf, "<number>%d</number>\n",
@@ -980,6 +982,7 @@ virNodeDevCapUSBDevParseXML(xmlXPathContextPtr ctxt,
data->usb_dev.vendor_name = virXPathString("string(./vendor[1])",
ctxt);
data->usb_dev.product_name = virXPathString("string(./product[1])",
ctxt);
+ data->usb_dev.serial = virXPathString("string(./serial[1])", ctxt);
ret = 0;
out:
@@ -1476,6 +1479,7 @@ void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
case VIR_NODE_DEV_CAP_USB_DEV:
VIR_FREE(data->usb_dev.product_name);
VIR_FREE(data->usb_dev.vendor_name);
+ VIR_FREE(data->usb_dev.serial);
break;
case VIR_NODE_DEV_CAP_USB_INTERFACE:
VIR_FREE(data->usb_if.description);
diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h
index 50e6805..51467c1 100644
--- a/src/conf/node_device_conf.h
+++ b/src/conf/node_device_conf.h
@@ -123,6 +123,7 @@ struct _virNodeDevCapsDef {
unsigned int vendor;
char *product_name;
char *vendor_name;
+ char *serial;
} usb_dev;
struct {
unsigned int number;
diff --git a/src/node_device/node_device_hal.c b/src/node_device/node_device_hal.c
index 8656b5d..2f85d45 100644
--- a/src/node_device/node_device_hal.c
+++ b/src/node_device/node_device_hal.c
@@ -221,6 +221,7 @@ gather_usb_device_cap(LibHalContext *ctx, const char *udi,
if (get_str_prop(ctx, udi, "usb_device.product",
&d->usb_dev.product_name) != 0)
(void)get_str_prop(ctx, udi, "info.product",
&d->usb_dev.product_name);
+ (void)get_str_prop(ctx, udi, "usb_device.serial",
&d->usb_dev.serial);
return 0;
}
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index 9a951d9..b3af192 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -575,6 +575,12 @@ static int udevProcessUSBDevice(struct udev_device *device,
goto out;
}
+ if (udevGetStringSysfsAttr(device,
+ "serial",
+ &data->usb_dev.serial) == PROPERTY_ERROR) {
+ goto out;
+ }
+
if (udevGenerateDeviceName(device, def, NULL) != 0) {
goto out;
}
diff --git a/tests/nodedevschemadata/usb_1_1_5_3.xml
b/tests/nodedevschemadata/usb_1_1_5_3.xml
new file mode 100644
index 0000000..9a8ee33
--- /dev/null
+++ b/tests/nodedevschemadata/usb_1_1_5_3.xml
@@ -0,0 +1,11 @@
+<device>
+ <name>usb_1_1_5_3</name>
+ <parent>usb_1_1_5</parent>
+ <capability type='usb_device'>
+ <bus>1</bus>
+ <device>36</device>
+ <product id='0xc069'>USB Laser Mouse</product>
+ <vendor id='0x046d'>Logitech</vendor>
+ <serial>ABCDEFGH123456789</serial>
+ </capability>
+</device>
diff --git a/tests/nodedevxml2xmltest.c b/tests/nodedevxml2xmltest.c
index 9390bf5..770af72 100644
--- a/tests/nodedevxml2xmltest.c
+++ b/tests/nodedevxml2xmltest.c
@@ -88,6 +88,7 @@ mymain(void)
DO_TEST("storage_serial_SATA_HTS721010G9SA00_MPCZ12Y0GNGWSE");
DO_TEST("usb_device_1d6b_1_0000_00_1d_0_if0");
DO_TEST("usb_device_1d6b_1_0000_00_1d_0");
+ DO_TEST("usb_1_1_5_3");
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
--
1.8.3.2