int
-qemuMonitorEmitGuestPanic(qemuMonitorPtr mon)
+qemuMonitorEmitGuestPanic(qemuMonitorPtr mon,
+ qemuMonitorEventPanicInfoPtr info)
{
int ret = -1;
VIR_DEBUG("mon=%p", mon);
- QEMU_MONITOR_CALLBACK(mon, ret, domainGuestPanic, mon->vm);
+ QEMU_MONITOR_CALLBACK(mon, ret, domainGuestPanic, mon->vm, info);
return ret;
}
return qemuMonitorJSONQueryNamedBlockNodes(mon);
}
+
+
+void
+qemuMonitorEventPanicInfoFree(qemuMonitorEventPanicInfoPtr info)
+{
+ if (!info)
+ return;
+
+ VIR_FREE(info);
+}
void *passwordOpaque;
};
+typedef enum {
+ QEMU_MONITOR_EVENT_PANIC_INFO_TYPE_NONE = 0,
+ QEMU_MONITOR_EVENT_PANIC_INFO_TYPE_HYPERV,
+
+ QEMU_MONITOR_EVENT_PANIC_INFO_TYPE_LAST
+} qemuMonitorEventPanicInfoType;
+
+typedef struct _qemuMonitorEventPanicInfoHyperv qemuMonitorEventPanicInfoHyperv;
+typedef qemuMonitorEventPanicInfoHyperv *qemuMonitorEventPanicInfoHypervPtr;
+struct _qemuMonitorEventPanicInfoHyperv {
+ /* Hyper-V specific guest panic information (HV crash MSRs) */
+ unsigned long long arg1;
+ unsigned long long arg2;
+ unsigned long long arg3;
+ unsigned long long arg4;
+ unsigned long long arg5;
+};
+
+typedef struct _qemuMonitorEventPanicInfo qemuMonitorEventPanicInfo;
+typedef qemuMonitorEventPanicInfo *qemuMonitorEventPanicInfoPtr;
+struct _qemuMonitorEventPanicInfo {
+ qemuMonitorEventPanicInfoType type;
+ union {
+ qemuMonitorEventPanicInfoHyperv hyperv;
+ } data;
+};
+
+void qemuMonitorEventPanicInfoFree(qemuMonitorEventPanicInfoPtr info);
typedef void (*qemuMonitorDestroyCallback)(qemuMonitorPtr mon,
virDomainObjPtr vm,
void *opaque);
typedef int (*qemuMonitorDomainGuestPanicCallback)(qemuMonitorPtr mon,
virDomainObjPtr vm,
+ qemuMonitorEventPanicInfoPtr info,
void *opaque);
typedef int (*qemuMonitorDomainDeviceDeletedCallback)(qemuMonitorPtr mon,
virDomainObjPtr vm,
int qemuMonitorEmitBalloonChange(qemuMonitorPtr mon,
unsigned long long actual);
int qemuMonitorEmitPMSuspendDisk(qemuMonitorPtr mon);
-int qemuMonitorEmitGuestPanic(qemuMonitorPtr mon);
+int qemuMonitorEmitGuestPanic(qemuMonitorPtr mon,
+ qemuMonitorEventPanicInfoPtr info);
int qemuMonitorEmitDeviceDeleted(qemuMonitorPtr mon,
const char *devAlias);
int qemuMonitorEmitNicRxFilterChanged(qemuMonitorPtr mon,
qemuMonitorEmitResume(mon);
}
-static void qemuMonitorJSONHandleGuestPanic(qemuMonitorPtr mon, virJSONValuePtr data ATTRIBUTE_UNUSED)
+
+static qemuMonitorEventPanicInfoPtr
+qemuMonitorJSONGuestPanicExtractInfoHyperv(virJSONValuePtr data)
+{
+ qemuMonitorEventPanicInfoPtr ret;
+
+ if (VIR_ALLOC(ret) < 0)
+ return NULL;
+
+ ret->type = QEMU_MONITOR_EVENT_PANIC_INFO_TYPE_HYPERV;
+
+ if (virJSONValueObjectGetNumberUlong(data, "arg1", &ret->data.hyperv.arg1) < 0 ||
+ virJSONValueObjectGetNumberUlong(data, "arg2", &ret->data.hyperv.arg2) < 0 ||
+ virJSONValueObjectGetNumberUlong(data, "arg3", &ret->data.hyperv.arg3) < 0 ||
+ virJSONValueObjectGetNumberUlong(data, "arg4", &ret->data.hyperv.arg4) < 0 ||
+ virJSONValueObjectGetNumberUlong(data, "arg5", &ret->data.hyperv.arg5) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("malformed hyperv panic data"));
+ goto error;
+ }
+
+ return ret;
+
+ error:
+ qemuMonitorEventPanicInfoFree(ret);
+ return NULL;
+}
+
+
+static qemuMonitorEventPanicInfoPtr
+qemuMonitorJSONGuestPanicExtractInfo(virJSONValuePtr data)
{
- qemuMonitorEmitGuestPanic(mon);
+ const char *type = virJSONValueObjectGetString(data, "type");
+
+ if (STREQ_NULLABLE(type, "hyper-v"))
+ return qemuMonitorJSONGuestPanicExtractInfoHyperv(data);
+
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unknown panic info type '%s'"), NULLSTR(type));
+ return NULL;
}
+
+static void
+qemuMonitorJSONHandleGuestPanic(qemuMonitorPtr mon,
+ virJSONValuePtr data)
+{
+ virJSONValuePtr infojson = virJSONValueObjectGetObject(data, "info");
+ qemuMonitorEventPanicInfoPtr info = NULL;
+
+ if (infojson)
+ info = qemuMonitorJSONGuestPanicExtractInfo(infojson);
+
+ qemuMonitorEmitGuestPanic(mon, info);
+}
+
+
static void qemuMonitorJSONHandleRTCChange(qemuMonitorPtr mon, virJSONValuePtr data)
{
long long offset = 0;
static int
qemuProcessHandleGuestPanic(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
+ qemuMonitorEventPanicInfoPtr info,
void *opaque)
{
virQEMUDriverPtr driver = opaque;
processEvent->eventType = QEMU_PROCESS_EVENT_GUESTPANIC;
processEvent->action = vm->def->onCrash;
processEvent->vm = vm;
+ processEvent->data = info;
/* Hold an extra reference because we can't allow 'vm' to be
* deleted before handling guest panic event is finished.
*/