All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefan Hajnoczi <stefanha@gmail.com>
To: Wen Congyang <wency@cn.fujitsu.com>
Cc: Kevin Wolf <kwolf@redhat.com>, Fam Zheng <famz@redhat.com>,
	Lai Jiangshan <laijs@cn.fujitsu.com>,
	qemu block <qemu-block@nongnu.org>,
	Jiang Yunhong <yunhong.jiang@intel.com>,
	Dong Eddie <eddie.dong@intel.com>,
	qemu devel <qemu-devel@nongnu.org>, Max Reitz <mreitz@redhat.com>,
	Alberto Garcia <berto@igalia.com>,
	Gonglei <arei.gonglei@huawei.com>,
	Stefan Hajnoczi <stefanha@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Yang Hongyang <yanghy@cn.fujitsu.com>,
	"Dr. David Alan Gilbert" <dgilbert@redhat.com>,
	zhanghailiang <zhang.zhanghailiang@huawei.com>
Subject: Re: [Qemu-devel] [PATCH COLO-Block v6 15/16] quorum: allow ignoring child errors
Date: Thu, 18 Jun 2015 14:06:39 +0100	[thread overview]
Message-ID: <20150618130639.GG25387@stefanha-thinkpad.redhat.com> (raw)
In-Reply-To: <1434617361-17778-16-git-send-email-wency@cn.fujitsu.com>

[-- Attachment #1: Type: text/plain, Size: 7177 bytes --]

On Thu, Jun 18, 2015 at 04:49:20PM +0800, Wen Congyang wrote:

CCing Alberto Garcia for the quorum block driver.

> If the child is not ready, read/write/getlength/flush will
> return -errno. It is not critical error, and can be ignored:
> 1. read/write:
>    Just not report the error event.
> 2. getlength:
>    just ignore it. If all children's getlength return -errno,
>    and be ignored, return -EIO.
> 3. flush:
>    Just ignore it. If all children's getlength return -errno,
>    and be ignored, return 0.
> 
> Usage: children.x.ignore-errors=true
> 
> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
> Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
> Signed-off-by: Gonglei <arei.gonglei@huawei.com>
> ---
>  block/quorum.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
>  1 file changed, 77 insertions(+), 7 deletions(-)
> 
> diff --git a/block/quorum.c b/block/quorum.c
> index 01cfac0..c5dbb69 100644
> --- a/block/quorum.c
> +++ b/block/quorum.c
> @@ -30,6 +30,7 @@
>  #define QUORUM_OPT_BLKVERIFY      "blkverify"
>  #define QUORUM_OPT_REWRITE        "rewrite-corrupted"
>  #define QUORUM_OPT_READ_PATTERN   "read-pattern"
> +#define QUORUM_CHILDREN_OPT_IGNORE_ERRORS   "ignore-errors"
>  
>  /* This union holds a vote hash value */
>  typedef union QuorumVoteValue {
> @@ -65,6 +66,7 @@ typedef struct QuorumVotes {
>  /* the following structure holds the state of one quorum instance */
>  typedef struct BDRVQuorumState {
>      BlockDriverState **bs; /* children BlockDriverStates */
> +    bool *ignore_errors;   /* ignore children's error? */
>      int num_children;      /* children count */
>      int threshold;         /* if less than threshold children reads gave the
>                              * same result a quorum error occurs.
> @@ -99,6 +101,7 @@ typedef struct QuorumChildRequest {
>      uint8_t *buf;
>      int ret;
>      QuorumAIOCB *parent;
> +    int index;
>  } QuorumChildRequest;
>  
>  /* Quorum will use the following structure to track progress of each read/write
> @@ -211,6 +214,7 @@ static QuorumAIOCB *quorum_aio_get(BDRVQuorumState *s,
>          acb->qcrs[i].buf = NULL;
>          acb->qcrs[i].ret = 0;
>          acb->qcrs[i].parent = acb;
> +        acb->qcrs[i].index = i;
>      }
>  
>      return acb;
> @@ -304,7 +308,7 @@ static void quorum_aio_cb(void *opaque, int ret)
>      acb->count++;
>      if (ret == 0) {
>          acb->success_count++;
> -    } else {
> +    } else if (!s->ignore_errors[sacb->index]) {
>          quorum_report_bad(acb, sacb->aiocb->bs->node_name, ret);
>      }
>      assert(acb->count <= s->num_children);
> @@ -719,19 +723,31 @@ static BlockAIOCB *quorum_aio_writev(BlockDriverState *bs,
>  static int64_t quorum_getlength(BlockDriverState *bs)
>  {
>      BDRVQuorumState *s = bs->opaque;
> -    int64_t result;
> +    int64_t result = -EIO;
>      int i;
>  
>      /* check that all file have the same length */
> -    result = bdrv_getlength(s->bs[0]);
> -    if (result < 0) {
> -        return result;
> -    }
> -    for (i = 1; i < s->num_children; i++) {
> +    for (i = 0; i < s->num_children; i++) {
>          int64_t value = bdrv_getlength(s->bs[i]);
> +
>          if (value < 0) {
>              return value;
>          }
> +
> +        if (value == 0 && s->ignore_errors[i]) {
> +            /*
> +             * If the child is not ready, it cannot return -errno,
> +             * otherwise refresh_total_sectors() will fail when
> +             * we open the child.
> +             */
> +            continue;
> +        }
> +
> +        if (result == -EIO) {
> +            result = value;
> +            continue;
> +        }
> +
>          if (value != result) {
>              return -EIO;
>          }
> @@ -769,6 +785,9 @@ static coroutine_fn int quorum_co_flush(BlockDriverState *bs)
>  
>      for (i = 0; i < s->num_children; i++) {
>          result = bdrv_co_flush(s->bs[i]);
> +        if (result < 0 && s->ignore_errors[i]) {
> +            result = 0;
> +        }
>          result_value.l = result;
>          quorum_count_vote(&error_votes, &result_value, i);
>      }
> @@ -843,6 +862,19 @@ static QemuOptsList quorum_runtime_opts = {
>      },
>  };
>  
> +static QemuOptsList quorum_children_common_opts = {
> +    .name = "quorum children",
> +    .head = QTAILQ_HEAD_INITIALIZER(quorum_children_common_opts.head),
> +    .desc = {
> +        {
> +            .name = QUORUM_CHILDREN_OPT_IGNORE_ERRORS,
> +            .type = QEMU_OPT_BOOL,
> +            .help = "ignore child I/O error",
> +        },
> +        { /* end of list */ }
> +    },
> +};
> +
>  static int parse_read_pattern(const char *opt)
>  {
>      int i;
> @@ -861,6 +893,37 @@ static int parse_read_pattern(const char *opt)
>      return -EINVAL;
>  }
>  
> +static int parse_children_options(BDRVQuorumState *s, QDict *options,
> +                                  const char *indexstr, int index,
> +                                  Error **errp)
> +{
> +    QemuOpts *children_opts = NULL;
> +    Error *local_err = NULL;
> +    int ret = 0;
> +    bool value;
> +
> +    children_opts = qemu_opts_create(&quorum_children_common_opts, NULL, 0,
> +                                     &error_abort);
> +    qemu_opts_absorb_qdict_by_index(children_opts, options, indexstr,
> +                                    &local_err);
> +    if (local_err) {
> +        ret = -EINVAL;
> +        goto out;
> +    }
> +
> +    value = qemu_opt_get_bool(children_opts, QUORUM_CHILDREN_OPT_IGNORE_ERRORS,
> +                              false);
> +    s->ignore_errors[index] = value;
> +
> +out:
> +    qemu_opts_del(children_opts);
> +    /* propagate error */
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +    }
> +    return ret;
> +}
> +
>  static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
>                         Error **errp)
>  {
> @@ -931,12 +994,18 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
>      /* allocate the children BlockDriverState array */
>      s->bs = g_new0(BlockDriverState *, s->num_children);
>      opened = g_new0(bool, s->num_children);
> +    s->ignore_errors = g_new0(bool, s->num_children);
>  
>      for (i = 0; i < s->num_children; i++) {
>          char indexstr[32];
>          ret = snprintf(indexstr, 32, "children.%d", i);
>          assert(ret < 32);
>  
> +        ret = parse_children_options(s, options, indexstr, i, &local_err);
> +        if (ret < 0) {
> +            goto close_exit;
> +        }
> +
>          ret = bdrv_open_image(&s->bs[i], NULL, options, indexstr, bs,
>                                &child_format, false, &local_err);
>          if (ret < 0) {
> @@ -979,6 +1048,7 @@ static void quorum_close(BlockDriverState *bs)
>      }
>  
>      g_free(s->bs);
> +    g_free(s->ignore_errors);
>  }
>  
>  static void quorum_detach_aio_context(BlockDriverState *bs)
> -- 
> 2.4.3
> 
> 

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

  reply	other threads:[~2015-06-18 13:11 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-18  8:49 [Qemu-devel] [PATCH COLO-Block v6 00/16] Block replication for continuous checkpoints Wen Congyang
2015-06-18  8:49 ` [Qemu-devel] [PATCH COLO-Block v6 01/16] docs: block replication's description Wen Congyang
2015-06-18 10:34   ` Stefan Hajnoczi
2015-06-18 10:51     ` Wen Congyang
2015-06-18  8:49 ` [Qemu-devel] [PATCH COLO-Block v6 02/16] allow writing to the backing file Wen Congyang
2015-06-18  8:49 ` [Qemu-devel] [PATCH COLO-Block v6 03/16] Allow creating backup jobs when opening BDS Wen Congyang
2015-06-18 10:40   ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
2015-06-18  8:49 ` [Qemu-devel] [PATCH COLO-Block v6 04/16] block: Parse "backing_reference" option to reference existing BDS Wen Congyang
2015-06-18 10:50   ` Stefan Hajnoczi
2015-06-18 11:40     ` Wen Congyang
2015-06-18  8:49 ` [Qemu-devel] [PATCH COLO-Block v6 05/16] Backup: clear all bitmap when doing block checkpoint Wen Congyang
2015-06-18  8:49 ` [Qemu-devel] [PATCH COLO-Block v6 06/16] Don't allow a disk use backing reference target Wen Congyang
2015-06-18 12:47   ` Stefan Hajnoczi
2015-06-18 15:17     ` Wen Congyang
2015-06-18  8:49 ` [Qemu-devel] [PATCH COLO-Block v6 07/16] Add new block driver interface to connect/disconnect the remote target Wen Congyang
2015-06-18 12:55   ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
2015-06-18 14:36     ` Wen Congyang
2015-06-18 16:06       ` Stefan Hajnoczi
2015-06-19  0:54         ` Wen Congyang
2015-06-19 10:49           ` Stefan Hajnoczi
2015-06-20  3:31             ` Wen Congyang
2015-06-22 12:39               ` Stefan Hajnoczi
2015-06-22 13:56                 ` Wen Congyang
2015-06-23 13:42                   ` Stefan Hajnoczi
2015-06-23 13:54                     ` Wen Congyang
2015-06-24 14:07               ` Dr. David Alan Gilbert
2015-06-25  1:01                 ` Wen Congyang
2015-06-26 19:03                   ` Dr. David Alan Gilbert
2015-06-29  1:05                     ` Wen Congyang
2015-06-30 19:01                       ` Dr. David Alan Gilbert
2015-07-01  1:01                         ` Wen Congyang
2015-07-01  8:11                           ` Dr. David Alan Gilbert
2015-07-01  8:18                             ` Wen Congyang
2015-07-01 18:42                               ` Dr. David Alan Gilbert
2015-07-02  0:55                                 ` Wen Congyang
2015-07-02  7:54                                   ` Dr. David Alan Gilbert
2015-07-02  8:05                                     ` Wen Congyang
2015-06-24  1:11             ` Wen Congyang
2015-06-23  6:44         ` Wen Congyang
2015-06-18  8:49 ` [Qemu-devel] [PATCH COLO-Block v6 08/16] NBD client: implement block driver interfaces to connect/disconnect NBD server Wen Congyang
2015-06-18  8:49 ` [Qemu-devel] [PATCH COLO-Block v6 09/16] Introduce a new -drive option to control whether to connect to remote target Wen Congyang
2015-06-18  8:49 ` [Qemu-devel] [PATCH COLO-Block v6 10/16] NBD client: connect to nbd server later Wen Congyang
2015-06-18  8:49 ` [Qemu-devel] [PATCH COLO-Block v6 11/16] Add new block driver interfaces to control block replication Wen Congyang
2015-06-18  8:49 ` [Qemu-devel] [PATCH COLO-Block v6 12/16] skip nbd_target when starting " Wen Congyang
2015-06-18  8:49 ` [Qemu-devel] [PATCH COLO-Block v6 13/16] quorum: implement block driver interfaces for " Wen Congyang
2015-06-18 13:06   ` Stefan Hajnoczi
2015-06-18  8:49 ` [Qemu-devel] [PATCH COLO-Block v6 14/16] introduce a new API qemu_opts_absorb_qdict_by_index() Wen Congyang
2015-06-18  8:49 ` [Qemu-devel] [PATCH COLO-Block v6 15/16] quorum: allow ignoring child errors Wen Congyang
2015-06-18 13:06   ` Stefan Hajnoczi [this message]
2015-06-18  8:49 ` [Qemu-devel] [PATCH COLO-Block v6 16/16] Implement new driver for block replication Wen Congyang

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=20150618130639.GG25387@stefanha-thinkpad.redhat.com \
    --to=stefanha@gmail.com \
    --cc=arei.gonglei@huawei.com \
    --cc=berto@igalia.com \
    --cc=dgilbert@redhat.com \
    --cc=eddie.dong@intel.com \
    --cc=famz@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=laijs@cn.fujitsu.com \
    --cc=mreitz@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    --cc=wency@cn.fujitsu.com \
    --cc=yanghy@cn.fujitsu.com \
    --cc=yunhong.jiang@intel.com \
    --cc=zhang.zhanghailiang@huawei.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.