All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
To: Juan Quintela <quintela@redhat.com>
Cc: kwolf@redhat.com, qemu-devel@nongnu.org, laine@redhat.com,
	lcapitulino@redhat.com
Subject: Re: [Qemu-devel] [PATCH 5/7] migration: create now section to store global state
Date: Mon, 20 Oct 2014 11:52:03 +0100	[thread overview]
Message-ID: <20141020105200.GG2517@work-vm> (raw)
In-Reply-To: <1413359710-2799-6-git-send-email-quintela@redhat.com>

* Juan Quintela (quintela@redhat.com) wrote:
> This includes a new section that for now just stores the current qemu state.
> 
> Right now, there are only one way to control what is the state of the
> target after migration.
> 
> - If you run the target qemu with -S, it would start stopped.
> - If you run the target qemu without -S, it would run just after migration finishes.
> 
> The problem here is what happens if we start the target without -S and
> there happens one error during migration that puts current state as
> -EIO.  Migration would ends (notice that the error happend doing block
> IO, network IO, i.e. nothing related with migration), and when
> migration finish, we would just "continue" running on destination,
> probably hanging the guest/corruption data, whatever.

A couple of questions:
   1) Does the ordering of loading this state matter - lets say that the source
     was in an error state, then all the other device states get loaded and then
     it loads your global_state which tells the destination is in error - is that
     too late ? Could the device emulation have already started doing some IO
     or something to the devices which it wouldn't have done if it knew there was
     already a problem?

   2) What's the advantage of the optional section over using the 'command' sections
      I use in postcopy; http://lists.gnu.org/archive/html/qemu-devel/2014-10/msg00337.html ?

Dave

> Signed-off-by: Juan Quintela <quintela@redhat.com>
> ---
>  include/migration/migration.h |  4 ++
>  migration.c                   | 88 +++++++++++++++++++++++++++++++++++++++++--
>  vl.c                          |  1 +
>  3 files changed, 90 insertions(+), 3 deletions(-)
> 
> diff --git a/include/migration/migration.h b/include/migration/migration.h
> index 3cb5ba8..bc1069b 100644
> --- a/include/migration/migration.h
> +++ b/include/migration/migration.h
> @@ -174,4 +174,8 @@ size_t ram_control_save_page(QEMUFile *f, ram_addr_t block_offset,
>                               ram_addr_t offset, size_t size,
>                               int *bytes_sent);
> 
> +void register_global_state(void);
> +void global_state_store(void);
> +char *global_state_get_runstate(void);
> +
>  #endif
> diff --git a/migration.c b/migration.c
> index 8d675b3..6f7e50e 100644
> --- a/migration.c
> +++ b/migration.c
> @@ -112,10 +112,20 @@ static void process_incoming_migration_co(void *opaque)
>          exit(EXIT_FAILURE);
>      }
> 
> -    if (autostart) {
> +    /* runstate == "" means that we haven't received it through the
> +     * wire, so we obey autostart.  runstate == runing means that we
> +     * need to run it, we need to make sure that we do it after
> +     * everything else has finished.  Every other state change is done
> +     * at the post_load function */
> +
> +    if (strcmp(global_state_get_runstate(), "running") == 0 ) {
>          vm_start();
> -    } else {
> -        runstate_set(RUN_STATE_PAUSED);
> +    } else if (strcmp(global_state_get_runstate(), "") == 0 ) {
> +        if (autostart) {
> +            vm_start();
> +        } else {
> +            runstate_set(RUN_STATE_PAUSED);
> +        }
>      }
>  }
> 
> @@ -608,6 +618,7 @@ static void *migration_thread(void *opaque)
>                  qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
>                  old_vm_running = runstate_is_running();
> 
> +                global_state_store();
>                  ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
>                  if (ret >= 0) {
>                      qemu_file_set_rate_limit(s->file, INT64_MAX);
> @@ -699,3 +710,74 @@ void migrate_fd_connect(MigrationState *s)
>      qemu_thread_create(&s->thread, "migration", migration_thread, s,
>                         QEMU_THREAD_JOINABLE);
>  }
> +
> +typedef struct {
> +    int32_t size;
> +    uint8_t runstate[100];
> +} GlobalState;
> +
> +static GlobalState global_state;
> +
> +void global_state_store(void)
> +{
> +    if (runstate_store((char*)global_state.runstate,
> +                       sizeof(global_state.runstate)) == -1) {
> +        printf("Runstate is too big\n");
> +        exit(-1);
> +    }
> +}
> +
> +char *global_state_get_runstate(void)
> +{
> +    return (char *)global_state.runstate;
> +}
> +
> +static int global_state_post_load(void *opaque, int version_id)
> +{
> +    GlobalState *s = opaque;
> +    int ret = 0;
> +    char *runstate = (char*)s->runstate;
> +
> +    printf("loaded state: %s\n", runstate);
> +
> +    if (strcmp(runstate, "running") != 0) {
> +
> +        RunState r = runstate_index(runstate);
> +
> +        if (r == -1) {
> +            printf("Unknown received state %s\n", runstate);
> +            return -1;
> +        }
> +        ret = vm_stop_force_state(r);
> +    }
> +
> +   return ret;
> +}
> +
> +static void global_state_pre_save(void *opaque)
> +{
> +    GlobalState *s = opaque;
> +
> +    s->size = strlen((char*)s->runstate) + 1;
> +    printf("saved state: %s\n", s->runstate);
> +}
> +
> +static const VMStateDescription vmstate_globalstate = {
> +    .name = "globalstate",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .post_load = global_state_post_load,
> +    .pre_save = global_state_pre_save,
> +    .fields = (VMStateField[]) {
> +        VMSTATE_INT32(size, GlobalState),
> +        VMSTATE_BUFFER(runstate, GlobalState),
> +        VMSTATE_END_OF_LIST()
> +    },
> +};
> +
> +void register_global_state(void)
> +{
> +    /* We would use it independently that we receive it */
> +    strcpy((char*)&global_state.runstate, "");
> +    vmstate_register(NULL, 0, &vmstate_globalstate, &global_state);
> +}
> diff --git a/vl.c b/vl.c
> index 1788b6a..75e855e 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -4511,6 +4511,7 @@ int main(int argc, char **argv, char **envp)
>          return 0;
>      }
> 
> +    register_global_state();
>      if (incoming) {
>          Error *local_err = NULL;
>          qemu_start_incoming_migration(incoming, &local_err);
> -- 
> 2.1.0
> 
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

  reply	other threads:[~2014-10-20 10:52 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-15  7:55 [Qemu-devel] [RFC 0/7] Optional toplevel sections Juan Quintela
2014-10-15  7:55 ` [Qemu-devel] [PATCH 1/7] migration: Create optional sections Juan Quintela
2014-10-15  7:55 ` [Qemu-devel] [PATCH 2/7] runstate: Add runstate store Juan Quintela
2014-10-20 10:24   ` Dr. David Alan Gilbert
2014-10-20 10:52     ` Juan Quintela
2014-10-20 15:18       ` Eric Blake
2014-10-22 11:18         ` Dr. David Alan Gilbert
2014-10-22 11:40           ` Markus Armbruster
2014-10-22 15:52             ` Eric Blake
2014-10-15  7:55 ` [Qemu-devel] [PATCH 3/7] runstate: create runstate_index function Juan Quintela
2014-10-15  7:55 ` [Qemu-devel] [PATCH 4/7] runstate: migration allows more transitions now Juan Quintela
2014-10-15 14:42   ` Eric Blake
2014-10-15 15:50     ` Juan Quintela
2014-11-03 12:46   ` Amit Shah
2014-10-15  7:55 ` [Qemu-devel] [PATCH 5/7] migration: create now section to store global state Juan Quintela
2014-10-20 10:52   ` Dr. David Alan Gilbert [this message]
2014-10-20 11:11   ` Kevin Wolf
2014-10-15  7:55 ` [Qemu-devel] [PATCH 6/7] global_state: Make section optional Juan Quintela
2014-10-15  7:55 ` [Qemu-devel] [PATCH 7/7] vmstate: Create optional sections Juan Quintela
2014-10-15 14:45   ` Eric Blake
2014-10-15 14:57 ` [Qemu-devel] [RFC 0/7] Optional toplevel sections Eric Blake
2014-10-15 15:59   ` Juan Quintela
2014-10-15 16:37     ` Eric Blake
2014-10-17 13:41     ` Paolo Bonzini
2014-10-20 14:59       ` Dr. David Alan Gilbert
2014-10-20 11:29 ` Kevin Wolf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20141020105200.GG2517@work-vm \
    --to=dgilbert@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=laine@redhat.com \
    --cc=lcapitulino@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.