From: Reda Sallahi <fullmanet@gmail.com>
To: qemu-devel@nongnu.org
Cc: qemu-block@nongnu.org, Kevin Wolf <kwolf@redhat.com>,
Max Reitz <mreitz@redhat.com>, Fam Zheng <famz@redhat.com>,
Stefan Hajnoczi <stefanha@redhat.com>,
Reda Sallahi <fullmanet@gmail.com>
Subject: [Qemu-devel] [PATCH 2/2] qemu-img: change opening method for the output in dd
Date: Fri, 7 Oct 2016 17:36:17 +0200 [thread overview]
Message-ID: <20161007153617.28704-3-fullmanet@gmail.com> (raw)
In-Reply-To: <20161007153617.28704-1-fullmanet@gmail.com>
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 <fullmanet@gmail.com>
---
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
--
2.10.0
next prev parent reply other threads:[~2016-10-07 15:36 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-07 15:36 [Qemu-devel] [PATCH 0/2] qemu-img: change img_open() and opening method in dd Reda Sallahi
2016-10-07 15:36 ` [Qemu-devel] [PATCH 1/2] qemu-img: make img_open() able to surpress file opening errors Reda Sallahi
2016-10-10 19:34 ` Max Reitz
2016-10-07 15:36 ` Reda Sallahi [this message]
2016-10-10 19:52 ` [Qemu-devel] [PATCH 2/2] qemu-img: change opening method for the output in dd Max Reitz
2016-10-10 20:00 ` [Qemu-devel] [PATCH 0/2] qemu-img: change img_open() and opening method " Max Reitz
2016-10-11 11:13 ` no-reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20161007153617.28704-3-fullmanet@gmail.com \
--to=fullmanet@gmail.com \
--cc=famz@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.