qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [RFC] Introduce vm_stop_permanent()


From: Blue Swirl
Subject: Re: [Qemu-devel] [RFC] Introduce vm_stop_permanent()
Date: Thu, 28 Jul 2011 00:44:58 +0300

On Wed, Jul 27, 2011 at 9:42 PM, Luiz Capitulino <address@hidden> 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 <address@hidden>
> ---
>  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
>
>
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]