From patchwork Fri Oct 7 15:36:17 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reda Sallahi X-Patchwork-Id: 9366441 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 42B7A60487 for ; Fri, 7 Oct 2016 15:41:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 34136296FE for ; Fri, 7 Oct 2016 15:41:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 288762971B; Fri, 7 Oct 2016 15:41:10 +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.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID 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 8C738296FE for ; Fri, 7 Oct 2016 15:41:09 +0000 (UTC) Received: from localhost ([::1]:36795 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bsXGm-0006HP-Hd for patchwork-qemu-devel@patchwork.kernel.org; Fri, 07 Oct 2016 11:41:08 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42107) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bsXCf-00035o-LV for qemu-devel@nongnu.org; Fri, 07 Oct 2016 11:36:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bsXCe-0007pq-8k for qemu-devel@nongnu.org; Fri, 07 Oct 2016 11:36:53 -0400 Received: from mail-wm0-x243.google.com ([2a00:1450:400c:c09::243]:36681) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bsXCd-0007p5-WB; Fri, 07 Oct 2016 11:36:52 -0400 Received: by mail-wm0-x243.google.com with SMTP id 123so3505444wmb.3; Fri, 07 Oct 2016 08:36:51 -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:in-reply-to:references; bh=wK0OYv+aa2t/vm20SxAXaqigv/eoLTkAu10pE8E8HI4=; b=ogj50+NVkI1zzKFH/pRY2KbgCeS0nCZyTDuIBIBZLjclpMjdMkWbtc2mgyRrjPqoee zDyBJlUmEFp2aUm8iRq95n2N+lNtJas2+lkapp5NO0BnkupZu4cBA+DGoXKoGNoU7K/+ fS5PAa77o3VWCfWAIrgErDQQpA1c6QSCN1Z0yUOBMHKN45pc0/zUaBbgjGjBXzMpXk0d JXKr7zSVq0LcWgzULPM+jCnCoBq14jWlfA62ksXGgVngIFExRk49mVxyGzXYWIiNtLcT Ta0bjlRKgfZwfXtM7KVW20ZiXu0ISVyAdRbTJ8Wk4zxbAxnoX2F5dD6xuxPWr/gSaEVK 1pSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=wK0OYv+aa2t/vm20SxAXaqigv/eoLTkAu10pE8E8HI4=; b=g6/6qfboHZCCU+rLodEhyAHqE4y0773RcOTMOKFar4ROBftPNH5iLPLkaPvp1bTzxg FM/GQRma0jzsmoQtep6QsqxQbkgCuETlhE3N+YUC4zGRb4YQFHDzvQuFp5ctXtnOWQ7P RnZJCi35wrd+zv5w1NTULg1iQOd/wAX72J2CexOMrxng5IBr0cbFv2g/rCsa9RlBtAJ3 lY1FIfrEc0Q70TuYCzOaf+6vqjXgbsb9fNOsdZh8381sMOWC1TvY3xCNifL5O/FgLB3t OSO5mLZ5BNj3GGdntdcFaOlCb/3/mx01IO28CpGo26YjCKcHFxDqYP9tsD2rCZdBlS9c H7Kw== X-Gm-Message-State: AA6/9RkAFgO2tK4J5D45VWokVIlVe3bCSfympJymkKErexcoQftqhjCLFDIwTsf4witH5Q== X-Received: by 10.28.15.202 with SMTP id 193mr18659133wmp.98.1475854611042; Fri, 07 Oct 2016 08:36:51 -0700 (PDT) Received: from cinque_stelle.sm14.sm.cri.epita.net ([163.5.208.20]) by smtp.gmail.com with ESMTPSA id 137sm3537659wmi.16.2016.10.07.08.36.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 07 Oct 2016 08:36:49 -0700 (PDT) From: Reda Sallahi To: qemu-devel@nongnu.org Date: Fri, 7 Oct 2016 17:36:17 +0200 Message-Id: <20161007153617.28704-3-fullmanet@gmail.com> X-Mailer: git-send-email 2.10.0 In-Reply-To: <20161007153617.28704-1-fullmanet@gmail.com> References: <20161007153617.28704-1-fullmanet@gmail.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:400c:c09::243 Subject: [Qemu-devel] [PATCH 2/2] qemu-img: change opening method for the output in dd 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 , Fam Zheng , qemu-block@nongnu.org, Max Reitz , Reda Sallahi , Stefan Hajnoczi Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP The subcommand dd was creating an output image regardless of whether there was one already created. With this patch we try to check first if the output image exists and resize it if necessary. Signed-off-by: Reda Sallahi --- qemu-img.c | 124 ++++++++++++++++++++++++++++++------------------- tests/qemu-iotests/160 | 1 - 2 files changed, 75 insertions(+), 50 deletions(-) diff --git a/qemu-img.c b/qemu-img.c index 6c088bd..9b590d4 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -3938,7 +3938,7 @@ static int img_dd(int argc, char **argv) int c, i; const char *out_fmt = "raw"; const char *fmt = NULL; - int64_t size = 0; + int64_t size = 0, out_size; int64_t block_count = 0, out_pos, in_pos; struct DdInfo dd = { .flags = 0, @@ -4042,36 +4042,6 @@ static int img_dd(int argc, char **argv) goto out; } - drv = bdrv_find_format(out_fmt); - if (!drv) { - error_report("Unknown file format"); - ret = -1; - goto out; - } - proto_drv = bdrv_find_protocol(out.filename, true, &local_err); - - if (!proto_drv) { - error_report_err(local_err); - ret = -1; - goto out; - } - if (!drv->create_opts) { - error_report("Format driver '%s' does not support image creation", - drv->format_name); - ret = -1; - goto out; - } - if (!proto_drv->create_opts) { - error_report("Protocol driver '%s' does not support image creation", - proto_drv->format_name); - ret = -1; - goto out; - } - create_opts = qemu_opts_append(create_opts, drv->create_opts); - create_opts = qemu_opts_append(create_opts, proto_drv->create_opts); - - opts = qemu_opts_create(create_opts, NULL, 0, &error_abort); - size = blk_getlength(blk1); if (size < 0) { error_report("Failed to get size for '%s'", in.filename); @@ -4083,31 +4053,87 @@ static int img_dd(int argc, char **argv) dd.count * in.bsz < size) { size = dd.count * in.bsz; } - /* Overflow means the specified offset is beyond input image's size */ - if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz || - size < in.bsz * in.offset)) { - qemu_opt_set_number(opts, BLOCK_OPT_SIZE, 0, &error_abort); + if (in.offset > INT64_MAX / in.bsz || size < in.offset * in.bsz) { + out_size = 0; } else { - qemu_opt_set_number(opts, BLOCK_OPT_SIZE, - size - in.bsz * in.offset, &error_abort); - } - - ret = bdrv_create(drv, out.filename, opts, &local_err); - if (ret < 0) { - error_reportf_err(local_err, - "%s: error while creating output image: ", - out.filename); - ret = -1; - goto out; + out_size = size - in.offset * in.bsz; } blk2 = img_open(image_opts, out.filename, out_fmt, BDRV_O_RDWR, - false, false, true); + false, false, false); if (!blk2) { - ret = -1; - goto out; + drv = bdrv_find_format(out_fmt); + if (!drv) { + error_report("Unknown file format"); + ret = -1; + goto out; + } + proto_drv = bdrv_find_protocol(out.filename, true, &local_err); + + if (!proto_drv) { + error_report_err(local_err); + ret = -1; + goto out; + } + if (!drv->create_opts) { + error_report("Format driver '%s' does not support image creation", + drv->format_name); + ret = -1; + goto out; + } + if (!proto_drv->create_opts) { + error_report("Protocol driver '%s' does not support image creation", + proto_drv->format_name); + ret = -1; + goto out; + } + create_opts = qemu_opts_append(create_opts, drv->create_opts); + create_opts = qemu_opts_append(create_opts, proto_drv->create_opts); + + opts = qemu_opts_create(create_opts, NULL, 0, &error_abort); + + qemu_opt_set_number(opts, BLOCK_OPT_SIZE, out_size, &error_abort); + + ret = bdrv_create(drv, out.filename, opts, &local_err); + if (ret < 0) { + error_reportf_err(local_err, + "%s: error while creating output image: ", + out.filename); + ret = -1; + goto out; + } + blk2 = img_open(image_opts, out.filename, out_fmt, BDRV_O_RDWR, + false, false, true); + if (!blk2) { + ret = -1; + goto out; + } + } else { + int64_t blk2sz = 0; + + if (!(dd.conv & C_NOTRUNC)) { + /* We make conv=notrunc mandatory for the moment to avoid + accidental destruction of the output image. Needs to be + changed when a better solution is found */ + error_report("conv=notrunc not specified"); + ret = -1; + goto out; + } + + blk2sz = blk_getlength(blk2); + if (blk2sz < 0) { + error_report("Failed to get size for '%s'", in.filename); + ret = -1; + goto out; + } + + if (in.offset <= INT64_MAX / in.bsz && size >= in.offset * in.bsz) { + if (blk2sz < out_size) { + blk_truncate(blk2, out_size); + } + } } if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz || diff --git a/tests/qemu-iotests/160 b/tests/qemu-iotests/160 index f44834f..53b3c30 100755 --- a/tests/qemu-iotests/160 +++ b/tests/qemu-iotests/160 @@ -65,7 +65,6 @@ for skip in $TEST_SKIP_BLOCKS; do echo "== Compare the images with qemu-img compare ==" $QEMU_IMG compare "$TEST_IMG.out.dd" "$TEST_IMG.out" - rm -f "$TEST_IMG.out.dd" done echo