mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
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.
This commit is contained in:
parent
7d5c27e923
commit
d7580dd643
@ -1358,11 +1358,12 @@ qemuMonitorEmitResume(qemuMonitorPtr mon)
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
qemuMonitorEmitGuestPanic(qemuMonitorPtr mon)
|
qemuMonitorEmitGuestPanic(qemuMonitorPtr mon,
|
||||||
|
qemuMonitorEventPanicInfoPtr info)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
VIR_DEBUG("mon=%p", mon);
|
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 ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4240,3 +4241,13 @@ qemuMonitorQueryNamedBlockNodes(qemuMonitorPtr mon)
|
|||||||
|
|
||||||
return qemuMonitorJSONQueryNamedBlockNodes(mon);
|
return qemuMonitorJSONQueryNamedBlockNodes(mon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
qemuMonitorEventPanicInfoFree(qemuMonitorEventPanicInfoPtr info)
|
||||||
|
{
|
||||||
|
if (!info)
|
||||||
|
return;
|
||||||
|
|
||||||
|
VIR_FREE(info);
|
||||||
|
}
|
||||||
|
@ -70,6 +70,34 @@ struct _qemuMonitorMessage {
|
|||||||
void *passwordOpaque;
|
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,
|
typedef void (*qemuMonitorDestroyCallback)(qemuMonitorPtr mon,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
@ -167,6 +195,7 @@ typedef int (*qemuMonitorDomainPMSuspendDiskCallback)(qemuMonitorPtr mon,
|
|||||||
void *opaque);
|
void *opaque);
|
||||||
typedef int (*qemuMonitorDomainGuestPanicCallback)(qemuMonitorPtr mon,
|
typedef int (*qemuMonitorDomainGuestPanicCallback)(qemuMonitorPtr mon,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
|
qemuMonitorEventPanicInfoPtr info,
|
||||||
void *opaque);
|
void *opaque);
|
||||||
typedef int (*qemuMonitorDomainDeviceDeletedCallback)(qemuMonitorPtr mon,
|
typedef int (*qemuMonitorDomainDeviceDeletedCallback)(qemuMonitorPtr mon,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
@ -346,7 +375,8 @@ int qemuMonitorEmitBlockJob(qemuMonitorPtr mon,
|
|||||||
int qemuMonitorEmitBalloonChange(qemuMonitorPtr mon,
|
int qemuMonitorEmitBalloonChange(qemuMonitorPtr mon,
|
||||||
unsigned long long actual);
|
unsigned long long actual);
|
||||||
int qemuMonitorEmitPMSuspendDisk(qemuMonitorPtr mon);
|
int qemuMonitorEmitPMSuspendDisk(qemuMonitorPtr mon);
|
||||||
int qemuMonitorEmitGuestPanic(qemuMonitorPtr mon);
|
int qemuMonitorEmitGuestPanic(qemuMonitorPtr mon,
|
||||||
|
qemuMonitorEventPanicInfoPtr info);
|
||||||
int qemuMonitorEmitDeviceDeleted(qemuMonitorPtr mon,
|
int qemuMonitorEmitDeviceDeleted(qemuMonitorPtr mon,
|
||||||
const char *devAlias);
|
const char *devAlias);
|
||||||
int qemuMonitorEmitNicRxFilterChanged(qemuMonitorPtr mon,
|
int qemuMonitorEmitNicRxFilterChanged(qemuMonitorPtr mon,
|
||||||
|
@ -548,11 +548,63 @@ static void qemuMonitorJSONHandleResume(qemuMonitorPtr mon, virJSONValuePtr data
|
|||||||
qemuMonitorEmitResume(mon);
|
qemuMonitorEmitResume(mon);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qemuMonitorJSONHandleGuestPanic(qemuMonitorPtr mon, virJSONValuePtr data ATTRIBUTE_UNUSED)
|
|
||||||
|
static qemuMonitorEventPanicInfoPtr
|
||||||
|
qemuMonitorJSONGuestPanicExtractInfoHyperv(virJSONValuePtr data)
|
||||||
{
|
{
|
||||||
qemuMonitorEmitGuestPanic(mon);
|
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)
|
||||||
|
{
|
||||||
|
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)
|
static void qemuMonitorJSONHandleRTCChange(qemuMonitorPtr mon, virJSONValuePtr data)
|
||||||
{
|
{
|
||||||
long long offset = 0;
|
long long offset = 0;
|
||||||
|
@ -1298,6 +1298,7 @@ qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
|||||||
static int
|
static int
|
||||||
qemuProcessHandleGuestPanic(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
qemuProcessHandleGuestPanic(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
|
qemuMonitorEventPanicInfoPtr info,
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
virQEMUDriverPtr driver = opaque;
|
virQEMUDriverPtr driver = opaque;
|
||||||
@ -1310,6 +1311,7 @@ qemuProcessHandleGuestPanic(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
|||||||
processEvent->eventType = QEMU_PROCESS_EVENT_GUESTPANIC;
|
processEvent->eventType = QEMU_PROCESS_EVENT_GUESTPANIC;
|
||||||
processEvent->action = vm->def->onCrash;
|
processEvent->action = vm->def->onCrash;
|
||||||
processEvent->vm = vm;
|
processEvent->vm = vm;
|
||||||
|
processEvent->data = info;
|
||||||
/* Hold an extra reference because we can't allow 'vm' to be
|
/* Hold an extra reference because we can't allow 'vm' to be
|
||||||
* deleted before handling guest panic event is finished.
|
* deleted before handling guest panic event is finished.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user