From patchwork Mon Aug 27 07:30:21 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benoit Canet X-Patchwork-Id: 180153 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id E7BFE2C00D2 for ; Mon, 27 Aug 2012 18:23:07 +1000 (EST) Received: from localhost ([::1]:43751 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T5tnB-0002Uq-Vu for incoming@patchwork.ozlabs.org; Mon, 27 Aug 2012 03:31:25 -0400 Received: from eggs.gnu.org ([208.118.235.92]:49775) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T5tma-0001B1-Fe for qemu-devel@nongnu.org; Mon, 27 Aug 2012 03:30:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1T5tmU-0000ix-5Q for qemu-devel@nongnu.org; Mon, 27 Aug 2012 03:30:48 -0400 Received: from mail-wg0-f53.google.com ([74.125.82.53]:62199) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T5tmT-0000iq-SQ for qemu-devel@nongnu.org; Mon, 27 Aug 2012 03:30:42 -0400 Received: by wgbfm10 with SMTP id fm10so2465980wgb.10 for ; Mon, 27 Aug 2012 00:30:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=qnCSqK37nsY6dlSDOmZCciTo4S6QHutEe9/jBmWhBkU=; b=iSOQXGU5IhRuh18wdwKOh/jEzfwPi/E1VeoIe8m0WDP6YnStcj7H8O0cf8aFuVvvAr pU/QMfVr+NvzTn51aAgKdYiSQehchLvkM06lI/wu8T3XUPzchgz1zbOtTbRPAupq9MGP BOFnzzjaJOJMfl6VdoW2FzU7H9y4DFSAn4HlqVV3dEAJ4mZ0fKL3VK3UPKXVXyfMhbTJ CW357yLP00i7AGTSGJuvDokwNQrQ2g/S9xknJpBFs2zbDAGekTqZCQ/SryMbifBduaU4 4N47jKPb0lLjxi7oaZKBCkBqa30KoAYI/1t85vikoqSCC4OYWDmpy/X0djG66h9pxB/V Qtpg== Received: by 10.180.78.5 with SMTP id x5mr23433870wiw.13.1346052641186; Mon, 27 Aug 2012 00:30:41 -0700 (PDT) Received: from Laure.box.in.irqsave.net (paradis.irqsave.net. [109.190.18.76]) by mx.google.com with ESMTPS id o2sm20688986wiz.11.2012.08.27.00.30.39 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 27 Aug 2012 00:30:40 -0700 (PDT) From: "=?UTF-8?q?Beno=C3=AEt=20Canet?=" To: qemu-devel@nongnu.org Date: Mon, 27 Aug 2012 09:30:21 +0200 Message-Id: <1346052629-15686-4-git-send-email-benoit@irqsave.net> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1346052629-15686-1-git-send-email-benoit@irqsave.net> References: <1346052629-15686-1-git-send-email-benoit@irqsave.net> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 74.125.82.53 Cc: kwolf@redhat.com, stefanha@linux.vnet.ibm.com, blauwirbel@gmail.com, pbonzini@redhat.com, eblake@redhat.com, =?UTF-8?q?Beno=C3=AEt=20Canet?= Subject: [Qemu-devel] [RFC V5 03/11] quorum: Add quorum_open() and quorum_close(). X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Valid quorum resources look like quorum:threshold/total:path/to/image_1, ... ,path/to/image_total ',' is used as a separator to allow to use networked path '\' is the escaping character for filename containing ',' '\' escape itself On the command line for quorum files "img,test.raw", "img2.raw" and "img3.raw" invocation look like: -drive file=quorum:2/3:img\\,,test.raw,,img2.raw,,img3.raw (note the double ,, and \\) Signed-off-by: Benoit Canet --- block/quorum.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/block/quorum.c b/block/quorum.c index 19a9a44..b9fb2b9 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -52,11 +52,134 @@ struct QuorumAIOCB { int vote_ret; }; +/* Valid quorum resources look like + * quorum:threshold/total:path/to/image_1, ... ,path/to/image_total + * + * ',' is used as a separator to allow to use network path + * '\' is the escaping character for filename containing ',' + */ +static int quorum_open(BlockDriverState *bs, const char *filename, int flags) +{ + BDRVQuorumState *s = bs->opaque; + int i, j, k, len, ret = 0; + char *a, *b, *names; + bool escape; + + /* Parse the quorum: prefix */ + if (strncmp(filename, "quorum:", strlen("quorum:"))) { + return -EINVAL; + } + + filename += strlen("quorum:"); + + /* Get threshold */ + errno = 0; + s->threshold = strtoul(filename, &a, 10); + if (*a != '/' || errno) { + return -EINVAL; + } + a++; + + /* Get total */ + errno = 0; + s->total = strtoul(a, &b, 10); + if (*b != ':' || errno) { + return -EINVAL; + } + b++; + + if (s->threshold < 1 || s->total < 2) { + return -EINVAL; + } + + if (s->threshold > s->total) { + return -EINVAL; + } + + s->bs = g_malloc0(sizeof(BlockDriverState *) * s->total); + /* Two allocations for all filenames: simpler to free */ + s->filenames = g_malloc0(sizeof(char *) * s->total); + names = g_strdup(b); + + /* Get the filenames pointers */ + escape = false; + s->filenames[0] = names; + len = strlen(names); + for (i = j = k = 0; i < len && j < s->total; i++) { + /* separation between two files */ + if (!escape && names[i] == ',') { + char *prev = s->filenames[j]; + prev[k] = '\0'; + s->filenames[++j] = prev + k + 1; + k = 0; + continue; + } + + escape = !escape && names[i] == '\\'; + + /* if we are not escaping copy */ + if (!escape) { + s->filenames[j][k++] = names[i]; + } + } + /* terminate last string */ + s->filenames[j][k] = '\0'; + + if ((j + 1) != s->total) { + ret = -EINVAL; + goto free_exit; + } + + /* Open files */ + for (i = 0; i < s->total; i++) { + s->bs[i] = bdrv_new(""); + ret = bdrv_open(s->bs[i], s->filenames[i], flags, NULL); + if (ret < 0) { + goto error_exit; + } + } + + goto exit; + +error_exit: + for (; i >= 0; i--) { + bdrv_delete(s->bs[i]); + s->bs[i] = NULL; + } +free_exit: + g_free(s->filenames[0]); + g_free(s->filenames); + s->filenames = NULL; + g_free(s->bs); +exit: + return ret; +} + +static void quorum_close(BlockDriverState *bs) +{ + BDRVQuorumState *s = bs->opaque; + int i; + + for (i = 0; i < s->total; i++) { + /* Ensure writes reach stable storage */ + bdrv_flush(s->bs[i]); + bdrv_delete(s->bs[i]); + } + + g_free(s->filenames[0]); + g_free(s->filenames); + s->filenames = NULL; + g_free(s->bs); +} + static BlockDriver bdrv_quorum = { .format_name = "quorum", .protocol_name = "quorum", .instance_size = sizeof(BDRVQuorumState), + + .bdrv_file_open = quorum_open, + .bdrv_close = quorum_close, }; static void bdrv_quorum_init(void)