mirror of https://github.com/xemu-project/xemu.git
shutdown: Preserve shutdown cause through replay
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>
This commit is contained in:
parent
aedbe19297
commit
802f045a5f
|
@ -13,6 +13,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qapi-types.h"
|
#include "qapi-types.h"
|
||||||
|
#include "sysemu.h"
|
||||||
|
|
||||||
/* replay clock kinds */
|
/* replay clock kinds */
|
||||||
enum ReplayClockKind {
|
enum ReplayClockKind {
|
||||||
|
@ -98,7 +99,7 @@ int64_t replay_read_clock(ReplayClockKind kind);
|
||||||
/* Events */
|
/* Events */
|
||||||
|
|
||||||
/*! Called when qemu shutdown is requested. */
|
/*! 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.
|
/*! Should be called at check points in the execution.
|
||||||
These check points are skipped, if they were not met.
|
These check points are skipped, if they were not met.
|
||||||
Saves checkpoint in the SAVE mode and validates in the PLAY mode.
|
Saves checkpoint in the SAVE mode and validates in the PLAY mode.
|
||||||
|
|
|
@ -22,8 +22,9 @@ enum ReplayEvents {
|
||||||
EVENT_EXCEPTION,
|
EVENT_EXCEPTION,
|
||||||
/* for async events */
|
/* for async events */
|
||||||
EVENT_ASYNC,
|
EVENT_ASYNC,
|
||||||
/* for shutdown request */
|
/* for shutdown requests, range allows recovery of ShutdownCause */
|
||||||
EVENT_SHUTDOWN,
|
EVENT_SHUTDOWN,
|
||||||
|
EVENT_SHUTDOWN_LAST = EVENT_SHUTDOWN + SHUTDOWN_CAUSE__MAX,
|
||||||
/* for character device write event */
|
/* for character device write event */
|
||||||
EVENT_CHAR_WRITE,
|
EVENT_CHAR_WRITE,
|
||||||
/* for character device read all event */
|
/* for character device read all event */
|
||||||
|
|
|
@ -49,8 +49,9 @@ bool replay_next_event_is(int event)
|
||||||
res = true;
|
res = true;
|
||||||
}
|
}
|
||||||
switch (replay_state.data_kind) {
|
switch (replay_state.data_kind) {
|
||||||
case EVENT_SHUTDOWN:
|
case EVENT_SHUTDOWN ... EVENT_SHUTDOWN_LAST:
|
||||||
replay_finish_event();
|
replay_finish_event();
|
||||||
|
/* TODO - pass replay_state.data_kind - EVENT_SHUTDOWN as cause */
|
||||||
qemu_system_shutdown_request();
|
qemu_system_shutdown_request();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -170,11 +171,11 @@ bool replay_has_interrupt(void)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void replay_shutdown_request(void)
|
void replay_shutdown_request(ShutdownCause cause)
|
||||||
{
|
{
|
||||||
if (replay_mode == REPLAY_MODE_RECORD) {
|
if (replay_mode == REPLAY_MODE_RECORD) {
|
||||||
replay_mutex_lock();
|
replay_mutex_lock();
|
||||||
replay_put_event(EVENT_SHUTDOWN);
|
replay_put_event(EVENT_SHUTDOWN + cause);
|
||||||
replay_mutex_unlock();
|
replay_mutex_unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
2
vl.c
2
vl.c
|
@ -1821,8 +1821,8 @@ void qemu_system_killed(int signal, pid_t pid)
|
||||||
void qemu_system_shutdown_request(void)
|
void qemu_system_shutdown_request(void)
|
||||||
{
|
{
|
||||||
trace_qemu_system_shutdown_request();
|
trace_qemu_system_shutdown_request();
|
||||||
replay_shutdown_request();
|
|
||||||
/* TODO - add a parameter to allow callers to specify reason */
|
/* TODO - add a parameter to allow callers to specify reason */
|
||||||
|
replay_shutdown_request(SHUTDOWN_CAUSE_HOST_ERROR);
|
||||||
shutdown_requested = SHUTDOWN_CAUSE_HOST_ERROR;
|
shutdown_requested = SHUTDOWN_CAUSE_HOST_ERROR;
|
||||||
qemu_notify_event();
|
qemu_notify_event();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue