qemu-block
[Top][All Lists]
Advanced

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

Re: [Qemu-block] [RFC PATCH COLO v2 03/13] NBD client: connect to nbd se


From: Paolo Bonzini
Subject: Re: [Qemu-block] [RFC PATCH COLO v2 03/13] NBD client: connect to nbd server later
Date: Wed, 25 Mar 2015 13:46:41 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0


On 25/03/2015 10:36, Wen Congyang wrote:
> The secondary qemu starts later than the primary qemu, so we
> cannot connect to nbd server in bdrv_open().
> 
> Signed-off-by: Wen Congyang <address@hidden>
> Signed-off-by: zhanghailiang <address@hidden>
> Signed-off-by: Gonglei <address@hidden>
> ---
>  block/nbd.c | 122 
> +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 108 insertions(+), 14 deletions(-)
> 
> diff --git a/block/nbd.c b/block/nbd.c
> index 2176186..3faf865 100644
> --- a/block/nbd.c
> +++ b/block/nbd.c
> @@ -44,6 +44,8 @@
>  typedef struct BDRVNBDState {
>      NbdClientSession client;
>      QemuOpts *socket_opts;
> +    char *export;
> +    bool connected;
>  } BDRVNBDState;
>  
>  static int nbd_parse_uri(const char *filename, QDict *options)
> @@ -254,50 +256,95 @@ static int nbd_establish_connection(BlockDriverState 
> *bs, Error **errp)
>      return sock;
>  }
>  
> -static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
> -                    Error **errp)
> +static int nbd_connect_server(BlockDriverState *bs, Error **errp)
>  {
>      BDRVNBDState *s = bs->opaque;
> -    char *export = NULL;
>      int result, sock;
> -    Error *local_err = NULL;
> -
> -    /* Pop the config into our state object. Exit if invalid. */
> -    nbd_config(s, options, &export, &local_err);
> -    if (local_err) {
> -        error_propagate(errp, local_err);
> -        return -EINVAL;
> -    }
>  
>      /* establish TCP connection, return error if it fails
>       * TODO: Configurable retry-until-timeout behaviour.
>       */
>      sock = nbd_establish_connection(bs, errp);
>      if (sock < 0) {
> -        g_free(export);
> +        g_free(s->export);
>          return sock;
>      }
>  
>      /* NBD handshake */
> -    result = nbd_client_init(bs, sock, export, errp);
> -    g_free(export);
> +    result = nbd_client_init(bs, sock, s->export, errp);
> +    g_free(s->export);
> +    s->export = NULL;
> +    if (!result) {
> +        s->connected = true;
> +    }
> +
>      return result;
>  }
>  
> +static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
> +                    Error **errp)
> +{
> +    BDRVNBDState *s = bs->opaque;
> +    Error *local_err = NULL;
> +
> +    /* Pop the config into our state object. Exit if invalid. */
> +    nbd_config(s, options, &s->export, &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return -EINVAL;
> +    }
> +
> +    return nbd_connect_server(bs, errp);
> +}
> +
> +static int nbd_open_colo(BlockDriverState *bs, QDict *options, int flags,
> +                         Error **errp)
> +{
> +    BDRVNBDState *s = bs->opaque;
> +    Error *local_err = NULL;
> +
> +    /* Pop the config into our state object. Exit if invalid. */
> +    nbd_config(s, options, &s->export, &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return -EINVAL;
> +    }
> +
> +    return 0;
> +}
> +
>  static int nbd_co_readv(BlockDriverState *bs, int64_t sector_num,
>                          int nb_sectors, QEMUIOVector *qiov)
>  {
> +    BDRVNBDState *s = bs->opaque;
> +
> +    if (!s->connected) {
> +        return -EIO;
> +    }
> +
>      return nbd_client_co_readv(bs, sector_num, nb_sectors, qiov);
>  }
>  
>  static int nbd_co_writev(BlockDriverState *bs, int64_t sector_num,
>                           int nb_sectors, QEMUIOVector *qiov)
>  {
> +    BDRVNBDState *s = bs->opaque;
> +
> +    if (!s->connected) {
> +        return -EIO;
> +    }
> +
>      return nbd_client_co_writev(bs, sector_num, nb_sectors, qiov);
>  }
>  
>  static int nbd_co_flush(BlockDriverState *bs)
>  {
> +    BDRVNBDState *s = bs->opaque;
> +
> +    if (!s->connected) {
> +        return -EIO;
> +    }
> +
>      return nbd_client_co_flush(bs);
>  }
>  
> @@ -310,6 +357,12 @@ static void nbd_refresh_limits(BlockDriverState *bs, 
> Error **errp)
>  static int nbd_co_discard(BlockDriverState *bs, int64_t sector_num,
>                            int nb_sectors)
>  {
> +    BDRVNBDState *s = bs->opaque;
> +
> +    if (!s->connected) {
> +        return -EIO;
> +    }
> +
>      return nbd_client_co_discard(bs, sector_num, nb_sectors);
>  }
>  
> @@ -319,23 +372,44 @@ static void nbd_close(BlockDriverState *bs)
>  
>      qemu_opts_del(s->socket_opts);
>      nbd_client_close(bs);
> +    s->connected = false;
>  }
>  
>  static int64_t nbd_getlength(BlockDriverState *bs)
>  {
>      BDRVNBDState *s = bs->opaque;
>  
> +    if (!s->connected) {
> +        /*
> +         * We cannot return -ENOTCONN, otherwise refresh_total_sectors()
> +         * will fail, and we cannot open nbd client.
> +         */
> +        return 0;
> +    }
> +
>      return s->client.size;
>  }
>  
>  static void nbd_detach_aio_context(BlockDriverState *bs)
>  {
> +    BDRVNBDState *s = bs->opaque;
> +
> +    if (!s->connected) {
> +        return;
> +    }
> +
>      nbd_client_detach_aio_context(bs);
>  }
>  
>  static void nbd_attach_aio_context(BlockDriverState *bs,
>                                     AioContext *new_context)
>  {
> +    BDRVNBDState *s = bs->opaque;
> +
> +    if (!s->connected) {
> +        return;
> +    }
> +
>      nbd_client_attach_aio_context(bs, new_context);
>  }
>  
> @@ -438,11 +512,31 @@ static BlockDriver bdrv_nbd_unix = {
>      .bdrv_refresh_filename      = nbd_refresh_filename,
>  };
>  
> +static BlockDriver bdrv_nbd_colo = {
> +    .format_name                = "nbd+colo",
> +    .protocol_name              = "nbd+colo",
> +    .instance_size              = sizeof(BDRVNBDState),
> +    .bdrv_parse_filename        = nbd_parse_filename,
> +    .bdrv_file_open             = nbd_open_colo,
> +    .bdrv_co_readv              = nbd_co_readv,
> +    .bdrv_co_writev             = nbd_co_writev,
> +    .bdrv_close                 = nbd_close,
> +    .bdrv_co_flush_to_os        = nbd_co_flush,
> +    .bdrv_co_discard            = nbd_co_discard,
> +    .bdrv_getlength             = nbd_getlength,
> +    .bdrv_detach_aio_context    = nbd_detach_aio_context,
> +    .bdrv_attach_aio_context    = nbd_attach_aio_context,
> +    .bdrv_refresh_filename      = nbd_refresh_filename,
> +
> +    .has_variable_length        = true,
> +};
> +
>  static void bdrv_nbd_init(void)
>  {
>      bdrv_register(&bdrv_nbd);
>      bdrv_register(&bdrv_nbd_tcp);
>      bdrv_register(&bdrv_nbd_unix);
> +    bdrv_register(&bdrv_nbd_colo);
>  }
>  
>  block_init(bdrv_nbd_init);
> 

Acked-by: Paolo Bonzini <address@hidden>



reply via email to

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