This is for early review, comments are welcome! qemu is adding a method to detect guest panic, and a new event GUEST_PANICKED[1]. This patch adds support for GUEST_PANICKED. But I have two questions: - to react to GUEST_PANICKED, can xml element <on_crash> be used as the action to take, or do I have to invent another xml element to configure the action? - Currently libvirt relies on watchdog to detect guest panic, but this way is not that reliable(there has to be a watchdog device, the watchdog itself has to be working when panic occurs), so it seems to be appropriate to remove this method from libvirt as there is a better one. But, will the removal cause any problems, such as backward compatibility, user confusion, etc.? [1] http://lists.nongnu.org/archive/html/qemu-devel/2012-10/msg04361.html --- src/qemu/qemu_command.c | 31 ++++++++++++++++++++----------- src/qemu/qemu_monitor.c | 10 ++++++++++ src/qemu/qemu_monitor.h | 3 +++ src/qemu/qemu_monitor_json.c | 9 +++++++++ src/qemu/qemu_process.c | 9 +++++++++ 5 files changed, 51 insertions(+), 11 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 898c4c0..0c3f9ff 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4300,6 +4300,9 @@ qemuBuildMachineArgStr(virCommandPtr cmd, const virDomainDefPtr def, qemuCapsPtr caps) { + virBuffer params = VIR_BUFFER_INITIALIZER; + char *tmp = NULL; + /* This should *never* be NULL, since we always provide * a machine in the capabilities data for QEMU. So this * check is just here as a safety in case the unexpected @@ -4307,29 +4310,35 @@ qemuBuildMachineArgStr(virCommandPtr cmd, if (!def->os.machine) return 0; - if (!def->mem.dump_core) { - /* if no parameter to the machine type is needed, we still use - * '-M' to keep the most of the compatibility with older versions. - */ - virCommandAddArgList(cmd, "-M", def->os.machine, NULL); - } else { + virBufferAsprintf(¶ms, ",enable_pv_event=on"); + + if (def->mem.dump_core) { if (!qemuCapsGet(caps, QEMU_CAPS_DUMP_GUEST_CORE)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("dump-guest-core is not available " " with this QEMU binary")); return -1; } + virBufferAsprintf(¶ms,",%s", + virDomainMemDumpTypeToString(def->mem.dump_core)); + } - /* However, in case there is a parameter to be added, we need to + tmp = virBufferContentAndReset(¶ms); + if (!tmp || strlen(tmp) == 0) { + /* if no parameter to the machine type is needed, we still use + * '-M' to keep the most of the compatibility with older versions. + */ + virCommandAddArgList(cmd, "-M", def->os.machine, NULL); + } else { + /* However, in case there are parameters to be added, we need to * use the "-machine" parameter because qemu is not parsing the * "-M" correctly */ virCommandAddArg(cmd, "-machine"); - virCommandAddArgFormat(cmd, - "%s,dump-guest-core=%s", - def->os.machine, - virDomainMemDumpTypeToString(def->mem.dump_core)); + virCommandAddArgFormat(cmd, "%s%s", def->os.machine, tmp); } + VIR_FREE(tmp); + return 0; } diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 2d9c44c..8ab7ed2 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1146,6 +1146,16 @@ int qemuMonitorEmitBalloonChange(qemuMonitorPtr mon, } +int qemuMonitorEmitPanic(qemuMonitorPtr mon) +{ + int ret = -1; + VIR_DEBUG("mon=%p", mon); + + QEMU_MONITOR_CALLBACK(mon, ret, domainPanic, mon->vm); + return ret; +} + + int qemuMonitorSetCapabilities(qemuMonitorPtr mon) { int ret; diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 8856d9f..ea0a474 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -138,6 +138,8 @@ struct _qemuMonitorCallbacks { unsigned long long actual); int (*domainPMSuspendDisk)(qemuMonitorPtr mon, virDomainObjPtr vm); + int (*domainPanic)(qemuMonitorPtr mon, + virDomainObjPtr vm); }; char *qemuMonitorEscapeArg(const char *in); @@ -216,6 +218,7 @@ int qemuMonitorEmitBlockJob(qemuMonitorPtr mon, int qemuMonitorEmitBalloonChange(qemuMonitorPtr mon, unsigned long long actual); int qemuMonitorEmitPMSuspendDisk(qemuMonitorPtr mon); +int qemuMonitorEmitPanic(qemuMonitorPtr mon); int qemuMonitorStartCPUs(qemuMonitorPtr mon, virConnectPtr conn); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index e495c0a..0adbefc 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -71,6 +71,8 @@ static void qemuMonitorJSONHandleBlockJobCompleted(qemuMonitorPtr mon, virJSONVa static void qemuMonitorJSONHandleBlockJobCanceled(qemuMonitorPtr mon, virJSONValuePtr data); static void qemuMonitorJSONHandleBalloonChange(qemuMonitorPtr mon, virJSONValuePtr data); static void qemuMonitorJSONHandlePMSuspendDisk(qemuMonitorPtr mon, virJSONValuePtr data); +static void qemuMonitorJSONHandlePanic(qemuMonitorPtr mon, virJSONValuePtr data); + typedef struct { const char *type; @@ -83,6 +85,7 @@ static qemuEventHandler eventHandlers[] = { { "BLOCK_JOB_CANCELLED", qemuMonitorJSONHandleBlockJobCanceled, }, { "BLOCK_JOB_COMPLETED", qemuMonitorJSONHandleBlockJobCompleted, }, { "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange, }, + { "GUEST_PANICKED", qemuMonitorJSONHandlePanic, }, { "POWERDOWN", qemuMonitorJSONHandlePowerdown, }, { "RESET", qemuMonitorJSONHandleReset, }, { "RTC_CHANGE", qemuMonitorJSONHandleRTCChange, }, @@ -4417,3 +4420,9 @@ cleanup: virJSONValueFree(reply); return ret; } + +static void qemuMonitorJSONHandlePanic(qemuMonitorPtr mon, + virJSONValuePtr data ATTRIBUTE_UNUSED) +{ + qemuMonitorEmitPanic(mon); +} diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 969e3ce..d3b37e0 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1235,6 +1235,14 @@ qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED, return 0; } +static int +qemuProcessHandlePanic(qemuMonitorPtr mon ATTRIBUTE_UNUSED, + virDomainObjPtr vm ATTRIBUTE_UNUSED) +{ + VIR_WARN("guest panicked."); + return 0; +} + static qemuMonitorCallbacks monitorCallbacks = { .destroy = qemuProcessHandleMonitorDestroy, @@ -1254,6 +1262,7 @@ static qemuMonitorCallbacks monitorCallbacks = { .domainPMSuspend = qemuProcessHandlePMSuspend, .domainBalloonChange = qemuProcessHandleBalloonChange, .domainPMSuspendDisk = qemuProcessHandlePMSuspendDisk, + .domainPanic = qemuProcessHandlePanic, }; static int -- 1.7.10.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list