From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:36604) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SwsT2-0006vK-9I for qemu-devel@nongnu.org; Thu, 02 Aug 2012 06:17:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SwsSw-00040r-1r for qemu-devel@nongnu.org; Thu, 02 Aug 2012 06:17:20 -0400 Received: from mail-wi0-f181.google.com ([209.85.212.181]:33626) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SwsSv-0003xg-SG for qemu-devel@nongnu.org; Thu, 02 Aug 2012 06:17:13 -0400 Received: by mail-wi0-f181.google.com with SMTP id hm2so3769121wib.10 for ; Thu, 02 Aug 2012 03:17:13 -0700 (PDT) From: "=?UTF-8?q?Beno=C3=AEt=20Canet?=" Date: Thu, 2 Aug 2012 12:16:43 +0200 Message-Id: <1343902604-13981-12-git-send-email-benoit@irqsave.net> In-Reply-To: <1343902604-13981-1-git-send-email-benoit@irqsave.net> References: <1343902604-13981-1-git-send-email-benoit@irqsave.net> Subject: [Qemu-devel] [RFC 11/12] qorum: Add qorum mechanism. List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kwolf@redhat.com, pbonzini@redhat.com, stefanha@linux.vnet.ibm.com, =?UTF-8?q?Beno=C3=AEt=20Canet?= Signed-off-by: Benoit Canet --- block/qorum.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 78 insertions(+), 6 deletions(-) diff --git a/block/qorum.c b/block/qorum.c index 772d138..1f307b6 100644 --- a/block/qorum.c +++ b/block/qorum.c @@ -175,7 +175,7 @@ static int qorum_check_ret(QorumAIOCB *acb) static void qorum_aio_bh(void *opaque) { QorumAIOCB *acb = opaque; - int i; + int i, ret; for (i = 0; i <= 2; i++) { if (acb->aios[i].buf) { @@ -185,7 +185,12 @@ static void qorum_aio_bh(void *opaque) } qemu_bh_delete(acb->bh); - acb->common.cb(acb->common.opaque, qorum_check_ret(acb)); + if (acb->vote_ret) { + ret = acb->vote_ret; + } else { + ret = qorum_check_ret(acb); + } + acb->common.cb(acb->common.opaque, ret); if (acb->finished) { *acb->finished = true; } @@ -229,10 +234,75 @@ static void qorum_aio_cb(void *opaque, int ret) sacb->ret = ret; acb->count++; assert(acb->count <= 3); - if (acb->count == 3) { - acb->bh = qemu_bh_new(qorum_aio_bh, acb); - qemu_bh_schedule(acb->bh); + if (acb->count < 3) { + return; } + + /* Do the qorum */ + if (acb->vote) { + acb->vote(acb); + } + + acb->bh = qemu_bh_new(qorum_aio_bh, acb); + qemu_bh_schedule(acb->bh); +} + +static void qorum_print_bad(QorumAIOCB *acb, const char *filename) +{ + fprintf(stderr, "qorum: corrected error in qorum file %s: sector_num=%" + PRId64 " nb_sectors=%i\n", filename, acb->sector_num, + acb->nb_sectors); +} + +static void qorum_print_failure(QorumAIOCB *acb) +{ + fprintf(stderr, "qorum: failure sector_num=%" PRId64 " nb_sectors=%i\n", + acb->sector_num, acb->nb_sectors); +} + +static void qorum_copy_qiov(QEMUIOVector *dest, QEMUIOVector *source) +{ + int i; + for (i = 0; i < source->niov; i++) { + memcpy(dest->iov[i].iov_base, + source->iov[i].iov_base, + source->iov[i].iov_len); + dest->iov[i].iov_len = source->iov[i].iov_len; + } + dest->niov = source->niov; + dest->nalloc = source->nalloc; + dest->size = source->size; +} + +static void qorum_vote(QorumAIOCB *acb) +{ + ssize_t a_b, b_c, a_c; + a_b = blkverify_iovec_compare(&acb->qiovs[0], &acb->qiovs[1]); + b_c = blkverify_iovec_compare(&acb->qiovs[1], &acb->qiovs[2]); + + /* Three vector identical -> qorum */ + if (a_b == b_c && a_b == -1) { + qorum_copy_qiov(acb->qiov, &acb->qiovs[0]); /*clone a */ + return; + } + if (a_b == -1) { + qorum_print_bad(acb, "C"); + qorum_copy_qiov(acb->qiov, &acb->qiovs[0]); /*clone a */ + return; + } + if (b_c == -1) { + qorum_print_bad(acb, "A"); + qorum_copy_qiov(acb->qiov, &acb->qiovs[1]); /*clone b */ + return; + } + a_c = blkverify_iovec_compare(&acb->qiovs[0], &acb->qiovs[2]); + if (a_c == -1) { + qorum_print_bad(acb, "B"); + qorum_copy_qiov(acb->qiov, &acb->qiovs[0]); /*clone a */ + return; + } + qorum_print_failure(acb); + acb->vote_ret = -EIO; } static BlockDriverAIOCB *qorum_aio_readv(BlockDriverState *bs, @@ -247,6 +317,8 @@ static BlockDriverAIOCB *qorum_aio_readv(BlockDriverState *bs, nb_sectors, cb, opaque); int i; + acb->vote = qorum_vote; + for (i = 0; i <= 2; i++) { acb->aios[i].buf = qemu_blockalign(bs->file, qiov->size); qemu_iovec_init(&acb->qiovs[i], qiov->niov); @@ -254,7 +326,7 @@ static BlockDriverAIOCB *qorum_aio_readv(BlockDriverState *bs, } for (i = 0; i <= 2; i++) { - bdrv_aio_readv(s->bs[i], sector_num, qiov, nb_sectors, + bdrv_aio_readv(s->bs[i], sector_num, &acb->qiovs[i], nb_sectors, qorum_aio_cb, &acb->aios[i]); } -- 1.7.9.5