Replace the VMSTOP macros with a proper state type

Today, when notifying a VM state change with vm_state_notify(),
we pass a VMSTOP macro as the 'reason' argument. This is not ideal
because the VMSTOP macros tell why qemu stopped and not exactly
what the current VM state is.

One example to demonstrate this problem is that vm_start() calls
vm_state_notify() with reason=0, which turns out to be VMSTOP_USER.

This commit fixes that by replacing the VMSTOP macros with a proper
state type called RunState.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
This commit is contained in:
Luiz Capitulino 2011-07-29 14:26:33 -03:00
parent bff046f86b
commit 1dfb4dd993
24 changed files with 91 additions and 76 deletions

View File

@ -1743,7 +1743,7 @@ static int audio_driver_init (AudioState *s, struct audio_driver *drv)
}
static void audio_vm_change_state_handler (void *opaque, int running,
int reason)
RunState state)
{
AudioState *s = opaque;
HWVoiceOut *hwo = NULL;

10
cpus.c
View File

@ -118,13 +118,13 @@ int cpu_is_stopped(CPUState *env)
return !vm_running || env->stopped;
}
static void do_vm_stop(int reason)
static void do_vm_stop(RunState state)
{
if (vm_running) {
cpu_disable_ticks();
vm_running = 0;
pause_all_vcpus();
vm_state_notify(0, reason);
vm_state_notify(0, state);
qemu_aio_flush();
bdrv_flush_all();
monitor_protocol_event(QEVENT_STOP, NULL);
@ -878,10 +878,10 @@ void cpu_stop_current(void)
}
}
void vm_stop(int reason)
void vm_stop(RunState state)
{
if (!qemu_thread_is_self(&io_thread)) {
qemu_system_vmstop_request(reason);
qemu_system_vmstop_request(state);
/*
* FIXME: should not return to device code in case
* vm_stop() has been requested.
@ -889,7 +889,7 @@ void vm_stop(int reason)
cpu_stop_current();
return;
}
do_vm_stop(reason);
do_vm_stop(state);
}
static int tcg_cpu_exec(CPUState *env)

View File

@ -2373,7 +2373,7 @@ void gdb_set_stop_cpu(CPUState *env)
}
#ifndef CONFIG_USER_ONLY
static void gdb_vm_state_change(void *opaque, int running, int reason)
static void gdb_vm_state_change(void *opaque, int running, RunState state)
{
GDBState *s = gdbserver_state;
CPUState *env = s->c_cpu;
@ -2384,8 +2384,8 @@ static void gdb_vm_state_change(void *opaque, int running, int reason)
if (running || s->state == RS_INACTIVE || s->state == RS_SYSCALL) {
return;
}
switch (reason) {
case VMSTOP_DEBUG:
switch (state) {
case RSTATE_DEBUG:
if (env->watchpoint_hit) {
switch (env->watchpoint_hit->flags & BP_MEM_ACCESS) {
case BP_MEM_READ:
@ -2408,25 +2408,25 @@ static void gdb_vm_state_change(void *opaque, int running, int reason)
tb_flush(env);
ret = GDB_SIGNAL_TRAP;
break;
case VMSTOP_USER:
case RSTATE_PAUSED:
ret = GDB_SIGNAL_INT;
break;
case VMSTOP_SHUTDOWN:
case RSTATE_SHUTDOWN:
ret = GDB_SIGNAL_QUIT;
break;
case VMSTOP_DISKFULL:
case RSTATE_IO_ERROR:
ret = GDB_SIGNAL_IO;
break;
case VMSTOP_WATCHDOG:
case RSTATE_WATCHDOG:
ret = GDB_SIGNAL_ALRM;
break;
case VMSTOP_PANIC:
case RSTATE_PANICKED:
ret = GDB_SIGNAL_ABRT;
break;
case VMSTOP_SAVEVM:
case VMSTOP_LOADVM:
case RSTATE_SAVEVM:
case RSTATE_RESTORE:
return;
case VMSTOP_MIGRATE:
case RSTATE_PRE_MIGRATE:
ret = GDB_SIGNAL_XCPU;
break;
default:
@ -2463,7 +2463,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
vm_stop(VMSTOP_DEBUG);
vm_stop(RSTATE_DEBUG);
#endif
s->state = RS_IDLE;
va_start(va, fmt);
@ -2537,7 +2537,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 */
vm_stop(VMSTOP_USER);
vm_stop(RSTATE_PAUSED);
} else
#endif
{
@ -2799,7 +2799,7 @@ static void gdb_chr_event(void *opaque, int event)
{
switch (event) {
case CHR_EVENT_OPENED:
vm_stop(VMSTOP_USER);
vm_stop(RSTATE_PAUSED);
gdb_has_xml = 0;
break;
default:
@ -2840,7 +2840,7 @@ static int gdb_monitor_write(CharDriverState *chr, const uint8_t *buf, int len)
static void gdb_sigterm_handler(int signal)
{
if (vm_running) {
vm_stop(VMSTOP_USER);
vm_stop(RSTATE_PAUSED);
}
}
#endif

View File

@ -1103,7 +1103,7 @@ static void ahci_irq_set(void *opaque, int n, int level)
{
}
static void ahci_dma_restart_cb(void *opaque, int running, int reason)
static void ahci_dma_restart_cb(void *opaque, int running, RunState state)
{
}

View File

@ -527,7 +527,7 @@ static int ide_handle_rw_error(IDEState *s, int error, int op)
s->bus->dma->ops->set_unit(s->bus->dma, s->unit);
s->bus->error_status = op;
bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
vm_stop(VMSTOP_DISKFULL);
vm_stop(RSTATE_IO_ERROR);
} else {
if (op & BM_STATUS_DMA_RETRY) {
dma_buf_commit(s, 0);
@ -1910,7 +1910,7 @@ static int ide_nop_int(IDEDMA *dma, int x)
return 0;
}
static void ide_nop_restart(void *opaque, int x, int y)
static void ide_nop_restart(void *opaque, int x, RunState y)
{
}

View File

@ -9,6 +9,7 @@
#include <hw/ide.h>
#include "iorange.h"
#include "dma.h"
#include "sysemu.h"
/* debug IDE devices */
//#define DEBUG_IDE
@ -387,7 +388,7 @@ typedef void EndTransferFunc(IDEState *);
typedef void DMAStartFunc(IDEDMA *, IDEState *, BlockDriverCompletionFunc *);
typedef int DMAFunc(IDEDMA *);
typedef int DMAIntFunc(IDEDMA *, int);
typedef void DMARestartFunc(void *, int, int);
typedef void DMARestartFunc(void *, int, RunState);
struct unreported_events {
bool eject_request;

View File

@ -222,7 +222,7 @@ static void bmdma_restart_bh(void *opaque)
}
}
static void bmdma_restart_cb(void *opaque, int running, int reason)
static void bmdma_restart_cb(void *opaque, int running, RunState state)
{
IDEDMA *dma = opaque;
BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);

View File

@ -59,7 +59,8 @@ static int kvmclock_post_load(void *opaque, int version_id)
return kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data);
}
static void kvmclock_vm_state_change(void *opaque, int running, int reason)
static void kvmclock_vm_state_change(void *opaque, int running,
RunState state)
{
KVMClockState *s = opaque;

View File

@ -1453,10 +1453,11 @@ static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
}
}
static void qxl_vm_change_state_handler(void *opaque, int running, int reason)
static void qxl_vm_change_state_handler(void *opaque, int running,
RunState state)
{
PCIQXLDevice *qxl = opaque;
qemu_spice_vm_change_state_handler(&qxl->ssd, running, reason);
qemu_spice_vm_change_state_handler(&qxl->ssd, running, state);
if (running) {
/*

View File

@ -217,7 +217,7 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type)
r->status |= SCSI_REQ_STATUS_RETRY | type;
bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
vm_stop(VMSTOP_DISKFULL);
vm_stop(RSTATE_IO_ERROR);
} else {
switch (error) {
case ENOMEM:
@ -338,7 +338,7 @@ static void scsi_dma_restart_bh(void *opaque)
}
}
static void scsi_dma_restart_cb(void *opaque, int running, int reason)
static void scsi_dma_restart_cb(void *opaque, int running, RunState state)
{
SCSIDiskState *s = opaque;

View File

@ -77,7 +77,7 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
req->next = s->rq;
s->rq = req;
bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
vm_stop(VMSTOP_DISKFULL);
vm_stop(RSTATE_IO_ERROR);
} else {
virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
bdrv_acct_done(s->bs, &req->acct);
@ -439,7 +439,8 @@ static void virtio_blk_dma_restart_bh(void *opaque)
virtio_submit_multiwrite(s->bs, &mrb);
}
static void virtio_blk_dma_restart_cb(void *opaque, int running, int reason)
static void virtio_blk_dma_restart_cb(void *opaque, int running,
RunState state)
{
VirtIOBlock *s = opaque;

View File

@ -837,7 +837,7 @@ void virtio_cleanup(VirtIODevice *vdev)
g_free(vdev);
}
static void virtio_vmstate_change(void *opaque, int running, int reason)
static void virtio_vmstate_change(void *opaque, int running, RunState state)
{
VirtIODevice *vdev = opaque;
bool backend_run = running && (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK);

View File

@ -132,7 +132,7 @@ void watchdog_perform_action(void)
case WDT_PAUSE: /* same as 'stop' command in monitor */
watchdog_mon_event("pause");
vm_stop(VMSTOP_WATCHDOG);
vm_stop(RSTATE_WATCHDOG);
break;
case WDT_DEBUG:

View File

@ -1014,7 +1014,7 @@ int kvm_cpu_exec(CPUState *env)
if (ret < 0) {
cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE);
vm_stop(VMSTOP_PANIC);
vm_stop(RSTATE_PANICKED);
}
env->exit_request = 0;

View File

@ -374,7 +374,7 @@ void migrate_fd_put_ready(void *opaque)
int old_vm_running = vm_running;
DPRINTF("done iterating\n");
vm_stop(VMSTOP_MIGRATE);
vm_stop(RSTATE_PRE_MIGRATE);
if ((qemu_savevm_state_complete(s->mon, s->file)) < 0) {
if (old_vm_running) {

View File

@ -1293,7 +1293,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_stop(RSTATE_PAUSED);
return 0;
}
@ -2828,7 +2828,7 @@ static void do_loadvm(Monitor *mon, const QDict *qdict)
int saved_vm_running = vm_running;
const char *name = qdict_get_str(qdict, "name");
vm_stop(VMSTOP_LOADVM);
vm_stop(RSTATE_RESTORE);
if (load_vmstate(name) == 0 && saved_vm_running) {
vm_start();

View File

@ -1116,7 +1116,8 @@ static void win32_rearm_timer(struct qemu_alarm_timer *t)
#endif /* _WIN32 */
static void alarm_timer_on_change_state_rearm(void *opaque, int running, int reason)
static void alarm_timer_on_change_state_rearm(void *opaque, int running,
RunState state)
{
if (running)
qemu_rearm_alarm_timer((struct qemu_alarm_timer *) opaque);

View File

@ -1603,7 +1603,7 @@ static int qemu_savevm_state(Monitor *mon, QEMUFile *f)
int ret;
saved_vm_running = vm_running;
vm_stop(VMSTOP_SAVEVM);
vm_stop(RSTATE_SAVEVM);
if (qemu_savevm_state_blocked(mon)) {
ret = -EINVAL;
@ -1932,7 +1932,7 @@ void do_savevm(Monitor *mon, const QDict *qdict)
}
saved_vm_running = vm_running;
vm_stop(VMSTOP_SAVEVM);
vm_stop(RSTATE_SAVEVM);
memset(sn, 0, sizeof(*sn));

View File

@ -9,6 +9,21 @@
#include "notify.h"
/* vl.c */
typedef enum {
RSTATE_NO_STATE,
RSTATE_DEBUG, /* qemu is running under gdb */
RSTATE_PANICKED, /* paused due to an internal error */
RSTATE_IO_ERROR, /* paused due to an I/O error */
RSTATE_PAUSED, /* paused by the user (ie. the 'stop' command) */
RSTATE_PRE_MIGRATE, /* paused preparing to finish migrate */
RSTATE_RESTORE, /* paused restoring the VM state */
RSTATE_RUNNING, /* qemu is running */
RSTATE_SAVEVM, /* paused saving VM state */
RSTATE_SHUTDOWN, /* guest shut down and -no-shutdown is in use */
RSTATE_WATCHDOG /* watchdog fired and qemu is configured to pause */
} RunState;
extern const char *bios_name;
extern int vm_running;
@ -18,34 +33,24 @@ int qemu_uuid_parse(const char *str, uint8_t *uuid);
#define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
typedef struct vm_change_state_entry VMChangeStateEntry;
typedef void VMChangeStateHandler(void *opaque, int running, int reason);
typedef void VMChangeStateHandler(void *opaque, int running, RunState state);
VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
void *opaque);
void qemu_del_vm_change_state_handler(VMChangeStateEntry *e);
void vm_state_notify(int running, int reason);
#define VMSTOP_USER 0
#define VMSTOP_DEBUG 1
#define VMSTOP_SHUTDOWN 2
#define VMSTOP_DISKFULL 3
#define VMSTOP_WATCHDOG 4
#define VMSTOP_PANIC 5
#define VMSTOP_SAVEVM 6
#define VMSTOP_LOADVM 7
#define VMSTOP_MIGRATE 8
void vm_state_notify(int running, RunState state);
#define VMRESET_SILENT false
#define VMRESET_REPORT true
void vm_start(void);
void vm_stop(int reason);
void vm_stop(RunState state);
void qemu_system_reset_request(void);
void qemu_system_shutdown_request(void);
void qemu_system_powerdown_request(void);
void qemu_system_debug_request(void);
void qemu_system_vmstop_request(int reason);
void qemu_system_vmstop_request(RunState reason);
int qemu_shutdown_requested_get(void);
int qemu_reset_requested_get(void);
int qemu_shutdown_requested(void);

View File

@ -334,7 +334,7 @@ static int kvm_inject_mce_oldstyle(CPUState *env)
return 0;
}
static void cpu_update_state(void *opaque, int running, int reason)
static void cpu_update_state(void *opaque, int running, RunState state)
{
CPUState *env = opaque;

View File

@ -255,7 +255,8 @@ void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd)
qemu_spice_destroy_primary_surface(ssd, 0, QXL_SYNC);
}
void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason)
void qemu_spice_vm_change_state_handler(void *opaque, int running,
RunState state)
{
SimpleSpiceDisplay *ssd = opaque;

View File

@ -22,6 +22,7 @@
#include "qemu-thread.h"
#include "console.h"
#include "pflib.h"
#include "sysemu.h"
#define NUM_MEMSLOTS 8
#define MEMSLOT_GENERATION_BITS 8
@ -88,7 +89,8 @@ void qemu_spice_destroy_update(SimpleSpiceDisplay *sdpy, SimpleSpiceUpdate *upda
void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd);
void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd);
void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd);
void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason);
void qemu_spice_vm_change_state_handler(void *opaque, int running,
RunState state);
void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds);
void qemu_spice_display_update(SimpleSpiceDisplay *ssd,

26
vl.c
View File

@ -1145,14 +1145,14 @@ void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
g_free (e);
}
void vm_state_notify(int running, int reason)
void vm_state_notify(int running, RunState state)
{
VMChangeStateEntry *e;
trace_vm_state_notify(running, reason);
trace_vm_state_notify(running, state);
for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
e->cb(e->opaque, running, reason);
e->cb(e->opaque, running, state);
}
}
@ -1161,7 +1161,7 @@ void vm_start(void)
if (!vm_running) {
cpu_enable_ticks();
vm_running = 1;
vm_state_notify(1, 0);
vm_state_notify(1, RSTATE_RUNNING);
resume_all_vcpus();
monitor_protocol_event(QEVENT_RESUME, NULL);
}
@ -1182,7 +1182,7 @@ static int shutdown_requested, shutdown_signal = -1;
static pid_t shutdown_pid;
static int powerdown_requested;
static int debug_requested;
static int vmstop_requested;
static RunState vmstop_requested = RSTATE_NO_STATE;
int qemu_shutdown_requested_get(void)
{
@ -1238,11 +1238,11 @@ static int qemu_debug_requested(void)
return r;
}
static int qemu_vmstop_requested(void)
static RunState qemu_vmstop_requested(void)
{
int r = vmstop_requested;
vmstop_requested = 0;
return r;
RunState s = vmstop_requested;
vmstop_requested = RSTATE_NO_STATE;
return s;
}
void qemu_register_reset(QEMUResetHandler *func, void *opaque)
@ -1317,9 +1317,9 @@ void qemu_system_debug_request(void)
qemu_notify_event();
}
void qemu_system_vmstop_request(int reason)
void qemu_system_vmstop_request(RunState state)
{
vmstop_requested = reason;
vmstop_requested = state;
qemu_notify_event();
}
@ -1469,13 +1469,13 @@ static void main_loop(void)
#endif
if (qemu_debug_requested()) {
vm_stop(VMSTOP_DEBUG);
vm_stop(RSTATE_DEBUG);
}
if (qemu_shutdown_requested()) {
qemu_kill_report();
monitor_protocol_event(QEVENT_SHUTDOWN, NULL);
if (no_shutdown) {
vm_stop(VMSTOP_SHUTDOWN);
vm_stop(RSTATE_SHUTDOWN);
} else
break;
}

View File

@ -846,7 +846,8 @@ static void xen_main_loop_prepare(XenIOState *state)
/* Initialise Xen */
static void xen_change_state_handler(void *opaque, int running, int reason)
static void xen_change_state_handler(void *opaque, int running,
RunState state)
{
if (running) {
/* record state running */
@ -854,11 +855,12 @@ static void xen_change_state_handler(void *opaque, int running, int reason)
}
}
static void xen_hvm_change_state_handler(void *opaque, int running, int reason)
static void xen_hvm_change_state_handler(void *opaque, int running,
RunState rstate)
{
XenIOState *state = opaque;
XenIOState *xstate = opaque;
if (running) {
xen_main_loop_prepare(state);
xen_main_loop_prepare(xstate);
}
}