On Wed, Jul 27, 2011 at 9:42 PM, Luiz Capitulino <lcapitul...@redhat.com> wrote: > This function should be used when the VM is not supposed to resume > execution (eg. by issuing 'cont' monitor command). > > Today, we allow the user to resume execution even when: > > o the guest shuts down and -no-shutdown is used > o there's a kvm internal error > o loading the VM state with -loadvm or "loadvm" in the monitor fails > > I think only badness can happen from the cases above.
I'd suppose a system_reset should bring the system back to sanity and then clear vm_permanent_stopped (where's -ly?) except maybe for KVM internal error if that can't be recovered. Then it would not very permanent anymore, so the name would need adjusting. > > Another possible candidate is migration, that's, when the VM is > automatically stopped following a successful migration. > > Signed-off-by: Luiz Capitulino <lcapitul...@redhat.com> > --- > cpus.c | 7 +++++++ > kvm-all.c | 2 +- > monitor.c | 9 +++++++-- > qerror.c | 4 ++++ > qerror.h | 3 +++ > sysemu.h | 2 ++ > vl.c | 4 +++- > 7 files changed, 27 insertions(+), 4 deletions(-) > > diff --git a/cpus.c b/cpus.c > index 6bf4e3f..5a4a480 100644 > --- a/cpus.c > +++ b/cpus.c > @@ -535,6 +535,13 @@ static void qemu_tcg_init_cpu_signals(void) > } > #endif /* _WIN32 */ > > +void vm_stop_permanent(int reason) > +{ > + vm_stop(reason); > + assert(!vm_permanent_stopped); > + vm_permanent_stopped = 1; > +} > + > #ifndef CONFIG_IOTHREAD > int qemu_init_main_loop(void) > { > diff --git a/kvm-all.c b/kvm-all.c > index cbc2532..4d0ceb3 100644 > --- a/kvm-all.c > +++ b/kvm-all.c > @@ -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_permanent(VMSTOP_PANIC); > } > > env->exit_request = 0; > diff --git a/monitor.c b/monitor.c > index 718935b..86e146c 100644 > --- a/monitor.c > +++ b/monitor.c > @@ -1307,7 +1307,10 @@ static int do_cont(Monitor *mon, const QDict *qdict, > QObject **ret_data) > { > struct bdrv_iterate_context context = { mon, 0 }; > > - if (incoming_expected) { > + if (vm_permanent_stopped) { > + qerror_report(QERR_VM_PERMANENT_STOPPED); > + return -1; > + } else if (incoming_expected) { > qerror_report(QERR_MIGRATION_EXPECTED); > return -1; > } > @@ -2814,7 +2817,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_permanent_stopped = 1; > + } else if (saved_vm_running) { > vm_start(); > } > } > diff --git a/qerror.c b/qerror.c > index 69c1bc9..c91f763 100644 > --- a/qerror.c > +++ b/qerror.c > @@ -219,6 +219,10 @@ static const QErrorStringTable qerror_table[] = { > "supported by this qemu version: %(feature)", > }, > { > + .error_fmt = QERR_VM_PERMANENT_STOPPED, > + .desc = "The Virtual Machine is permanently stopped", > + }, > + { > .error_fmt = QERR_VNC_SERVER_FAILED, > .desc = "Could not start VNC server on %(target)", > }, > diff --git a/qerror.h b/qerror.h > index 8058456..c759172 100644 > --- a/qerror.h > +++ b/qerror.h > @@ -181,6 +181,9 @@ QError *qobject_to_qerror(const QObject *obj); > #define QERR_UNKNOWN_BLOCK_FORMAT_FEATURE \ > "{ 'class': 'UnknownBlockFormatFeature', 'data': { 'device': %s, > 'format': %s, 'feature': %s } }" > > +#define QERR_VM_PERMANENT_STOPPED \ > + "{ 'class': 'PermanentStopped', 'data': {} }" > + > #define QERR_VNC_SERVER_FAILED \ > "{ 'class': 'VNCServerFailed', 'data': { 'target': %s } }" > > diff --git a/sysemu.h b/sysemu.h > index d3013f5..af90fa3 100644 > --- a/sysemu.h > +++ b/sysemu.h > @@ -12,6 +12,7 @@ > extern const char *bios_name; > > extern int vm_running; > +extern int vm_permanent_stopped; > extern const char *qemu_name; > extern uint8_t qemu_uuid[]; > int qemu_uuid_parse(const char *str, uint8_t *uuid); > @@ -39,6 +40,7 @@ void qemu_del_vm_change_state_handler(VMChangeStateEntry > *e); > > void vm_start(void); > void vm_stop(int reason); > +void vm_stop_permanent(int reason); > > void qemu_system_reset_request(void); > void qemu_system_shutdown_request(void); > diff --git a/vl.c b/vl.c > index 4b6688b..96403ac 100644 > --- a/vl.c > +++ b/vl.c > @@ -186,6 +186,7 @@ NICInfo nd_table[MAX_NICS]; > int vm_running; > int autostart; > int incoming_expected; /* Started with -incoming and waiting for incoming */ > +int vm_permanent_stopped = 0; /* qemu will never resume if set */ > static int rtc_utc = 1; > static int rtc_date_offset = -1; /* -1 means no change */ > QEMUClock *rtc_clock; > @@ -1397,7 +1398,7 @@ static void main_loop(void) > qemu_kill_report(); > monitor_protocol_event(QEVENT_SHUTDOWN, NULL); > if (no_shutdown) { > - vm_stop(VMSTOP_SHUTDOWN); > + vm_stop_permanent(VMSTOP_SHUTDOWN); > } else > break; > } > @@ -3315,6 +3316,7 @@ int main(int argc, char **argv, char **envp) > qemu_system_reset(VMRESET_SILENT); > if (loadvm) { > if (load_vmstate(loadvm) < 0) { > + vm_permanent_stopped = 1; > autostart = 0; > } > } > -- > 1.7.6.347.g4db0d > > >