[PATCH 0/6] virCommand cleanups
by Peter Krempa
Some cleanups I've accumulated.
Peter Krempa (6):
virPipeImpl: Don't overwrite error
virCommandAddEnvBuffer: Remove unused function
util: vircommand: Add wrappers for virCommand error checking
virCommandFDSet: Remove return value
virCommandSetSendBuffer: Provide saner semantics
commandtest: test27: Remove pointless 'cleanup' label
src/libvirt_private.syms | 1 -
src/qemu/qemu_tpm.c | 50 ++-------
src/util/vircommand.c | 230 ++++++++++++++++++---------------------
src/util/vircommand.h | 9 +-
src/util/virutil.c | 2 -
tests/commandtest.c | 49 ++-------
6 files changed, 131 insertions(+), 210 deletions(-)
--
2.29.2
3 years, 9 months
[PATCH] feat(usb-hostdev): add ability to filter by USB serial strings too
by Giel van Schijndel
This patch adds the ability to select a specific USB device when
multiple are available with the same vendor and product IDs.
As an example, I'm using this to pass through a specific USB mouse to my
guest VM. I happen to have two of the exact same model (Logitech MX518),
differing only in their serial number, and only wish to pass through one
of them to my VM.
An example of the config snippet I'm using with this:
<hostdev mode='subsystem' type='usb' managed='yes'>
<source>
<vendor id='0x046d'/>
<product id='0xc08e'/>
<serial>0D3087538362</serial>
</source>
</hostdev>
Without this patch I would either get an error message on attempted
startup, complaining about having found multiple devices with the same
product or vendor id. Or alternatively I'd have to set the bus number
and device number. Unfortunately the latter tends to change with every
reboot, and in my case whenever my monitor comes out of standby (I'm
using its builtin USB hub).
---
docs/formatdomain.rst | 6 ++
docs/schemas/domaincommon.rng | 10 +++
src/conf/domain_conf.c | 15 ++++
src/conf/domain_conf.h | 3 +-
src/hypervisor/virhostdev.c | 14 ++--
src/util/virusb.c | 66 ++++++++++++-----
src/util/virusb.h | 2 +
tests/virusbtest.c | 71 +++++++++++--------
.../sys_bus_usb/devices/1-1.5.4/serial | 1 +
.../sys_bus_usb/devices/1-1.5.5/serial | 1 +
.../sys_bus_usb/devices/1-1.5.6/serial | 1 +
11 files changed, 137 insertions(+), 53 deletions(-)
create mode 100644 tests/virusbtestdata/sys_bus_usb/devices/1-1.5.4/serial
create mode 100644 tests/virusbtestdata/sys_bus_usb/devices/1-1.5.5/serial
create mode 100644 tests/virusbtestdata/sys_bus_usb/devices/1-1.5.6/serial
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 2587106191..6d011cc789 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -3864,6 +3864,7 @@ for PCI (KVM only) and 1.0.6 for SCSI (KVM only)` :
<source startupPolicy='optional'>
<vendor id='0x1234'/>
<product id='0xbeef'/>
+ <serial>TANT14-B4732</serial>
</source>
<boot order='2'/>
</hostdev>
@@ -4041,6 +4042,11 @@ or:
optional drop if missing at any start attempt
========= =====================================================================
+ :since:`Since 7.1.0`, the ``source`` element of USB devices may contain
+ the ``serial`` element which can be used in addition to ``vendor`` and
+ ``product`` to select a specific USB device if multiple devices with the
+ same vendor and product id are present.
+
``pci``
PCI devices can only be described by their ``address``.
:since:`Since 6.8.0 (Xen only)` , the ``source`` element of a PCI device
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index e6de934456..d6eb29a9a8 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -5355,6 +5355,11 @@
<ref name="usbId"/>
</attribute>
</element>
+ <optional>
+ <element name="serial">
+ <ref name="usbSerial"/>
+ </element>
+ </optional>
</define>
<define name="usbaddress">
<element name="address">
@@ -7053,6 +7058,11 @@
<param name="pattern">(0x)?[0-9a-fA-F]{1,4}</param>
</data>
</define>
+ <define name="usbSerial">
+ <data type="string">
+ <param name="pattern">[A-Za-z0-9_\.\+\- ]+</param>
+ </data>
+ </define>
<define name="usbVersion">
<data type="string">
<param name="pattern">[0-9]{1,2}.[0-9]{1,2}</param>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b731744f04..4967d62989 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3078,6 +3078,8 @@ void virDomainHostdevDefClear(virDomainHostdevDefPtr def)
VIR_FREE(def->source.subsys.u.scsi_host.wwpn);
break;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
+ VIR_FREE(def->source.subsys.u.usb.serial);
+ break;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
@@ -6703,6 +6705,16 @@ virDomainHostdevSubsysUSBDefParseXML(xmlNodePtr node,
"%s", _("usb product needs id"));
return -1;
}
+ } else if (!usbsrc->serial &&
+ virXMLNodeNameEqual(cur, "serial")) {
+ g_autofree char *serial = virXMLNodeContentString(cur);
+ if (!serial) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("usb serial needs content"));
+ return -1;
+ }
+
+ usbsrc->serial = g_steal_pointer(&serial);
} else if (virXMLNodeNameEqual(cur, "address")) {
g_autofree char *bus = NULL;
g_autofree char *device = NULL;
@@ -25089,6 +25101,9 @@ virDomainHostdevDefFormatSubsysUSB(virBufferPtr buf,
if (usbsrc->vendor) {
virBufferAsprintf(&sourceChildBuf, "<vendor id='0x%.4x'/>\n", usbsrc->vendor);
virBufferAsprintf(&sourceChildBuf, "<product id='0x%.4x'/>\n", usbsrc->product);
+ if (usbsrc->serial) {
+ virBufferEscapeString(&sourceChildBuf, "<serial>%s</serial>\n", usbsrc->serial);
+ }
}
if (usbsrc->bus || usbsrc->device)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 930eed60de..a66b815901 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -227,12 +227,13 @@ VIR_ENUM_DECL(virDomainHostdevSubsysSCSIProtocol);
struct _virDomainHostdevSubsysUSB {
bool autoAddress; /* bus/device were filled automatically based
- on vendor/product */
+ on vendor/product (optionally serial) */
unsigned bus;
unsigned device;
unsigned vendor;
unsigned product;
+ char *serial;
};
struct _virDomainHostdevSubsysPCI {
diff --git a/src/hypervisor/virhostdev.c b/src/hypervisor/virhostdev.c
index 743aaa84d6..f9fd42b24d 100644
--- a/src/hypervisor/virhostdev.c
+++ b/src/hypervisor/virhostdev.c
@@ -1324,6 +1324,7 @@ virHostdevFindUSBDevice(virDomainHostdevDefPtr hostdev,
virDomainHostdevSubsysUSBPtr usbsrc = &hostdev->source.subsys.u.usb;
unsigned vendor = usbsrc->vendor;
unsigned product = usbsrc->product;
+ const char *serial = usbsrc->serial;
unsigned bus = usbsrc->bus;
unsigned device = usbsrc->device;
bool autoAddress = usbsrc->autoAddress;
@@ -1332,7 +1333,7 @@ virHostdevFindUSBDevice(virDomainHostdevDefPtr hostdev,
*usb = NULL;
if (vendor && bus) {
- rc = virUSBDeviceFind(vendor, product, bus, device,
+ rc = virUSBDeviceFind(vendor, product, serial, bus, device,
NULL,
autoAddress ? false : mandatory,
usb);
@@ -1354,7 +1355,8 @@ virHostdevFindUSBDevice(virDomainHostdevDefPtr hostdev,
if (vendor) {
g_autoptr(virUSBDeviceList) devs = NULL;
- rc = virUSBDeviceFindByVendor(vendor, product, NULL, mandatory, &devs);
+ rc = virUSBDeviceFindByVendor(vendor, product, serial, NULL, mandatory,
+ &devs);
if (rc < 0) {
return -1;
} else if (rc == 0) {
@@ -1362,9 +1364,11 @@ virHostdevFindUSBDevice(virDomainHostdevDefPtr hostdev,
} else if (rc > 1) {
if (autoAddress) {
virReportError(VIR_ERR_OPERATION_FAILED,
- _("Multiple USB devices for %x:%x were found,"
- " but none of them is at bus:%u device:%u"),
- vendor, product, bus, device);
+ _("Multiple USB devices for %x:%x (serial: %s)"
+ " were found, but none of them is at bus:%u"
+ " device:%u"),
+ vendor, product, serial ? serial : "<none>", bus,
+ device);
} else {
virReportError(VIR_ERR_OPERATION_FAILED,
_("Multiple USB devices for %x:%x, "
diff --git a/src/util/virusb.c b/src/util/virusb.c
index 6d897600e5..d945d71b98 100644
--- a/src/util/virusb.c
+++ b/src/util/virusb.c
@@ -81,21 +81,31 @@ static int virUSBOnceInit(void)
VIR_ONCE_GLOBAL_INIT(virUSB);
-static int virUSBSysReadFile(const char *f_name, const char *d_name,
- int base, unsigned int *value)
+static char* virUSBSysReadFile(const char *f_name, const char *d_name)
{
- g_autofree char *buf = NULL;
g_autofree char *filename = NULL;
- char *ignore = NULL;
+ char* buf;
filename = g_strdup_printf(USB_SYSFS "/devices/%s/%s", d_name, f_name);
if (virFileReadAll(filename, 1024, &buf) < 0)
+ return NULL;
+
+ return buf;
+}
+
+static int virUSBSysReadIntFile(const char *f_name, const char *d_name,
+ int base, unsigned int *value)
+{
+ g_autofree char *buf = NULL;
+ char *ignore = NULL;
+
+ if (!(buf = virUSBSysReadFile(f_name, d_name)))
return -1;
if (virStrToLong_ui(buf, &ignore, base, value) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Could not parse usb file %s"), filename);
+ _("Could not parse usb file %s/%s"), d_name, f_name);
return -1;
}
@@ -105,6 +115,7 @@ static int virUSBSysReadFile(const char *f_name, const char *d_name,
static virUSBDeviceListPtr
virUSBDeviceSearch(unsigned int vendor,
unsigned int product,
+ const char *serial,
unsigned int bus,
unsigned int devno,
const char *vroot,
@@ -132,11 +143,11 @@ virUSBDeviceSearch(unsigned int vendor,
if (strchr(de->d_name, ':'))
continue;
- if (virUSBSysReadFile("idVendor", de->d_name,
+ if (virUSBSysReadIntFile("idVendor", de->d_name,
16, &found_vend) < 0)
goto cleanup;
- if (virUSBSysReadFile("idProduct", de->d_name,
+ if (virUSBSysReadIntFile("idProduct", de->d_name,
16, &found_prod) < 0)
goto cleanup;
@@ -150,13 +161,31 @@ virUSBDeviceSearch(unsigned int vendor,
goto cleanup;
}
- if (virUSBSysReadFile("devnum", de->d_name,
+ if (virUSBSysReadIntFile("devnum", de->d_name,
10, &found_devno) < 0)
goto cleanup;
- if ((flags & USB_DEVICE_FIND_BY_VENDOR) &&
- (found_prod != product || found_vend != vendor))
- continue;
+ if (flags & USB_DEVICE_FIND_BY_VENDOR) {
+ if (found_prod != product || found_vend != vendor)
+ continue;
+
+ if (serial) {
+ g_autofree char *found_serial = virUSBSysReadFile("serial", de->d_name);
+ size_t len;
+
+ if (!found_serial)
+ continue;
+ len = strlen(found_serial);
+ if (!len)
+ continue;
+
+ if (found_serial[len - 1] == '\n')
+ found_serial[len - 1] = '\0';
+
+ if (strcmp(found_serial, serial))
+ continue;
+ }
+ }
if (flags & USB_DEVICE_FIND_BY_BUS) {
if (found_bus != bus || found_devno != devno)
@@ -188,6 +217,7 @@ virUSBDeviceSearch(unsigned int vendor,
int
virUSBDeviceFindByVendor(unsigned int vendor,
unsigned int product,
+ const char *serial,
const char *vroot,
bool mandatory,
virUSBDeviceListPtr *devices)
@@ -195,7 +225,7 @@ virUSBDeviceFindByVendor(unsigned int vendor,
virUSBDeviceListPtr list;
int count;
- if (!(list = virUSBDeviceSearch(vendor, product, 0, 0,
+ if (!(list = virUSBDeviceSearch(vendor, product, serial, 0, 0,
vroot,
USB_DEVICE_FIND_BY_VENDOR)))
return -1;
@@ -203,15 +233,16 @@ virUSBDeviceFindByVendor(unsigned int vendor,
if (list->count == 0) {
virObjectUnref(list);
if (!mandatory) {
- VIR_DEBUG("Did not find USB device %04x:%04x",
- vendor, product);
+ VIR_DEBUG("Did not find USB device %04x:%04x (serial %s)",
+ vendor, product, serial ? serial : "<none>");
if (devices)
*devices = NULL;
return 0;
}
virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Did not find USB device %04x:%04x"), vendor, product);
+ _("Did not find USB device %04x:%04x (serial %s)"),
+ vendor, product, serial ? serial : "<none>");
return -1;
}
@@ -233,7 +264,7 @@ virUSBDeviceFindByBus(unsigned int bus,
{
virUSBDeviceListPtr list;
- if (!(list = virUSBDeviceSearch(0, 0, bus, devno,
+ if (!(list = virUSBDeviceSearch(0, 0, NULL, bus, devno,
vroot,
USB_DEVICE_FIND_BY_BUS)))
return -1;
@@ -266,6 +297,7 @@ virUSBDeviceFindByBus(unsigned int bus,
int
virUSBDeviceFind(unsigned int vendor,
unsigned int product,
+ const char *serial,
unsigned int bus,
unsigned int devno,
const char *vroot,
@@ -275,7 +307,7 @@ virUSBDeviceFind(unsigned int vendor,
virUSBDeviceListPtr list;
unsigned int flags = USB_DEVICE_FIND_BY_VENDOR|USB_DEVICE_FIND_BY_BUS;
- if (!(list = virUSBDeviceSearch(vendor, product, bus, devno,
+ if (!(list = virUSBDeviceSearch(vendor, product, serial, bus, devno,
vroot, flags)))
return -1;
diff --git a/src/util/virusb.h b/src/util/virusb.h
index 42a3303952..c9d5330fac 100644
--- a/src/util/virusb.h
+++ b/src/util/virusb.h
@@ -45,12 +45,14 @@ int virUSBDeviceFindByBus(unsigned int bus,
int virUSBDeviceFindByVendor(unsigned int vendor,
unsigned int product,
+ const char* serial,
const char *vroot,
bool mandatory,
virUSBDeviceListPtr *devices);
int virUSBDeviceFind(unsigned int vendor,
unsigned int product,
+ const char* serial,
unsigned int bus,
unsigned int devno,
const char *vroot,
diff --git a/tests/virusbtest.c b/tests/virusbtest.c
index 7df4e3aec3..cba4d57d9a 100644
--- a/tests/virusbtest.c
+++ b/tests/virusbtest.c
@@ -37,12 +37,14 @@ struct findTestInfo {
const char *name;
unsigned int vendor;
unsigned int product;
+ const char *serial;
unsigned int bus;
unsigned int devno;
const char *vroot;
bool mandatory;
int how;
bool expectFailure;
+ unsigned int expectResults;
};
static int testDeviceFileActor(virUSBDevicePtr dev,
@@ -76,12 +78,12 @@ static int testDeviceFind(const void *opaque)
switch (info->how) {
case FIND_BY_ALL:
- rv = virUSBDeviceFind(info->vendor, info->product,
+ rv = virUSBDeviceFind(info->vendor, info->product, info->serial,
info->bus, info->devno,
info->vroot, info->mandatory, &dev);
break;
case FIND_BY_VENDOR:
- rv = virUSBDeviceFindByVendor(info->vendor, info->product,
+ rv = virUSBDeviceFindByVendor(info->vendor, info->product, info->serial,
info->vroot, info->mandatory, &devs);
break;
case FIND_BY_BUS:
@@ -117,6 +119,13 @@ static int testDeviceFind(const void *opaque)
if (virUSBDeviceFileIterate(device, testDeviceFileActor, NULL) < 0)
goto cleanup;
}
+
+ if (ndevs != info->expectResults) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "different amount of results"
+ " than expected (%zu != %u)", ndevs,
+ info->expectResults);
+ goto cleanup;
+ }
break;
}
@@ -157,7 +166,7 @@ testUSBList(const void *opaque G_GNUC_UNUSED)
goto cleanup;
#define EXPECTED_NDEVS_ONE 3
- if (virUSBDeviceFindByVendor(0x1d6b, 0x0002, NULL, true, &devlist) < 0)
+ if (virUSBDeviceFindByVendor(0x1d6b, 0x0002, NULL, NULL, true, &devlist) < 0)
goto cleanup;
ndevs = virUSBDeviceListCount(devlist);
@@ -181,7 +190,7 @@ testUSBList(const void *opaque G_GNUC_UNUSED)
goto cleanup;
#define EXPECTED_NDEVS_TWO 3
- if (virUSBDeviceFindByVendor(0x18d1, 0x4e22, NULL, true, &devlist) < 0)
+ if (virUSBDeviceFindByVendor(0x18d1, 0x4e22, NULL, NULL, true, &devlist) < 0)
goto cleanup;
ndevs = virUSBDeviceListCount(devlist);
@@ -201,7 +210,7 @@ testUSBList(const void *opaque G_GNUC_UNUSED)
EXPECTED_NDEVS_ONE + EXPECTED_NDEVS_TWO) < 0)
goto cleanup;
- if (virUSBDeviceFind(0x18d1, 0x4e22, 1, 20, NULL, true, &dev) < 0)
+ if (virUSBDeviceFind(0x18d1, 0x4e22, NULL, 1, 20, NULL, true, &dev) < 0)
goto cleanup;
if (!virUSBDeviceListFind(list, dev)) {
@@ -235,48 +244,50 @@ mymain(void)
{
int rv = 0;
-#define DO_TEST_FIND_FULL(name, vend, prod, bus, devno, vroot, mand, how, fail) \
+#define DO_TEST_FIND_FULL(name, vend, prod, serial, bus, devno, vroot, mand, how, fail, expected) \
do { \
- struct findTestInfo data = { name, vend, prod, bus, \
- devno, vroot, mand, how, fail \
+ struct findTestInfo data = { name, vend, prod, serial, bus, \
+ devno, vroot, mand, how, fail, expected \
}; \
if (virTestRun("USBDeviceFind " name, testDeviceFind, &data) < 0) \
rv = -1; \
} while (0)
-#define DO_TEST_FIND(name, vend, prod, bus, devno) \
- DO_TEST_FIND_FULL(name, vend, prod, bus, devno, NULL, true, \
- FIND_BY_ALL, false)
-#define DO_TEST_FIND_FAIL(name, vend, prod, bus, devno) \
- DO_TEST_FIND_FULL(name, vend, prod, bus, devno, NULL, true, \
- FIND_BY_ALL, true)
+#define DO_TEST_FIND(name, vend, prod, serial, bus, devno, expected) \
+ DO_TEST_FIND_FULL(name, vend, prod, serial, bus, devno, NULL, true, \
+ FIND_BY_ALL, false, expected)
+#define DO_TEST_FIND_FAIL(name, vend, prod, serial, bus, devno) \
+ DO_TEST_FIND_FULL(name, vend, prod, serial, bus, devno, NULL, true, \
+ FIND_BY_ALL, true, 0)
#define DO_TEST_FIND_BY_BUS(name, bus, devno) \
- DO_TEST_FIND_FULL(name, 101, 202, bus, devno, NULL, true, \
- FIND_BY_BUS, false)
+ DO_TEST_FIND_FULL(name, 101, 202, NULL, bus, devno, NULL, true, \
+ FIND_BY_BUS, false, 1)
#define DO_TEST_FIND_BY_BUS_FAIL(name, bus, devno) \
- DO_TEST_FIND_FULL(name, 101, 202, bus, devno, NULL, true, \
- FIND_BY_BUS, true)
+ DO_TEST_FIND_FULL(name, 101, 202, NULL, bus, devno, NULL, true, \
+ FIND_BY_BUS, true, 0)
-#define DO_TEST_FIND_BY_VENDOR(name, vend, prod) \
- DO_TEST_FIND_FULL(name, vend, prod, 123, 456, NULL, true, \
- FIND_BY_VENDOR, false)
-#define DO_TEST_FIND_BY_VENDOR_FAIL(name, vend, prod) \
- DO_TEST_FIND_FULL(name, vend, prod, 123, 456, NULL, true, \
- FIND_BY_VENDOR, true)
+#define DO_TEST_FIND_BY_VENDOR(name, vend, prod, serial, expected) \
+ DO_TEST_FIND_FULL(name, vend, prod, serial, 123, 456, NULL, true, \
+ FIND_BY_VENDOR, false, expected)
+#define DO_TEST_FIND_BY_VENDOR_FAIL(name, vend, prod, serial) \
+ DO_TEST_FIND_FULL(name, vend, prod, serial, 123, 456, NULL, true, \
+ FIND_BY_VENDOR, true, 0)
- DO_TEST_FIND("Nexus", 0x18d1, 0x4e22, 1, 20);
- DO_TEST_FIND_FAIL("Nexus wrong devnum", 0x18d1, 0x4e22, 1, 25);
- DO_TEST_FIND_FAIL("Bogus", 0xf00d, 0xbeef, 1024, 768);
+ DO_TEST_FIND("Nexus", 0x18d1, 0x4e22, NULL, 1, 20, 1);
+ DO_TEST_FIND_FAIL("Nexus wrong devnum", 0x18d1, 0x4e22, NULL, 1, 25);
+ DO_TEST_FIND_FAIL("Bogus", 0xf00d, 0xbeef, NULL, 1024, 768);
DO_TEST_FIND_BY_BUS("integrated camera", 1, 5);
DO_TEST_FIND_BY_BUS_FAIL("wrong bus/devno combination", 2, 20);
DO_TEST_FIND_BY_BUS_FAIL("missing bus", 5, 20);
DO_TEST_FIND_BY_BUS_FAIL("missing devnum", 1, 158);
- DO_TEST_FIND_BY_VENDOR("Nexus (multiple results)", 0x18d1, 0x4e22);
- DO_TEST_FIND_BY_VENDOR_FAIL("Bogus vendor and product", 0xf00d, 0xbeef);
- DO_TEST_FIND_BY_VENDOR_FAIL("Valid vendor", 0x1d6b, 0xbeef);
+ DO_TEST_FIND_BY_VENDOR("Nexus (multiple results)", 0x18d1, 0x4e22, NULL, 3);
+ DO_TEST_FIND_BY_VENDOR("Nexus (with serial)", 0x18d1, 0x4e22, "TANT14-B4732", 1);
+ DO_TEST_FIND_BY_VENDOR_FAIL("Bogus vendor and product", 0xf00d, 0xbeef, NULL);
+ DO_TEST_FIND_BY_VENDOR_FAIL("Valid vendor", 0x1d6b, 0xbeef, NULL);
+ DO_TEST_FIND_BY_VENDOR_FAIL("Bogus serial", 0x18d1, 0x4e22, "BOGUS");
if (virTestRun("USB List test", testUSBList, NULL) < 0)
rv = -1;
diff --git a/tests/virusbtestdata/sys_bus_usb/devices/1-1.5.4/serial b/tests/virusbtestdata/sys_bus_usb/devices/1-1.5.4/serial
new file mode 100644
index 0000000000..6bee213c08
--- /dev/null
+++ b/tests/virusbtestdata/sys_bus_usb/devices/1-1.5.4/serial
@@ -0,0 +1 @@
+20200222113321
diff --git a/tests/virusbtestdata/sys_bus_usb/devices/1-1.5.5/serial b/tests/virusbtestdata/sys_bus_usb/devices/1-1.5.5/serial
new file mode 100644
index 0000000000..14764cdc37
--- /dev/null
+++ b/tests/virusbtestdata/sys_bus_usb/devices/1-1.5.5/serial
@@ -0,0 +1 @@
+0123:4b:01.7
diff --git a/tests/virusbtestdata/sys_bus_usb/devices/1-1.5.6/serial b/tests/virusbtestdata/sys_bus_usb/devices/1-1.5.6/serial
new file mode 100644
index 0000000000..b20f2081b7
--- /dev/null
+++ b/tests/virusbtestdata/sys_bus_usb/devices/1-1.5.6/serial
@@ -0,0 +1 @@
+TANT14-B4732
--
2.27.0
3 years, 10 months
[libvirt PATCH] cpu_map: Install x86_EPYC-Milan.xml
by Jiri Denemark
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
src/cpu_map/meson.build | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/cpu_map/meson.build b/src/cpu_map/meson.build
index 48f69f623c..013fc62a02 100644
--- a/src/cpu_map/meson.build
+++ b/src/cpu_map/meson.build
@@ -34,6 +34,7 @@ cpumap_data = [
'x86_Dhyana.xml',
'x86_EPYC-IBPB.xml',
'x86_EPYC.xml',
+ 'x86_EPYC-Milan.xml',
'x86_EPYC-Rome.xml',
'x86_features.xml',
'x86_Haswell-IBRS.xml',
--
2.30.0
3 years, 10 months
using libvirt 4.5 with upstream qemu
by Thanos Makatos
I'm trying to use QEMU master with libvirt 4.5 and QEMU seems to be hanging
when I try to start a guest.
My environment is a modified CentOS 7.9 installation using libvirt 4.5.0. When
I use a modified version of QEMU 2.12 (reasonably close to the stock CentOS
version) everything works fine. When I try to use a fairly recent version of
QEMU (e.g. v5.2.0-729-g89ff714f4b).
qemu 118657 1.6 0.0 0 0 ? Z 14:50 0:00 [qemu-kvm] <defunct>
qemu 118664 0.0 0.0 207340 3560 ? Ssl 14:50 0:00 /usr/libexec/qemu-kvm -S -no-user-config -nodefaults -nographic -machine none,accel=kvm:tcg -qmp unix:/var/lib/libvirt/qemu/capabilities.monitor.sock,server,nowait -pidfile /var/lib/libvirt/qemu/capabilities.pidfile -daemonize
qemu 118666 0.0 0.0 275008 13916 ? Sl 14:50 0:00 /usr/libexec/qemu-kvm -S -no-user-config -nodefaults -nographic -machine none,accel=kvm:tcg -qmp unix:/var/lib/libvirt/qemu/capabilities.monitor.sock,server,nowait -pidfile /var/lib/libvirt/qemu/capabilities.pidfile -daemonize
/var/lib/libvirt/qemu/capabilities.pidfile contains the PID of the 2nd QEMU
process and by experimenting I found that by killing the QEMU process NOT in
the PID file the same thing happens again (maybe once more or twice) and then
the guest boots fine.
Does libvirt have some specific QEMU dependency? Is there some compatibility
matrix I might have missed? I understand this may not be a supported
configuration given that I'm not using vanilla libvirt/QEMU, however I'd
appreciate some pointers so I can further debug this. I've trying debugging
this in case there's some obvious error but didn't find anything interesting.
Any ideas?
3 years, 10 months
[libvirt PATCH] cpu_map: Add EPYC-Milan x86 CPU model
by Jiri Denemark
Introduced in QEMU 6.0.0 by 623972ceae091b31331ae4a1dc94fe5cbb891937
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
src/cpu_map/index.xml | 1 +
src/cpu_map/x86_EPYC-Milan.xml | 92 ++++++++++++++++++++++++++++++++++
2 files changed, 93 insertions(+)
create mode 100644 src/cpu_map/x86_EPYC-Milan.xml
diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml
index 2e0685df68..ffe1fa91e5 100644
--- a/src/cpu_map/index.xml
+++ b/src/cpu_map/index.xml
@@ -68,6 +68,7 @@
<include filename='x86_EPYC.xml'/>
<include filename='x86_EPYC-IBPB.xml'/>
<include filename='x86_EPYC-Rome.xml'/>
+ <include filename='x86_EPYC-Milan.xml'/>
<!-- Hygon CPU models -->
<include filename='x86_Dhyana.xml'/>
diff --git a/src/cpu_map/x86_EPYC-Milan.xml b/src/cpu_map/x86_EPYC-Milan.xml
new file mode 100644
index 0000000000..53f0cd6aac
--- /dev/null
+++ b/src/cpu_map/x86_EPYC-Milan.xml
@@ -0,0 +1,92 @@
+<cpus>
+ <model name='EPYC-Milan'>
+ <decode host='on' guest='on'/>
+ <signature family='25' model='1'/>
+ <vendor name='AMD'/>
+ <feature name='3dnowprefetch'/>
+ <feature name='abm'/>
+ <feature name='adx'/>
+ <feature name='aes'/>
+ <feature name='amd-ssbd'/>
+ <feature name='amd-stibp'/>
+ <feature name='apic'/>
+ <feature name='arat'/>
+ <feature name='avx'/>
+ <feature name='avx2'/>
+ <feature name='bmi1'/>
+ <feature name='bmi2'/>
+ <feature name='clflush'/>
+ <feature name='clflushopt'/>
+ <feature name='clwb'/>
+ <feature name='clzero'/>
+ <feature name='cmov'/>
+ <feature name='cr8legacy'/>
+ <feature name='cx16'/>
+ <feature name='cx8'/>
+ <feature name='de'/>
+ <feature name='erms'/>
+ <feature name='f16c'/>
+ <feature name='fma'/>
+ <feature name='fpu'/>
+ <feature name='fsgsbase'/>
+ <feature name='fsrm'/>
+ <feature name='fxsr'/>
+ <feature name='fxsr_opt'/>
+ <feature name='ibpb'/>
+ <feature name='ibrs'/>
+ <feature name='invpcid'/>
+ <feature name='lahf_lm'/>
+ <feature name='lm'/>
+ <feature name='mca'/>
+ <feature name='mce'/>
+ <feature name='misalignsse'/>
+ <feature name='mmx'/>
+ <feature name='mmxext'/>
+ <feature name='movbe'/>
+ <feature name='msr'/>
+ <feature name='mtrr'/>
+ <feature name='npt'/>
+ <feature name='nrip-save'/>
+ <feature name='nx'/>
+ <feature name='osvw'/>
+ <feature name='pae'/>
+ <feature name='pat'/>
+ <feature name='pcid'/>
+ <feature name='pclmuldq'/>
+ <feature name='pdpe1gb'/>
+ <feature name='perfctr_core'/>
+ <feature name='pge'/>
+ <feature name='pku'/>
+ <feature name='pni'/>
+ <feature name='popcnt'/>
+ <feature name='pse'/>
+ <feature name='pse36'/>
+ <feature name='rdpid'/>
+ <feature name='rdrand'/>
+ <feature name='rdseed'/>
+ <feature name='rdtscp'/>
+ <feature name='sep'/>
+ <feature name='sha-ni'/>
+ <feature name='smap'/>
+ <feature name='smep'/>
+ <feature name='sse'/>
+ <feature name='sse2'/>
+ <feature name='sse4.1'/>
+ <feature name='sse4.2'/>
+ <feature name='sse4a'/>
+ <feature name='ssse3'/>
+ <feature name='svm'/>
+ <feature name='svme-addr-check'/>
+ <feature name='syscall'/>
+ <feature name='tsc'/>
+ <feature name='umip'/>
+ <feature name='vme'/>
+ <feature name='wbnoinvd'/>
+ <feature name='xgetbv1'/>
+ <feature name='xsave'/>
+ <feature name='xsavec'/>
+ <feature name='xsaveerptr'/>
+ <feature name='xsaveopt'/>
+ <feature name='xsaves'/>
+ </model>
+</cpus>
--
2.30.0
3 years, 10 months
[PATCH] libxl: Fix node device detach when driver unspecified
by Jim Fehlig
Commit 887dd0d331 caused a small regression in NodeDeviceDetach in the libxl
driver when the 'driver' parameter is not specified. E.g.
error: Failed to detach device pci_0000_0a_10_0
error: An error occurred, but the cause is unknown
If the driver name is not specified, NULL is passed to
virDomainDriverNodeDeviceDetachFlags, in which case virPCIDeviceSetStubDriver
is never called to set the stub to pciback. Fix it by setting the driver to
"xen" if it is not specified when invoking NodeDeviceDetach.
Signed-off-by: Jim Fehlig <jfehlig(a)suse.com>
---
src/libxl/libxl_driver.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 75a8d46af0..348434ca72 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -5777,6 +5777,9 @@ libxlNodeDeviceDetachFlags(virNodeDevicePtr dev,
virCheckFlags(0, -1);
+ if (!driverName)
+ driverName = "xen";
+
if (driverName && STRNEQ(driverName, "xen")) {
virReportError(VIR_ERR_INVALID_ARG,
_("unsupported driver name '%s'"), driverName);
--
2.29.2
3 years, 10 months
[PATCH] hyperv: Fix 32bit compilation
by Cole Robinson
Example:
../src/hyperv/hyperv_driver.c:3007:54: error: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 7 has type ‘size_t’ {aka ‘unsigned int’} [-Werror=format=]
3007 | virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not attach serial port %lu"), i);
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
Pushed
src/hyperv/hyperv_driver.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index 701456cdb3..e4f537bd12 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -3004,7 +3004,7 @@ hypervDomainDefineXML(virConnectPtr conn, const char *xml)
/* Attach serials */
for (i = 0; i < def->nserials; i++) {
if (hypervDomainAttachSerial(domain, def->serials[i]) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not attach serial port %lu"), i);
+ virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not attach serial port %zu"), i);
goto error;
}
}
@@ -3012,7 +3012,7 @@ hypervDomainDefineXML(virConnectPtr conn, const char *xml)
/* Attach networks */
for (i = 0; i < def->nnets; i++) {
if (hypervDomainAttachSyntheticEthernetAdapter(domain, def->nets[i], hostname) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not attach network %lu"), i);
+ virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not attach network %zu"), i);
goto error;
}
}
--
2.29.2
3 years, 10 months
[PATCH v2 0/3] Use g_autoptr and g_autofree
by Kristina Hanicova
This is v2 from
https://listman.redhat.com/archives/libvir-list/2021-February/msg01129.html
I changed variable names in patch 1/3 as suggested by Laine. Patches 2/3
and 3/3 have already been reviewed-by and I am sending them for
completeness.
This uses g_autofree (if possible) in file networkcommon_conf and
g_autoptr instead of virNetDevIPRouteFree where possible.
Kristina Hanicova (3):
networkcommon_conf: Use g_autofree where possible
Use g_autoptr instead of virNetDevIPRouteFree if possible
Remove redundant variables/labels
src/conf/domain_conf.c | 3 +-
src/conf/networkcommon_conf.c | 90 +++++++++++++++--------------------
src/lxc/lxc_native.c | 10 ++--
src/vz/vz_sdk.c | 3 +-
4 files changed, 44 insertions(+), 62 deletions(-)
--
2.29.2
3 years, 10 months
[libvirt PATCH 0/5] cpu_map: Sync with Qemu
by Tim Wiederhake
Qemu updated its list of known cpu features. Follow suit.
Tim Wiederhake (5):
cpu_map/sync_qemu_i386.py: Add mapping for amd-ssbd
cpu_map/sync_qemu_i386.py: Add mapping for ibrs
cpu_map/sync_qemu_i386.py: Add mapping for svme-addr-check
cpumap: Add support for ibrs CPU feature
cpumap: Add support for svme-addr-check CPU feature
src/cpu_map/sync_qemu_i386.py | 3 +++
src/cpu_map/x86_features.xml | 6 ++++++
tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml | 1 +
tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml | 1 +
4 files changed, 11 insertions(+)
--
2.26.2
3 years, 10 months
[PATCH] tools: Fix dry run of libvirt_recover_xattrs.sh
by Michal Privoznik
The libvirt_recover_xattrs.sh script can be used to remove stale
XATTRs that were left behind by secdrivers (which should happen
only if there' an imbalance between set and restore calls).
Anyway, the script has '-n' switch which is supposed to perform
just a dry run, i.e. just to report which files have XATTRs set
without any attempt to remove them.
But, when rewriting the script a few months ago a typo was
introduced which made the script report no files even if there
were files with XATTRs.
Fixes: 5377177f80da40ee7d47601400b50835f093715a
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
tools/libvirt_recover_xattrs.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/libvirt_recover_xattrs.sh b/tools/libvirt_recover_xattrs.sh
index 59f1f3f476..be6ee84b5f 100755
--- a/tools/libvirt_recover_xattrs.sh
+++ b/tools/libvirt_recover_xattrs.sh
@@ -90,7 +90,7 @@ fix_xattrs() {
for i in $(getfattr -R -d -m ${XATTR_PREFIX} --absolute-names ${DIR} 2>/dev/null | grep "^# file:" | cut -d':' -f 2); do
if [ ${DRY_RUN} -ne 0 ]; then
- getfattr -d -m $p --absolute-names $i | grep -v "^# file:"
+ getfattr -d -m ${XATTR_PREFIX} --absolute-names $i
continue
fi
--
2.26.2
3 years, 10 months