[PATCH 0/3] qemu: fix off-by-one memory allocation
by Peter Krempa
String list was allocated without extra element.
Peter Krempa (3):
qemuBlockBitmapsHandleCommitStart: Fix allocation of string list
qemuBlockBitmapsHandleCommitFinish: Use proper variable to iterate
qemublocktest: Add tests for re-enabling of bitmaps after commit
src/qemu/qemu_block.c | 4 +-
.../bitmap/snapshots-synthetic-broken.json | 18 ++++++++
.../bitmap/snapshots-synthetic-broken.out | 2 +
.../snapshots-synthetic-broken-1-2 | 30 ++++++++++++
.../snapshots-synthetic-broken-1-3 | 46 +++++++++++++++++++
.../snapshots-synthetic-broken-1-4 | 46 +++++++++++++++++++
.../snapshots-synthetic-broken-1-5 | 46 +++++++++++++++++++
.../snapshots-synthetic-broken-2-3 | 46 +++++++++++++++++++
.../snapshots-synthetic-broken-2-4 | 46 +++++++++++++++++++
.../snapshots-synthetic-broken-2-5 | 46 +++++++++++++++++++
10 files changed, 328 insertions(+), 2 deletions(-)
--
2.24.1
4 years, 9 months
[PATCH 1/1] virhostcpu.c: fix 'die' parsing for Power hosts
by Daniel Henrique Barboza
Commit 7b79ee2f78 makes assumptions about die_id parsing in
the sysfs that aren't true for Power hosts. In both Power8
and Power9 the die_id is set to -1:
$ cat /sys/devices/system/cpu/cpu0/topology/die_id
-1
This breaks the parsing being done in virHostCPUGetDie(),
which is using an uInt instead, stopping the VM to start:
virFileReadValueUint:4128 : internal error: Invalid unsigned integer
value '-1' in file '/sys/devices/system/cpu/cpu0/topology/die_id'
This isn't necessarily a PowerPC only behavior. Linux kernel commit
0e344d8c70 added in the former Documentation/cputopology.txt, now
Documentation/admin-guide/cputopology.rst, that:
---
To be consistent on all architectures, include/linux/topology.h
provides default definitions for any of the above macros that are
not defined by include/asm-XXX/topology.h:
1) topology_physical_package_id: -1
2) topology_die_id: -1
(...)
---
This means that it might be expected that an architecture that
does not implement the die_id element will mark it as -1 in
sysfs.
It is not required to change die_id implementation from uInt to
Int because of that. Instead, let's change the parsing of the
die_id in virHostCPUGetDie() to read an integer value and, in
case it's -1, default it to zero like in case of file not found.
This is enough to solve the issue Power hosts are experiencing.
Fixes: 7b79ee2f78bbf2af76df2f6466919e19ae05aeeb
Signed-off-by: Daniel Henrique Barboza <danielhb413(a)gmail.com>
---
src/util/virhostcpu.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
index c1b39e772a..8d7841517e 100644
--- a/src/util/virhostcpu.c
+++ b/src/util/virhostcpu.c
@@ -220,15 +220,20 @@ virHostCPUGetSocket(unsigned int cpu, unsigned int *socket)
int
virHostCPUGetDie(unsigned int cpu, unsigned int *die)
{
- int ret = virFileReadValueUint(die,
- "%s/cpu/cpu%u/topology/die_id",
- SYSFS_SYSTEM_PATH, cpu);
+ int die_id;
+ int ret = virFileReadValueInt(&die_id,
+ "%s/cpu/cpu%u/topology/die_id",
+ SYSFS_SYSTEM_PATH, cpu);
- /* If the file is not there, it's 0 */
- if (ret == -2)
+ /* If the file is not there, it's 0.
+ * PowerPC hosts can report die_id = -1, which for our
+ * case here it's the same as absent file. */
+ if (ret == -2 || die_id < 0)
*die = 0;
else if (ret < 0)
return -1;
+ else
+ *die = die_id;
return 0;
}
--
2.24.1
4 years, 9 months
[PATCHv2] qemu: convert DomainLogContext class to use GObject
by Gaurav Agrawal
Signed-off-by: Gaurav Agrawal <agrawalgaurav(a)gnome.org>
---
src/qemu/qemu_domain.c | 35 +++++++++++++++++++----------------
src/qemu/qemu_domain.h | 5 +++--
src/qemu/qemu_process.c | 4 ++--
3 files changed, 24 insertions(+), 20 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 7c962fb062..86e2ac7e41 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -151,7 +151,7 @@ qemuDomainObjFromDomain(virDomainPtr domain)
struct _qemuDomainLogContext {
- virObject parent;
+ GObject parent;
int writefd;
int readfd; /* Only used if manager == NULL */
@@ -161,37 +161,46 @@ struct _qemuDomainLogContext {
virLogManagerPtr manager;
};
-static virClassPtr qemuDomainLogContextClass;
+G_DEFINE_TYPE(qemuDomainLogContext, qemu_domain_log_context, G_TYPE_OBJECT);
static virClassPtr qemuDomainSaveCookieClass;
-static void qemuDomainLogContextDispose(void *obj);
+static void qemuDomainLogContextFinalize(GObject *obj);
static void qemuDomainSaveCookieDispose(void *obj);
static int
qemuDomainOnceInit(void)
{
- if (!VIR_CLASS_NEW(qemuDomainLogContext, virClassForObject()))
- return -1;
-
if (!VIR_CLASS_NEW(qemuDomainSaveCookie, virClassForObject()))
return -1;
return 0;
}
+static void qemu_domain_log_context_init(qemuDomainLogContext *logctxt G_GNUC_UNUSED)
+{
+}
+
+static void qemu_domain_log_context_class_init(qemuDomainLogContextClass *klass)
+{
+ GObjectClass *obj = G_OBJECT_CLASS(klass);
+
+ obj->finalize = qemuDomainLogContextFinalize;
+}
+
VIR_ONCE_GLOBAL_INIT(qemuDomain);
static void
-qemuDomainLogContextDispose(void *obj)
+qemuDomainLogContextFinalize(GObject *object)
{
- qemuDomainLogContextPtr ctxt = obj;
+ qemuDomainLogContextPtr ctxt = QEMU_DOMAIN_LOG_CONTEXT(object);
VIR_DEBUG("ctxt=%p", ctxt);
virLogManagerFree(ctxt->manager);
VIR_FREE(ctxt->path);
VIR_FORCE_CLOSE(ctxt->writefd);
VIR_FORCE_CLOSE(ctxt->readfd);
+ G_OBJECT_CLASS(qemu_domain_log_context_parent_class)->finalize(object);
}
const char *
@@ -10587,13 +10596,7 @@ qemuDomainLogContextPtr qemuDomainLogContextNew(virQEMUDriverPtr driver,
qemuDomainLogContextMode mode)
{
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
- qemuDomainLogContextPtr ctxt = NULL;
-
- if (qemuDomainInitialize() < 0)
- return NULL;
-
- if (!(ctxt = virObjectNew(qemuDomainLogContextClass)))
- return NULL;
+ qemuDomainLogContextPtr ctxt = QEMU_DOMAIN_LOG_CONTEXT(g_object_new(QEMU_TYPE_DOMAIN_LOG_CONTEXT, NULL));
VIR_DEBUG("Context new %p stdioLogD=%d", ctxt, cfg->stdioLogD);
ctxt->writefd = -1;
@@ -10662,7 +10665,7 @@ qemuDomainLogContextPtr qemuDomainLogContextNew(virQEMUDriverPtr driver,
return ctxt;
error:
- virObjectUnref(ctxt);
+ g_clear_object(&ctxt);
return NULL;
}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 835321f54d..2f8b2f1399 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -21,6 +21,7 @@
#pragma once
+#include <glib-object.h>
#include "virthread.h"
#include "vircgroup.h"
#include "virperf.h"
@@ -601,9 +602,9 @@ struct qemuProcessEvent {
void qemuProcessEventFree(struct qemuProcessEvent *event);
-typedef struct _qemuDomainLogContext qemuDomainLogContext;
+#define QEMU_TYPE_DOMAIN_LOG_CONTEXT qemu_domain_log_context_get_type()
+G_DECLARE_FINAL_TYPE(qemuDomainLogContext, qemu_domain_log_context, QEMU, DOMAIN_LOG_CONTEXT, GObject);
typedef qemuDomainLogContext *qemuDomainLogContextPtr;
-G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuDomainLogContext, virObjectUnref);
typedef struct _qemuDomainSaveCookie qemuDomainSaveCookie;
typedef qemuDomainSaveCookie *qemuDomainSaveCookiePtr;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 454db21b31..e8401030a2 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1929,7 +1929,7 @@ static void
qemuProcessMonitorLogFree(void *opaque)
{
qemuDomainLogContextPtr logCtxt = opaque;
- virObjectUnref(logCtxt);
+ g_clear_object(&logCtxt);
}
@@ -1983,7 +1983,7 @@ qemuConnectMonitor(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob,
driver);
if (mon && logCtxt) {
- virObjectRef(logCtxt);
+ g_object_ref(logCtxt);
qemuMonitorSetDomainLog(mon,
qemuProcessMonitorReportLogError,
logCtxt,
--
2.24.1
4 years, 9 months
[libvirt PATCH] nodedev: fix race in API usage vs initial device enumeration
by Daniel P. Berrangé
During startup the udev node device driver impl uses a background thread
to populate the list of devices to avoid blocking the daemon startup
entirely. There is no synchronization to the public APIs, so it is
possible for an application to start calling APIs before the device
initialization is complete.
This was not a problem in the old approach where libvirtd was started
on boot, as initialization would easily complete before any APIs were
called.
With the use of socket activation, however, APIs are invoked from the
very moment the daemon starts. This is easily seen by doing a
'virsh -c nodedev:///system list'
the first time it runs it will only show one or two devices. The second
time it runs it will show all devices. The solution is to introduce a
flag and condition variable for APIs to synchronize against before
returning any data.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/conf/virnodedeviceobj.h | 2 ++
src/node_device/node_device_driver.c | 44 ++++++++++++++++++++++++++++
src/node_device/node_device_hal.c | 15 ++++++++++
src/node_device/node_device_udev.c | 13 ++++++++
4 files changed, 74 insertions(+)
diff --git a/src/conf/virnodedeviceobj.h b/src/conf/virnodedeviceobj.h
index c4d3c55d73..c9df8dedab 100644
--- a/src/conf/virnodedeviceobj.h
+++ b/src/conf/virnodedeviceobj.h
@@ -36,6 +36,8 @@ typedef struct _virNodeDeviceDriverState virNodeDeviceDriverState;
typedef virNodeDeviceDriverState *virNodeDeviceDriverStatePtr;
struct _virNodeDeviceDriverState {
virMutex lock;
+ virCond initCond;
+ bool initialized;
/* pid file FD, ensures two copies of the driver can't use the same root */
int lockFD;
diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c
index da92a4cf94..ee175e1095 100644
--- a/src/node_device/node_device_driver.c
+++ b/src/node_device/node_device_driver.c
@@ -156,6 +156,22 @@ nodeDeviceUnlock(void)
}
+static int
+nodeDeviceWaitInit(void)
+{
+ nodeDeviceLock();
+ while (!driver->initialized) {
+ if (virCondWait(&driver->initCond, &driver->lock) < 0) {
+ virReportSystemError(errno, "%s",
+ _("failed to wait on condition"));
+ nodeDeviceUnlock();
+ return -1;
+ }
+ }
+ nodeDeviceUnlock();
+ return 0;
+}
+
int
nodeNumOfDevices(virConnectPtr conn,
const char *cap,
@@ -166,6 +182,9 @@ nodeNumOfDevices(virConnectPtr conn,
virCheckFlags(0, -1);
+ if (nodeDeviceWaitInit() < 0)
+ return -1;
+
return virNodeDeviceObjListNumOfDevices(driver->devs, conn, cap,
virNodeNumOfDevicesCheckACL);
}
@@ -183,6 +202,9 @@ nodeListDevices(virConnectPtr conn,
virCheckFlags(0, -1);
+ if (nodeDeviceWaitInit() < 0)
+ return -1;
+
return virNodeDeviceObjListGetNames(driver->devs, conn,
virNodeListDevicesCheckACL,
cap, names, maxnames);
@@ -199,6 +221,9 @@ nodeConnectListAllNodeDevices(virConnectPtr conn,
if (virConnectListAllNodeDevicesEnsureACL(conn) < 0)
return -1;
+ if (nodeDeviceWaitInit() < 0)
+ return -1;
+
return virNodeDeviceObjListExport(conn, driver->devs, devices,
virConnectListAllNodeDevicesCheckACL,
flags);
@@ -228,6 +253,9 @@ nodeDeviceLookupByName(virConnectPtr conn,
virNodeDeviceDefPtr def;
virNodeDevicePtr device = NULL;
+ if (nodeDeviceWaitInit() < 0)
+ return NULL;
+
if (!(obj = nodeDeviceObjFindByName(name)))
return NULL;
def = virNodeDeviceObjGetDef(obj);
@@ -256,6 +284,9 @@ nodeDeviceLookupSCSIHostByWWN(virConnectPtr conn,
virCheckFlags(0, NULL);
+ if (nodeDeviceWaitInit() < 0)
+ return NULL;
+
if (!(obj = virNodeDeviceObjListFindSCSIHostByWWNs(driver->devs,
wwnn, wwpn)))
return NULL;
@@ -470,6 +501,10 @@ nodeDeviceCreateXML(virConnectPtr conn,
const char *virt_type = NULL;
virCheckFlags(0, NULL);
+
+ if (nodeDeviceWaitInit() < 0)
+ return NULL;
+
virt_type = virConnectGetType(conn);
if (!(def = virNodeDeviceDefParseString(xmlDesc, CREATE_DEVICE, virt_type)))
@@ -512,6 +547,9 @@ nodeDeviceDestroy(virNodeDevicePtr device)
g_autofree char *wwpn = NULL;
unsigned int parent_host;
+ if (nodeDeviceWaitInit() < 0)
+ return -1;
+
if (!(obj = nodeDeviceObjFindByName(device->name)))
return -1;
def = virNodeDeviceObjGetDef(obj);
@@ -564,6 +602,9 @@ nodeConnectNodeDeviceEventRegisterAny(virConnectPtr conn,
if (virConnectNodeDeviceEventRegisterAnyEnsureACL(conn) < 0)
return -1;
+ if (nodeDeviceWaitInit() < 0)
+ return -1;
+
if (virNodeDeviceEventStateRegisterID(conn, driver->nodeDeviceEventState,
device, eventID, callback,
opaque, freecb, &callbackID) < 0)
@@ -580,6 +621,9 @@ nodeConnectNodeDeviceEventDeregisterAny(virConnectPtr conn,
if (virConnectNodeDeviceEventDeregisterAnyEnsureACL(conn) < 0)
return -1;
+ if (nodeDeviceWaitInit() < 0)
+ return -1;
+
if (virObjectEventStateDeregisterID(conn,
driver->nodeDeviceEventState,
callbackID, true) < 0)
diff --git a/src/node_device/node_device_hal.c b/src/node_device/node_device_hal.c
index a48b4ffcd1..653f54ceca 100644
--- a/src/node_device/node_device_hal.c
+++ b/src/node_device/node_device_hal.c
@@ -611,6 +611,15 @@ nodeStateInitialize(bool privileged G_GNUC_UNUSED,
VIR_FREE(driver);
return VIR_DRV_STATE_INIT_ERROR;
}
+
+ if (virCondInit(&driver->initCond) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to initialize condition variable"));
+ virMutexDestroy(&driver->lock);
+ VIR_FREE(driver);
+ return VIR_DRV_STATE_INIT_ERROR;
+ }
+
nodeDeviceLock();
if (privileged) {
@@ -701,6 +710,11 @@ nodeStateInitialize(bool privileged G_GNUC_UNUSED,
}
VIR_FREE(udi);
+ nodeDeviceLock();
+ driver->initialized = true;
+ nodeDeviceUnlock();
+ virCondBroadcast(&driver->initCond);
+
return VIR_DRV_STATE_INIT_COMPLETE;
failure:
@@ -733,6 +747,7 @@ nodeStateCleanup(void)
VIR_FREE(driver->stateDir);
nodeDeviceUnlock();
+ virCondDestroy(&driver->initCond);
virMutexDestroy(&driver->lock);
VIR_FREE(driver);
return 0;
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index 536cae6c30..87bdbc5a0b 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -1477,6 +1477,7 @@ nodeStateCleanup(void)
virPidFileRelease(driver->stateDir, "driver", driver->lockFD);
VIR_FREE(driver->stateDir);
+ virCondDestroy(&driver->initCond);
virMutexDestroy(&driver->lock);
VIR_FREE(driver);
@@ -1744,6 +1745,11 @@ nodeStateInitializeEnumerate(void *opaque)
if (udevEnumerateDevices(udev) != 0)
goto error;
+ nodeDeviceLock();
+ driver->initialized = true;
+ nodeDeviceUnlock();
+ virCondBroadcast(&driver->initCond);
+
return;
error:
@@ -1806,6 +1812,13 @@ nodeStateInitialize(bool privileged,
VIR_FREE(driver);
return VIR_DRV_STATE_INIT_ERROR;
}
+ if (virCondInit(&driver->initCond) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to initialize condition variable"));
+ virMutexDestroy(&driver->lock);
+ VIR_FREE(driver);
+ return VIR_DRV_STATE_INIT_ERROR;
+ }
driver->privileged = privileged;
--
2.24.1
4 years, 9 months
[libvirt PATCH] tests: validate parsing of CPUs with dies > 1
by Daniel P. Berrangé
Add sample data files for validating handling of a QEMU guest started
with:
-smp 7,maxcpus=16,sockets=2,dies=2,cores=2,threads=2
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
...qemumonitorjson-cpuinfo-x86-dies-cpus.json | 95 ++++++++++
...umonitorjson-cpuinfo-x86-dies-hotplug.json | 171 ++++++++++++++++++
.../qemumonitorjson-cpuinfo-x86-dies.data | 108 +++++++++++
tests/qemumonitorjsontest.c | 1 +
4 files changed, 375 insertions(+)
create mode 100644 tests/qemumonitorjsondata/qemumonitorjson-cpuinfo-x86-dies-cpus.json
create mode 100644 tests/qemumonitorjsondata/qemumonitorjson-cpuinfo-x86-dies-hotplug.json
create mode 100644 tests/qemumonitorjsondata/qemumonitorjson-cpuinfo-x86-dies.data
diff --git a/tests/qemumonitorjsondata/qemumonitorjson-cpuinfo-x86-dies-cpus.json b/tests/qemumonitorjsondata/qemumonitorjson-cpuinfo-x86-dies-cpus.json
new file mode 100644
index 0000000000..f90e4ba175
--- /dev/null
+++ b/tests/qemumonitorjsondata/qemumonitorjson-cpuinfo-x86-dies-cpus.json
@@ -0,0 +1,95 @@
+{
+ "return": [
+ {
+ "arch": "x86",
+ "thread-id": 1538346,
+ "props": {
+ "core-id": 0,
+ "thread-id": 0,
+ "die-id": 0,
+ "socket-id": 0
+ },
+ "qom-path": "/machine/unattached/device[0]",
+ "cpu-index": 0,
+ "target": "x86_64"
+ },
+ {
+ "arch": "x86",
+ "thread-id": 1538347,
+ "props": {
+ "core-id": 0,
+ "thread-id": 1,
+ "die-id": 0,
+ "socket-id": 0
+ },
+ "qom-path": "/machine/unattached/device[2]",
+ "cpu-index": 1,
+ "target": "x86_64"
+ },
+ {
+ "arch": "x86",
+ "thread-id": 1538348,
+ "props": {
+ "core-id": 1,
+ "thread-id": 0,
+ "die-id": 0,
+ "socket-id": 0
+ },
+ "qom-path": "/machine/unattached/device[3]",
+ "cpu-index": 2,
+ "target": "x86_64"
+ },
+ {
+ "arch": "x86",
+ "thread-id": 1538349,
+ "props": {
+ "core-id": 1,
+ "thread-id": 1,
+ "die-id": 0,
+ "socket-id": 0
+ },
+ "qom-path": "/machine/unattached/device[4]",
+ "cpu-index": 3,
+ "target": "x86_64"
+ },
+ {
+ "arch": "x86",
+ "thread-id": 1538350,
+ "props": {
+ "core-id": 0,
+ "thread-id": 0,
+ "die-id": 1,
+ "socket-id": 0
+ },
+ "qom-path": "/machine/unattached/device[5]",
+ "cpu-index": 4,
+ "target": "x86_64"
+ },
+ {
+ "arch": "x86",
+ "thread-id": 1538351,
+ "props": {
+ "core-id": 0,
+ "thread-id": 1,
+ "die-id": 1,
+ "socket-id": 0
+ },
+ "qom-path": "/machine/unattached/device[6]",
+ "cpu-index": 5,
+ "target": "x86_64"
+ },
+ {
+ "arch": "x86",
+ "thread-id": 1538352,
+ "props": {
+ "core-id": 1,
+ "thread-id": 0,
+ "die-id": 1,
+ "socket-id": 0
+ },
+ "qom-path": "/machine/unattached/device[7]",
+ "cpu-index": 6,
+ "target": "x86_64"
+ }
+ ]
+}
diff --git a/tests/qemumonitorjsondata/qemumonitorjson-cpuinfo-x86-dies-hotplug.json b/tests/qemumonitorjsondata/qemumonitorjson-cpuinfo-x86-dies-hotplug.json
new file mode 100644
index 0000000000..294f470b91
--- /dev/null
+++ b/tests/qemumonitorjsondata/qemumonitorjson-cpuinfo-x86-dies-hotplug.json
@@ -0,0 +1,171 @@
+{
+ "return": [
+ {
+ "props": {
+ "core-id": 1,
+ "thread-id": 1,
+ "die-id": 1,
+ "socket-id": 1
+ },
+ "vcpus-count": 1,
+ "type": "host-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 1,
+ "thread-id": 0,
+ "die-id": 1,
+ "socket-id": 1
+ },
+ "vcpus-count": 1,
+ "type": "host-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 0,
+ "thread-id": 1,
+ "die-id": 1,
+ "socket-id": 1
+ },
+ "vcpus-count": 1,
+ "type": "host-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 0,
+ "thread-id": 0,
+ "die-id": 1,
+ "socket-id": 1
+ },
+ "vcpus-count": 1,
+ "type": "host-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 1,
+ "thread-id": 1,
+ "die-id": 0,
+ "socket-id": 1
+ },
+ "vcpus-count": 1,
+ "type": "host-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 1,
+ "thread-id": 0,
+ "die-id": 0,
+ "socket-id": 1
+ },
+ "vcpus-count": 1,
+ "type": "host-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 0,
+ "thread-id": 1,
+ "die-id": 0,
+ "socket-id": 1
+ },
+ "vcpus-count": 1,
+ "type": "host-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 0,
+ "thread-id": 0,
+ "die-id": 0,
+ "socket-id": 1
+ },
+ "vcpus-count": 1,
+ "type": "host-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 1,
+ "thread-id": 1,
+ "die-id": 1,
+ "socket-id": 0
+ },
+ "vcpus-count": 1,
+ "type": "host-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 1,
+ "thread-id": 0,
+ "die-id": 1,
+ "socket-id": 0
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[7]",
+ "type": "host-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 0,
+ "thread-id": 1,
+ "die-id": 1,
+ "socket-id": 0
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[6]",
+ "type": "host-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 0,
+ "thread-id": 0,
+ "die-id": 1,
+ "socket-id": 0
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[5]",
+ "type": "host-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 1,
+ "thread-id": 1,
+ "die-id": 0,
+ "socket-id": 0
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[4]",
+ "type": "host-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 1,
+ "thread-id": 0,
+ "die-id": 0,
+ "socket-id": 0
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[3]",
+ "type": "host-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 0,
+ "thread-id": 1,
+ "die-id": 0,
+ "socket-id": 0
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[2]",
+ "type": "host-x86_64-cpu"
+ },
+ {
+ "props": {
+ "core-id": 0,
+ "thread-id": 0,
+ "die-id": 0,
+ "socket-id": 0
+ },
+ "vcpus-count": 1,
+ "qom-path": "/machine/unattached/device[0]",
+ "type": "host-x86_64-cpu"
+ }
+ ]
+}
diff --git a/tests/qemumonitorjsondata/qemumonitorjson-cpuinfo-x86-dies.data b/tests/qemumonitorjsondata/qemumonitorjson-cpuinfo-x86-dies.data
new file mode 100644
index 0000000000..9dfca1e625
--- /dev/null
+++ b/tests/qemumonitorjsondata/qemumonitorjson-cpuinfo-x86-dies.data
@@ -0,0 +1,108 @@
+[vcpu libvirt-id='0']
+ online=yes
+ hotpluggable=no
+ thread-id='1538346'
+ enable-id='1'
+ query-cpus-id='0'
+ type='host-x86_64-cpu'
+ qom_path='/machine/unattached/device[0]'
+ topology: socket='0' core='0' thread='0' vcpus='1'
+[vcpu libvirt-id='1']
+ online=yes
+ hotpluggable=no
+ thread-id='1538347'
+ enable-id='2'
+ query-cpus-id='1'
+ type='host-x86_64-cpu'
+ qom_path='/machine/unattached/device[2]'
+ topology: socket='0' core='0' thread='1' vcpus='1'
+[vcpu libvirt-id='2']
+ online=yes
+ hotpluggable=no
+ thread-id='1538348'
+ enable-id='3'
+ query-cpus-id='2'
+ type='host-x86_64-cpu'
+ qom_path='/machine/unattached/device[3]'
+ topology: socket='0' core='1' thread='0' vcpus='1'
+[vcpu libvirt-id='3']
+ online=yes
+ hotpluggable=no
+ thread-id='1538349'
+ enable-id='4'
+ query-cpus-id='3'
+ type='host-x86_64-cpu'
+ qom_path='/machine/unattached/device[4]'
+ topology: socket='0' core='1' thread='1' vcpus='1'
+[vcpu libvirt-id='4']
+ online=yes
+ hotpluggable=no
+ thread-id='1538350'
+ enable-id='5'
+ query-cpus-id='4'
+ type='host-x86_64-cpu'
+ qom_path='/machine/unattached/device[5]'
+ topology: socket='0' core='0' thread='0' vcpus='1'
+[vcpu libvirt-id='5']
+ online=yes
+ hotpluggable=no
+ thread-id='1538351'
+ enable-id='6'
+ query-cpus-id='5'
+ type='host-x86_64-cpu'
+ qom_path='/machine/unattached/device[6]'
+ topology: socket='0' core='0' thread='1' vcpus='1'
+[vcpu libvirt-id='6']
+ online=yes
+ hotpluggable=no
+ thread-id='1538352'
+ enable-id='7'
+ query-cpus-id='6'
+ type='host-x86_64-cpu'
+ qom_path='/machine/unattached/device[7]'
+ topology: socket='0' core='1' thread='0' vcpus='1'
+[vcpu libvirt-id='7']
+ online=no
+ hotpluggable=yes
+ type='host-x86_64-cpu'
+ topology: socket='0' core='1' thread='1' vcpus='1'
+[vcpu libvirt-id='8']
+ online=no
+ hotpluggable=yes
+ type='host-x86_64-cpu'
+ topology: socket='1' core='0' thread='0' vcpus='1'
+[vcpu libvirt-id='9']
+ online=no
+ hotpluggable=yes
+ type='host-x86_64-cpu'
+ topology: socket='1' core='0' thread='1' vcpus='1'
+[vcpu libvirt-id='10']
+ online=no
+ hotpluggable=yes
+ type='host-x86_64-cpu'
+ topology: socket='1' core='1' thread='0' vcpus='1'
+[vcpu libvirt-id='11']
+ online=no
+ hotpluggable=yes
+ type='host-x86_64-cpu'
+ topology: socket='1' core='1' thread='1' vcpus='1'
+[vcpu libvirt-id='12']
+ online=no
+ hotpluggable=yes
+ type='host-x86_64-cpu'
+ topology: socket='1' core='0' thread='0' vcpus='1'
+[vcpu libvirt-id='13']
+ online=no
+ hotpluggable=yes
+ type='host-x86_64-cpu'
+ topology: socket='1' core='0' thread='1' vcpus='1'
+[vcpu libvirt-id='14']
+ online=no
+ hotpluggable=yes
+ type='host-x86_64-cpu'
+ topology: socket='1' core='1' thread='0' vcpus='1'
+[vcpu libvirt-id='15']
+ online=no
+ hotpluggable=yes
+ type='host-x86_64-cpu'
+ topology: socket='1' core='1' thread='1' vcpus='1'
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index 0a6760a794..ba60a97e7c 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -3235,6 +3235,7 @@ mymain(void)
DO_TEST_CPU_INFO("x86-full", 11);
DO_TEST_CPU_INFO("x86-node-full", 8);
DO_TEST_CPU_INFO_FAST("x86-full-fast", 11);
+ DO_TEST_CPU_INFO_FAST("x86-dies", 16);
DO_TEST_CPU_INFO("ppc64-basic", 24);
DO_TEST_CPU_INFO("ppc64-hotplug-1", 24);
--
2.24.1
4 years, 9 months
[libvirt PATCH 0/3] nodedev: fix device reset/detach/reattach with split daemons
by Daniel P. Berrangé
The virNodeDevice{Reset,ReAttach,Dettach} methods are a little
unusual because they are registered by the virt driver, but
use the virNodeDevicePtr object associated with the nodedev
driver.
In the split daemon world, we tried to dispatch them to the
virnodedevd daemon which has no impl registered. Dispatching
them to the virt driver has some quirks, we need to ensure
we have two virNodeDevicePtr instances, once for the virConnectPtr
of the virt driver and one for the virConnectPtr of the nodedev
driver.
Daniel P. Berrangé (3):
rpc: fix dispatch for node device APIs for virt drivers
rpc: avoid name lookup when dispatching node device APIs
qemu: lookup node device against nodedev driver before getting XML
src/libxl/libxl_driver.c | 63 +++++++++++++++++++++++++++--
src/qemu/qemu_driver.c | 63 +++++++++++++++++++++++++++--
src/remote/remote_daemon_dispatch.c | 7 ++++
src/rpc/gendispatch.pl | 10 ++++-
4 files changed, 135 insertions(+), 8 deletions(-)
--
2.24.1
4 years, 9 months
[libvirt PATCH] qemu: fix detection of vCPU pids when multiple dies are present
by Daniel P. Berrangé
The logic for querying hotpluggable CPUs needs to sort the list
of CPUs returned by QEMU. Unfortunately our sorting method failed
to use the die_id field, so CPUs were not correctly sorted.
This is seen when configuring a guest with partially populated
CPUs
<vcpu placement='static' current='1'>16</vcpu>
<cpu...>
<topology sockets='4' dies='2' cores='1' threads='2'/>
</cpu>
Then trying to start it would fail:
# virsh -c qemu:///system start demo
error: Failed to start domain demo
error: internal error: qemu didn't report thread id for vcpu '0'
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/qemu/qemu_domain.c | 10 ++++++++--
src/qemu/qemu_monitor.c | 2 ++
src/qemu/qemu_monitor.h | 2 ++
src/qemu/qemu_monitor_json.c | 4 ++++
4 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 4b467afa81..acb93d24ae 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -13537,8 +13537,14 @@ qemuDomainRefreshVcpuInfo(virQEMUDriverPtr driver,
}
if (validTIDs)
- VIR_DEBUG("vCPU[%zu] PID %llu is valid",
- i, (unsigned long long)info[i].tid);
+ VIR_DEBUG("vCPU[%zu] PID %llu is valid "
+ "(node=%d socket=%d die=%d core=%d thread=%d)",
+ i, (unsigned long long)info[i].tid,
+ info[i].node_id,
+ info[i].socket_id,
+ info[i].die_id,
+ info[i].core_id,
+ info[i].thread_id);
}
VIR_DEBUG("Extracting vCPU information validTIDs=%d", validTIDs);
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index e3d621f038..017b818f73 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1615,6 +1615,7 @@ qemuMonitorCPUInfoClear(qemuMonitorCPUInfoPtr cpus,
cpus[i].id = 0;
cpus[i].qemu_id = -1;
cpus[i].socket_id = -1;
+ cpus[i].die_id = -1;
cpus[i].core_id = -1;
cpus[i].thread_id = -1;
cpus[i].node_id = -1;
@@ -1770,6 +1771,7 @@ qemuMonitorGetCPUInfoHotplug(struct qemuMonitorQueryHotpluggableCpusEntry *hotpl
vcpus[mastervcpu].hotpluggable = !!hotplugvcpus[i].alias ||
!vcpus[mastervcpu].online;
vcpus[mastervcpu].socket_id = hotplugvcpus[i].socket_id;
+ vcpus[mastervcpu].die_id = hotplugvcpus[i].die_id;
vcpus[mastervcpu].core_id = hotplugvcpus[i].core_id;
vcpus[mastervcpu].thread_id = hotplugvcpus[i].thread_id;
vcpus[mastervcpu].node_id = hotplugvcpus[i].node_id;
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 6ccea909e9..be4195e734 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -561,6 +561,7 @@ struct qemuMonitorQueryHotpluggableCpusEntry {
/* topology information -1 if qemu didn't report given parameter */
int node_id;
int socket_id;
+ int die_id;
int core_id;
int thread_id;
@@ -583,6 +584,7 @@ struct _qemuMonitorCPUInfo {
/* topology info for hotplug purposes. Hotplug of given vcpu impossible if
* all entries are -1 */
int socket_id;
+ int die_id;
int core_id;
int thread_id;
int node_id;
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 3eac80c060..04affb851f 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -8565,6 +8565,7 @@ qemuMonitorJSONProcessHotpluggableCpusReply(virJSONValuePtr vcpu,
ignore_value(virJSONValueObjectGetNumberInt(props, "node-id", &entry->node_id));
ignore_value(virJSONValueObjectGetNumberInt(props, "socket-id", &entry->socket_id));
+ ignore_value(virJSONValueObjectGetNumberInt(props, "die-id", &entry->die_id));
ignore_value(virJSONValueObjectGetNumberInt(props, "core-id", &entry->core_id));
ignore_value(virJSONValueObjectGetNumberInt(props, "thread-id", &entry->thread_id));
@@ -8599,6 +8600,9 @@ qemuMonitorQueryHotpluggableCpusEntrySort(const void *p1,
if (a->socket_id != b->socket_id)
return a->socket_id - b->socket_id;
+ if (a->die_id != b->die_id)
+ return a->die_id - b->die_id;
+
if (a->core_id != b->core_id)
return a->core_id - b->core_id;
--
2.24.1
4 years, 9 months
[PATCH v2 0/5] Refactor qemuDomainSecretAESSetup
by Peter Krempa
As requested in:
https://www.redhat.com/archives/libvir-list/2020-March/msg00377.html
this is an incremental refactor of qemuDomainSecretAESSetup. Posted only
as an individual refactor to omit re-sending the 26 other patches from
the original series.
Peter Krempa (5):
qemuDomainSecretInfo: Register autoptr cleanup function
qemuDomainSecretAESSetup: Automatically free non-secret locals
qemuDomainSecretAESSetup: Allocate and return 'secinfo' here
qemuDomainSecretAESSetup: Split out lookup of secret data
Remove qemuDomainSecretInfoNew
src/qemu/qemu_domain.c | 178 ++++++++++++++++++-----------------------
src/qemu/qemu_domain.h | 2 +
2 files changed, 82 insertions(+), 98 deletions(-)
--
2.24.1
4 years, 9 months
[libvirt PATCH 0/3] cpu: Honor check='full' for host-passthrough CPUs
by Jiri Denemark
See patch 3/3 for explanation.
Jiri Denemark (3):
cpu: Change control flow in virCPUUpdateLive
cpu_x86: Prepare virCPUx86UpdateLive for easier extension
cpu: Honor check='full' for host-passthrough CPUs
src/cpu/cpu.c | 12 +++++++-----
src/cpu/cpu_x86.c | 20 +++++++++++++++++---
2 files changed, 24 insertions(+), 8 deletions(-)
--
2.25.1
4 years, 9 months