libvirt
src/qemu/qemu_process.c:
static int qemuProcessHandleGuestPanic(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virDomainObjPtr vm, void *opaque)
qemuMonitorJSONIOProcess (mon=mon@entry=0x7fcd540065c0,
data=0x557298ed9580 "{\"timestamp\": {\"seconds\": 1490341608, \"microseconds\": 410320}, \"event\": \"GUEST_PANICKED\", \"data\": {\"action\": \"pause\"}}\r\n", len=120, msg=msg@entry=0x0) at qemu/qemu_monitor_json.c:250
qemu
hw/misc/pvpanic.c:
static void handle_event(int event)
vl.c
void qemu_system_guest_panicked(void)
前端驱动
static int pvpanic_add(struct acpi_device *device)
{
......
//注册pvpanic_panic_nb到panic_notifier_list,在panic函数中调用
atomic_notifier_chain_register(&panic_notifier_list,
&pvpanic_panic_nb);
......
}
//发送panic事件通知,就是写入一个pio,然后被hypervisro截获
static void
pvpanic_send_event(unsigned int event)
{
outb(event, port);
}
static int
pvpanic_panic_notify(struct notifier_block *nb, unsigned long code,
void *unused)
{
pvpanic_send_event(PVPANIC_PANICKED);
return NOTIFY_DONE;
}
static struct notifier_block pvpanic_panic_nb = {
.notifier_call = pvpanic_panic_notify,
};
XXOO
内核
void panic(const char *fmt, ...){
//执行kdump
crash_kexec(NULL);
//没有kdump的,进行notifier的通知
atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
......
}