QEMU reports win-dmp as available only when the guest is Windows and 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. Signed-off-by: Denis V. Lunev <[email protected]> --- src/qemu/qemu_driver.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 8ec9e1f9c4..b59a714a81 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3532,6 +3532,31 @@ getAutoDumpPath(virQEMUDriver *driver, return g_strdup_printf("%s/%s-%s", cfg->autoDumpPath, domname, nowstr); } +/* win-dmp is reported only for a Windows guest that has published a + * vmcoreinfo dump header, so prefer it whenever QEMU confirms it. */ +static unsigned int +qemuDomainGetAutoDumpFormat(virDomainObj *vm) +{ + qemuDomainObjPrivate *priv = vm->privateData; + unsigned int dumpformat = VIR_DOMAIN_CORE_DUMP_FORMAT_RAW; + int rc; + + 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 +3583,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 +3603,7 @@ processWatchdogEvent(virQEMUDriver *driver, virDomainObjEndAsyncJob(vm); } + static int doCoreDumpToAutoDumpPath(virQEMUDriver *driver, virDomainObj *vm, @@ -3592,7 +3618,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; -- 2.53.0
