From bd2bc6c0f356e4b974c23f35a17fdc257a579306 Mon Sep 17 00:00:00 2001 From: Gleb Natapov <gleb@redhat.com> Date: Wed, 1 Jul 2009 14:07:24 +0300 Subject: [PATCH 2/3] provide stop reason on demand Store VM stop reason and provide it on monitor by demand. Upstream status: not upstream. Never will be. BZ: 505999 Signed-off-by: Gleb Natapov <gleb@redhat.com> Message-ID: <20090701110724.GA27539@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> Bugzilla: 505999 RH-Upstream-status: not-applicable Acked-by: Juan Quintela <quintela@redhat.com> Acked-by: Luiz Capitulino <lcapitulino@redhat.com> Acked-by: Glauber Costa <glommer@redhat.com> --- qemu/gdbstub.c | 3 +++ qemu/hw/ide.c | 7 ++++--- qemu/hw/scsi-disk.c | 7 ++++--- qemu/hw/virtio-blk.c | 7 ++++--- qemu/migration-exec.c | 1 + qemu/migration.c | 1 + qemu/monitor.c | 8 ++++++++ qemu/qemu-kvm.c | 1 + qemu/savevm.c | 3 +++ qemu/sysemu.h | 2 ++ qemu/vl.c | 2 ++ 11 files changed, 33 insertions(+), 9 deletions(-) diff --git a/qemu/gdbstub.c b/qemu/gdbstub.c index 4701382..a9bd058 100644 --- a/qemu/gdbstub.c +++ b/qemu/gdbstub.c @@ -1940,6 +1940,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...) gdb_current_syscall_cb = cb; s->state = RS_SYSCALL; #ifndef CONFIG_USER_ONLY + strncpy(vm_stop_reason, "gdbstab", STOP_REASON_LEN); vm_stop(EXCP_DEBUG); #endif s->state = RS_IDLE; @@ -2014,6 +2015,7 @@ static void gdb_read_byte(GDBState *s, int ch) if (vm_running) { /* when the CPU is running, we cannot do anything except stop it when receiving a char */ + strncpy(vm_stop_reason, "gdbstab", STOP_REASON_LEN); vm_stop(EXCP_INTERRUPT); } else #endif @@ -2265,6 +2267,7 @@ static void gdb_chr_event(void *opaque, int event) { switch (event) { case CHR_EVENT_RESET: + strncpy(vm_stop_reason, "gdbstab", STOP_REASON_LEN); vm_stop(EXCP_INTERRUPT); gdb_has_xml = 0; break; diff --git a/qemu/hw/ide.c b/qemu/hw/ide.c index 6e56b4c..dd56f82 100644 --- a/qemu/hw/ide.c +++ b/qemu/hw/ide.c @@ -885,9 +885,10 @@ static int ide_handle_write_error(IDEState *s, int error, int op) s->bmdma->ide_if = s; s->bmdma->status |= op; vm_stop(0); - term_printf_async(VMSTOP_ASYNC_EVENT, - "VM is stopped due to disk write error: %s: %s\n", - bdrv_get_device_name(s->bs), strerror(error)); + snprintf(vm_stop_reason, STOP_REASON_LEN, + "VM is stopped due to disk write error: %s: %s", + bdrv_get_device_name(s->bs), strerror(error)); + term_printf_async(VMSTOP_ASYNC_EVENT, "%s\n", vm_stop_reason); } else { if (op == BM_STATUS_DMA_RETRY) ide_dma_error(s); diff --git a/qemu/hw/scsi-disk.c b/qemu/hw/scsi-disk.c index 391066d..e4fc1bb 100644 --- a/qemu/hw/scsi-disk.c +++ b/qemu/hw/scsi-disk.c @@ -229,9 +229,10 @@ static int scsi_handle_write_error(SCSIRequest *r, int error) || action == BLOCK_ERR_STOP_ANY) { r->status |= SCSI_REQ_STATUS_RETRY; vm_stop(0); - term_printf_async(VMSTOP_ASYNC_EVENT, - "VM is stopped due to disk write error: %s: %s\n", - bdrv_get_device_name(r->dev->bdrv), strerror(error)); + snprintf(vm_stop_reason, STOP_REASON_LEN, + "VM is stopped due to disk write error: %s: %s", + bdrv_get_device_name(r->dev->bdrv), strerror(error)); + term_printf_async(VMSTOP_ASYNC_EVENT, "%s\n", vm_stop_reason); } else { scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_HARDWARE_ERROR); diff --git a/qemu/hw/virtio-blk.c b/qemu/hw/virtio-blk.c index baea65d..ed8575b 100644 --- a/qemu/hw/virtio-blk.c +++ b/qemu/hw/virtio-blk.c @@ -66,9 +66,10 @@ static int virtio_blk_handle_write_error(VirtIOBlockReq *req, int error) req->next = s->rq; s->rq = req; vm_stop(0); - term_printf_async(VMSTOP_ASYNC_EVENT, - "VM is stopped due to disk write error: %s: %s\n", - bdrv_get_device_name(req->dev->bs), strerror(error)); + snprintf(vm_stop_reason, STOP_REASON_LEN, + "VM is stopped due to disk write error: %s: %s", + bdrv_get_device_name(s->bs), strerror(error)); + term_printf_async(VMSTOP_ASYNC_EVENT, "%s\n", vm_stop_reason); } else { virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR); } diff --git a/qemu/migration-exec.c b/qemu/migration-exec.c index 5e4108d..6b66344 100644 --- a/qemu/migration-exec.c +++ b/qemu/migration-exec.c @@ -132,6 +132,7 @@ int exec_start_incoming_migration(const char *command) dprintf("Unable to apply qemu wrapper to popen file\n"); return -errno; } + strncpy(vm_stop_reason, "incomming migration", STOP_REASON_LEN); vm_stop(0); /* just in case */ ret = qemu_loadvm_state(f); if (ret < 0) { diff --git a/qemu/migration.c b/qemu/migration.c index c748444..99512c6 100644 --- a/qemu/migration.c +++ b/qemu/migration.c @@ -255,6 +255,7 @@ void migrate_fd_put_ready(void *opaque) dprintf("iterate\n"); if (qemu_savevm_state_iterate(s->file) == 1) { dprintf("done iterating\n"); + strncpy(vm_stop_reason, "migration", STOP_REASON_LEN); vm_stop(0); qemu_aio_flush(); diff --git a/qemu/monitor.c b/qemu/monitor.c index 072d4b3..1b1c939 100644 --- a/qemu/monitor.c +++ b/qemu/monitor.c @@ -610,6 +610,7 @@ static void do_log(const char *items) static void do_stop(void) { + strncpy(vm_stop_reason, "monitor command", STOP_REASON_LEN); vm_stop(EXCP_INTERRUPT); } @@ -1569,6 +1570,11 @@ static void do_info_balloon(void) term_printf("balloon: actual=%d\n", (int)(actual >> 20)); } +static void do_info_stop_reason(void) +{ + term_printf("%s\n", vm_stop_reason); +} + static term_cmd_t term_cmds[] = { { "help|?", "s?", do_help, "[cmd]", "show the help" }, @@ -1756,6 +1762,8 @@ static term_cmd_t info_cmds[] = { { "migrate", "", do_info_migrate, "", "show migration status" }, { "balloon", "", do_info_balloon, "", "show balloon information" }, + { "stop-reason", "", do_info_stop_reason, + "", "show vm stop reason (valid only if vm is stopped)" }, { NULL, NULL, }, }; diff --git a/qemu/qemu-kvm.c b/qemu/qemu-kvm.c index 22e4aa5..f11a289 100644 --- a/qemu/qemu-kvm.c +++ b/qemu/qemu-kvm.c @@ -606,6 +606,7 @@ int kvm_main_loop(void) #ifdef CONFIG_GDBSTUB else if (kvm_debug_cpu_requested) { gdb_set_stop_cpu(kvm_debug_cpu_requested); + strncpy(vm_stop_reason, "gdbstub", STOP_REASON_LEN); vm_stop(EXCP_DEBUG); kvm_debug_cpu_requested = NULL; } diff --git a/qemu/savevm.c b/qemu/savevm.c index f3b9707..7089b7d 100644 --- a/qemu/savevm.c +++ b/qemu/savevm.c @@ -826,6 +826,7 @@ int qemu_savevm_state(QEMUFile *f) int ret; saved_vm_running = vm_running; + strncpy(vm_stop_reason, "savevm", STOP_REASON_LEN); vm_stop(0); bdrv_flush_all(); @@ -1094,6 +1095,7 @@ void do_savevm(const char *name) qemu_aio_flush(); saved_vm_running = vm_running; + strncpy(vm_stop_reason, "savevm", STOP_REASON_LEN); vm_stop(0); must_delete = 0; @@ -1190,6 +1192,7 @@ void do_loadvm(const char *name) qemu_aio_flush(); saved_vm_running = vm_running; + strncpy(vm_stop_reason, "savevm", STOP_REASON_LEN); vm_stop(0); for(i = 0; i <= nb_drives; i++) { diff --git a/qemu/sysemu.h b/qemu/sysemu.h index e522a33..b0e4755 100644 --- a/qemu/sysemu.h +++ b/qemu/sysemu.h @@ -25,6 +25,8 @@ void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque); void vm_start(void); void vm_stop(int reason); +#define STOP_REASON_LEN 1024 +extern char vm_stop_reason[]; uint64_t ram_bytes_remaining(void); uint64_t ram_bytes_transferred(void); diff --git a/qemu/vl.c b/qemu/vl.c index 7dd48f0..69d7586 100644 --- a/qemu/vl.c +++ b/qemu/vl.c @@ -3685,6 +3685,8 @@ void vm_start(void) } } +char vm_stop_reason[STOP_REASON_LEN]; + void vm_stop(int reason) { if (vm_running) { -- 1.6.3.rc4.29.g8146