qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH v5 02/17] migration: Create migration_ioc_proces


From: Daniel P. Berrange
Subject: Re: [Qemu-devel] [PATCH v5 02/17] migration: Create migration_ioc_process_incoming()
Date: Wed, 19 Jul 2017 14:38:29 +0100
User-agent: Mutt/1.8.3 (2017-05-23)

On Mon, Jul 17, 2017 at 03:42:23PM +0200, Juan Quintela wrote:
> We need to receive the ioc to be able to implement multifd.
> 
> Signed-off-by: Juan Quintela <address@hidden>
> ---
>  migration/channel.c   |  3 +--
>  migration/migration.c | 16 +++++++++++++---
>  migration/migration.h |  2 ++
>  3 files changed, 16 insertions(+), 5 deletions(-)
> 
> diff --git a/migration/channel.c b/migration/channel.c
> index 719055d..5b777ef 100644
> --- a/migration/channel.c
> +++ b/migration/channel.c
> @@ -36,8 +36,7 @@ gboolean migration_channel_process_incoming(QIOChannel *ioc)
>              error_report_err(local_err);
>          }
>      } else {
> -        QEMUFile *f = qemu_fopen_channel_input(ioc);
> -        migration_fd_process_incoming(f);
> +        return migration_ioc_process_incoming(ioc);
>      }
>      return FALSE; /* unregister */
>  }

This is going to break TLS with multi FD I'm afraid.


We have two code paths:

 1. Non-TLS

    event loop POLLIN on migration listener socket
     +-> socket_accept_incoming_migration()
          +-> migration_channel_process_incoming()
               +-> migration_ioc_process_incoming()
                    -> returns FALSE if all required FD channels are now present

 2. TLS

    event loop POLLIN on migration listener socket
     +-> socket_accept_incoming_migration()
          +-> migration_channel_process_incoming()
               +-> migration_tls_channel_process_incoming
                    -> Registers watch for TLS handhsake on client socket
                    -> returns FALSE immediately to remove listener watch

    event loop POLLIN on migration *client* socket
     +-> migration_tls_incoming_handshake
          +-> migration_channel_process_incoming()
               +-> migration_ioc_process_incoming()
                    -> return value ignored


So, in this patch your going to immediately unregister the
migration listener socket watch when the TLS handshake
starts.

You can't rely on propagating a return value back from
migration_ioc_process_incoming(), because that is called
from a different context when using TLS.

To fix this we need to migrati onsocket_accept_incoming_migration()
so that it can do a call like

   if (migration_expect_more_clients())
       return TRUE;
   else
       return FALSE;

and have migration_expect_more_clients() do something like

    if (migrate_use_multifd() && mulitfd_recv_state->count < thread_count)
        return TRUE;
    else
        return FALSE;

> diff --git a/migration/migration.c b/migration/migration.c
> index a0db40d..c24ad03 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -299,17 +299,15 @@ static void process_incoming_migration_bh(void *opaque)
>  
>  static void process_incoming_migration_co(void *opaque)
>  {
> -    QEMUFile *f = opaque;
>      MigrationIncomingState *mis = migration_incoming_get_current();
>      PostcopyState ps;
>      int ret;
>  
> -    mis->from_src_file = f;
>      mis->largest_page_size = qemu_ram_pagesize_largest();
>      postcopy_state_set(POSTCOPY_INCOMING_NONE);
>      migrate_set_state(&mis->state, MIGRATION_STATUS_NONE,
>                        MIGRATION_STATUS_ACTIVE);
> -    ret = qemu_loadvm_state(f);
> +    ret = qemu_loadvm_state(mis->from_src_file);
>  
>      ps = postcopy_state_get();
>      trace_process_incoming_migration_co_end(ret, ps);
> @@ -362,6 +360,18 @@ void migration_fd_process_incoming(QEMUFile *f)
>      qemu_coroutine_enter(co);
>  }
>  
> +gboolean migration_ioc_process_incoming(QIOChannel *ioc)
> +{
> +    MigrationIncomingState *mis = migration_incoming_get_current();
> +
> +    if (!mis->from_src_file) {
> +        QEMUFile *f = qemu_fopen_channel_input(ioc);
> +        mis->from_src_file = f;
> +        migration_fd_process_incoming(f);
> +    }
> +    return FALSE; /* unregister */
> +}
> +
>  /*
>   * Send a 'SHUT' message on the return channel with the given value
>   * to indicate that we've finished with the RP.  Non-0 value indicates
> diff --git a/migration/migration.h b/migration/migration.h
> index 148c9fa..5a18aea 100644
> --- a/migration/migration.h
> +++ b/migration/migration.h
> @@ -20,6 +20,7 @@
>  #include "exec/cpu-common.h"
>  #include "qemu/coroutine_int.h"
>  #include "hw/qdev.h"
> +#include "io/channel.h"
>  
>  /* State for the incoming migration */
>  struct MigrationIncomingState {
> @@ -152,6 +153,7 @@ struct MigrationState
>  void migrate_set_state(int *state, int old_state, int new_state);
>  
>  void migration_fd_process_incoming(QEMUFile *f);
> +gboolean migration_ioc_process_incoming(QIOChannel *ioc);
>  
>  uint64_t migrate_max_downtime(void);
>  
> -- 
> 2.9.4
> 

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



reply via email to

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