提交 d7580dd6 编写于 作者: P Peter Krempa

qemu: monitor: Extract additional info from GUEST_PANICKED event

For certain kinds of panic notifiers (notably hyper-v) qemu is able to
report some data regarding the crash passed from the guest.

Make the data accessible to the callback in qemu so that it can be
processed further.
上级 7d5c27e9
......@@ -1358,11 +1358,12 @@ qemuMonitorEmitResume(qemuMonitorPtr mon)
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;
}
......@@ -4240,3 +4241,13 @@ qemuMonitorQueryNamedBlockNodes(qemuMonitorPtr mon)
return qemuMonitorJSONQueryNamedBlockNodes(mon);
}
void
qemuMonitorEventPanicInfoFree(qemuMonitorEventPanicInfoPtr info)
{
if (!info)
return;
VIR_FREE(info);
}
......@@ -70,6 +70,34 @@ struct _qemuMonitorMessage {
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,
......@@ -167,6 +195,7 @@ typedef int (*qemuMonitorDomainPMSuspendDiskCallback)(qemuMonitorPtr mon,
void *opaque);
typedef int (*qemuMonitorDomainGuestPanicCallback)(qemuMonitorPtr mon,
virDomainObjPtr vm,
qemuMonitorEventPanicInfoPtr info,
void *opaque);
typedef int (*qemuMonitorDomainDeviceDeletedCallback)(qemuMonitorPtr mon,
virDomainObjPtr vm,
......@@ -346,7 +375,8 @@ int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
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,
......
......@@ -548,11 +548,63 @@ static void qemuMonitorJSONHandleResume(qemuMonitorPtr mon, virJSONValuePtr data
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;
......
......@@ -1298,6 +1298,7 @@ qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
static int
qemuProcessHandleGuestPanic(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
qemuMonitorEventPanicInfoPtr info,
void *opaque)
{
virQEMUDriverPtr driver = opaque;
......@@ -1310,6 +1311,7 @@ qemuProcessHandleGuestPanic(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
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.
*/
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册