From patchwork Wed Oct 5 09:33:08 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Denis V. Lunev" X-Patchwork-Id: 9362685 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id BAB20600C8 for ; Wed, 5 Oct 2016 09:35:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AA15828627 for ; Wed, 5 Oct 2016 09:35:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9E439286C3; Wed, 5 Oct 2016 09:35:55 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C357828627 for ; Wed, 5 Oct 2016 09:35:54 +0000 (UTC) Received: from localhost ([::1]:47445 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bricD-0004bP-L4 for patchwork-qemu-devel@patchwork.kernel.org; Wed, 05 Oct 2016 05:35:53 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42678) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1briZp-00034h-Hi for qemu-devel@nongnu.org; Wed, 05 Oct 2016 05:33:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1briZj-0006WB-JT for qemu-devel@nongnu.org; Wed, 05 Oct 2016 05:33:25 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:17834 helo=relay.sw.ru) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1briZj-0006VA-31 for qemu-devel@nongnu.org; Wed, 05 Oct 2016 05:33:19 -0400 Received: from iris.sw.ru ([10.30.2.139]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id u959X81U022826; Wed, 5 Oct 2016 12:33:10 +0300 (MSK) From: "Denis V. Lunev" To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Wed, 5 Oct 2016 12:33:08 +0300 Message-Id: <1475659988-20500-3-git-send-email-den@openvz.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1475659988-20500-1-git-send-email-den@openvz.org> References: <1475659988-20500-1-git-send-email-den@openvz.org> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x X-Received-From: 195.214.232.25 Subject: [Qemu-devel] [PATCH 2/2] nbd: add zero-init parameter X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , den@openvz.org, Denis Plotnikov , Max Reitz , Paolo Bonzini Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Denis Plotnikov When using a nbd block device, the info about necessity of prior disk zeroing could significantly improve the speed of certain operations (e.g. backups). This patch also will allow to preserve QCOW2 images during migration. Management software now may specify zero-init option and thus abscent areas in the original QCOW2 image will not be marked as zeroes in the target image. This is tight distiction but it is here. Signed-off-by: Denis Plotnikov Signed-off-by: Denis V. Lunev CC: Paolo Bonzini CC: Kevin Wolf CC: Max Reitz --- block/nbd.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 4 deletions(-) diff --git a/block/nbd.c b/block/nbd.c index 3b133ed..f9dfe57 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -36,19 +36,35 @@ #include "qapi/qmp/qjson.h" #include "qapi/qmp/qint.h" #include "qapi/qmp/qstring.h" +#include "qapi/qmp/qbool.h" #include "qemu/cutils.h" #define EN_OPTSTR "exportname" +#define ZI_OPTSTR "zero-init" -#define PATH_PARAM (1u << 0) +#define PATH_PARAM (1u << 0) +#define ZERO_INIT_PARAM (1u << 1) typedef struct BDRVNBDState { NbdClientSession client; /* For nbd_refresh_filename() */ char *path, *host, *port, *export, *tlscredsid; + bool zero_init; } BDRVNBDState; +static bool set_option_zero_init(QDict *options, const char *value) +{ + if (strcmp(value, "on") == 0) { + qdict_put(options, "zero-init", qbool_from_bool(true)); + } else if (strcmp(value, "off") == 0) { + qdict_put(options, "zero-init", qbool_from_bool(false)); + } else { + return false; + } + return true; +} + /* * helpers for dealing with option parsing * to ease futher params adding and managing @@ -69,7 +85,13 @@ static bool parse_query_params(QueryParams *qp, QDict *options, qdict_put(options, "path", qstring_from_str(param->value)); continue; } - + if ((ZERO_INIT_PARAM & param_flags) && + strcmp(param->name, "zero-init") == 0) { + if (!set_option_zero_init(options, param->value)) { + return false; + } + continue; + } } return true; } @@ -123,13 +145,13 @@ static int nbd_parse_uri(const char *filename, QDict *options) qp = query_params_parse(uri->query); if (is_unix) { - /* nbd+unix:///export?socket=path */ + /* nbd+unix:///export?socket=path{,zero-init=[on|off]} */ if (uri->server || uri->port) { ret = -EINVAL; goto out; } - if (!parse_query_params(qp, options, PATH_PARAM)) { + if (!parse_query_params(qp, options, PATH_PARAM | ZERO_INIT_PARAM)) { ret = -EINVAL; goto out; } @@ -160,6 +182,11 @@ static int nbd_parse_uri(const char *filename, QDict *options) ret = -EINVAL; goto out; } + + if (!parse_query_params(qp, options, ZERO_INIT_PARAM)) { + ret = -EINVAL; + goto out; + } } out: @@ -187,6 +214,8 @@ static void nbd_parse_filename(const char *filename, QDict *options, return; } + set_option_zero_init(options, "off"); + if (strstr(filename, "://")) { int ret = nbd_parse_uri(filename, options); if (ret < 0) { @@ -266,6 +295,11 @@ static void nbd_parse_filename(const char *filename, QDict *options, .type = QEMU_OPT_STRING, .help = "Name of the NBD export to open", }, + { + .name = ZI_OPTSTR, + .type = QEMU_OPT_BOOL, + .help = "Zero-initialized image flag", + }, }, }; @@ -289,6 +323,11 @@ static void nbd_parse_filename(const char *filename, QDict *options, qdict_put(options, "export", qstring_from_str(value)); } + value = qemu_opt_get(opts, ZI_OPTSTR); + if (value) { + qdict_put(options, ZI_OPTSTR, + qbool_from_bool(strcmp(value, "on") == 0)); + } qemu_opts_del(opts); } @@ -337,6 +376,8 @@ static SocketAddress *nbd_config(BDRVNBDState *s, QemuOpts *opts, Error **errp) s->export = g_strdup(qemu_opt_get(opts, "export")); + s->zero_init = strcmp(qemu_opt_get(opts, "zero-init"), "on") == 0; + return saddr; } @@ -427,6 +468,11 @@ static QemuOptsList nbd_runtime_opts = { .type = QEMU_OPT_STRING, .help = "ID of the TLS credentials to use", }, + { + .name = "zero-init", + .type = QEMU_OPT_BOOL, + .help = "Zero-initialized image flag", + }, }, }; @@ -585,9 +631,19 @@ static void nbd_refresh_filename(BlockDriverState *bs, QDict *options) QOBJECT(qstring_from_str(s->tlscredsid))); } + if (s->zero_init) { + qdict_put(opts, "zero-init", qbool_from_bool(true)); + } + bs->full_open_options = opts; } +static int nbd_has_zero_init(BlockDriverState *bs) +{ + BDRVNBDState *s = bs->opaque; + return s->zero_init; +} + static BlockDriver bdrv_nbd = { .format_name = "nbd", .protocol_name = "nbd", @@ -604,6 +660,7 @@ static BlockDriver bdrv_nbd = { .bdrv_detach_aio_context = nbd_detach_aio_context, .bdrv_attach_aio_context = nbd_attach_aio_context, .bdrv_refresh_filename = nbd_refresh_filename, + .bdrv_has_zero_init = nbd_has_zero_init, }; static BlockDriver bdrv_nbd_tcp = { @@ -622,6 +679,7 @@ static BlockDriver bdrv_nbd_tcp = { .bdrv_detach_aio_context = nbd_detach_aio_context, .bdrv_attach_aio_context = nbd_attach_aio_context, .bdrv_refresh_filename = nbd_refresh_filename, + .bdrv_has_zero_init = nbd_has_zero_init, }; static BlockDriver bdrv_nbd_unix = { @@ -640,6 +698,7 @@ static BlockDriver bdrv_nbd_unix = { .bdrv_detach_aio_context = nbd_detach_aio_context, .bdrv_attach_aio_context = nbd_attach_aio_context, .bdrv_refresh_filename = nbd_refresh_filename, + .bdrv_has_zero_init = nbd_has_zero_init, }; static void bdrv_nbd_init(void)