]> git.proxmox.com Git - mirror_qemu.git/commitdiff
shutdown: Preserve shutdown cause through replay
authorEric Blake <eblake@redhat.com>
Mon, 15 May 2017 21:41:12 +0000 (16:41 -0500)
committerMarkus Armbruster <armbru@redhat.com>
Tue, 23 May 2017 11:28:17 +0000 (13:28 +0200)
With the recent addition of ShutdownCause, we want to be able to pass
a cause through any shutdown request, and then faithfully replay that
cause when later replaying the same sequence.  The easiest way is to
expand the reply event mechanism to track a series of values for
EVENT_SHUTDOWN, one corresponding to each value of ShutdownCause.

We are free to change the replay stream as needed, since there are
already no guarantees about being able to use a replay stream by
any other version of qemu than the one that generated it.

The cause is not actually fed back until the next patch changes the
signature for requesting a shutdown; a TODO marks that upcoming change.

Yes, this uses the gcc/clang extension of a ranged case label,
but this is not the first time we've used non-C99 constructs.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
Message-Id: <20170515214114.15442-4-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
include/sysemu/replay.h
replay/replay-internal.h
replay/replay.c
vl.c

index f1c0712795dc6d089641fbaef8c11458bc210fe6..fa14d0ec0b295953fb3234d6a330fe2dd1b7e12e 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include "qapi-types.h"
+#include "sysemu.h"
 
 /* replay clock kinds */
 enum ReplayClockKind {
@@ -98,7 +99,7 @@ int64_t replay_read_clock(ReplayClockKind kind);
 /* Events */
 
 /*! Called when qemu shutdown is requested. */
-void replay_shutdown_request(void);
+void replay_shutdown_request(ShutdownCause cause);
 /*! Should be called at check points in the execution.
     These check points are skipped, if they were not met.
     Saves checkpoint in the SAVE mode and validates in the PLAY mode.
index ed66ed803ce41c1f733f2d1e471852ffafcceb99..3ebb19912a7841a27f468555960ab535a95e4abe 100644 (file)
@@ -22,8 +22,9 @@ enum ReplayEvents {
     EVENT_EXCEPTION,
     /* for async events */
     EVENT_ASYNC,
-    /* for shutdown request */
+    /* for shutdown requests, range allows recovery of ShutdownCause */
     EVENT_SHUTDOWN,
+    EVENT_SHUTDOWN_LAST = EVENT_SHUTDOWN + SHUTDOWN_CAUSE__MAX,
     /* for character device write event */
     EVENT_CHAR_WRITE,
     /* for character device read all event */
index f810628cac525cad3202de1bb3dc7d9fc424a239..bf94e812611ddbd4cf1ef91a2610eba6fd7a138c 100644 (file)
@@ -49,8 +49,9 @@ bool replay_next_event_is(int event)
             res = true;
         }
         switch (replay_state.data_kind) {
-        case EVENT_SHUTDOWN:
+        case EVENT_SHUTDOWN ... EVENT_SHUTDOWN_LAST:
             replay_finish_event();
+            /* TODO - pass replay_state.data_kind - EVENT_SHUTDOWN as cause */
             qemu_system_shutdown_request();
             break;
         default:
@@ -170,11 +171,11 @@ bool replay_has_interrupt(void)
     return res;
 }
 
-void replay_shutdown_request(void)
+void replay_shutdown_request(ShutdownCause cause)
 {
     if (replay_mode == REPLAY_MODE_RECORD) {
         replay_mutex_lock();
-        replay_put_event(EVENT_SHUTDOWN);
+        replay_put_event(EVENT_SHUTDOWN + cause);
         replay_mutex_unlock();
     }
 }
diff --git a/vl.c b/vl.c
index d90ae3f20a3b6c243838112d9c44696d053f0e87..909519ff8399fd702418442bfb6a5eaba5aed0c0 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -1821,8 +1821,8 @@ void qemu_system_killed(int signal, pid_t pid)
 void qemu_system_shutdown_request(void)
 {
     trace_qemu_system_shutdown_request();
-    replay_shutdown_request();
     /* TODO - add a parameter to allow callers to specify reason */
+    replay_shutdown_request(SHUTDOWN_CAUSE_HOST_ERROR);
     shutdown_requested = SHUTDOWN_CAUSE_HOST_ERROR;
     qemu_notify_event();
 }