From patchwork Thu Aug 11 04:02:32 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reda Sallahi X-Patchwork-Id: 9274421 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 5253960780 for ; Thu, 11 Aug 2016 04:03:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 421C328495 for ; Thu, 11 Aug 2016 04:03:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 35167284B5; Thu, 11 Aug 2016 04:03:21 +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 99A9228495 for ; Thu, 11 Aug 2016 04:03:20 +0000 (UTC) Received: from localhost ([::1]:45325 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bXhDD-0002c1-0v for patchwork-qemu-devel@patchwork.kernel.org; Thu, 11 Aug 2016 00:03:19 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33258) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bXhCx-0002Vw-Qz for qemu-devel@nongnu.org; Thu, 11 Aug 2016 00:03:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bXhCt-0007C6-Kv for qemu-devel@nongnu.org; Thu, 11 Aug 2016 00:03:02 -0400 Received: from mail-wm0-x242.google.com ([2a00:1450:400c:c09::242]:35086) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bXhCt-0007BD-Ah; Thu, 11 Aug 2016 00:02:59 -0400 Received: by mail-wm0-x242.google.com with SMTP id i5so650093wmg.2; Wed, 10 Aug 2016 21:02:59 -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; bh=QSvgO7sRILxaSLegY/+iiQfR8iKa6Gl03nmj2KTYRVk=; b=VcFyqfZHB9Y7MafIf/xVGCO3YUEoe0BPjpYnS5dMU+Txuz8inLtLDdcGID4b4PqjG/ YU2cadqQjhs0Mip3wJc/nV9d894ykZ+hZQwwBV5S+8BW2G6p6sVYYoTKyl/BCcs3FueR muliCqXQPFk0cm6vo/cED6mcltlXqavwm3ZUMfv6t77SkTp2fq5GPZAaZ5DHnDgilqxi bdQOxnji9IKJ4otxl0OWoSbKL1fRSTxOVTXXjukm2wuFA0H6DtK64uK5IZt6ndNATL8N QY94SoBLfQ5FQrs5gkdZ6prJjSJjYsmgoqO78ahNd7YSr1xIZiDw6I22Bz1Hg4O4A63B ICwQ== 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; bh=QSvgO7sRILxaSLegY/+iiQfR8iKa6Gl03nmj2KTYRVk=; b=jJk1IIzdFSaDbSN6S9cEX4Xzs59ujhA/HfLJe2tnpJqXNWhPFrs9z2CXGY+qmleXpY 044VnqOb7gvgGHSYBS1OnipozgkXpVlA/AYZpi3YJciI6QJPBPXuXUXVer87y67on++P k0nJu6utdOl1PjECY0iQ8OIT4c+6BxUmdr8hL9xUPLQFlgQ8A8nI2bb4qFnDuACoDgTI rdPq+u0XO7bcXcNwF++NbeyVi+4SBbHRQTguCDOcpT86NZEm4NbfKqHiBHBYEd/yJxbh y7w1QbCaDxcNCOuEXpuEl0mYpqRSK1oNuAOZDMZQ07NCIxwYkpeSDOBtrJOfvpC6NN1T QDgw== X-Gm-Message-State: AEkooutqfJfKm3W9NsuzF7xR568vR+fF5Tzq4Uoim+VwmFCgRAS2M2rbaxGyzm8GoQhI4w== X-Received: by 10.28.61.215 with SMTP id k206mr6752573wma.80.1470888177881; Wed, 10 Aug 2016 21:02:57 -0700 (PDT) Received: from localhost.localdomain (ram94-2-82-66-69-246.fbx.proxad.net. [82.66.69.246]) by smtp.gmail.com with ESMTPSA id d62sm1053371wmd.7.2016.08.10.21.02.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 Aug 2016 21:02:57 -0700 (PDT) From: Reda Sallahi To: qemu-devel@nongnu.org Date: Thu, 11 Aug 2016 06:02:32 +0200 Message-Id: <20160811040232.30905-1-fullmanet@gmail.com> X-Mailer: git-send-email 2.9.2 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:400c:c09::242 Subject: [Qemu-devel] [PATCH] 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 dd was creating an output image regardless of whether there was one already created. With this patch we try to open first the output image and resize it if necessary. Signed-off-by: Reda Sallahi --- Depends on: [PATCH v2] qemu-img: add conv=notrunc option to dd qemu-img.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 76 insertions(+), 15 deletions(-) diff --git a/qemu-img.c b/qemu-img.c index 7c546c1..dfa0e63 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -3919,6 +3919,8 @@ static int img_dd(int argc, char **argv) char *tmp; BlockDriver *drv = NULL, *proto_drv = NULL; BlockBackend *blk1 = NULL, *blk2 = NULL; + BlockDriverState *bs = NULL; + QDict *qoptions = NULL; QemuOpts *opts = NULL; QemuOptsList *create_opts = NULL; Error *local_err = NULL; @@ -4080,22 +4082,60 @@ static int img_dd(int argc, char **argv) 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); - } else { - qemu_opt_set_number(opts, BLOCK_OPT_SIZE, - size - in.bsz * in.offset, &error_abort); - } + qoptions = qdict_new(); + qdict_put(qoptions, "driver", qstring_from_str(out_fmt)); - 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; + bs = bdrv_open(out.filename, NULL, qoptions, BDRV_O_RDWR, &local_err); + + if (!bs) { + 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); + + /* Overflow means the specified offset is beyond input image's size */ + if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz || + size < in.offset * in.bsz)) { + qemu_opt_set_number(opts, BLOCK_OPT_SIZE, + 0, &error_abort); + } else { + qemu_opt_set_number(opts, BLOCK_OPT_SIZE, + size - in.offset * in.bsz, &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, @@ -4117,6 +4157,26 @@ static int img_dd(int argc, char **argv) in_pos = in.offset * in.bsz; } + if (bs) { + int64_t blk2sz = blk_getlength(blk2); + if (blk2sz < 0) { + error_report("Failed to get size for '%s'", in.filename); + ret = -1; + goto out; + } + + if (!(dd.conv & C_NOTRUNC)) { + blk_truncate(blk2, 0); + } + if (!(dd.flags & C_SKIP) || (in.offset <= INT64_MAX / in.bsz && + size >= in.offset * in.bsz)) { + if (!(dd.conv & C_NOTRUNC) || + blk2sz < size - in.offset * in.bsz) { + blk_truncate(blk2, size - in.offset * in.bsz); + } + } + } + in.buf = g_new(uint8_t, in.bsz); for (out_pos = 0; in_pos < size; block_count++) { @@ -4152,6 +4212,7 @@ out: qemu_opts_free(create_opts); blk_unref(blk1); blk_unref(blk2); + bdrv_unref(bs); g_free(in.filename); g_free(out.filename); g_free(in.buf);