qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 1/8] Introduce the VMStatus type


From: Luiz Capitulino
Subject: [Qemu-devel] [PATCH 1/8] Introduce the VMStatus type
Date: Tue, 5 Jul 2011 15:17:44 -0300

We need to track the VM status so that QMP can report it to clients.

This commit adds the VMStatus type and related functions. The
vm_status_set() function is used to keep track of the current
VM status.

The current statuses are:

    - debug: guest is running under gdb
    - inmigrate: guest is paused waiting for an incoming migration
    - postmigrate: guest is paused following a successful migration
    - internal-error: Fatal internal error that prevents further guest
                execution
    - load-state-error: guest is paused following a failed 'loadvm'
    - io-error: the last IOP has failed and the device is configured
                to pause on I/O errors
    - watchdog-error: the watchdog action is configured to pause and
                      has been triggered
    - paused: guest has been paused via the 'stop' command
    - prelaunch: QEMU was started with -S and guest has not started
    - running: guest is actively running
    - shutdown: guest is shut down (and -no-shutdown is in use)

Signed-off-by: Luiz Capitulino <address@hidden>
---
 gdbstub.c       |    4 ++++
 hw/ide/core.c   |    1 +
 hw/scsi-disk.c  |    1 +
 hw/virtio-blk.c |    1 +
 hw/watchdog.c   |    1 +
 kvm-all.c       |    1 +
 migration.c     |    3 +++
 monitor.c       |    5 ++++-
 sysemu.h        |   19 +++++++++++++++++++
 vl.c            |   37 +++++++++++++++++++++++++++++++++++++
 10 files changed, 72 insertions(+), 1 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index c085a5a..61b700a 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2358,6 +2358,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const 
char *fmt, ...)
     s->state = RS_SYSCALL;
 #ifndef CONFIG_USER_ONLY
     vm_stop(VMSTOP_DEBUG);
+    vm_status_set(VMST_DEBUG);
 #endif
     s->state = RS_IDLE;
     va_start(va, fmt);
@@ -2432,6 +2433,7 @@ static void gdb_read_byte(GDBState *s, int ch)
         /* when the CPU is running, we cannot do anything except stop
            it when receiving a char */
         vm_stop(VMSTOP_USER);
+        vm_status_set(VMST_DEBUG);
     } else
 #endif
     {
@@ -2694,6 +2696,7 @@ static void gdb_chr_event(void *opaque, int event)
     switch (event) {
     case CHR_EVENT_OPENED:
         vm_stop(VMSTOP_USER);
+        vm_status_set(VMST_DEBUG);
         gdb_has_xml = 0;
         break;
     default:
@@ -2735,6 +2738,7 @@ static void gdb_sigterm_handler(int signal)
 {
     if (vm_running) {
         vm_stop(VMSTOP_USER);
+        vm_status_set(VMST_DEBUG);
     }
 }
 #endif
diff --git a/hw/ide/core.c b/hw/ide/core.c
index ca17a43..bf9df41 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -523,6 +523,7 @@ static int ide_handle_rw_error(IDEState *s, int error, int 
op)
         s->bus->error_status = op;
         bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
         vm_stop(VMSTOP_DISKFULL);
+        vm_status_set(VMST_IOERROR);
     } else {
         if (op & BM_STATUS_DMA_RETRY) {
             dma_buf_commit(s, 0);
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index a8c7372..66037fd 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -216,6 +216,7 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, 
int type)
 
         bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
         vm_stop(VMSTOP_DISKFULL);
+        vm_status_set(VMST_IOERROR);
     } else {
         if (type == SCSI_REQ_STATUS_RETRY_READ) {
             scsi_req_data(&r->req, 0);
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 91e0394..bf70200 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -79,6 +79,7 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, 
int error,
         s->rq = req;
         bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
         vm_stop(VMSTOP_DISKFULL);
+        vm_status_set(VMST_IOERROR);
     } else {
         virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
         bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read);
diff --git a/hw/watchdog.c b/hw/watchdog.c
index 1c900a1..d130cbb 100644
--- a/hw/watchdog.c
+++ b/hw/watchdog.c
@@ -133,6 +133,7 @@ void watchdog_perform_action(void)
     case WDT_PAUSE:             /* same as 'stop' command in monitor */
         watchdog_mon_event("pause");
         vm_stop(VMSTOP_WATCHDOG);
+        vm_status_set(VMST_WATCHDOG);
         break;
 
     case WDT_DEBUG:
diff --git a/kvm-all.c b/kvm-all.c
index cbc2532..aee9e0a 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1015,6 +1015,7 @@ int kvm_cpu_exec(CPUState *env)
     if (ret < 0) {
         cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE);
         vm_stop(VMSTOP_PANIC);
+        vm_status_set(VMST_INTERROR);
     }
 
     env->exit_request = 0;
diff --git a/migration.c b/migration.c
index af3a1f2..674792f 100644
--- a/migration.c
+++ b/migration.c
@@ -394,6 +394,9 @@ void migrate_fd_put_ready(void *opaque)
             }
             state = MIG_STATE_ERROR;
         }
+        if (state == MIG_STATE_COMPLETED) {
+            vm_status_set(VMST_POSTMIGRATE);
+        }
         s->state = state;
         notifier_list_notify(&migration_state_notifiers);
     }
diff --git a/monitor.c b/monitor.c
index 67ceb46..1cb3191 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1258,6 +1258,7 @@ static void do_singlestep(Monitor *mon, const QDict 
*qdict)
 static int do_stop(Monitor *mon, const QDict *qdict, QObject **ret_data)
 {
     vm_stop(VMSTOP_USER);
+    vm_status_set(VMST_PAUSED);
     return 0;
 }
 
@@ -2782,7 +2783,9 @@ static void do_loadvm(Monitor *mon, const QDict *qdict)
 
     vm_stop(VMSTOP_LOADVM);
 
-    if (load_vmstate(name) == 0 && saved_vm_running) {
+    if (load_vmstate(name) < 0) {
+        vm_status_set(VMST_LOADERROR);
+    } else if (saved_vm_running) {
         vm_start();
     }
 }
diff --git a/sysemu.h b/sysemu.h
index d3013f5..7308ac5 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -77,6 +77,25 @@ int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f);
 void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f);
 int qemu_loadvm_state(QEMUFile *f);
 
+typedef enum {
+    VMST_NOSTATUS,
+    VMST_DEBUG,
+    VMST_INMIGRATE,
+    VMST_POSTMIGRATE,
+    VMST_INTERROR,
+    VMST_IOERROR,
+    VMST_LOADERROR,
+    VMST_PAUSED,
+    VMST_PRELAUNCH,
+    VMST_RUNNING,
+    VMST_SHUTDOWN,
+    VMST_WATCHDOG,
+    VMST_MAX,
+} VMStatus;
+
+void vm_status_set(VMStatus s);
+const char *vm_status_get_name(void);
+
 /* SLIRP */
 void do_info_slirp(Monitor *mon);
 
diff --git a/vl.c b/vl.c
index fcd7395..fb7208f 100644
--- a/vl.c
+++ b/vl.c
@@ -309,6 +309,37 @@ static int default_driver_check(QemuOpts *opts, void 
*opaque)
 }
 
 /***********************************************************/
+/* VMStatus */
+
+static const char *const vm_status_name[VMST_MAX] = {
+    [VMST_DEBUG] = "debug",
+    [VMST_INMIGRATE] = "inmigrate",
+    [VMST_POSTMIGRATE] = "postmigrate",
+    [VMST_INTERROR] = "internal-error",
+    [VMST_IOERROR] = "io-error",
+    [VMST_LOADERROR] = "load-state-error",
+    [VMST_PAUSED] = "paused",
+    [VMST_PRELAUNCH] = "prelaunch",
+    [VMST_RUNNING] = "running",
+    [VMST_SHUTDOWN] = "shutdown",
+    [VMST_WATCHDOG] = "watchdog-error",
+};
+
+static VMStatus qemu_vm_status = VMST_NOSTATUS;
+
+void vm_status_set(VMStatus s)
+{
+    assert(s > VMST_NOSTATUS && s < VMST_MAX);
+    qemu_vm_status = s;
+}
+
+const char *vm_status_get_name(void)
+{
+    assert(qemu_vm_status > VMST_NOSTATUS && qemu_vm_status < VMST_MAX);
+    return vm_status_name[qemu_vm_status];
+}
+
+/***********************************************************/
 /* real time host monotonic timer */
 
 /***********************************************************/
@@ -1150,6 +1181,7 @@ void vm_start(void)
         vm_state_notify(1, 0);
         resume_all_vcpus();
         monitor_protocol_event(QEVENT_RESUME, NULL);
+        vm_status_set(VMST_RUNNING);
     }
 }
 
@@ -1392,12 +1424,14 @@ static void main_loop(void)
 
         if (qemu_debug_requested()) {
             vm_stop(VMSTOP_DEBUG);
+            vm_status_set(VMST_DEBUG);
         }
         if (qemu_shutdown_requested()) {
             qemu_kill_report();
             monitor_protocol_event(QEVENT_SHUTDOWN, NULL);
             if (no_shutdown) {
                 vm_stop(VMSTOP_SHUTDOWN);
+                vm_status_set(VMST_SHUTDOWN);
                 no_shutdown = 0;
             } else
                 break;
@@ -2476,6 +2510,7 @@ int main(int argc, char **argv, char **envp)
                 break;
             case QEMU_OPTION_S:
                 autostart = 0;
+                vm_status_set(VMST_PRELAUNCH);
                 break;
            case QEMU_OPTION_k:
                keyboard_layout = optarg;
@@ -3307,11 +3342,13 @@ int main(int argc, char **argv, char **envp)
     qemu_system_reset(VMRESET_SILENT);
     if (loadvm) {
         if (load_vmstate(loadvm) < 0) {
+            vm_status_set(VMST_LOADERROR);
             autostart = 0;
         }
     }
 
     if (incoming) {
+        vm_status_set(VMST_INMIGRATE);
         int ret = qemu_start_incoming_migration(incoming);
         if (ret < 0) {
             fprintf(stderr, "Migration failed. Exit code %s(%d), exiting.\n",
-- 
1.7.6.131.g99019




reply via email to

[Prev in Thread] Current Thread [Next in Thread]