提交 7f67d892 编写于 作者: A Anthony Liguori

Merge remote-tracking branch 'qmp/queue/qmp' into staging

...@@ -1743,7 +1743,7 @@ static int audio_driver_init (AudioState *s, struct audio_driver *drv) ...@@ -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, static void audio_vm_change_state_handler (void *opaque, int running,
int reason) RunState state)
{ {
AudioState *s = opaque; AudioState *s = opaque;
HWVoiceOut *hwo = NULL; HWVoiceOut *hwo = NULL;
......
...@@ -115,16 +115,16 @@ void cpu_synchronize_all_post_init(void) ...@@ -115,16 +115,16 @@ void cpu_synchronize_all_post_init(void)
int cpu_is_stopped(CPUState *env) int cpu_is_stopped(CPUState *env)
{ {
return !vm_running || env->stopped; return !runstate_is_running() || env->stopped;
} }
static void do_vm_stop(int reason) static void do_vm_stop(RunState state)
{ {
if (vm_running) { if (runstate_is_running()) {
cpu_disable_ticks(); cpu_disable_ticks();
vm_running = 0;
pause_all_vcpus(); pause_all_vcpus();
vm_state_notify(0, reason); runstate_set(state);
vm_state_notify(0, state);
qemu_aio_flush(); qemu_aio_flush();
bdrv_flush_all(); bdrv_flush_all();
monitor_protocol_event(QEVENT_STOP, NULL); monitor_protocol_event(QEVENT_STOP, NULL);
...@@ -136,7 +136,7 @@ static int cpu_can_run(CPUState *env) ...@@ -136,7 +136,7 @@ static int cpu_can_run(CPUState *env)
if (env->stop) { if (env->stop) {
return 0; return 0;
} }
if (env->stopped || !vm_running) { if (env->stopped || !runstate_is_running()) {
return 0; return 0;
} }
return 1; return 1;
...@@ -147,7 +147,7 @@ static bool cpu_thread_is_idle(CPUState *env) ...@@ -147,7 +147,7 @@ static bool cpu_thread_is_idle(CPUState *env)
if (env->stop || env->queued_work_first) { if (env->stop || env->queued_work_first) {
return false; return false;
} }
if (env->stopped || !vm_running) { if (env->stopped || !runstate_is_running()) {
return true; return true;
} }
if (!env->halted || qemu_cpu_has_work(env) || if (!env->halted || qemu_cpu_has_work(env) ||
...@@ -878,10 +878,10 @@ void cpu_stop_current(void) ...@@ -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)) { 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 * FIXME: should not return to device code in case
* vm_stop() has been requested. * vm_stop() has been requested.
...@@ -889,7 +889,7 @@ void vm_stop(int reason) ...@@ -889,7 +889,7 @@ void vm_stop(int reason)
cpu_stop_current(); cpu_stop_current();
return; return;
} }
do_vm_stop(reason); do_vm_stop(state);
} }
static int tcg_cpu_exec(CPUState *env) static int tcg_cpu_exec(CPUState *env)
......
...@@ -15,7 +15,6 @@ void cpu_synchronize_all_post_init(void); ...@@ -15,7 +15,6 @@ void cpu_synchronize_all_post_init(void);
/* vl.c */ /* vl.c */
extern int smp_cores; extern int smp_cores;
extern int smp_threads; extern int smp_threads;
void vm_state_notify(int running, int reason);
bool cpu_exec_all(void); bool cpu_exec_all(void);
void set_numa_modes(void); void set_numa_modes(void);
void set_cpu_log(const char *optarg); void set_cpu_log(const char *optarg);
......
...@@ -2373,7 +2373,7 @@ void gdb_set_stop_cpu(CPUState *env) ...@@ -2373,7 +2373,7 @@ void gdb_set_stop_cpu(CPUState *env)
} }
#ifndef CONFIG_USER_ONLY #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; GDBState *s = gdbserver_state;
CPUState *env = s->c_cpu; CPUState *env = s->c_cpu;
...@@ -2384,8 +2384,8 @@ static void gdb_vm_state_change(void *opaque, int running, int reason) ...@@ -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) { if (running || s->state == RS_INACTIVE || s->state == RS_SYSCALL) {
return; return;
} }
switch (reason) { switch (state) {
case VMSTOP_DEBUG: case RSTATE_DEBUG:
if (env->watchpoint_hit) { if (env->watchpoint_hit) {
switch (env->watchpoint_hit->flags & BP_MEM_ACCESS) { switch (env->watchpoint_hit->flags & BP_MEM_ACCESS) {
case BP_MEM_READ: case BP_MEM_READ:
...@@ -2408,25 +2408,25 @@ static void gdb_vm_state_change(void *opaque, int running, int reason) ...@@ -2408,25 +2408,25 @@ static void gdb_vm_state_change(void *opaque, int running, int reason)
tb_flush(env); tb_flush(env);
ret = GDB_SIGNAL_TRAP; ret = GDB_SIGNAL_TRAP;
break; break;
case VMSTOP_USER: case RSTATE_PAUSED:
ret = GDB_SIGNAL_INT; ret = GDB_SIGNAL_INT;
break; break;
case VMSTOP_SHUTDOWN: case RSTATE_SHUTDOWN:
ret = GDB_SIGNAL_QUIT; ret = GDB_SIGNAL_QUIT;
break; break;
case VMSTOP_DISKFULL: case RSTATE_IO_ERROR:
ret = GDB_SIGNAL_IO; ret = GDB_SIGNAL_IO;
break; break;
case VMSTOP_WATCHDOG: case RSTATE_WATCHDOG:
ret = GDB_SIGNAL_ALRM; ret = GDB_SIGNAL_ALRM;
break; break;
case VMSTOP_PANIC: case RSTATE_PANICKED:
ret = GDB_SIGNAL_ABRT; ret = GDB_SIGNAL_ABRT;
break; break;
case VMSTOP_SAVEVM: case RSTATE_SAVEVM:
case VMSTOP_LOADVM: case RSTATE_RESTORE:
return; return;
case VMSTOP_MIGRATE: case RSTATE_PRE_MIGRATE:
ret = GDB_SIGNAL_XCPU; ret = GDB_SIGNAL_XCPU;
break; break;
default: default:
...@@ -2463,7 +2463,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...) ...@@ -2463,7 +2463,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
gdb_current_syscall_cb = cb; gdb_current_syscall_cb = cb;
s->state = RS_SYSCALL; s->state = RS_SYSCALL;
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
vm_stop(VMSTOP_DEBUG); vm_stop(RSTATE_DEBUG);
#endif #endif
s->state = RS_IDLE; s->state = RS_IDLE;
va_start(va, fmt); va_start(va, fmt);
...@@ -2534,10 +2534,10 @@ static void gdb_read_byte(GDBState *s, int ch) ...@@ -2534,10 +2534,10 @@ static void gdb_read_byte(GDBState *s, int ch)
if (ch != '$') if (ch != '$')
return; return;
} }
if (vm_running) { if (runstate_is_running()) {
/* when the CPU is running, we cannot do anything except stop /* when the CPU is running, we cannot do anything except stop
it when receiving a char */ it when receiving a char */
vm_stop(VMSTOP_USER); vm_stop(RSTATE_PAUSED);
} else } else
#endif #endif
{ {
...@@ -2799,7 +2799,7 @@ static void gdb_chr_event(void *opaque, int event) ...@@ -2799,7 +2799,7 @@ static void gdb_chr_event(void *opaque, int event)
{ {
switch (event) { switch (event) {
case CHR_EVENT_OPENED: case CHR_EVENT_OPENED:
vm_stop(VMSTOP_USER); vm_stop(RSTATE_PAUSED);
gdb_has_xml = 0; gdb_has_xml = 0;
break; break;
default: default:
...@@ -2839,8 +2839,8 @@ static int gdb_monitor_write(CharDriverState *chr, const uint8_t *buf, int len) ...@@ -2839,8 +2839,8 @@ static int gdb_monitor_write(CharDriverState *chr, const uint8_t *buf, int len)
#ifndef _WIN32 #ifndef _WIN32
static void gdb_sigterm_handler(int signal) static void gdb_sigterm_handler(int signal)
{ {
if (vm_running) { if (runstate_is_running()) {
vm_stop(VMSTOP_USER); vm_stop(RSTATE_PAUSED);
} }
} }
#endif #endif
......
...@@ -732,7 +732,7 @@ static void DMA_run(void *opaque) ...@@ -732,7 +732,7 @@ static void DMA_run(void *opaque)
struct fs_dma_ctrl *etraxfs_dmac = opaque; struct fs_dma_ctrl *etraxfs_dmac = opaque;
int p = 1; int p = 1;
if (vm_running) if (runstate_is_running())
p = etraxfs_dmac_run(etraxfs_dmac); p = etraxfs_dmac_run(etraxfs_dmac);
if (p) if (p)
......
...@@ -1103,7 +1103,7 @@ static void ahci_irq_set(void *opaque, int n, int level) ...@@ -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)
{ {
} }
......
...@@ -527,7 +527,7 @@ static int ide_handle_rw_error(IDEState *s, int error, int op) ...@@ -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->dma->ops->set_unit(s->bus->dma, s->unit);
s->bus->error_status = op; s->bus->error_status = op;
bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read); bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
vm_stop(VMSTOP_DISKFULL); vm_stop(RSTATE_IO_ERROR);
} else { } else {
if (op & BM_STATUS_DMA_RETRY) { if (op & BM_STATUS_DMA_RETRY) {
dma_buf_commit(s, 0); dma_buf_commit(s, 0);
...@@ -1910,7 +1910,7 @@ static int ide_nop_int(IDEDMA *dma, int x) ...@@ -1910,7 +1910,7 @@ static int ide_nop_int(IDEDMA *dma, int x)
return 0; return 0;
} }
static void ide_nop_restart(void *opaque, int x, int y) static void ide_nop_restart(void *opaque, int x, RunState y)
{ {
} }
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <hw/ide.h> #include <hw/ide.h>
#include "iorange.h" #include "iorange.h"
#include "dma.h" #include "dma.h"
#include "sysemu.h"
/* debug IDE devices */ /* debug IDE devices */
//#define DEBUG_IDE //#define DEBUG_IDE
...@@ -387,7 +388,7 @@ typedef void EndTransferFunc(IDEState *); ...@@ -387,7 +388,7 @@ typedef void EndTransferFunc(IDEState *);
typedef void DMAStartFunc(IDEDMA *, IDEState *, BlockDriverCompletionFunc *); typedef void DMAStartFunc(IDEDMA *, IDEState *, BlockDriverCompletionFunc *);
typedef int DMAFunc(IDEDMA *); typedef int DMAFunc(IDEDMA *);
typedef int DMAIntFunc(IDEDMA *, int); typedef int DMAIntFunc(IDEDMA *, int);
typedef void DMARestartFunc(void *, int, int); typedef void DMARestartFunc(void *, int, RunState);
struct unreported_events { struct unreported_events {
bool eject_request; bool eject_request;
......
...@@ -222,7 +222,7 @@ static void bmdma_restart_bh(void *opaque) ...@@ -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; IDEDMA *dma = opaque;
BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma); BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
......
...@@ -46,7 +46,7 @@ static void kvmclock_pre_save(void *opaque) ...@@ -46,7 +46,7 @@ static void kvmclock_pre_save(void *opaque)
* it on next vmsave (which would return a different value). Will be reset * it on next vmsave (which would return a different value). Will be reset
* when the VM is continued. * when the VM is continued.
*/ */
s->clock_valid = !vm_running; s->clock_valid = !runstate_is_running();
} }
static int kvmclock_post_load(void *opaque, int version_id) static int kvmclock_post_load(void *opaque, int version_id)
...@@ -59,7 +59,8 @@ static int kvmclock_post_load(void *opaque, int version_id) ...@@ -59,7 +59,8 @@ static int kvmclock_post_load(void *opaque, int version_id)
return kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data); 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; KVMClockState *s = opaque;
......
...@@ -1453,10 +1453,11 @@ static void qxl_hw_text_update(void *opaque, console_ch_t *chardata) ...@@ -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; 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) { if (running) {
/* /*
......
...@@ -217,7 +217,7 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type) ...@@ -217,7 +217,7 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type)
r->status |= SCSI_REQ_STATUS_RETRY | type; r->status |= SCSI_REQ_STATUS_RETRY | type;
bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read); bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
vm_stop(VMSTOP_DISKFULL); vm_stop(RSTATE_IO_ERROR);
} else { } else {
switch (error) { switch (error) {
case ENOMEM: case ENOMEM:
...@@ -338,7 +338,7 @@ static void scsi_dma_restart_bh(void *opaque) ...@@ -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; SCSIDiskState *s = opaque;
......
...@@ -77,7 +77,7 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error, ...@@ -77,7 +77,7 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
req->next = s->rq; req->next = s->rq;
s->rq = req; s->rq = req;
bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read); bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
vm_stop(VMSTOP_DISKFULL); vm_stop(RSTATE_IO_ERROR);
} else { } else {
virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR); virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
bdrv_acct_done(s->bs, &req->acct); bdrv_acct_done(s->bs, &req->acct);
...@@ -439,7 +439,8 @@ static void virtio_blk_dma_restart_bh(void *opaque) ...@@ -439,7 +439,8 @@ static void virtio_blk_dma_restart_bh(void *opaque)
virtio_submit_multiwrite(s->bs, &mrb); 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; VirtIOBlock *s = opaque;
......
...@@ -847,7 +847,7 @@ void virtio_cleanup(VirtIODevice *vdev) ...@@ -847,7 +847,7 @@ void virtio_cleanup(VirtIODevice *vdev)
g_free(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; VirtIODevice *vdev = opaque;
bool backend_run = running && (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK); bool backend_run = running && (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK);
...@@ -880,7 +880,7 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id, ...@@ -880,7 +880,7 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
vdev->queue_sel = 0; vdev->queue_sel = 0;
vdev->config_vector = VIRTIO_NO_VECTOR; vdev->config_vector = VIRTIO_NO_VECTOR;
vdev->vq = g_malloc0(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX); vdev->vq = g_malloc0(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX);
vdev->vm_running = vm_running; vdev->vm_running = runstate_is_running();
for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
vdev->vq[i].vector = VIRTIO_NO_VECTOR; vdev->vq[i].vector = VIRTIO_NO_VECTOR;
vdev->vq[i].vdev = vdev; vdev->vq[i].vdev = vdev;
......
...@@ -132,7 +132,7 @@ void watchdog_perform_action(void) ...@@ -132,7 +132,7 @@ void watchdog_perform_action(void)
case WDT_PAUSE: /* same as 'stop' command in monitor */ case WDT_PAUSE: /* same as 'stop' command in monitor */
watchdog_mon_event("pause"); watchdog_mon_event("pause");
vm_stop(VMSTOP_WATCHDOG); vm_stop(RSTATE_WATCHDOG);
break; break;
case WDT_DEBUG: case WDT_DEBUG:
......
...@@ -1014,7 +1014,7 @@ int kvm_cpu_exec(CPUState *env) ...@@ -1014,7 +1014,7 @@ int kvm_cpu_exec(CPUState *env)
if (ret < 0) { if (ret < 0) {
cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE); cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE);
vm_stop(VMSTOP_PANIC); vm_stop(RSTATE_PANICKED);
} }
env->exit_request = 0; env->exit_request = 0;
......
...@@ -70,10 +70,11 @@ void process_incoming_migration(QEMUFile *f) ...@@ -70,10 +70,11 @@ void process_incoming_migration(QEMUFile *f)
qemu_announce_self(); qemu_announce_self();
DPRINTF("successfully loaded vm state\n"); DPRINTF("successfully loaded vm state\n");
incoming_expected = false; if (autostart) {
if (autostart)
vm_start(); vm_start();
} else {
runstate_set(RSTATE_PRE_LAUNCH);
}
} }
int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data) int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
...@@ -371,10 +372,10 @@ void migrate_fd_put_ready(void *opaque) ...@@ -371,10 +372,10 @@ void migrate_fd_put_ready(void *opaque)
DPRINTF("iterate\n"); DPRINTF("iterate\n");
if (qemu_savevm_state_iterate(s->mon, s->file) == 1) { if (qemu_savevm_state_iterate(s->mon, s->file) == 1) {
int state; int state;
int old_vm_running = vm_running; int old_vm_running = runstate_is_running();
DPRINTF("done iterating\n"); DPRINTF("done iterating\n");
vm_stop(VMSTOP_MIGRATE); vm_stop(RSTATE_PRE_MIGRATE);
if ((qemu_savevm_state_complete(s->mon, s->file)) < 0) { if ((qemu_savevm_state_complete(s->mon, s->file)) < 0) {
if (old_vm_running) { if (old_vm_running) {
...@@ -390,6 +391,9 @@ void migrate_fd_put_ready(void *opaque) ...@@ -390,6 +391,9 @@ void migrate_fd_put_ready(void *opaque)
} }
state = MIG_STATE_ERROR; state = MIG_STATE_ERROR;
} }
if (state == MIG_STATE_COMPLETED) {
runstate_set(RSTATE_POST_MIGRATE);
}
s->state = state; s->state = state;
notifier_list_notify(&migration_state_notifiers, NULL); notifier_list_notify(&migration_state_notifiers, NULL);
} }
......
...@@ -1293,7 +1293,7 @@ static void do_singlestep(Monitor *mon, const QDict *qdict) ...@@ -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) static int do_stop(Monitor *mon, const QDict *qdict, QObject **ret_data)
{ {
vm_stop(VMSTOP_USER); vm_stop(RSTATE_PAUSED);
return 0; return 0;
} }
...@@ -1311,10 +1311,15 @@ static int do_cont(Monitor *mon, const QDict *qdict, QObject **ret_data) ...@@ -1311,10 +1311,15 @@ static int do_cont(Monitor *mon, const QDict *qdict, QObject **ret_data)
{ {
struct bdrv_iterate_context context = { mon, 0 }; struct bdrv_iterate_context context = { mon, 0 };
if (incoming_expected) { if (runstate_check(RSTATE_IN_MIGRATE)) {
qerror_report(QERR_MIGRATION_EXPECTED); qerror_report(QERR_MIGRATION_EXPECTED);
return -1; return -1;
} else if (runstate_check(RSTATE_PANICKED) ||
runstate_check(RSTATE_SHUTDOWN)) {
qerror_report(QERR_RESET_REQUIRED);
return -1;
} }
bdrv_iterate(encrypted_bdrv_it, &context); bdrv_iterate(encrypted_bdrv_it, &context);
/* only resume the vm if all keys are set and valid */ /* only resume the vm if all keys are set and valid */
if (!context.err) { if (!context.err) {
...@@ -2613,6 +2618,7 @@ static int do_inject_nmi(Monitor *mon, const QDict *qdict, QObject **ret_data) ...@@ -2613,6 +2618,7 @@ static int do_inject_nmi(Monitor *mon, const QDict *qdict, QObject **ret_data)
static void do_info_status_print(Monitor *mon, const QObject *data) static void do_info_status_print(Monitor *mon, const QObject *data)
{ {
QDict *qdict; QDict *qdict;
const char *status;
qdict = qobject_to_qdict(data); qdict = qobject_to_qdict(data);
...@@ -2626,13 +2632,17 @@ static void do_info_status_print(Monitor *mon, const QObject *data) ...@@ -2626,13 +2632,17 @@ static void do_info_status_print(Monitor *mon, const QObject *data)
monitor_printf(mon, "paused"); monitor_printf(mon, "paused");
} }
status = qdict_get_str(qdict, "status");
if (strcmp(status, "paused") && strcmp(status, "running")) {
monitor_printf(mon, " (%s)", status);
}
monitor_printf(mon, "\n"); monitor_printf(mon, "\n");
} }
static void do_info_status(Monitor *mon, QObject **ret_data) static void do_info_status(Monitor *mon, QObject **ret_data)
{ {
*ret_data = qobject_from_jsonf("{ 'running': %i, 'singlestep': %i }", *ret_data = qobject_from_jsonf("{ 'running': %i, 'singlestep': %i, 'status': %s }", runstate_is_running(), singlestep, runstate_as_string());
vm_running, singlestep);
} }
static qemu_acl *find_acl(Monitor *mon, const char *name) static qemu_acl *find_acl(Monitor *mon, const char *name)
...@@ -2825,10 +2835,10 @@ static int do_closefd(Monitor *mon, const QDict *qdict, QObject **ret_data) ...@@ -2825,10 +2835,10 @@ static int do_closefd(Monitor *mon, const QDict *qdict, QObject **ret_data)
static void do_loadvm(Monitor *mon, const QDict *qdict) static void do_loadvm(Monitor *mon, const QDict *qdict)
{ {
int saved_vm_running = vm_running; int saved_vm_running = runstate_is_running();
const char *name = qdict_get_str(qdict, "name"); const char *name = qdict_get_str(qdict, "name");
vm_stop(VMSTOP_LOADVM); vm_stop(RSTATE_RESTORE);
if (load_vmstate(name) == 0 && saved_vm_running) { if (load_vmstate(name) == 0 && saved_vm_running) {
vm_start(); vm_start();
......
...@@ -230,7 +230,7 @@ static void icount_adjust(void) ...@@ -230,7 +230,7 @@ static void icount_adjust(void)
int64_t delta; int64_t delta;
static int64_t last_delta; static int64_t last_delta;
/* If the VM is not running, then do nothing. */ /* If the VM is not running, then do nothing. */
if (!vm_running) if (!runstate_is_running())
return; return;
cur_time = cpu_get_clock(); cur_time = cpu_get_clock();
...@@ -388,7 +388,7 @@ static void icount_warp_rt(void *opaque) ...@@ -388,7 +388,7 @@ static void icount_warp_rt(void *opaque)
return; return;
} }
if (vm_running) { if (runstate_is_running()) {
int64_t clock = qemu_get_clock_ns(rt_clock); int64_t clock = qemu_get_clock_ns(rt_clock);
int64_t warp_delta = clock - vm_clock_warp_start; int64_t warp_delta = clock - vm_clock_warp_start;
if (use_icount == 1) { if (use_icount == 1) {
...@@ -710,7 +710,7 @@ void qemu_run_all_timers(void) ...@@ -710,7 +710,7 @@ void qemu_run_all_timers(void)
} }
/* vm time timers */ /* vm time timers */
if (vm_running) { if (runstate_is_running()) {
qemu_run_timers(vm_clock); qemu_run_timers(vm_clock);
} }
...@@ -1116,7 +1116,8 @@ static void win32_rearm_timer(struct qemu_alarm_timer *t) ...@@ -1116,7 +1116,8 @@ static void win32_rearm_timer(struct qemu_alarm_timer *t)
#endif /* _WIN32 */ #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) if (running)
qemu_rearm_alarm_timer((struct qemu_alarm_timer *) opaque); qemu_rearm_alarm_timer((struct qemu_alarm_timer *) opaque);
......
...@@ -193,6 +193,10 @@ static const QErrorStringTable qerror_table[] = { ...@@ -193,6 +193,10 @@ static const QErrorStringTable qerror_table[] = {
.error_fmt = QERR_QMP_EXTRA_MEMBER, .error_fmt = QERR_QMP_EXTRA_MEMBER,
.desc = "QMP input object member '%(member)' is unexpected", .desc = "QMP input object member '%(member)' is unexpected",
}, },
{
.error_fmt = QERR_RESET_REQUIRED,
.desc = "Resetting the Virtual Machine is required",
},
{ {
.error_fmt = QERR_SET_PASSWD_FAILED, .error_fmt = QERR_SET_PASSWD_FAILED,
.desc = "Could not set password", .desc = "Could not set password",
......
...@@ -163,6 +163,9 @@ QError *qobject_to_qerror(const QObject *obj); ...@@ -163,6 +163,9 @@ QError *qobject_to_qerror(const QObject *obj);
#define QERR_QMP_EXTRA_MEMBER \ #define QERR_QMP_EXTRA_MEMBER \
"{ 'class': 'QMPExtraInputObjectMember', 'data': { 'member': %s } }" "{ 'class': 'QMPExtraInputObjectMember', 'data': { 'member': %s } }"
#define QERR_RESET_REQUIRED \
"{ 'class': 'ResetRequired', 'data': {} }"
#define QERR_SET_PASSWD_FAILED \ #define QERR_SET_PASSWD_FAILED \
"{ 'class': 'SetPasswdFailed', 'data': {} }" "{ 'class': 'SetPasswdFailed', 'data': {} }"
......
...@@ -1573,11 +1573,28 @@ Return a json-object with the following information: ...@@ -1573,11 +1573,28 @@ Return a json-object with the following information:
- "running": true if the VM is running, or false if it is paused (json-bool) - "running": true if the VM is running, or false if it is paused (json-bool)
- "singlestep": true if the VM is in single step mode, - "singlestep": true if the VM is in single step mode,
false otherwise (json-bool) false otherwise (json-bool)
- "status": one of the following values (json-string)
"debug" - QEMU is running on a debugger
"inmigrate" - guest is paused waiting for an incoming migration
"internal-error" - An internal error that prevents further guest
execution has occurred
"io-error" - the last IOP has failed and the device is configured
to pause on I/O errors
"paused" - guest has been paused via the 'stop' command
"postmigrate" - guest is paused following a successful 'migrate'
"prelaunch" - QEMU was started with -S and guest has not started
"finish-migrate" - guest is paused to finish the migration process
"restore-vm" - guest is paused to restore VM state
"running" - guest is actively running
"save-vm" - guest is paused to save the VM state
"shutdown" - guest is shut down (and -no-shutdown is in use)
"watchdog" - the watchdog action is configured to pause and
has been triggered
Example: Example:
-> { "execute": "query-status" } -> { "execute": "query-status" }
<- { "return": { "running": true, "singlestep": false } } <- { "return": { "running": true, "singlestep": false, "status": "running" } }
EQMP EQMP
......
...@@ -1602,8 +1602,8 @@ static int qemu_savevm_state(Monitor *mon, QEMUFile *f) ...@@ -1602,8 +1602,8 @@ static int qemu_savevm_state(Monitor *mon, QEMUFile *f)
int saved_vm_running; int saved_vm_running;
int ret; int ret;
saved_vm_running = vm_running; saved_vm_running = runstate_is_running();
vm_stop(VMSTOP_SAVEVM); vm_stop(RSTATE_SAVEVM);
if (qemu_savevm_state_blocked(mon)) { if (qemu_savevm_state_blocked(mon)) {
ret = -EINVAL; ret = -EINVAL;
...@@ -1931,8 +1931,8 @@ void do_savevm(Monitor *mon, const QDict *qdict) ...@@ -1931,8 +1931,8 @@ void do_savevm(Monitor *mon, const QDict *qdict)
return; return;
} }
saved_vm_running = vm_running; saved_vm_running = runstate_is_running();
vm_stop(VMSTOP_SAVEVM); vm_stop(RSTATE_SAVEVM);
memset(sn, 0, sizeof(*sn)); memset(sn, 0, sizeof(*sn));
......
...@@ -9,42 +9,56 @@ ...@@ -9,42 +9,56 @@
#include "notify.h" #include "notify.h"
/* vl.c */ /* vl.c */
typedef enum {
RSTATE_NO_STATE,
RSTATE_DEBUG, /* qemu is running under gdb */
RSTATE_IN_MIGRATE, /* paused waiting for an incoming migration */
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_POST_MIGRATE, /* paused following a successful migration */
RSTATE_PRE_LAUNCH, /* qemu was started with -S and haven't started */
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 */
RSTATE_MAX
} RunState;
extern const char *bios_name; extern const char *bios_name;
extern int vm_running;
extern const char *qemu_name; extern const char *qemu_name;
extern uint8_t qemu_uuid[]; extern uint8_t qemu_uuid[];
int qemu_uuid_parse(const char *str, uint8_t *uuid); 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" #define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
void runstate_init(void);
bool runstate_check(RunState state);
void runstate_set(RunState new_state);
int runstate_is_running(void);
const char *runstate_as_string(void);
typedef struct vm_change_state_entry VMChangeStateEntry; 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, VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
void *opaque); void *opaque);
void qemu_del_vm_change_state_handler(VMChangeStateEntry *e); void qemu_del_vm_change_state_handler(VMChangeStateEntry *e);
void vm_state_notify(int running, RunState state);
#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
#define VMRESET_SILENT false #define VMRESET_SILENT false
#define VMRESET_REPORT true #define VMRESET_REPORT true
void vm_start(void); void vm_start(void);
void vm_stop(int reason); void vm_stop(RunState state);
void qemu_system_reset_request(void); void qemu_system_reset_request(void);
void qemu_system_shutdown_request(void); void qemu_system_shutdown_request(void);
void qemu_system_powerdown_request(void); void qemu_system_powerdown_request(void);
void qemu_system_debug_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_shutdown_requested_get(void);
int qemu_reset_requested_get(void); int qemu_reset_requested_get(void);
int qemu_shutdown_requested(void); int qemu_shutdown_requested(void);
......
...@@ -334,7 +334,7 @@ static int kvm_inject_mce_oldstyle(CPUState *env) ...@@ -334,7 +334,7 @@ static int kvm_inject_mce_oldstyle(CPUState *env)
return 0; 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; CPUState *env = opaque;
...@@ -1130,7 +1130,7 @@ static int kvm_get_msrs(CPUState *env) ...@@ -1130,7 +1130,7 @@ static int kvm_get_msrs(CPUState *env)
if (!env->tsc_valid) { if (!env->tsc_valid) {
msrs[n++].index = MSR_IA32_TSC; msrs[n++].index = MSR_IA32_TSC;
env->tsc_valid = !vm_running; env->tsc_valid = !runstate_is_running();
} }
#ifdef TARGET_X86_64 #ifdef TARGET_X86_64
......
...@@ -409,7 +409,7 @@ static void sdl_update_caption(void) ...@@ -409,7 +409,7 @@ static void sdl_update_caption(void)
char icon_title[1024]; char icon_title[1024];
const char *status = ""; const char *status = "";
if (!vm_running) if (!runstate_is_running())
status = " [Stopped]"; status = " [Stopped]";
else if (gui_grab) { else if (gui_grab) {
if (alt_grab) if (alt_grab)
...@@ -853,8 +853,8 @@ static void sdl_refresh(DisplayState *ds) ...@@ -853,8 +853,8 @@ static void sdl_refresh(DisplayState *ds)
{ {
SDL_Event ev1, *ev = &ev1; SDL_Event ev1, *ev = &ev1;
if (last_vm_running != vm_running) { if (last_vm_running != runstate_is_running()) {
last_vm_running = vm_running; last_vm_running = runstate_is_running();
sdl_update_caption(); sdl_update_caption();
} }
......
...@@ -255,7 +255,8 @@ void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd) ...@@ -255,7 +255,8 @@ void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd)
qemu_spice_destroy_primary_surface(ssd, 0, QXL_SYNC); 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; SimpleSpiceDisplay *ssd = opaque;
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "qemu-thread.h" #include "qemu-thread.h"
#include "console.h" #include "console.h"
#include "pflib.h" #include "pflib.h"
#include "sysemu.h"
#define NUM_MEMSLOTS 8 #define NUM_MEMSLOTS 8
#define MEMSLOT_GENERATION_BITS 8 #define MEMSLOT_GENERATION_BITS 8
...@@ -88,7 +89,8 @@ void qemu_spice_destroy_update(SimpleSpiceDisplay *sdpy, SimpleSpiceUpdate *upda ...@@ -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_memslot(SimpleSpiceDisplay *ssd);
void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd); void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd);
void qemu_spice_destroy_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_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds);
void qemu_spice_display_update(SimpleSpiceDisplay *ssd, void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
......
...@@ -185,9 +185,7 @@ int mem_prealloc = 0; /* force preallocation of physical target memory */ ...@@ -185,9 +185,7 @@ int mem_prealloc = 0; /* force preallocation of physical target memory */
#endif #endif
int nb_nics; int nb_nics;
NICInfo nd_table[MAX_NICS]; NICInfo nd_table[MAX_NICS];
int vm_running;
int autostart; int autostart;
int incoming_expected; /* Started with -incoming and waiting for incoming */
static int rtc_utc = 1; static int rtc_utc = 1;
static int rtc_date_offset = -1; /* -1 means no change */ static int rtc_date_offset = -1; /* -1 means no change */
QEMUClock *rtc_clock; QEMUClock *rtc_clock;
...@@ -322,6 +320,120 @@ static int default_driver_check(QemuOpts *opts, void *opaque) ...@@ -322,6 +320,120 @@ static int default_driver_check(QemuOpts *opts, void *opaque)
return 0; return 0;
} }
/***********************************************************/
/* QEMU state */
static RunState current_run_state = RSTATE_NO_STATE;
typedef struct {
RunState from;
RunState to;
} RunStateTransition;
static const RunStateTransition runstate_transitions_def[] = {
/* from -> to */
{ RSTATE_NO_STATE, RSTATE_RUNNING },
{ RSTATE_NO_STATE, RSTATE_IN_MIGRATE },
{ RSTATE_NO_STATE, RSTATE_PRE_LAUNCH },
{ RSTATE_DEBUG, RSTATE_RUNNING },
{ RSTATE_IN_MIGRATE, RSTATE_RUNNING },
{ RSTATE_IN_MIGRATE, RSTATE_PRE_LAUNCH },
{ RSTATE_PANICKED, RSTATE_PAUSED },
{ RSTATE_IO_ERROR, RSTATE_RUNNING },
{ RSTATE_PAUSED, RSTATE_RUNNING },
{ RSTATE_POST_MIGRATE, RSTATE_RUNNING },
{ RSTATE_PRE_LAUNCH, RSTATE_RUNNING },
{ RSTATE_PRE_LAUNCH, RSTATE_POST_MIGRATE },
{ RSTATE_PRE_MIGRATE, RSTATE_RUNNING },
{ RSTATE_PRE_MIGRATE, RSTATE_POST_MIGRATE },
{ RSTATE_RESTORE, RSTATE_RUNNING },
{ RSTATE_RUNNING, RSTATE_DEBUG },
{ RSTATE_RUNNING, RSTATE_PANICKED },
{ RSTATE_RUNNING, RSTATE_IO_ERROR },
{ RSTATE_RUNNING, RSTATE_PAUSED },
{ RSTATE_RUNNING, RSTATE_PRE_MIGRATE },
{ RSTATE_RUNNING, RSTATE_RESTORE },
{ RSTATE_RUNNING, RSTATE_SAVEVM },
{ RSTATE_RUNNING, RSTATE_SHUTDOWN },
{ RSTATE_RUNNING, RSTATE_WATCHDOG },
{ RSTATE_SAVEVM, RSTATE_RUNNING },
{ RSTATE_SHUTDOWN, RSTATE_PAUSED },
{ RSTATE_WATCHDOG, RSTATE_RUNNING },
{ RSTATE_MAX, RSTATE_MAX },
};
static bool runstate_valid_transitions[RSTATE_MAX][RSTATE_MAX];
static const char *const runstate_name_tbl[RSTATE_MAX] = {
[RSTATE_DEBUG] = "debug",
[RSTATE_IN_MIGRATE] = "incoming-migration",
[RSTATE_PANICKED] = "internal-error",
[RSTATE_IO_ERROR] = "io-error",
[RSTATE_PAUSED] = "paused",
[RSTATE_POST_MIGRATE] = "post-migrate",
[RSTATE_PRE_LAUNCH] = "prelaunch",
[RSTATE_PRE_MIGRATE] = "finish-migrate",
[RSTATE_RESTORE] = "restore-vm",
[RSTATE_RUNNING] = "running",
[RSTATE_SAVEVM] = "save-vm",
[RSTATE_SHUTDOWN] = "shutdown",
[RSTATE_WATCHDOG] = "watchdog",
};
bool runstate_check(RunState state)
{
return current_run_state == state;
}
void runstate_init(void)
{
const RunStateTransition *p;
memset(&runstate_valid_transitions, 0, sizeof(runstate_valid_transitions));
for (p = &runstate_transitions_def[0]; p->from != RSTATE_MAX; p++) {
runstate_valid_transitions[p->from][p->to] = true;
}
}
/* This function will abort() on invalid state transitions */
void runstate_set(RunState new_state)
{
if (new_state >= RSTATE_MAX ||
!runstate_valid_transitions[current_run_state][new_state]) {
fprintf(stderr, "invalid runstate transition\n");
abort();
}
current_run_state = new_state;
}
const char *runstate_as_string(void)
{
assert(current_run_state > RSTATE_NO_STATE &&
current_run_state < RSTATE_MAX);
return runstate_name_tbl[current_run_state];
}
int runstate_is_running(void)
{
return runstate_check(RSTATE_RUNNING);
}
/***********************************************************/ /***********************************************************/
/* real time host monotonic timer */ /* real time host monotonic timer */
...@@ -1145,23 +1257,23 @@ void qemu_del_vm_change_state_handler(VMChangeStateEntry *e) ...@@ -1145,23 +1257,23 @@ void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
g_free (e); g_free (e);
} }
void vm_state_notify(int running, int reason) void vm_state_notify(int running, RunState state)
{ {
VMChangeStateEntry *e; 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) { 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);
} }
} }
void vm_start(void) void vm_start(void)
{ {
if (!vm_running) { if (!runstate_is_running()) {
cpu_enable_ticks(); cpu_enable_ticks();
vm_running = 1; runstate_set(RSTATE_RUNNING);
vm_state_notify(1, 0); vm_state_notify(1, RSTATE_RUNNING);
resume_all_vcpus(); resume_all_vcpus();
monitor_protocol_event(QEVENT_RESUME, NULL); monitor_protocol_event(QEVENT_RESUME, NULL);
} }
...@@ -1182,7 +1294,7 @@ static int shutdown_requested, shutdown_signal = -1; ...@@ -1182,7 +1294,7 @@ static int shutdown_requested, shutdown_signal = -1;
static pid_t shutdown_pid; static pid_t shutdown_pid;
static int powerdown_requested; static int powerdown_requested;
static int debug_requested; static int debug_requested;
static int vmstop_requested; static RunState vmstop_requested = RSTATE_NO_STATE;
int qemu_shutdown_requested_get(void) int qemu_shutdown_requested_get(void)
{ {
...@@ -1238,11 +1350,11 @@ static int qemu_debug_requested(void) ...@@ -1238,11 +1350,11 @@ static int qemu_debug_requested(void)
return r; return r;
} }
static int qemu_vmstop_requested(void) static RunState qemu_vmstop_requested(void)
{ {
int r = vmstop_requested; RunState s = vmstop_requested;
vmstop_requested = 0; vmstop_requested = RSTATE_NO_STATE;
return r; return s;
} }
void qemu_register_reset(QEMUResetHandler *func, void *opaque) void qemu_register_reset(QEMUResetHandler *func, void *opaque)
...@@ -1318,9 +1430,9 @@ void qemu_system_debug_request(void) ...@@ -1318,9 +1430,9 @@ void qemu_system_debug_request(void)
qemu_notify_event(); 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(); qemu_notify_event();
} }
...@@ -1470,13 +1582,13 @@ static void main_loop(void) ...@@ -1470,13 +1582,13 @@ static void main_loop(void)
#endif #endif
if (qemu_debug_requested()) { if (qemu_debug_requested()) {
vm_stop(VMSTOP_DEBUG); vm_stop(RSTATE_DEBUG);
} }
if (qemu_shutdown_requested()) { if (qemu_shutdown_requested()) {
qemu_kill_report(); qemu_kill_report();
monitor_protocol_event(QEVENT_SHUTDOWN, NULL); monitor_protocol_event(QEVENT_SHUTDOWN, NULL);
if (no_shutdown) { if (no_shutdown) {
vm_stop(VMSTOP_SHUTDOWN); vm_stop(RSTATE_SHUTDOWN);
} else } else
break; break;
} }
...@@ -1485,6 +1597,10 @@ static void main_loop(void) ...@@ -1485,6 +1597,10 @@ static void main_loop(void)
cpu_synchronize_all_states(); cpu_synchronize_all_states();
qemu_system_reset(VMRESET_REPORT); qemu_system_reset(VMRESET_REPORT);
resume_all_vcpus(); resume_all_vcpus();
if (runstate_check(RSTATE_PANICKED) ||
runstate_check(RSTATE_SHUTDOWN)) {
runstate_set(RSTATE_PAUSED);
}
} }
if (qemu_powerdown_requested()) { if (qemu_powerdown_requested()) {
monitor_protocol_event(QEVENT_POWERDOWN, NULL); monitor_protocol_event(QEVENT_POWERDOWN, NULL);
...@@ -2203,6 +2319,8 @@ int main(int argc, char **argv, char **envp) ...@@ -2203,6 +2319,8 @@ int main(int argc, char **argv, char **envp)
g_mem_set_vtable(&mem_trace); g_mem_set_vtable(&mem_trace);
g_thread_init(NULL); g_thread_init(NULL);
runstate_init();
init_clocks(); init_clocks();
qemu_cache_utils_init(envp); qemu_cache_utils_init(envp);
...@@ -2953,7 +3071,6 @@ int main(int argc, char **argv, char **envp) ...@@ -2953,7 +3071,6 @@ int main(int argc, char **argv, char **envp)
break; break;
case QEMU_OPTION_incoming: case QEMU_OPTION_incoming:
incoming = optarg; incoming = optarg;
incoming_expected = true;
break; break;
case QEMU_OPTION_nodefaults: case QEMU_OPTION_nodefaults:
default_serial = 0; default_serial = 0;
...@@ -3439,6 +3556,7 @@ int main(int argc, char **argv, char **envp) ...@@ -3439,6 +3556,7 @@ int main(int argc, char **argv, char **envp)
} }
if (incoming) { if (incoming) {
runstate_set(RSTATE_IN_MIGRATE);
int ret = qemu_start_incoming_migration(incoming); int ret = qemu_start_incoming_migration(incoming);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "Migration failed. Exit code %s(%d), exiting.\n", fprintf(stderr, "Migration failed. Exit code %s(%d), exiting.\n",
...@@ -3447,6 +3565,8 @@ int main(int argc, char **argv, char **envp) ...@@ -3447,6 +3565,8 @@ int main(int argc, char **argv, char **envp)
} }
} else if (autostart) { } else if (autostart) {
vm_start(); vm_start();
} else {
runstate_set(RSTATE_PRE_LAUNCH);
} }
os_setup_post(); os_setup_post();
......
...@@ -736,7 +736,7 @@ static void cpu_handle_ioreq(void *opaque) ...@@ -736,7 +736,7 @@ static void cpu_handle_ioreq(void *opaque)
* guest resumes and does a hlt with interrupts disabled which * guest resumes and does a hlt with interrupts disabled which
* causes Xen to powerdown the domain. * causes Xen to powerdown the domain.
*/ */
if (vm_running) { if (runstate_is_running()) {
if (qemu_shutdown_requested_get()) { if (qemu_shutdown_requested_get()) {
destroy_hvm_domain(); destroy_hvm_domain();
} }
...@@ -846,7 +846,8 @@ static void xen_main_loop_prepare(XenIOState *state) ...@@ -846,7 +846,8 @@ static void xen_main_loop_prepare(XenIOState *state)
/* Initialise Xen */ /* 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) { if (running) {
/* record state running */ /* record state running */
...@@ -854,11 +855,12 @@ static void xen_change_state_handler(void *opaque, int running, int reason) ...@@ -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) { if (running) {
xen_main_loop_prepare(state); xen_main_loop_prepare(xstate);
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册