qemu: auto-select win-dmp for crash- and watchdog-triggered dumps

Where QEMU_CAPS_WIN_DMP_GUEST_AWARE is present, QEMU reports win-dmp
as available only for a guest that has published a vmcoreinfo dump
header. In that case prefer it over the elf default: converting an
elf dump into a Windows-debuggable format afterwards is possible but
complicated and unreliable.

Add qemuDomainGetAutoDumpFormat(), which probes win-dmp support
right before an auto-triggered dump and falls back to elf
otherwise. Use it from both doCoreDumpToAutoDumpPath() (on_crash)
and processWatchdogEvent() (watchdog dump). virDomainCoreDump() and
virDomainCoreDumpWithFormat() are left untouched, since RAW there
is a documented part of their API contract, standing in for an
explicit caller request rather than an internal default.

The probe is best-effort: reset any error left by a failed monitor
call or QMP command, so it cannot leak past a dump that otherwise
succeeds.

Without the capability the probe is skipped: older QEMU offers win-dmp
on any x86 machine, where the resulting dump is useless.

Signed-off-by: Denis V. Lunev <den@openvz.org>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Denis V. Lunev authored and Daniel P. Berrangé committed 2026-09-02 18:29:16 +01:00
1 parent 8972619929
commit 193398620e
2 files changed
+38 -2

No files matched your search

+7
View File
@@ -19,6 +19,13 @@ v12.8.0 (unreleased)
* **Improvements**
* qemu: Select the win-dmp format for Windows guest crash dumps
Dumps triggered by ``<on_crash>`` and by watchdog handling used QEMU's elf
default, which WinDbg cannot load. Where QEMU reports the format as
available only to a guest that can use it, such dumps are now written in
win-dmp format instead.
* **Bug fixes**
+31 -2
View File
@@ -3532,6 +3532,34 @@ getAutoDumpPath(virQEMUDriver *driver,
return g_strdup_printf("%s/%s-%s", cfg->autoDumpPath, domname, nowstr);
}
/* Older QEMU offers win-dmp on any x86 machine, so trust the capability
* query only where QEMU says the answer depends on the guest. */
static unsigned int
qemuDomainGetAutoDumpFormat(virDomainObj *vm)
{
qemuDomainObjPrivate *priv = vm->privateData;
unsigned int dumpformat = VIR_DOMAIN_CORE_DUMP_FORMAT_RAW;
int rc;
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_WIN_DMP_GUEST_AWARE))
return dumpformat;
if (qemuDomainObjEnterMonitorAsync(vm, VIR_ASYNC_JOB_DUMP) < 0) {
virResetLastError();
return dumpformat;
}
rc = qemuMonitorGetDumpGuestMemoryCapability(priv->mon, "win-dmp");
if (rc < 0)
virResetLastError();
else if (rc > 0)
dumpformat = VIR_DOMAIN_CORE_DUMP_FORMAT_WIN_DMP;
qemuDomainObjExitMonitor(vm);
return dumpformat;
}
static void
processWatchdogEvent(virQEMUDriver *driver,
virDomainObj *vm,
@@ -3558,7 +3586,7 @@ processWatchdogEvent(virQEMUDriver *driver,
flags |= cfg->autoDumpBypassCache ? VIR_DUMP_BYPASS_CACHE: 0;
if ((ret = doCoreDump(driver, vm, dumpfile, flags,
VIR_DOMAIN_CORE_DUMP_FORMAT_RAW)) < 0)
qemuDomainGetAutoDumpFormat(vm))) < 0)
virReportError(VIR_ERR_OPERATION_FAILED,
"%s", _("Dump failed"));
@@ -3578,6 +3606,7 @@ processWatchdogEvent(virQEMUDriver *driver,
virDomainObjEndAsyncJob(vm);
}
static int
doCoreDumpToAutoDumpPath(virQEMUDriver *driver,
virDomainObj *vm,
@@ -3592,7 +3621,7 @@ doCoreDumpToAutoDumpPath(virQEMUDriver *driver,
flags |= cfg->autoDumpBypassCache ? VIR_DUMP_BYPASS_CACHE: 0;
if ((ret = doCoreDump(driver, vm, dumpfile, flags,
VIR_DOMAIN_CORE_DUMP_FORMAT_RAW)) < 0)
qemuDomainGetAutoDumpFormat(vm))) < 0)
virReportError(VIR_ERR_OPERATION_FAILED,
"%s", _("Dump failed"));
return ret;