Re: [Qemu-devel] [Qemu-block] [PATCH] block: failed qemu-img command should return non-zero exit code

2016-10-09 Thread Reda Sallahi
On Sun, Oct 09, 2016 at 05:17:27PM +0800, Xu Tian wrote:
> If backing file can not open when do qemu-img rebase, var 'ret' not
> assign a no-zero value, qemu-img process go out with exit code zero.
> 
> Signed-off-by: Xu Tian 
> ---
>  qemu-img.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/qemu-img.c b/qemu-img.c
> index 46f2a6d..37dcade 100644
> --- a/qemu-img.c
> +++ b/qemu-img.c
> @@ -2918,6 +2918,7 @@ static int img_rebase(int argc, char **argv)
>  error_reportf_err(local_err,
>"Could not open old backing file '%s': ",
>backing_name);
> +ret = -1;
>  goto out;
>  }
>  
> @@ -2935,6 +2936,7 @@ static int img_rebase(int argc, char **argv)
>  error_reportf_err(local_err,
>"Could not open new backing file '%s': ",
>out_baseimg);
> +ret = -1;
>  goto out;
>  }
>  }
> -- 
> 2.5.5
> 
>

Hi Xu,

You should also CC qemu-devel@nongnu.org (and maybe Max Reitz too) in your
patch.

-- 
Reda




[Qemu-devel] [PATCH 2/2] qemu-img: change opening method for the output in dd

2016-10-07 Thread Reda Sallahi
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 <fullma...@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, _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, _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, _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, _abort);
-}
-
-ret = bdrv_create(drv, out.filename, opts, _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, _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, _abort);
+
+qemu_opt_set_number(opts, BLOCK_OPT_SIZE, out_size, _abort);
+
+ret = bdrv_create(drv, out.filename, opts, _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)) {
+  

[Qemu-devel] [PATCH 0/2] qemu-img: change img_open() and opening method in dd

2016-10-07 Thread Reda Sallahi
The patch series include the previously submitted patch:
[PATCH v5] qemu-img: change opening method for the output in dd

Changes from v5:
* Replace access() with a modified version of img_open() in img_dd()

Depends on:
[PATCH v3] qemu-img: add conv=notrunc option to dd

Reda Sallahi (2):
  qemu-img: make img_open() able to surpress file opening errors
  qemu-img: change opening method for the output in dd

 qemu-img.c | 176 +
 1 file changed, 106 insertions(+), 70 deletions(-)

-- 
2.10.0




[Qemu-devel] [PATCH 1/2] qemu-img: make img_open() able to surpress file opening errors

2016-10-07 Thread Reda Sallahi
Previously img_open() always printed file opening errors even if the intended
action is just to check the file existence as is sometimes the case in
qemu-img dd.

This adds an argument (openerror) to img_open() that specifies whether to print
an opening error or not.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
 qemu-img.c | 54 ++
 tests/qemu-iotests/160 |  1 +
 2 files changed, 33 insertions(+), 22 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 219fd86..6c088bd 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -269,7 +269,7 @@ static int img_open_password(BlockBackend *blk, const char 
*filename,
 
 static BlockBackend *img_open_opts(const char *optstr,
QemuOpts *opts, int flags, bool 
writethrough,
-   bool quiet)
+   bool quiet, bool openerror)
 {
 QDict *options;
 Error *local_err = NULL;
@@ -277,7 +277,9 @@ static BlockBackend *img_open_opts(const char *optstr,
 options = qemu_opts_to_qdict(opts, NULL);
 blk = blk_new_open(NULL, NULL, options, flags, _err);
 if (!blk) {
-error_reportf_err(local_err, "Could not open '%s': ", optstr);
+if (openerror) {
+error_reportf_err(local_err, "Could not open '%s': ", optstr);
+}
 return NULL;
 }
 blk_set_enable_write_cache(blk, !writethrough);
@@ -291,7 +293,8 @@ static BlockBackend *img_open_opts(const char *optstr,
 
 static BlockBackend *img_open_file(const char *filename,
const char *fmt, int flags,
-   bool writethrough, bool quiet)
+   bool writethrough, bool quiet,
+   bool openerror)
 {
 BlockBackend *blk;
 Error *local_err = NULL;
@@ -304,7 +307,9 @@ static BlockBackend *img_open_file(const char *filename,
 
 blk = blk_new_open(filename, NULL, options, flags, _err);
 if (!blk) {
-error_reportf_err(local_err, "Could not open '%s': ", filename);
+if (openerror) {
+error_reportf_err(local_err, "Could not open '%s': ", filename);
+}
 return NULL;
 }
 blk_set_enable_write_cache(blk, !writethrough);
@@ -320,7 +325,7 @@ static BlockBackend *img_open_file(const char *filename,
 static BlockBackend *img_open(bool image_opts,
   const char *filename,
   const char *fmt, int flags, bool writethrough,
-  bool quiet)
+  bool quiet, bool openerror)
 {
 BlockBackend *blk;
 if (image_opts) {
@@ -334,9 +339,11 @@ static BlockBackend *img_open(bool image_opts,
 if (!opts) {
 return NULL;
 }
-blk = img_open_opts(filename, opts, flags, writethrough, quiet);
+blk = img_open_opts(filename, opts, flags, writethrough, quiet,
+openerror);
 } else {
-blk = img_open_file(filename, fmt, flags, writethrough, quiet);
+blk = img_open_file(filename, fmt, flags, writethrough, quiet,
+openerror);
 }
 return blk;
 }
@@ -706,7 +713,7 @@ static int img_check(int argc, char **argv)
 return 1;
 }
 
-blk = img_open(image_opts, filename, fmt, flags, writethrough, quiet);
+blk = img_open(image_opts, filename, fmt, flags, writethrough, quiet, 
true);
 if (!blk) {
 return 1;
 }
@@ -898,7 +905,7 @@ static int img_commit(int argc, char **argv)
 return 1;
 }
 
-blk = img_open(image_opts, filename, fmt, flags, writethrough, quiet);
+blk = img_open(image_opts, filename, fmt, flags, writethrough, quiet, 
true);
 if (!blk) {
 return 1;
 }
@@ -1232,13 +1239,15 @@ static int img_compare(int argc, char **argv)
 goto out3;
 }
 
-blk1 = img_open(image_opts, filename1, fmt1, flags, writethrough, quiet);
+blk1 = img_open(image_opts, filename1, fmt1, flags, writethrough, quiet,
+true);
 if (!blk1) {
 ret = 2;
 goto out3;
 }
 
-blk2 = img_open(image_opts, filename2, fmt2, flags, writethrough, quiet);
+blk2 = img_open(image_opts, filename2, fmt2, flags, writethrough, quiet,
+true);
 if (!blk2) {
 ret = 2;
 goto out2;
@@ -1943,7 +1952,7 @@ static int img_convert(int argc, char **argv)
 total_sectors = 0;
 for (bs_i = 0; bs_i < bs_n; bs_i++) {
 blk[bs_i] = img_open(image_opts, argv[optind + bs_i],
- fmt, src_flags, src_writethrough, quiet);
+ fmt, src_flags, src_writethrough, quiet, true);
 if (!blk[bs_i]) {
 ret = -1;
 goto out;
@@ -2088,7 +2097,8 @@ static int img_convert(int argc, char **argv)
   

[Qemu-devel] [PATCH v2] sh4: fix broken link to documentation

2016-08-31 Thread Reda Sallahi
The page that was previously linked in the source code and the README file is
no longer available so it now returns a 404 error message.

This puts a previous snapshot from archive.org instead.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
Changes from v1:
* Add the 'https://' part to the link in hw/sh4/shix.c.

 hw/sh4/shix.c | 2 +-
 target-sh4/README.sh4 | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/sh4/shix.c b/hw/sh4/shix.c
index ccc9e75..14d4007 100644
--- a/hw/sh4/shix.c
+++ b/hw/sh4/shix.c
@@ -23,7 +23,7 @@
  */
 /*
Shix 2.0 board by Alexis Polti, described at
-   http://perso.enst.fr/~polti/realisations/shix20/
+   
https://web.archive.org/web/20070917001736/perso.enst.fr/~polti/realisations/shix20
 
More information in target-sh4/README.sh4
 */
diff --git a/target-sh4/README.sh4 b/target-sh4/README.sh4
index e578830..ece0464 100644
--- a/target-sh4/README.sh4
+++ b/target-sh4/README.sh4
@@ -25,7 +25,7 @@ Goals
 
 The primary model being worked on is the soft MMU target to be able to
 emulate the Shix 2.0 board by Alexis Polti, described at
-http://perso.enst.fr/~polti/realisations/shix20/
+https://web.archive.org/web/20070917001736/http://perso.enst.fr/~polti/realisations/shix20/
 
 Ultimately, qemu will be coupled with a system C or a verilog
 simulator to simulate the whole board functionalities.
-- 
2.9.3




[Qemu-devel] [PATCH] sh4: fix broken link to documentation

2016-08-31 Thread Reda Sallahi
The page that was previously linked in the source code and the README file is
no longer available so it now returns a 404 error message.

This puts a previous snapshot from archive.org instead.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
 hw/sh4/shix.c | 2 +-
 target-sh4/README.sh4 | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/sh4/shix.c b/hw/sh4/shix.c
index ccc9e75..2ac79fc 100644
--- a/hw/sh4/shix.c
+++ b/hw/sh4/shix.c
@@ -23,7 +23,7 @@
  */
 /*
Shix 2.0 board by Alexis Polti, described at
-   http://perso.enst.fr/~polti/realisations/shix20/
+   web.archive.org/web/20070917001736/perso.enst.fr/~polti/realisations/shix20
 
More information in target-sh4/README.sh4
 */
diff --git a/target-sh4/README.sh4 b/target-sh4/README.sh4
index e578830..ece0464 100644
--- a/target-sh4/README.sh4
+++ b/target-sh4/README.sh4
@@ -25,7 +25,7 @@ Goals
 
 The primary model being worked on is the soft MMU target to be able to
 emulate the Shix 2.0 board by Alexis Polti, described at
-http://perso.enst.fr/~polti/realisations/shix20/
+https://web.archive.org/web/20070917001736/http://perso.enst.fr/~polti/realisations/shix20/
 
 Ultimately, qemu will be coupled with a system C or a verilog
 simulator to simulate the whole board functionalities.
-- 
2.9.3




[Qemu-devel] [PATCH v2 6/7] qemu-img: clean up dd documentation

2016-08-26 Thread Reda Sallahi
The dd section on qemu-img --help was a bit hard to read since it was not
well aligned. This patch fixes the display problem and also makes the
sentences on the .texi file more consistent with one another (uppercase and
conjugasion).

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefa...@redhat.com>
---
 qemu-img.c| 48 +---
 qemu-img.texi | 48 
 2 files changed, 49 insertions(+), 47 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 55977ff..207e16c 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -169,37 +169,39 @@ static void QEMU_NORETURN help(void)
"  '-s' run in Strict mode - fail on different image size or sector 
allocation\n"
"\n"
"Parameters to dd subcommand:\n"
-   "  'bs=BYTES' read and write up to BYTES bytes at a time "
+   "  'bs=BYTES' read and write up to BYTES bytes at a time "
"(default: 512)\n"
-   "  'count=N' copy only N input blocks\n"
-   "  'if=FILE' read from FILE\n"
-   "  'of=FILE' write to FILE\n"
-   "  'skip=N' skip N bs-sized blocks at the start of input\n"
-   "  'seek=N' seek N bs-sized blocks at the start of output\n"
-   "  'conv=CONVS' do not truncate the output file\n"
+   "  'count=N'  copy only N input blocks\n"
+   "  'if=FILE'  read from FILE\n"
+   "  'of=FILE'  write to FILE\n"
+   "  'skip=N'   skip N bs-sized blocks at the start of input\n"
+   "  'seek=N'   seek N bs-sized blocks at the start of output\n"
+   "  'conv=CONVS'   do not truncate the output file\n"
"  'iflags=FLAGS' read using the comma-separated flags list\n"
"  'oflags=FLAGS' read using the comma-separated flags list\n"
"  'status=LEVEL' the LEVEL of information to print to stderr\n\n"
"List of LEVELS for dd:\n"
-   "  'none'   surpresses everything but error messages\n"
-   "  'noxfer' surpresses the final transfer statistics\n\n"
+   "  'none' surpress everything but error messages\n"
+   "  'noxfer'   surpress the final transfer statistics\n\n"
"List of CONVS for dd:\n"
-   "  'notrunc'   do not truncate the output file\n"
-   "  'noerror'   continue in the event of read errors\n"
-   "  'excl'  fail if output already exists\n"
-   "  'nocreat'   do not create the output file\n"
-   "  'fsync' physically write output file data before finishing\n"
-   "  'fdatasync' physically write output file data before finishing\n"
-   "  'sync'  pad every input block with NULs\n"
-   "  'sparse'seek rather than write the output for NUL input"
+   "  'notrunc'  do not truncate the output file\n"
+   "  'noerror'  continue in the event of read errors\n"
+   "  'excl' fail if output already exists\n"
+   "  'nocreat'  do not create the output file\n"
+   "  'fsync'physically write output file data before"
+   " finishing\n"
+   "  'fdatasync'physically write output file data before"
+   " finishing\n"
+   "  'sync' pad every input block with NULs\n"
+   "  'sparse'   seek rather than write the output for NUL input"
" blocks\n\n"
"List of FLAGS for dd:\n"
-   "  'direct'  use direct I/O for data\n"
-   "  'dsync'   use synchronized I/O for data\n"
-   "  'sync'use synchronized I/O for data\n"
-   "  'count_bytes' use 'count=N' as a byte count (iflag only)\n"
-   "  'skip_bytes'  use 'skip=N' as a byte count (iflag only)\n"
-   "  'seek_bytes'  use 'seek=N' as a byte count (oflag only)\n";
+   "  'direct'   use direct I/O for data\n"
+   "  'dsync'use synchronized I/O for data\n"
+   "  'sync' use synchronized I/O for data\n"
+   "  'count_bytes'  use 'count=N' as a byte count (iflag only)\n"
+   "  'skip_bytes'   use 'skip=N' as a byte count (iflag only)\n"
+   "  'seek_bytes'   use 'seek=N' as a byte count (oflag only)\n";
 
 printf("%s\n

[Qemu-devel] [PATCH v2 4/7] qemu-img: delete not used variable and an unecessary check

2016-08-26 Thread Reda Sallahi
block_count is not used in img_dd() and the C_SKIP check is unecessary so
this patch removes both of them.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefa...@redhat.com>
---
 qemu-img.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index a4d0556..bd3e80d 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -4066,7 +4066,7 @@ static int img_dd(int argc, char **argv)
 const char *fmt = NULL;
 const char *out_filename;
 int64_t size = 0, out_size = 0;
-int64_t block_count = 0, out_pos, in_pos, sparse_count = 0;
+int64_t out_pos, in_pos, sparse_count = 0;
 bool writethrough = false;
 int flags = 0;
 int ibsz = 0, obsz = 0, bsz;
@@ -4344,8 +4344,7 @@ static int img_dd(int argc, char **argv)
 }
 }
 
-if (dd.flags & C_SKIP && (in.offset > INT64_MAX / ibsz ||
-  size < in.offset * ibsz)) {
+if (in.offset > INT64_MAX / ibsz || size < in.offset * ibsz) {
 /* We give a warning if the skip option is bigger than the input
  * size and create an empty output disk image (i.e. like dd(1)).
  */
@@ -4357,7 +4356,7 @@ static int img_dd(int argc, char **argv)
 
 in.buf = g_new(uint8_t, in.bsz);
 
-for (out_pos = out.offset * obsz; in_pos < size; block_count++) {
+for (out_pos = out.offset * obsz; in_pos < size;) {
 int in_ret, out_ret;
 bsz = in.bsz;
 
-- 
2.9.3




[Qemu-devel] [PATCH v2 7/7] qemu-img: add a test suite for the count option

2016-08-26 Thread Reda Sallahi
The count option for dd lacked a test suite so this adds one with four test
cases.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefa...@redhat.com>
---
 tests/qemu-iotests/168 | 75 ++
 tests/qemu-iotests/168.out | 51 +++
 tests/qemu-iotests/group   |  1 +
 3 files changed, 127 insertions(+)
 create mode 100755 tests/qemu-iotests/168
 create mode 100644 tests/qemu-iotests/168.out

diff --git a/tests/qemu-iotests/168 b/tests/qemu-iotests/168
new file mode 100755
index 000..3ed655e
--- /dev/null
+++ b/tests/qemu-iotests/168
@@ -0,0 +1,75 @@
+#! /bin/bash
+#
+# qemu-img dd test for count option
+#
+# Copyright (C) 2016 Reda Sallahi
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+owner=fullma...@gmail.com
+
+seq="$(basename $0)"
+echo "QA output created by $seq"
+
+here="$PWD"
+status=1
+
+_cleanup()
+{
+_cleanup_test_img
+rm -f "$TEST_IMG.out" "$TEST_IMG.out.dd"
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+. ./common.rc
+. ./common.filter
+. ./common.pattern
+
+_supported_fmt raw
+_supported_proto file
+_supported_os Linux
+
+TEST_COUNT_BLOCKS="1 4 19 43K"
+
+for count in $TEST_COUNT_BLOCKS; do
+echo
+echo "== Creating image =="
+
+size=1M
+_make_test_img $size
+_check_test_img
+
+$QEMU_IO -c "write -P 0xa 565k 384k" "$TEST_IMG" | _filter_qemu_io
+
+echo
+echo "== Converting the image with dd with count=$count =="
+
+$QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" count=$count \
+  -O "$IMGFMT" status=none conv=notrunc
+
+TEST_IMG="$TEST_IMG.out" _check_test_img
+
+dd if="$TEST_IMG" of="$TEST_IMG.out.dd" count=$count status=none
+
+echo
+echo "== Compare the images with qemu-img compare =="
+
+$QEMU_IMG compare "$TEST_IMG.out.dd" "$TEST_IMG.out"
+done
+
+echo
+echo "*** done"
+rm -f "$seq.full"
+status=0
diff --git a/tests/qemu-iotests/168.out b/tests/qemu-iotests/168.out
new file mode 100644
index 000..768a687
--- /dev/null
+++ b/tests/qemu-iotests/168.out
@@ -0,0 +1,51 @@
+QA output created by 168
+
+== Creating image ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
+No errors were found on the image.
+wrote 393216/393216 bytes at offset 578560
+384 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with count=1 ==
+No errors were found on the image.
+
+== Compare the images with qemu-img compare ==
+Images are identical.
+
+== Creating image ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
+No errors were found on the image.
+wrote 393216/393216 bytes at offset 578560
+384 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with count=4 ==
+No errors were found on the image.
+
+== Compare the images with qemu-img compare ==
+Images are identical.
+
+== Creating image ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
+No errors were found on the image.
+wrote 393216/393216 bytes at offset 578560
+384 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with count=19 ==
+No errors were found on the image.
+
+== Compare the images with qemu-img compare ==
+Images are identical.
+
+== Creating image ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
+No errors were found on the image.
+wrote 393216/393216 bytes at offset 578560
+384 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with count=43K ==
+No errors were found on the image.
+
+== Compare the images with qemu-img compare ==
+Images are identical.
+
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index fbe0ffe..9e47975 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -167,3 +167,4 @@
 165 rw auto quick
 166 rw auto quick
 167 rw auto quick
+168 rw auto quick
-- 
2.9.3




[Qemu-devel] [PATCH v2 5/7] qemu-img: add status option to dd

2016-08-26 Thread Reda Sallahi
This patch adds the status option to the subcommand dd. With this dd will
display by default the number of blocks read/written, the transfer rate, etc.
like dd(1).

The noxfer and none levels will allow the user to surpress the final transfer
statistics and everything except error messages respectively.

A test case was added to test the status option.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
 qemu-img-cmds.hx   |  4 +--
 qemu-img.c | 87 ++
 qemu-img.texi  |  9 -
 tests/qemu-iotests/159 |  2 +-
 tests/qemu-iotests/160 |  2 +-
 tests/qemu-iotests/161 |  2 +-
 tests/qemu-iotests/163 |  4 +--
 tests/qemu-iotests/164 |  4 +--
 tests/qemu-iotests/165 | 11 +++---
 tests/qemu-iotests/166 |  2 +-
 tests/qemu-iotests/167 | 77 
 tests/qemu-iotests/167.out | 17 +
 tests/qemu-iotests/group   |  1 +
 13 files changed, 200 insertions(+), 22 deletions(-)
 create mode 100755 tests/qemu-iotests/167
 create mode 100644 tests/qemu-iotests/167.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 933ce3c..6315c64 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -46,9 +46,9 @@ STEXI
 ETEXI
 
 DEF("dd", img_dd,
-"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] [seek=blocks] [conv=convs] [iflag=flags] [oflag=flags] if=input 
of=output")
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] [seek=blocks] [conv=convs] [iflag=flags] [oflag=flags] 
[status=level] if=input of=output")
 STEXI
-@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] 
[seek=@var{blocks}] [conv=@var{convs}] [iflag=@var{flags}] [oflag=@var{flags}] 
if=@var{input} of=@var{output}
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] 
[seek=@var{blocks}] [conv=@var{convs}] [iflag=@var{flags}] [oflag=@var{flags}] 
[status=@var{level}] if=@var{input} of=@var{output}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index bd3e80d..55977ff 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -178,7 +178,11 @@ static void QEMU_NORETURN help(void)
"  'seek=N' seek N bs-sized blocks at the start of output\n"
"  'conv=CONVS' do not truncate the output file\n"
"  'iflags=FLAGS' read using the comma-separated flags list\n"
-   "  'oflags=FLAGS' read using the comma-separated flags list\n\n"
+   "  'oflags=FLAGS' read using the comma-separated flags list\n"
+   "  'status=LEVEL' the LEVEL of information to print to stderr\n\n"
+   "List of LEVELS for dd:\n"
+   "  'none'   surpresses everything but error messages\n"
+   "  'noxfer' surpresses the final transfer statistics\n\n"
"List of CONVS for dd:\n"
"  'notrunc'   do not truncate the output file\n"
"  'noerror'   continue in the event of read errors\n"
@@ -3832,11 +3836,13 @@ out:
 #define C_CONV0100
 #define C_IFLAG   0200
 #define C_OFLAG   0400
+#define C_STATUS  01000
 
 struct DdInfo {
 unsigned int flags;
 int64_t count;
 unsigned int conv;
+unsigned int status;
 };
 
 struct DdIo {
@@ -4049,6 +4055,30 @@ static int img_dd_conv(const char *arg,
 return ret;
 }
 
+#define C_STATUS_DEFAULT  00
+#define C_STATUS_NONE 01
+#define C_STATUS_NOXFER   02
+
+static int img_dd_status(const char *arg,
+ struct DdIo *in, struct DdIo *out,
+ struct DdInfo *dd)
+{
+const struct DdSymbols dd_status[] = {
+{ "none", C_STATUS_NONE },
+{ "noxfer", C_STATUS_NOXFER },
+{ NULL, 0 }
+};
+
+for (int j = 0; dd_status[j].name != NULL; j++) {
+if (!strcmp(arg, dd_status[j].name)) {
+dd->status = dd_status[j].value;
+return 0;
+}
+}
+
+error_report("invalid status level: '%s'", arg);
+return 1;
+}
 
 static int img_dd(int argc, char **argv)
 {
@@ -4067,13 +4097,16 @@ static int img_dd(int argc, char **argv)
 const char *out_filename;
 int64_t size = 0, out_size = 0;
 int64_t out_pos, in_pos, sparse_count = 0;
+int64_t in_read = 0, out_wrt = 0; /* Read/write count for status= */
 bool writethrough = false;
 int flags = 0;
 int ibsz = 0, obsz = 0, bsz;
+struct timeval starttv, endtv;
 struct DdInfo dd = {
 .flags = 0,
 .count = 0,
-.conv = 0
+.conv = 0,
+.status = C_STATUS_DEFAULT
 };
 struct DdIo in = {
 .bsz = 512, /* Block size is by defa

[Qemu-devel] [PATCH v2 1/7] qemu-img: add seek option to dd

2016-08-26 Thread Reda Sallahi
This patch adds the seek option which allows qemu-img dd to skip a number of
blocks on the output before copying the input.

A test case was added to test the seek option.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefa...@redhat.com>
---
 qemu-img-cmds.hx   |  4 +--
 qemu-img.c | 45 +++-
 qemu-img.texi  |  4 ++-
 tests/qemu-iotests/161 | 73 ++
 tests/qemu-iotests/161.out | 51 
 tests/qemu-iotests/group   |  1 +
 6 files changed, 167 insertions(+), 11 deletions(-)
 create mode 100755 tests/qemu-iotests/161
 create mode 100644 tests/qemu-iotests/161.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 18685ac..e79a577 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -46,9 +46,9 @@ STEXI
 ETEXI
 
 DEF("dd", img_dd,
-"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] [conv=notrunc] if=input of=output")
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] [seek=blocks] [conv=notrunc] if=input of=output")
 STEXI
-@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] [conv=notrunc] 
if=@var{input} of=@var{output}
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] 
[seek=@var{blocks}] [conv=notrunc] if=@var{input} of=@var{output}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 816a406..7d313fd 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -175,6 +175,7 @@ static void QEMU_NORETURN help(void)
"  'if=FILE' read from FILE\n"
"  'of=FILE' write to FILE\n"
"  'skip=N' skip N bs-sized blocks at the start of input\n"
+   "  'seek=N' seek N bs-sized blocks at the start of output\n"
"  'conv=notrunc' do not truncate the output file\n";
 
 printf("%s\nSupported formats:", help_msg);
@@ -3808,7 +3809,8 @@ out:
 #define C_IF  04
 #define C_OF  010
 #define C_SKIP020
-#define C_CONV040
+#define C_SEEK040
+#define C_CONV0100
 
 struct DdInfo {
 unsigned int flags;
@@ -3897,6 +3899,22 @@ static int img_dd_skip(const char *arg,
 return 0;
 }
 
+static int img_dd_seek(const char *arg,
+   struct DdIo *in, struct DdIo *out,
+   struct DdInfo *dd)
+{
+char *end;
+
+out->offset = qemu_strtosz_suffix(arg, , QEMU_STRTOSZ_DEFSUFFIX_B);
+
+if (out->offset < 0 || *end) {
+error_report("invalid number: '%s'", arg);
+return 1;
+}
+
+return 0;
+}
+
 #define C_NOTRUNC 01
 
 static int img_dd_conv(const char *arg,
@@ -3927,7 +3945,7 @@ static int img_dd(int argc, char **argv)
 const char *out_fmt = "raw";
 const char *fmt = NULL;
 const char *out_filename;
-int64_t size = 0, out_size;
+int64_t size = 0, out_size = 0;
 int64_t block_count = 0, out_pos, in_pos;
 struct DdInfo dd = {
 .flags = 0,
@@ -3953,6 +3971,7 @@ static int img_dd(int argc, char **argv)
 { "if", img_dd_if, C_IF },
 { "of", img_dd_of, C_OF },
 { "skip", img_dd_skip, C_SKIP },
+{ "seek", img_dd_seek, C_SEEK },
 { "conv", img_dd_conv, C_CONV },
 { NULL, NULL, 0 }
 };
@@ -4019,6 +4038,14 @@ static int img_dd(int argc, char **argv)
 arg = NULL;
 }
 
+/* Overflow check for seek */
+if (out.offset > INT64_MAX / out.bsz) {
+error_report("seek with the block size specified is too large "
+ "for data type used");
+ret = -1;
+goto out;
+}
+
 if (!(dd.flags & C_IF && dd.flags & C_OF)) {
 error_report("Must specify both input and output files");
 ret = -1;
@@ -4044,9 +4071,9 @@ static int img_dd(int argc, char **argv)
 }
 /* Overflow means the specified offset is beyond input image's size */
 if (in.offset > INT64_MAX / in.bsz || size < in.offset * in.bsz) {
-out_size = 0;
+out_size = out.offset * out.bsz;
 } else {
-out_size = size - in.offset * in.bsz;
+out_size = size - in.offset * in.bsz + out.offset * out.bsz;
 }
 
 out_filename = out.filename;
@@ -4132,10 +4159,12 @@ static int img_dd(int argc, char **argv)
 goto out;
 }
 
-if (in.offset <= INT64_MAX / in.bsz && size >= in.offset * in.bsz) {
-if (blk2sz < out_size) {
-blk_truncate(blk2, out_size);
+if (in.offset > INT64_MAX / in.bsz || size < in.offset * in.bsz) {
+ 

[Qemu-devel] [PATCH v2 3/7] qemu-img: add more conv= conversions to dd

2016-08-26 Thread Reda Sallahi
This patch adds excl, nocreat, noerror, sync, fsync, fdatasync and sparse to
the conversion list. They have the same meaning as the ones on GNU dd(1).

Two tests were added to test the conv= option.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
 qemu-img-cmds.hx   |   4 +-
 qemu-img.c | 129 +++--
 qemu-img.texi  |  26 +++--
 tests/qemu-iotests/165 | 109 ++
 tests/qemu-iotests/165.out |  33 
 tests/qemu-iotests/166 |  73 +
 tests/qemu-iotests/166.out |  19 +++
 tests/qemu-iotests/group   |   2 +
 8 files changed, 363 insertions(+), 32 deletions(-)
 create mode 100755 tests/qemu-iotests/165
 create mode 100644 tests/qemu-iotests/165.out
 create mode 100755 tests/qemu-iotests/166
 create mode 100644 tests/qemu-iotests/166.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 25eaf71..933ce3c 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -46,9 +46,9 @@ STEXI
 ETEXI
 
 DEF("dd", img_dd,
-"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] [seek=blocks] [conv=notrunc] [iflag=flags] [oflag=flags] if=input 
of=output")
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] [seek=blocks] [conv=convs] [iflag=flags] [oflag=flags] if=input 
of=output")
 STEXI
-@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] 
[seek=@var{blocks}] [conv=notrunc] [iflag=@var{flags}] [oflag=@var{flags}] 
if=@var{input} of=@var{output}
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] 
[seek=@var{blocks}] [conv=@var{convs}] [iflag=@var{flags}] [oflag=@var{flags}] 
if=@var{input} of=@var{output}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 7b2c525..a4d0556 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -176,9 +176,19 @@ static void QEMU_NORETURN help(void)
"  'of=FILE' write to FILE\n"
"  'skip=N' skip N bs-sized blocks at the start of input\n"
"  'seek=N' seek N bs-sized blocks at the start of output\n"
-   "  'conv=notrunc' do not truncate the output file\n"
+   "  'conv=CONVS' do not truncate the output file\n"
"  'iflags=FLAGS' read using the comma-separated flags list\n"
"  'oflags=FLAGS' read using the comma-separated flags list\n\n"
+   "List of CONVS for dd:\n"
+   "  'notrunc'   do not truncate the output file\n"
+   "  'noerror'   continue in the event of read errors\n"
+   "  'excl'  fail if output already exists\n"
+   "  'nocreat'   do not create the output file\n"
+   "  'fsync' physically write output file data before finishing\n"
+   "  'fdatasync' physically write output file data before finishing\n"
+   "  'sync'  pad every input block with NULs\n"
+   "  'sparse'seek rather than write the output for NUL input"
+   " blocks\n\n"
"List of FLAGS for dd:\n"
"  'direct'  use direct I/O for data\n"
"  'dsync'   use synchronized I/O for data\n"
@@ -3932,21 +3942,6 @@ static int img_dd_seek(const char *arg,
 return 0;
 }
 
-#define C_NOTRUNC 01
-
-static int img_dd_conv(const char *arg,
-   struct DdIo *in, struct DdIo *out,
-   struct DdInfo *dd)
-{
-if (!strcmp(arg, "notrunc")) {
-dd->conv |= C_NOTRUNC;
-return 0;
-} else {
-error_report("invalid conversion: '%s'", arg);
-return 1;
-}
-}
-
 #define C_DIRECT  01
 #define C_IOFLAG_SYNC 02
 #define C_DSYNC   04
@@ -3954,7 +3949,7 @@ static int img_dd_conv(const char *arg,
 #define C_SKIP_BYTES  020
 #define C_SEEK_BYTES  040
 
-static int img_dd_flag(const char *arg, struct DdIo *io,
+static int img_dd_flag(const char *arg, struct DdIo *io, struct DdInfo *dd,
const struct DdSymbols *flags, const char *err_str)
 {
 int ret = 0;
@@ -3968,7 +3963,11 @@ static int img_dd_flag(const char *arg, struct DdIo *io,
 int j;
 for (j = 0; flags[j].name != NULL; j++) {
 if (!strcmp(tok, flags[j].name)) {
-io->flags |= flags[j].value;
+if (dd) {
+dd->conv |= flags[j].value;
+} else {
+io->flags |= flags[j].value;
+}
 break;
 }
 }
@@ -3996,7 +3995,7 @@ static int img_dd_

[Qemu-devel] [PATCH v2 2/7] qemu-img: add iflag and oflag options to dd

2016-08-26 Thread Reda Sallahi
This adds the iflag and oflag options which defines the list of flags used
for reading and writing respectively. The list is comma-separated.

The iflag option supports direct, dsync, sync, count_bytes and skip_bytes
and oflag supports direct, dsync, sync and seek_bytes. They are similar to
their counterparts on GNU dd(1).

Two tests were added to test iflag and oflag.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
 qemu-img-cmds.hx   |   4 +-
 qemu-img.c | 172 +++--
 qemu-img.texi  |  32 +++--
 tests/qemu-iotests/163 | 103 +++
 tests/qemu-iotests/163.out | 135 +++
 tests/qemu-iotests/164 | 100 ++
 tests/qemu-iotests/164.out |  75 
 tests/qemu-iotests/group   |   2 +
 8 files changed, 595 insertions(+), 28 deletions(-)
 create mode 100755 tests/qemu-iotests/163
 create mode 100644 tests/qemu-iotests/163.out
 create mode 100755 tests/qemu-iotests/164
 create mode 100644 tests/qemu-iotests/164.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index e79a577..25eaf71 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -46,9 +46,9 @@ STEXI
 ETEXI
 
 DEF("dd", img_dd,
-"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] [seek=blocks] [conv=notrunc] if=input of=output")
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] [seek=blocks] [conv=notrunc] [iflag=flags] [oflag=flags] if=input 
of=output")
 STEXI
-@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] 
[seek=@var{blocks}] [conv=notrunc] if=@var{input} of=@var{output}
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] 
[seek=@var{blocks}] [conv=notrunc] [iflag=@var{flags}] [oflag=@var{flags}] 
if=@var{input} of=@var{output}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 7d313fd..7b2c525 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -176,7 +176,16 @@ static void QEMU_NORETURN help(void)
"  'of=FILE' write to FILE\n"
"  'skip=N' skip N bs-sized blocks at the start of input\n"
"  'seek=N' seek N bs-sized blocks at the start of output\n"
-   "  'conv=notrunc' do not truncate the output file\n";
+   "  'conv=notrunc' do not truncate the output file\n"
+   "  'iflags=FLAGS' read using the comma-separated flags list\n"
+   "  'oflags=FLAGS' read using the comma-separated flags list\n\n"
+   "List of FLAGS for dd:\n"
+   "  'direct'  use direct I/O for data\n"
+   "  'dsync'   use synchronized I/O for data\n"
+   "  'sync'use synchronized I/O for data\n"
+   "  'count_bytes' use 'count=N' as a byte count (iflag only)\n"
+   "  'skip_bytes'  use 'skip=N' as a byte count (iflag only)\n"
+   "  'seek_bytes'  use 'seek=N' as a byte count (oflag only)\n";
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_format(format_print, NULL);
@@ -3811,6 +3820,8 @@ out:
 #define C_SKIP020
 #define C_SEEK040
 #define C_CONV0100
+#define C_IFLAG   0200
+#define C_OFLAG   0400
 
 struct DdInfo {
 unsigned int flags;
@@ -3823,6 +3834,7 @@ struct DdIo {
 char *filename;
 uint8_t *buf;
 int64_t offset;
+unsigned int flags;
 };
 
 struct DdOpts {
@@ -3831,6 +3843,11 @@ struct DdOpts {
 unsigned int flag;
 };
 
+struct DdSymbols {
+const char *name;
+unsigned int value;
+};
+
 static int img_dd_bs(const char *arg,
  struct DdIo *in, struct DdIo *out,
  struct DdInfo *dd)
@@ -3930,6 +3947,73 @@ static int img_dd_conv(const char *arg,
 }
 }
 
+#define C_DIRECT  01
+#define C_IOFLAG_SYNC 02
+#define C_DSYNC   04
+#define C_COUNT_BYTES 010
+#define C_SKIP_BYTES  020
+#define C_SEEK_BYTES  040
+
+static int img_dd_flag(const char *arg, struct DdIo *io,
+   const struct DdSymbols *flags, const char *err_str)
+{
+int ret = 0;
+const char *tok;
+char *str, *tmp;
+
+tmp = str = g_strdup(arg);
+
+while (tmp != NULL && !ret) {
+tok = qemu_strsep(, ",");
+int j;
+for (j = 0; flags[j].name != NULL; j++) {
+if (!strcmp(tok, flags[j].name)) {
+io->flags |= flags[j].value;
+break;
+}
+}
+if (flags[j].name == NULL) {
+error_report("%s: '%s'", err_str, tok);
+ret = 1;
+}
+}
+
+g_free(str);
+
+ 

[Qemu-devel] [PATCH v2 0/7] qemu-img dd

2016-08-26 Thread Reda Sallahi
Hi everyone,

This patchset adds additional options to qemu-img dd.

Depends on:
[PATCH v5] qemu-img: change opening method for the output in dd

Changes from v1:
* Use for qemu_{timersub,gettimeofday} instead of timersub and gettimeofday.
* Add skip= and seek= options for test case 167.
* Put the common part in img_dd_iflag(), img_dd_oflag() and img_dd_conv()
into a new function img_dd_flag().

Reda Sallahi (7):
  qemu-img: add seek option to dd
  qemu-img: add iflag and oflag options to dd
  qemu-img: add more conv= conversions to dd
  qemu-img: delete not used variable and an unecessary check
  qemu-img: add status option to dd
  qemu-img: clean up dd documentation
  qemu-img: add a test suite for the count option

 qemu-img-cmds.hx   |   4 +-
 qemu-img.c | 400 +++--
 qemu-img.texi  |  69 +++-
 tests/qemu-iotests/159 |   2 +-
 tests/qemu-iotests/160 |   2 +-
 tests/qemu-iotests/161 |  73 +
 tests/qemu-iotests/161.out |  51 ++
 tests/qemu-iotests/163 | 103 
 tests/qemu-iotests/163.out | 135 +++
 tests/qemu-iotests/164 | 100 
 tests/qemu-iotests/164.out |  75 +
 tests/qemu-iotests/165 | 110 +
 tests/qemu-iotests/165.out |  33 
 tests/qemu-iotests/166 |  73 +
 tests/qemu-iotests/166.out |  19 +++
 tests/qemu-iotests/167 |  77 +
 tests/qemu-iotests/167.out |  17 ++
 tests/qemu-iotests/168 |  75 +
 tests/qemu-iotests/168.out |  51 ++
 tests/qemu-iotests/group   |   7 +
 20 files changed, 1418 insertions(+), 58 deletions(-)
 create mode 100755 tests/qemu-iotests/161
 create mode 100644 tests/qemu-iotests/161.out
 create mode 100755 tests/qemu-iotests/163
 create mode 100644 tests/qemu-iotests/163.out
 create mode 100755 tests/qemu-iotests/164
 create mode 100644 tests/qemu-iotests/164.out
 create mode 100755 tests/qemu-iotests/165
 create mode 100644 tests/qemu-iotests/165.out
 create mode 100755 tests/qemu-iotests/166
 create mode 100644 tests/qemu-iotests/166.out
 create mode 100755 tests/qemu-iotests/167
 create mode 100644 tests/qemu-iotests/167.out
 create mode 100755 tests/qemu-iotests/168
 create mode 100644 tests/qemu-iotests/168.out

-- 
2.9.3




[Qemu-devel] [PATCH v5] qemu-img: change opening method for the output in dd

2016-08-26 Thread Reda Sallahi
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.

We also make it mandatory to specify conv=notrunc when the file already
exists.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
Depends on:
[PATCH v3] qemu-img: add conv=notrunc option to dd

Changes from v4:
* Use access() to check file existence first and remove blk_new_open()
Changes from v3:
* Remove unnecessary checks
Changes from v2:
* Remove redundant code
Changes from v1:
* add --image-opts handling

 qemu-img.c | 142 +++--
 1 file changed, 92 insertions(+), 50 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index f8ba5e5..816a406 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -3919,14 +3919,15 @@ static int img_dd(int argc, char **argv)
 char *tmp;
 BlockDriver *drv = NULL, *proto_drv = NULL;
 BlockBackend *blk1 = NULL, *blk2 = NULL;
-QemuOpts *opts = NULL;
+QemuOpts *opts = NULL, *qopts = NULL;
 QemuOptsList *create_opts = NULL;
 Error *local_err = NULL;
 bool image_opts = false;
 int c, i;
 const char *out_fmt = "raw";
 const char *fmt = NULL;
-int64_t size = 0;
+const char *out_filename;
+int64_t size = 0, out_size;
 int64_t block_count = 0, out_pos, in_pos;
 struct DdInfo dd = {
 .flags = 0,
@@ -4030,36 +4031,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, _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, _abort);
-
 size = blk_getlength(blk1);
 if (size < 0) {
 error_report("Failed to get size for '%s'", in.filename);
@@ -4071,31 +4042,101 @@ 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, _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, _abort);
+out_size = size - in.offset * in.bsz;
 }
 
-ret = bdrv_create(drv, out.filename, opts, _err);
-if (ret < 0) {
-error_reportf_err(local_err,
-  "%s: error while creating output image: ",
-  out.filename);
-ret = -1;
-goto out;
+out_filename = out.filename;
+if (image_opts) {
+qopts = qemu_opts_parse_noisily(qemu_find_opts("source"),
+out.filename, true);
+out_filename = qemu_opt_get(qopts, "filename");
 }
 
-blk2 = img_open(image_opts, out.filename, out_fmt, BDRV_O_RDWR,
-false, false);
+ret = access(out_filename, F_OK); /* Check if file exists */
 
-if (!blk2) {
-ret = -1;
-goto out;
+if (ret == -1) {
+ret = 0; /* Reset */
+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, _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->for

Re: [Qemu-devel] [PATCH 3/7] qemu-img: add more conv= conversions to dd

2016-08-22 Thread Reda Sallahi
On Mon, Aug 22, 2016 at 09:35:26AM -0400, Stefan Hajnoczi wrote:
> On Mon, Aug 22, 2016 at 09:55:13AM +0200, Reda Sallahi wrote:
> > @@ -4325,20 +4388,43 @@ static int img_dd(int argc, char **argv)
> >  
> >  for (out_pos = out.offset * obsz; in_pos < size; block_count++) {
> >  int in_ret, out_ret;
> > +bsz = in.bsz;
> >  
> >  if (in_pos + in.bsz > size) {
> > -in_ret = blk_pread(blk1, in_pos, in.buf, size - in_pos);
> > -} else {
> > -in_ret = blk_pread(blk1, in_pos, in.buf, in.bsz);
> > +bsz = size - in_pos;
> > +}
> > +
> > +if (dd.conv & C_SYNC) {
> > +memset(in.buf, 0, in.bsz);
> >  }
> 
> Why is memset necessary?

When we set conv=noerror,sync sync tells dd to pad each block with NULs so
that if there is an error it preserves the size of the input read.

-- 
Reda




Re: [Qemu-devel] [PATCH 5/7] qemu-img: add status option to dd

2016-08-22 Thread Reda Sallahi
I should have checked the previous test suites because : 

Mon, Aug 22, 2016 at 09:55:15AM +0200, Reda Sallahi wrote:
>  
>  if (in.offset > INT64_MAX / ibsz || size < in.offset * ibsz) {
> -/* We give a warning if the skip option is bigger than the input
> - * size and create an empty output disk image (i.e. like dd(1)).
> - */
> -error_report("%s: cannot skip to specified offset", in.filename);
> -in_pos = size;
> +if (!(dd.status & C_STATUS_NONE)) {
> +/* We give a warning if the skip option is bigger than the input
> + * size and create an empty output disk image (i.e. like dd(1)).
> + */
> +error_report("%s: cannot skip to specified offset", in.filename);
> +in_pos = size;
> +}

in_pos = size should have gone outside of this last block. This means in_pos
is set to size only if dd.status != C_STATUS_NONE.

> +$QEMU_IMG compare "$TEST_IMG" "$TEST_IMG.out"

And also this should have been $TEST_IMG.out.dd.

I fixed this just now (and with a test file that also adds in skip and seek)
and will send it in the next version.

-- 
Reda




[Qemu-devel] [PATCH 4/7] qemu-img: delete not used variable and an unecessary check

2016-08-22 Thread Reda Sallahi
block_count is not used in img_dd() and the C_SKIP check is unecessary so
this patch removes both of them.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
 qemu-img.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index ae3828e..cf78dfe 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -4093,7 +4093,7 @@ static int img_dd(int argc, char **argv)
 const char *out_fmt = "raw";
 const char *fmt = NULL;
 int64_t size = 0, out_size = 0;
-int64_t block_count = 0, out_pos, in_pos, sparse_count = 0;
+int64_t out_pos, in_pos, sparse_count = 0;
 bool writethrough = false;
 int flags = 0;
 int ibsz = 0, obsz = 0, bsz;
@@ -4373,8 +4373,7 @@ static int img_dd(int argc, char **argv)
 }
 }
 
-if (dd.flags & C_SKIP && (in.offset > INT64_MAX / ibsz ||
-  size < in.offset * ibsz)) {
+if (in.offset > INT64_MAX / ibsz || size < in.offset * ibsz) {
 /* We give a warning if the skip option is bigger than the input
  * size and create an empty output disk image (i.e. like dd(1)).
  */
@@ -4386,7 +4385,7 @@ static int img_dd(int argc, char **argv)
 
 in.buf = g_new(uint8_t, in.bsz);
 
-for (out_pos = out.offset * obsz; in_pos < size; block_count++) {
+for (out_pos = out.offset * obsz; in_pos < size;) {
 int in_ret, out_ret;
 bsz = in.bsz;
 
-- 
2.9.3




[Qemu-devel] [PATCH 7/7] qemu-img: add a test suite for the count option

2016-08-22 Thread Reda Sallahi
The count option for dd lacked a test suite so this adds one with four test
cases.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
 tests/qemu-iotests/168 | 75 ++
 tests/qemu-iotests/168.out | 51 +++
 tests/qemu-iotests/group   |  1 +
 3 files changed, 127 insertions(+)
 create mode 100755 tests/qemu-iotests/168
 create mode 100644 tests/qemu-iotests/168.out

diff --git a/tests/qemu-iotests/168 b/tests/qemu-iotests/168
new file mode 100755
index 000..3ed655e
--- /dev/null
+++ b/tests/qemu-iotests/168
@@ -0,0 +1,75 @@
+#! /bin/bash
+#
+# qemu-img dd test for count option
+#
+# Copyright (C) 2016 Reda Sallahi
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+owner=fullma...@gmail.com
+
+seq="$(basename $0)"
+echo "QA output created by $seq"
+
+here="$PWD"
+status=1
+
+_cleanup()
+{
+_cleanup_test_img
+rm -f "$TEST_IMG.out" "$TEST_IMG.out.dd"
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+. ./common.rc
+. ./common.filter
+. ./common.pattern
+
+_supported_fmt raw
+_supported_proto file
+_supported_os Linux
+
+TEST_COUNT_BLOCKS="1 4 19 43K"
+
+for count in $TEST_COUNT_BLOCKS; do
+echo
+echo "== Creating image =="
+
+size=1M
+_make_test_img $size
+_check_test_img
+
+$QEMU_IO -c "write -P 0xa 565k 384k" "$TEST_IMG" | _filter_qemu_io
+
+echo
+echo "== Converting the image with dd with count=$count =="
+
+$QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" count=$count \
+  -O "$IMGFMT" status=none conv=notrunc
+
+TEST_IMG="$TEST_IMG.out" _check_test_img
+
+dd if="$TEST_IMG" of="$TEST_IMG.out.dd" count=$count status=none
+
+echo
+echo "== Compare the images with qemu-img compare =="
+
+$QEMU_IMG compare "$TEST_IMG.out.dd" "$TEST_IMG.out"
+done
+
+echo
+echo "*** done"
+rm -f "$seq.full"
+status=0
diff --git a/tests/qemu-iotests/168.out b/tests/qemu-iotests/168.out
new file mode 100644
index 000..768a687
--- /dev/null
+++ b/tests/qemu-iotests/168.out
@@ -0,0 +1,51 @@
+QA output created by 168
+
+== Creating image ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
+No errors were found on the image.
+wrote 393216/393216 bytes at offset 578560
+384 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with count=1 ==
+No errors were found on the image.
+
+== Compare the images with qemu-img compare ==
+Images are identical.
+
+== Creating image ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
+No errors were found on the image.
+wrote 393216/393216 bytes at offset 578560
+384 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with count=4 ==
+No errors were found on the image.
+
+== Compare the images with qemu-img compare ==
+Images are identical.
+
+== Creating image ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
+No errors were found on the image.
+wrote 393216/393216 bytes at offset 578560
+384 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with count=19 ==
+No errors were found on the image.
+
+== Compare the images with qemu-img compare ==
+Images are identical.
+
+== Creating image ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
+No errors were found on the image.
+wrote 393216/393216 bytes at offset 578560
+384 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with count=43K ==
+No errors were found on the image.
+
+== Compare the images with qemu-img compare ==
+Images are identical.
+
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index fbe0ffe..9e47975 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -167,3 +167,4 @@
 165 rw auto quick
 166 rw auto quick
 167 rw auto quick
+168 rw auto quick
-- 
2.9.3




[Qemu-devel] [PATCH 5/7] qemu-img: add status option to dd

2016-08-22 Thread Reda Sallahi
This patch adds the status option to the subcommand dd. With this dd will
display by default the number of blocks read/written, the transfer rate, etc.
like dd(1).

The noxfer and none levels will allow the user to surpress the final transfer
statistics and everything except error messages respectively.

A test case was added to test the status option.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
 qemu-img-cmds.hx   |  4 +--
 qemu-img.c | 90 ++
 qemu-img.texi  |  9 -
 tests/qemu-iotests/159 |  2 +-
 tests/qemu-iotests/160 |  2 +-
 tests/qemu-iotests/161 |  2 +-
 tests/qemu-iotests/163 |  4 +--
 tests/qemu-iotests/164 |  4 +--
 tests/qemu-iotests/165 | 11 +++---
 tests/qemu-iotests/166 |  2 +-
 tests/qemu-iotests/167 | 77 +++
 tests/qemu-iotests/167.out | 17 +
 tests/qemu-iotests/group   |  1 +
 13 files changed, 202 insertions(+), 23 deletions(-)
 create mode 100755 tests/qemu-iotests/167
 create mode 100644 tests/qemu-iotests/167.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 933ce3c..6315c64 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -46,9 +46,9 @@ STEXI
 ETEXI
 
 DEF("dd", img_dd,
-"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] [seek=blocks] [conv=convs] [iflag=flags] [oflag=flags] if=input 
of=output")
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] [seek=blocks] [conv=convs] [iflag=flags] [oflag=flags] 
[status=level] if=input of=output")
 STEXI
-@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] 
[seek=@var{blocks}] [conv=@var{convs}] [iflag=@var{flags}] [oflag=@var{flags}] 
if=@var{input} of=@var{output}
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] 
[seek=@var{blocks}] [conv=@var{convs}] [iflag=@var{flags}] [oflag=@var{flags}] 
[status=@var{level}] if=@var{input} of=@var{output}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index cf78dfe..00b15c5 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -178,7 +178,11 @@ static void QEMU_NORETURN help(void)
"  'seek=N' seek N bs-sized blocks at the start of output\n"
"  'conv=CONVS' do not truncate the output file\n"
"  'iflags=FLAGS' read using the comma-separated flags list\n"
-   "  'oflags=FLAGS' read using the comma-separated flags list\n\n"
+   "  'oflags=FLAGS' read using the comma-separated flags list\n"
+   "  'status=LEVEL' the LEVEL of information to print to stderr\n\n"
+   "List of LEVELS for dd:\n"
+   "  'none'   surpresses everything but error messages\n"
+   "  'noxfer' surpresses the final transfer statistics\n\n"
"List of CONVS for dd:\n"
"  'notrunc'   do not truncate the output file\n"
"  'noerror'   continue in the event of read errors\n"
@@ -3832,11 +3836,13 @@ out:
 #define C_CONV0100
 #define C_IFLAG   0200
 #define C_OFLAG   0400
+#define C_STATUS  01000
 
 struct DdInfo {
 unsigned int flags;
 int64_t count;
 unsigned int conv;
+unsigned status;
 };
 
 struct DdIo {
@@ -4077,6 +4083,31 @@ static int img_dd_oflag(const char *arg,
 return ret;
 }
 
+#define C_STATUS_DEFAULT  00
+#define C_STATUS_NONE 01
+#define C_STATUS_NOXFER   02
+
+static int img_dd_status(const char *arg,
+ struct DdIo *in, struct DdIo *out,
+ struct DdInfo *dd)
+{
+const struct DdSymbols dd_status[] = {
+{ "none", C_STATUS_NONE },
+{ "noxfer", C_STATUS_NOXFER },
+{ NULL, 0 }
+};
+
+for (int j = 0; dd_status[j].name != NULL; j++) {
+if (!strcmp(arg, dd_status[j].name)) {
+dd->status = dd_status[j].value;
+return 0;
+}
+}
+
+error_report("invalid status level: '%s'", arg);
+return 1;
+}
+
 static int img_dd(int argc, char **argv)
 {
 int ret = 0;
@@ -4094,13 +4125,16 @@ static int img_dd(int argc, char **argv)
 const char *fmt = NULL;
 int64_t size = 0, out_size = 0;
 int64_t out_pos, in_pos, sparse_count = 0;
+int64_t in_read = 0, out_wrt = 0; /* Read/write count for status= */
 bool writethrough = false;
 int flags = 0;
 int ibsz = 0, obsz = 0, bsz;
+struct timeval starttv, endtv;
 struct DdInfo dd = {
 .flags = 0,
 .count = 0,
-.conv = 0
+.conv = 0,
+.status = C_STATUS_DEFAULT
 };
 struct DdIo in = {
 .bsz = 512, /* Block 

[Qemu-devel] [PATCH 1/7] qemu-img: add seek option to dd

2016-08-22 Thread Reda Sallahi
This patch adds the seek option which allows qemu-img dd to skip a number of
blocks on the output before copying the input.

A test case was added to test the seek option.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
 qemu-img-cmds.hx   |  4 +--
 qemu-img.c | 45 +++-
 qemu-img.texi  |  4 ++-
 tests/qemu-iotests/161 | 73 ++
 tests/qemu-iotests/161.out | 51 
 tests/qemu-iotests/group   |  1 +
 6 files changed, 167 insertions(+), 11 deletions(-)
 create mode 100755 tests/qemu-iotests/161
 create mode 100644 tests/qemu-iotests/161.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 18685ac..e79a577 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -46,9 +46,9 @@ STEXI
 ETEXI
 
 DEF("dd", img_dd,
-"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] [conv=notrunc] if=input of=output")
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] [seek=blocks] [conv=notrunc] if=input of=output")
 STEXI
-@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] [conv=notrunc] 
if=@var{input} of=@var{output}
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] 
[seek=@var{blocks}] [conv=notrunc] if=@var{input} of=@var{output}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 57b99d8..a1c0381 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -175,6 +175,7 @@ static void QEMU_NORETURN help(void)
"  'if=FILE' read from FILE\n"
"  'of=FILE' write to FILE\n"
"  'skip=N' skip N bs-sized blocks at the start of input\n"
+   "  'seek=N' seek N bs-sized blocks at the start of output\n"
"  'conv=notrunc' do not truncate the output file\n";
 
 printf("%s\nSupported formats:", help_msg);
@@ -3808,7 +3809,8 @@ out:
 #define C_IF  04
 #define C_OF  010
 #define C_SKIP020
-#define C_CONV040
+#define C_SEEK040
+#define C_CONV0100
 
 struct DdInfo {
 unsigned int flags;
@@ -3897,6 +3899,22 @@ static int img_dd_skip(const char *arg,
 return 0;
 }
 
+static int img_dd_seek(const char *arg,
+   struct DdIo *in, struct DdIo *out,
+   struct DdInfo *dd)
+{
+char *end;
+
+out->offset = qemu_strtosz_suffix(arg, , QEMU_STRTOSZ_DEFSUFFIX_B);
+
+if (out->offset < 0 || *end) {
+error_report("invalid number: '%s'", arg);
+return 1;
+}
+
+return 0;
+}
+
 #define C_NOTRUNC 01
 
 static int img_dd_conv(const char *arg,
@@ -3927,7 +3945,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, out_size;
+int64_t size = 0, out_size = 0;
 int64_t block_count = 0, out_pos, in_pos;
 struct DdInfo dd = {
 .flags = 0,
@@ -3953,6 +3971,7 @@ static int img_dd(int argc, char **argv)
 { "if", img_dd_if, C_IF },
 { "of", img_dd_of, C_OF },
 { "skip", img_dd_skip, C_SKIP },
+{ "seek", img_dd_seek, C_SEEK },
 { "conv", img_dd_conv, C_CONV },
 { NULL, NULL, 0 }
 };
@@ -4019,6 +4038,14 @@ static int img_dd(int argc, char **argv)
 arg = NULL;
 }
 
+/* Overflow check for seek */
+if (out.offset > INT64_MAX / out.bsz) {
+error_report("seek with the block size specified is too large "
+ "for data type used");
+ret = -1;
+goto out;
+}
+
 if (!(dd.flags & C_IF && dd.flags & C_OF)) {
 error_report("Must specify both input and output files");
 ret = -1;
@@ -4044,9 +4071,9 @@ static int img_dd(int argc, char **argv)
 }
 /* Overflow means the specified offset is beyond input image's size */
 if (in.offset > INT64_MAX / in.bsz || size < in.offset * in.bsz) {
-out_size = 0;
+out_size = out.offset * out.bsz;
 } else {
-out_size = size - in.offset * in.bsz;
+out_size = size - in.offset * in.bsz + out.offset * out.bsz;
 }
 
 if (image_opts) {
@@ -4131,10 +4158,12 @@ static int img_dd(int argc, char **argv)
 goto out;
 }
 
-if (in.offset <= INT64_MAX / in.bsz && size >= in.offset * in.bsz) {
-if (blk2sz < out_size) {
-blk_truncate(blk2, out_size);
+if (in.offset > INT64_MAX / in.bsz || size < in.offset * in.bsz) {
+if (blk2sz < out.offset * out.bsz) {
+   

[Qemu-devel] [PATCH 6/7] qemu-img: clean up dd documentation

2016-08-22 Thread Reda Sallahi
The dd section on qemu-img --help was a bit hard to read since it was not
well aligned. This patch fixes the display problem and also makes the
sentences on the .texi file more consistent with one another (uppercase and
conjugasion).

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
 qemu-img.c| 48 +---
 qemu-img.texi | 48 
 2 files changed, 49 insertions(+), 47 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 00b15c5..2d00918 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -169,37 +169,39 @@ static void QEMU_NORETURN help(void)
"  '-s' run in Strict mode - fail on different image size or sector 
allocation\n"
"\n"
"Parameters to dd subcommand:\n"
-   "  'bs=BYTES' read and write up to BYTES bytes at a time "
+   "  'bs=BYTES' read and write up to BYTES bytes at a time "
"(default: 512)\n"
-   "  'count=N' copy only N input blocks\n"
-   "  'if=FILE' read from FILE\n"
-   "  'of=FILE' write to FILE\n"
-   "  'skip=N' skip N bs-sized blocks at the start of input\n"
-   "  'seek=N' seek N bs-sized blocks at the start of output\n"
-   "  'conv=CONVS' do not truncate the output file\n"
+   "  'count=N'  copy only N input blocks\n"
+   "  'if=FILE'  read from FILE\n"
+   "  'of=FILE'  write to FILE\n"
+   "  'skip=N'   skip N bs-sized blocks at the start of input\n"
+   "  'seek=N'   seek N bs-sized blocks at the start of output\n"
+   "  'conv=CONVS'   do not truncate the output file\n"
"  'iflags=FLAGS' read using the comma-separated flags list\n"
"  'oflags=FLAGS' read using the comma-separated flags list\n"
"  'status=LEVEL' the LEVEL of information to print to stderr\n\n"
"List of LEVELS for dd:\n"
-   "  'none'   surpresses everything but error messages\n"
-   "  'noxfer' surpresses the final transfer statistics\n\n"
+   "  'none' surpress everything but error messages\n"
+   "  'noxfer'   surpress the final transfer statistics\n\n"
"List of CONVS for dd:\n"
-   "  'notrunc'   do not truncate the output file\n"
-   "  'noerror'   continue in the event of read errors\n"
-   "  'excl'  fail if output already exists\n"
-   "  'nocreat'   do not create the output file\n"
-   "  'fsync' physically write output file data before finishing\n"
-   "  'fdatasync' physically write output file data before finishing\n"
-   "  'sync'  pad every input block with NULs\n"
-   "  'sparse'seek rather than write the output for NUL input"
+   "  'notrunc'  do not truncate the output file\n"
+   "  'noerror'  continue in the event of read errors\n"
+   "  'excl' fail if output already exists\n"
+   "  'nocreat'  do not create the output file\n"
+   "  'fsync'physically write output file data before"
+   " finishing\n"
+   "  'fdatasync'physically write output file data before"
+   " finishing\n"
+   "  'sync' pad every input block with NULs\n"
+   "  'sparse'   seek rather than write the output for NUL input"
" blocks\n\n"
"List of FLAGS for dd:\n"
-   "  'direct'  use direct I/O for data\n"
-   "  'dsync'   use synchronized I/O for data\n"
-   "  'sync'use synchronized I/O for data\n"
-   "  'count_bytes' use 'count=N' as a byte count (iflag only)\n"
-   "  'skip_bytes'  use 'skip=N' as a byte count (iflag only)\n"
-   "  'seek_bytes'  use 'seek=N' as a byte count (oflag only)\n";
+   "  'direct'   use direct I/O for data\n"
+   "  'dsync'use synchronized I/O for data\n"
+   "  'sync' use synchronized I/O for data\n"
+   "  'count_bytes'  use 'count=N' as a byte count (iflag only)\n"
+   "  'skip_bytes'   use 'skip=N' as a byte count (iflag only)\n"
+   "  'seek_bytes'   use 'seek=N' as a byte count (oflag only)\n";
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_f

[Qemu-devel] [PATCH 3/7] qemu-img: add more conv= conversions to dd

2016-08-22 Thread Reda Sallahi
This patch adds excl, nocreat, noerror, sync, fsync, fdatasync and sparse to
the conversion list. They have the same meaning as the ones on GNU dd(1).

Two tests were added to test the conv= option.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
 qemu-img-cmds.hx   |   4 +-
 qemu-img.c | 122 +++--
 qemu-img.texi  |  26 --
 tests/qemu-iotests/165 | 109 
 tests/qemu-iotests/165.out |  33 
 tests/qemu-iotests/166 |  73 +++
 tests/qemu-iotests/166.out |  19 +++
 tests/qemu-iotests/group   |   2 +
 8 files changed, 367 insertions(+), 21 deletions(-)
 create mode 100755 tests/qemu-iotests/165
 create mode 100644 tests/qemu-iotests/165.out
 create mode 100755 tests/qemu-iotests/166
 create mode 100644 tests/qemu-iotests/166.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 25eaf71..933ce3c 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -46,9 +46,9 @@ STEXI
 ETEXI
 
 DEF("dd", img_dd,
-"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] [seek=blocks] [conv=notrunc] [iflag=flags] [oflag=flags] if=input 
of=output")
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] [seek=blocks] [conv=convs] [iflag=flags] [oflag=flags] if=input 
of=output")
 STEXI
-@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] 
[seek=@var{blocks}] [conv=notrunc] [iflag=@var{flags}] [oflag=@var{flags}] 
if=@var{input} of=@var{output}
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] 
[seek=@var{blocks}] [conv=@var{convs}] [iflag=@var{flags}] [oflag=@var{flags}] 
if=@var{input} of=@var{output}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 710c5a2..ae3828e 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -176,9 +176,19 @@ static void QEMU_NORETURN help(void)
"  'of=FILE' write to FILE\n"
"  'skip=N' skip N bs-sized blocks at the start of input\n"
"  'seek=N' seek N bs-sized blocks at the start of output\n"
-   "  'conv=notrunc' do not truncate the output file\n"
+   "  'conv=CONVS' do not truncate the output file\n"
"  'iflags=FLAGS' read using the comma-separated flags list\n"
"  'oflags=FLAGS' read using the comma-separated flags list\n\n"
+   "List of CONVS for dd:\n"
+   "  'notrunc'   do not truncate the output file\n"
+   "  'noerror'   continue in the event of read errors\n"
+   "  'excl'  fail if output already exists\n"
+   "  'nocreat'   do not create the output file\n"
+   "  'fsync' physically write output file data before finishing\n"
+   "  'fdatasync' physically write output file data before finishing\n"
+   "  'sync'  pad every input block with NULs\n"
+   "  'sparse'seek rather than write the output for NUL input"
+   " blocks\n\n"
"List of FLAGS for dd:\n"
"  'direct'  use direct I/O for data\n"
"  'dsync'   use synchronized I/O for data\n"
@@ -3932,19 +3942,59 @@ static int img_dd_seek(const char *arg,
 return 0;
 }
 
-#define C_NOTRUNC 01
+#define C_NOTRUNC   01
+#define C_SYNC  02
+#define C_NOERROR   04
+#define C_FDATASYNC 010
+#define C_FSYNC 020
+#define C_EXCL  040
+#define C_NOCREAT   0100
+#define C_SPARSE0200
 
 static int img_dd_conv(const char *arg,
struct DdIo *in, struct DdIo *out,
struct DdInfo *dd)
 {
-if (!strcmp(arg, "notrunc")) {
-dd->conv |= C_NOTRUNC;
-return 0;
-} else {
-error_report("invalid conversion: '%s'", arg);
-return 1;
+const char *tok;
+char *str, *tmp;
+int ret = 0;
+const struct DdSymbols conv[] = {
+{ "notrunc", C_NOTRUNC },
+{ "sync", C_SYNC },
+{ "noerror", C_NOERROR },
+{ "fdatasync", C_FDATASYNC },
+{ "fsync", C_FSYNC },
+{ "excl", C_EXCL },
+{ "nocreat", C_NOCREAT },
+{ "sparse", C_SPARSE },
+{ NULL, 0 }
+};
+
+tmp = str = g_strdup(arg);
+
+while (tmp != NULL && !ret) {
+tok = qemu_strsep(, ",");
+int j;
+for (j = 0; conv[j].name != NULL; j++) {
+if (!strcmp(tok, conv[j].name)) {
+if ((dd->c

[Qemu-devel] [PATCH 2/7] qemu-img: add iflag and oflag options to dd

2016-08-22 Thread Reda Sallahi
This adds the iflag and oflag options which defines the list of flags used
for reading and writing respectively. The list is comma-separated.

The iflag option supports direct, dsync, sync, count_bytes and skip_bytes
and oflag supports direct, dsync, sync and seek_bytes. They are similar to
their counterparts on GNU dd(1).

Two tests were added to test iflag and oflag.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
 qemu-img-cmds.hx   |   4 +-
 qemu-img.c | 185 -
 qemu-img.texi  |  32 +++-
 tests/qemu-iotests/163 | 103 +
 tests/qemu-iotests/163.out | 135 +
 tests/qemu-iotests/164 | 100 
 tests/qemu-iotests/164.out |  75 ++
 tests/qemu-iotests/group   |   2 +
 8 files changed, 609 insertions(+), 27 deletions(-)
 create mode 100755 tests/qemu-iotests/163
 create mode 100644 tests/qemu-iotests/163.out
 create mode 100755 tests/qemu-iotests/164
 create mode 100644 tests/qemu-iotests/164.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index e79a577..25eaf71 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -46,9 +46,9 @@ STEXI
 ETEXI
 
 DEF("dd", img_dd,
-"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] [seek=blocks] [conv=notrunc] if=input of=output")
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] [seek=blocks] [conv=notrunc] [iflag=flags] [oflag=flags] if=input 
of=output")
 STEXI
-@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] 
[seek=@var{blocks}] [conv=notrunc] if=@var{input} of=@var{output}
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] 
[seek=@var{blocks}] [conv=notrunc] [iflag=@var{flags}] [oflag=@var{flags}] 
if=@var{input} of=@var{output}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index a1c0381..710c5a2 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -176,7 +176,16 @@ static void QEMU_NORETURN help(void)
"  'of=FILE' write to FILE\n"
"  'skip=N' skip N bs-sized blocks at the start of input\n"
"  'seek=N' seek N bs-sized blocks at the start of output\n"
-   "  'conv=notrunc' do not truncate the output file\n";
+   "  'conv=notrunc' do not truncate the output file\n"
+   "  'iflags=FLAGS' read using the comma-separated flags list\n"
+   "  'oflags=FLAGS' read using the comma-separated flags list\n\n"
+   "List of FLAGS for dd:\n"
+   "  'direct'  use direct I/O for data\n"
+   "  'dsync'   use synchronized I/O for data\n"
+   "  'sync'use synchronized I/O for data\n"
+   "  'count_bytes' use 'count=N' as a byte count (iflag only)\n"
+   "  'skip_bytes'  use 'skip=N' as a byte count (iflag only)\n"
+   "  'seek_bytes'  use 'seek=N' as a byte count (oflag only)\n";
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_format(format_print, NULL);
@@ -3811,6 +3820,8 @@ out:
 #define C_SKIP020
 #define C_SEEK040
 #define C_CONV0100
+#define C_IFLAG   0200
+#define C_OFLAG   0400
 
 struct DdInfo {
 unsigned int flags;
@@ -3823,6 +3834,7 @@ struct DdIo {
 char *filename;
 uint8_t *buf;
 int64_t offset;
+unsigned int flags;
 };
 
 struct DdOpts {
@@ -3831,6 +3843,11 @@ struct DdOpts {
 unsigned int flag;
 };
 
+struct DdSymbols {
+const char *name;
+unsigned int value;
+};
+
 static int img_dd_bs(const char *arg,
  struct DdIo *in, struct DdIo *out,
  struct DdInfo *dd)
@@ -3930,6 +3947,86 @@ static int img_dd_conv(const char *arg,
 }
 }
 
+#define C_DIRECT  01
+#define C_IOFLAG_SYNC 02
+#define C_DSYNC   04
+#define C_COUNT_BYTES 010
+#define C_SKIP_BYTES  020
+#define C_SEEK_BYTES  040
+
+static int img_dd_iflag(const char *arg,
+struct DdIo *in, struct DdIo *out,
+struct DdInfo *dd)
+{
+const char *tok;
+char *str, *tmp;
+int ret = 0;
+const struct DdSymbols flags[] = {
+{ "direct", C_DIRECT },
+{ "dsync", C_DSYNC },
+{ "sync", C_IOFLAG_SYNC },
+{ "count_bytes", C_COUNT_BYTES },
+{ "skip_bytes", C_SKIP_BYTES },
+{ NULL, 0}
+};
+
+tmp = str = g_strdup(arg);
+
+while (tmp != NULL && !ret) {
+tok = qemu_strsep(, ",");
+int j;
+for (j = 0; flags[j].name != NULL; j++) 

[Qemu-devel] [PATCH 0/7] qemu-img dd

2016-08-22 Thread Reda Sallahi
Hi everyone,

This patchset adds additional options to qemu-img dd.

Depends on:
[PATCH v4] qemu-img: change opening method for the output in dd

Reda Sallahi (7):
  qemu-img: add seek option to dd
  qemu-img: add iflag and oflag options to dd
  qemu-img: add more conv= conversions to dd
  qemu-img: delete not used variable and an unecessary check
  qemu-img: add status option to dd
  qemu-img: clean up dd documentation
  qemu-img: add a test suite for the count option

 qemu-img-cmds.hx   |   4 +-
 qemu-img.c | 431 -
 qemu-img.texi  |  69 +++-
 tests/qemu-iotests/159 |   2 +-
 tests/qemu-iotests/160 |   2 +-
 tests/qemu-iotests/161 |  73 
 tests/qemu-iotests/161.out |  51 ++
 tests/qemu-iotests/163 | 103 +++
 tests/qemu-iotests/163.out | 135 ++
 tests/qemu-iotests/164 | 100 +++
 tests/qemu-iotests/164.out |  75 
 tests/qemu-iotests/165 | 110 
 tests/qemu-iotests/165.out |  33 
 tests/qemu-iotests/166 |  73 
 tests/qemu-iotests/166.out |  19 ++
 tests/qemu-iotests/167 |  77 
 tests/qemu-iotests/167.out |  17 ++
 tests/qemu-iotests/168 |  75 
 tests/qemu-iotests/168.out |  51 ++
 tests/qemu-iotests/group   |   7 +
 20 files changed, 1449 insertions(+), 58 deletions(-)
 create mode 100755 tests/qemu-iotests/161
 create mode 100644 tests/qemu-iotests/161.out
 create mode 100755 tests/qemu-iotests/163
 create mode 100644 tests/qemu-iotests/163.out
 create mode 100755 tests/qemu-iotests/164
 create mode 100644 tests/qemu-iotests/164.out
 create mode 100755 tests/qemu-iotests/165
 create mode 100644 tests/qemu-iotests/165.out
 create mode 100755 tests/qemu-iotests/166
 create mode 100644 tests/qemu-iotests/166.out
 create mode 100755 tests/qemu-iotests/167
 create mode 100644 tests/qemu-iotests/167.out
 create mode 100755 tests/qemu-iotests/168
 create mode 100644 tests/qemu-iotests/168.out

-- 
2.9.3




[Qemu-devel] [PATCH v4] qemu-img: change opening method for the output in dd

2016-08-20 Thread Reda Sallahi
The subcommand 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.

We also make it mandatory to specify conv=notrunc when the file already
exists.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
Depends on:
[PATCH v3] qemu-img: add conv=notrunc option to dd

Changes from v3:
* Remove unnecessary checks
Changes from v2:
* Remove redundant code
Changes from v1:
* add --image-opts handling

 qemu-img.c | 139 +++--
 1 file changed, 90 insertions(+), 49 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index f8ba5e5..57b99d8 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -3919,14 +3919,15 @@ static int img_dd(int argc, char **argv)
 char *tmp;
 BlockDriver *drv = NULL, *proto_drv = NULL;
 BlockBackend *blk1 = NULL, *blk2 = NULL;
-QemuOpts *opts = NULL;
+QDict *qoptions = NULL;
+QemuOpts *opts = NULL, *qopts = NULL;
 QemuOptsList *create_opts = NULL;
 Error *local_err = NULL;
 bool image_opts = false;
 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,
@@ -4030,36 +4031,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, _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, _abort);
-
 size = blk_getlength(blk1);
 if (size < 0) {
 error_report("Failed to get size for '%s'", in.filename);
@@ -4071,31 +4042,100 @@ 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, _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, _abort);
+out_size = size - in.offset * in.bsz;
 }
 
-ret = bdrv_create(drv, out.filename, opts, _err);
-if (ret < 0) {
-error_reportf_err(local_err,
-  "%s: error while creating output image: ",
-  out.filename);
-ret = -1;
-goto out;
+if (image_opts) {
+qopts = qemu_opts_parse_noisily(qemu_find_opts("source"),
+out.filename, true);
+if (!opts) {
+ret = -1;
+goto out;
+}
+qoptions = qemu_opts_to_qdict(qopts, NULL);
+} else {
+qoptions = qdict_new();
+qdict_put(qoptions, "driver", qstring_from_str(out_fmt));
 }
 
-blk2 = img_open(image_opts, out.filename, out_fmt, BDRV_O_RDWR,
-false, false);
+blk2 = blk_new_open(image_opts ? NULL : out.filename,
+NULL, qoptions, BDRV_O_RDWR, NULL);
 
 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, _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 
crea

Re: [Qemu-devel] [PATCH v3] qemu-img: change opening method for the output in dd

2016-08-19 Thread Reda Sallahi
On Tue, Aug 16, 2016 at 12:09:06PM +0100, Stefan Hajnoczi wrote:
> On Mon, Aug 15, 2016 at 02:11:49PM +0200, Reda Sallahi wrote:
> > +blk2 = blk_new_open(image_opts ? NULL : out.filename,
> > +NULL, qoptions, BDRV_O_RDWR, NULL);
> 
> This code duplicates a subset of img_open().  Why can't you use
> img_open() or at least img_open_opts()/img_open_file()?

If I used img_open() here (or img_open_opts()/img_open_file() for that
matter) it would have written on stderr that the file couldn't be opened
here even though in this case it's not error if we can create the output
image and open it later on.

-- 
Reda




[Qemu-devel] [PATCH v3] qemu-img: change opening method for the output in dd

2016-08-15 Thread Reda Sallahi
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.

We also make it mandatory to specify conv=notrunc when the file already
exists.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
Depends on:
[PATCH v3] qemu-img: add conv=notrunc option to dd

Changes from v2:
* Remove redundant code
Changes from v1:
* add --image-opts handling

 qemu-img.c | 149 -
 1 file changed, 98 insertions(+), 51 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index d08905b..8af6dd9 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -3919,7 +3919,8 @@ static int img_dd(int argc, char **argv)
 char *tmp;
 BlockDriver *drv = NULL, *proto_drv = NULL;
 BlockBackend *blk1 = NULL, *blk2 = NULL;
-QemuOpts *opts = NULL;
+QDict *qoptions = NULL;
+QemuOpts *opts = NULL, *qopts = NULL;
 QemuOptsList *create_opts = NULL;
 Error *local_err = NULL;
 bool image_opts = false;
@@ -4030,36 +4031,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, _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, _abort);
-
 size = blk_getlength(blk1);
 if (size < 0) {
 error_report("Failed to get size for '%s'", in.filename);
@@ -4071,31 +4042,106 @@ 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, _abort);
+if (image_opts) {
+qopts = qemu_opts_parse_noisily(qemu_find_opts("source"),
+out.filename, true);
+if (!opts) {
+ret = -1;
+goto out;
+}
+qoptions = qemu_opts_to_qdict(qopts, NULL);
 } else {
-qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
-size - in.bsz * in.offset, _abort);
+qoptions = qdict_new();
+qdict_put(qoptions, "driver", qstring_from_str(out_fmt));
 }
 
-ret = bdrv_create(drv, out.filename, opts, _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);
+blk2 = blk_new_open(image_opts ? NULL : out.filename,
+NULL, qoptions, BDRV_O_RDWR, NULL);
 
 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, _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, _abort);
+
+/* Overflow means the specified offset is beyond input image's size */
+if (dd.fl

[Qemu-devel] [PATCH v2] qemu-img: change opening method for the output in dd

2016-08-11 Thread Reda Sallahi
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.

We also make it mandatory to specify conv=notrunc when the file already
exists.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
Depends on:
[PATCH v3] qemu-img: add conv=notrunc option to dd

Changes from v1:
* add --image-opts handling

 qemu-img.c | 119 ++---
 1 file changed, 98 insertions(+), 21 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index d08905b..3973990 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -3919,7 +3919,8 @@ static int img_dd(int argc, char **argv)
 char *tmp;
 BlockDriver *drv = NULL, *proto_drv = NULL;
 BlockBackend *blk1 = NULL, *blk2 = NULL;
-QemuOpts *opts = NULL;
+QDict *qoptions = NULL;
+QemuOpts *opts = NULL, *qopts = NULL;
 QemuOptsList *create_opts = NULL;
 Error *local_err = NULL;
 bool image_opts = false;
@@ -4071,31 +4072,106 @@ 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, _abort);
+if (image_opts) {
+qopts = qemu_opts_parse_noisily(qemu_find_opts("source"),
+out.filename, true);
+if (!opts) {
+ret = -1;
+goto out;
+}
+qoptions = qemu_opts_to_qdict(qopts, NULL);
 } else {
-qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
-size - in.bsz * in.offset, _abort);
+qoptions = qdict_new();
+qdict_put(qoptions, "driver", qstring_from_str(out_fmt));
 }
 
-ret = bdrv_create(drv, out.filename, opts, _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);
+blk2 = blk_new_open((image_opts ? NULL : out.filename),
+NULL, qoptions, BDRV_O_RDWR, NULL);
 
 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, _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, _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, _abort);
+} else {
+qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
+size - in.offset * in.bsz, _abort);
+}
+
+ret = bdrv_create(drv, out.filename, opts, _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);
+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"

[Qemu-devel] [PATCH v3] qemu-img: add conv=notrunc option to dd

2016-08-11 Thread Reda Sallahi
This adds the conv=notrunc option to dd which tells dd to not truncate the
output.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
Depends on:
[PATCH v5] qemu-img: add skip option to dd

Changes from v2:
* Delete the mandatory conv=notrunc
Changes from v1:
* Added comment

 qemu-img-cmds.hx   |  4 ++--
 qemu-img.c | 22 +-
 qemu-img.texi  |  7 +--
 tests/qemu-iotests/158 |  2 +-
 tests/qemu-iotests/159 |  3 ++-
 tests/qemu-iotests/160 |  7 ---
 6 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index f054599..18685ac 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -46,9 +46,9 @@ STEXI
 ETEXI
 
 DEF("dd", img_dd,
-"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] if=input of=output")
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] [conv=notrunc] if=input of=output")
 STEXI
-@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] if=@var{input} 
of=@var{output}
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] [conv=notrunc] 
if=@var{input} of=@var{output}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 3adec86..d08905b 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -174,7 +174,8 @@ static void QEMU_NORETURN help(void)
"  'count=N' copy only N input blocks\n"
"  'if=FILE' read from FILE\n"
"  'of=FILE' write to FILE\n"
-   "  'skip=N' skip N bs-sized blocks at the start of input\n";
+   "  'skip=N' skip N bs-sized blocks at the start of input\n"
+   "  'conv=notrunc' do not truncate the output file\n";
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_format(format_print, NULL);
@@ -3807,10 +3808,12 @@ out:
 #define C_IF  04
 #define C_OF  010
 #define C_SKIP020
+#define C_CONV040
 
 struct DdInfo {
 unsigned int flags;
 int64_t count;
+unsigned int conv;
 };
 
 struct DdIo {
@@ -3894,6 +3897,21 @@ static int img_dd_skip(const char *arg,
 return 0;
 }
 
+#define C_NOTRUNC 01
+
+static int img_dd_conv(const char *arg,
+   struct DdIo *in, struct DdIo *out,
+   struct DdInfo *dd)
+{
+if (!strcmp(arg, "notrunc")) {
+dd->conv |= C_NOTRUNC;
+return 0;
+} else {
+error_report("invalid conversion: '%s'", arg);
+return 1;
+}
+}
+
 static int img_dd(int argc, char **argv)
 {
 int ret = 0;
@@ -3913,6 +3931,7 @@ static int img_dd(int argc, char **argv)
 struct DdInfo dd = {
 .flags = 0,
 .count = 0,
+.conv = 0
 };
 struct DdIo in = {
 .bsz = 512, /* Block size is by default 512 bytes */
@@ -3933,6 +3952,7 @@ static int img_dd(int argc, char **argv)
 { "if", img_dd_if, C_IF },
 { "of", img_dd_of, C_OF },
 { "skip", img_dd_skip, C_SKIP },
+{ "conv", img_dd_conv, C_CONV },
 { NULL, NULL, 0 }
 };
 const struct option long_options[] = {
diff --git a/qemu-img.texi b/qemu-img.texi
index 174aae3..002dde2 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -150,9 +150,12 @@ sets the number of input blocks to copy
 @item if=@var{input}
 sets the input file
 @item of=@var{output}
-sets the output file
+sets the output file. dd truncates the output file to zero if 'conv=notrunc'
+is not specified.
 @item skip=@var{blocks}
 sets the number of input blocks to skip
+@item conv=notrunc
+makes dd not truncate output file to zero
 @end table
 
 Command description:
@@ -326,7 +329,7 @@ skipped. This is useful for formats such as @code{rbd} if 
the target
 volume has already been created with site specific options that cannot
 be supplied through qemu-img.
 
-@item dd [-f @var{fmt}] [-O @var{output_fmt}] [bs=@var{block_size}] 
[count=@var{blocks}] [skip=@var{blocks}] if=@var{input} of=@var{output}
+@item dd [-f @var{fmt}] [-O @var{output_fmt}] [bs=@var{block_size}] 
[count=@var{blocks}] [skip=@var{blocks}] [conv=notrunc] if=@var{input} 
of=@var{output}
 
 Dd copies from @var{input} file to @var{output} file converting it from
 @var{fmt} format to @var{output_fmt} format.
diff --git a/tests/qemu-iotests/158 b/tests/qemu-iotests/158
index 5b335db..63e2a10 100755
--- a/tests/qemu-iotests/158
+++ b/tests/qemu-iotests/158
@@ -53,7 +53,7 @@ $QEMU_IO -c "write -P 0xa 0 $size" "$TEST_IMG" | 
_filter_qemu_io
 echo
 echo "== Converting the image with dd =="
 
-$QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" -O "$IMGFMT"
+$QEMU_IMG dd if="$TEST_IMG" of=

[Qemu-devel] [PATCH] qemu-img: change opening method for the output in dd

2016-08-10 Thread Reda Sallahi
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 <fullma...@gmail.com>
---
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, _abort);
-} else {
-qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
-size - in.bsz * in.offset, _abort);
-}
+qoptions = qdict_new();
+qdict_put(qoptions, "driver", qstring_from_str(out_fmt));
 
-ret = bdrv_create(drv, out.filename, opts, _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, _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, _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, _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, _abort);
+} else {
+qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
+size - in.offset * in.bsz, _abort);
+}
+
+ret = bdrv_create(drv, out.filename, opts, _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);
-- 
2.9.2




[Qemu-devel] [PATCH v2] qemu-img: add conv=notrunc option to dd

2016-08-10 Thread Reda Sallahi
This adds the conv=notrunc option to dd which tells dd to not truncate the
output.

For the time being we make it mandatory to specify conv=notrunc.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
Depends on:
[PATCH v5] qemu-img: add skip option to dd

Changes from v1:
* Added comment

 qemu-img-cmds.hx   |  4 ++--
 qemu-img.c | 30 +-
 qemu-img.texi  |  7 +--
 tests/qemu-iotests/158 |  2 +-
 tests/qemu-iotests/159 |  3 ++-
 tests/qemu-iotests/160 |  7 ---
 6 files changed, 43 insertions(+), 10 deletions(-)

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index f054599..18685ac 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -46,9 +46,9 @@ STEXI
 ETEXI
 
 DEF("dd", img_dd,
-"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] if=input of=output")
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] [conv=notrunc] if=input of=output")
 STEXI
-@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] if=@var{input} 
of=@var{output}
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] [conv=notrunc] 
if=@var{input} of=@var{output}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 3adec86..7c546c1 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -174,7 +174,8 @@ static void QEMU_NORETURN help(void)
"  'count=N' copy only N input blocks\n"
"  'if=FILE' read from FILE\n"
"  'of=FILE' write to FILE\n"
-   "  'skip=N' skip N bs-sized blocks at the start of input\n";
+   "  'skip=N' skip N bs-sized blocks at the start of input\n"
+   "  'conv=notrunc' do not truncate the output file\n";
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_format(format_print, NULL);
@@ -3807,10 +3808,12 @@ out:
 #define C_IF  04
 #define C_OF  010
 #define C_SKIP020
+#define C_CONV040
 
 struct DdInfo {
 unsigned int flags;
 int64_t count;
+unsigned int conv;
 };
 
 struct DdIo {
@@ -3894,6 +3897,21 @@ static int img_dd_skip(const char *arg,
 return 0;
 }
 
+#define C_NOTRUNC 01
+
+static int img_dd_conv(const char *arg,
+   struct DdIo *in, struct DdIo *out,
+   struct DdInfo *dd)
+{
+if (!strcmp(arg, "notrunc")) {
+dd->conv |= C_NOTRUNC;
+return 0;
+} else {
+error_report("invalid conversion: '%s'", arg);
+return 1;
+}
+}
+
 static int img_dd(int argc, char **argv)
 {
 int ret = 0;
@@ -3913,6 +3931,7 @@ static int img_dd(int argc, char **argv)
 struct DdInfo dd = {
 .flags = 0,
 .count = 0,
+.conv = 0
 };
 struct DdIo in = {
 .bsz = 512, /* Block size is by default 512 bytes */
@@ -3933,6 +3952,7 @@ static int img_dd(int argc, char **argv)
 { "if", img_dd_if, C_IF },
 { "of", img_dd_of, C_OF },
 { "skip", img_dd_skip, C_SKIP },
+{ "conv", img_dd_conv, C_CONV },
 { NULL, NULL, 0 }
 };
 const struct option long_options[] = {
@@ -3997,6 +4017,14 @@ static int img_dd(int argc, char **argv)
 g_free(arg);
 arg = NULL;
 }
+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;
+}
 
 if (!(dd.flags & C_IF && dd.flags & C_OF)) {
 error_report("Must specify both input and output files");
diff --git a/qemu-img.texi b/qemu-img.texi
index 174aae3..002dde2 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -150,9 +150,12 @@ sets the number of input blocks to copy
 @item if=@var{input}
 sets the input file
 @item of=@var{output}
-sets the output file
+sets the output file. dd truncates the output file to zero if 'conv=notrunc'
+is not specified.
 @item skip=@var{blocks}
 sets the number of input blocks to skip
+@item conv=notrunc
+makes dd not truncate output file to zero
 @end table
 
 Command description:
@@ -326,7 +329,7 @@ skipped. This is useful for formats such as @code{rbd} if 
the target
 volume has already been created with site specific options that cannot
 be supplied through qemu-img.
 
-@item dd [-f @var{fmt}] [-O @var{output_fmt}] [bs=@var{block_size}] 
[count=@var{blocks}] [skip=@var{blocks}] if=@var{input} of=@var{output}
+@item dd [-f @var{fmt}] [-O @var{output_fmt}] [bs=@var{block_size}] 
[count=@var{blocks}] [skip=@var{blocks

[Qemu-devel] [PATCH] qemu-img: add conv=notrunc option to dd

2016-08-10 Thread Reda Sallahi
This adds the conv=notrunc option to dd which tells dd to not truncate the
output.

For the time being we make it mandatory to specify conv=notrunc.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
 qemu-img-cmds.hx   |  4 ++--
 qemu-img.c | 31 ---
 qemu-img.texi  | 15 +--
 tests/qemu-iotests/158 |  2 +-
 tests/qemu-iotests/159 |  3 ++-
 tests/qemu-iotests/160 |  7 ---
 6 files changed, 46 insertions(+), 16 deletions(-)

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index f054599..18685ac 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -46,9 +46,9 @@ STEXI
 ETEXI
 
 DEF("dd", img_dd,
-"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] if=input of=output")
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] [conv=notrunc] if=input of=output")
 STEXI
-@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] if=@var{input} 
of=@var{output}
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] [conv=notrunc] 
if=@var{input} of=@var{output}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 3adec86..16b56b8 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -174,7 +174,8 @@ static void QEMU_NORETURN help(void)
"  'count=N' copy only N input blocks\n"
"  'if=FILE' read from FILE\n"
"  'of=FILE' write to FILE\n"
-   "  'skip=N' skip N bs-sized blocks at the start of input\n";
+   "  'skip=N' skip N bs-sized blocks at the start of input\n"
+   "  'conv=notrunc' do not truncate the output file\n";
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_format(format_print, NULL);
@@ -3807,10 +3808,12 @@ out:
 #define C_IF  04
 #define C_OF  010
 #define C_SKIP020
+#define C_CONV040
 
 struct DdInfo {
 unsigned int flags;
 int64_t count;
+unsigned int conv;
 };
 
 struct DdIo {
@@ -3894,6 +3897,21 @@ static int img_dd_skip(const char *arg,
 return 0;
 }
 
+#define C_NOTRUNC 01
+
+static int img_dd_conv(const char *arg,
+   struct DdIo *in, struct DdIo *out,
+   struct DdInfo *dd)
+{
+if (!strcmp(arg, "notrunc")) {
+dd->conv |= C_NOTRUNC;
+return 0;
+} else {
+error_report("invalid conversion: '%s'", arg);
+return 1;
+}
+}
+
 static int img_dd(int argc, char **argv)
 {
 int ret = 0;
@@ -3909,10 +3927,11 @@ static int img_dd(int argc, char **argv)
 const char *out_fmt = "raw";
 const char *fmt = NULL;
 int64_t size = 0;
-int64_t block_count = 0, out_pos, in_pos;
+int64_t out_pos, in_pos;
 struct DdInfo dd = {
 .flags = 0,
 .count = 0,
+.conv = 0
 };
 struct DdIo in = {
 .bsz = 512, /* Block size is by default 512 bytes */
@@ -3933,6 +3952,7 @@ static int img_dd(int argc, char **argv)
 { "if", img_dd_if, C_IF },
 { "of", img_dd_of, C_OF },
 { "skip", img_dd_skip, C_SKIP },
+{ "conv", img_dd_conv, C_CONV },
 { NULL, NULL, 0 }
 };
 const struct option long_options[] = {
@@ -3997,6 +4017,11 @@ static int img_dd(int argc, char **argv)
 g_free(arg);
 arg = NULL;
 }
+if (!(dd.conv & C_NOTRUNC)) {
+error_report("conv=notrunc not specified");
+ret = -1;
+goto out;
+}
 
 if (!(dd.flags & C_IF && dd.flags & C_OF)) {
 error_report("Must specify both input and output files");
@@ -4091,7 +4116,7 @@ static int img_dd(int argc, char **argv)
 
 in.buf = g_new(uint8_t, in.bsz);
 
-for (out_pos = 0; in_pos < size; block_count++) {
+for (out_pos = 0; in_pos < size; ) {
 int in_ret, out_ret;
 
 if (in_pos + in.bsz > size) {
diff --git a/qemu-img.texi b/qemu-img.texi
index 174aae3..891af14 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -144,15 +144,18 @@ Parameters to dd subcommand:
 @table @option
 
 @item bs=@var{block_size}
-defines the block size
+Defines the block size.
 @item count=@var{blocks}
-sets the number of input blocks to copy
+Sets the number of input blocks to copy.
 @item if=@var{input}
-sets the input file
+Sets the input file.
 @item of=@var{output}
-sets the output file
+Sets the output file. dd truncates the output file to zero if 'conv=notrunc'
+is not specified.
 @item skip=@var{blocks}
-sets the number of input blocks to skip
+Sets the number of input blocks to skip.
+@item conv=notrunc
+Makes dd not truncate output file to zero.
 @end table
 
 Command description:
@

[Qemu-devel] [PATCH] qemu-img: add seek option to dd

2016-08-10 Thread Reda Sallahi
This patch adds the seek option which allows qemu-img dd to skip a number of
blocks on the output before copying the input.

A test case was added to test the seek option.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
Depends on:
[PATCH v5] qemu-img: add skip option to dd

 qemu-img-cmds.hx   |   4 +-
 qemu-img.c | 116 ++---
 qemu-img.texi  |   4 +-
 tests/qemu-iotests/161 |  72 
 tests/qemu-iotests/161.out |  51 
 tests/qemu-iotests/group   |   1 +
 6 files changed, 228 insertions(+), 20 deletions(-)
 create mode 100755 tests/qemu-iotests/161
 create mode 100644 tests/qemu-iotests/161.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index f054599..826ce3f 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -46,9 +46,9 @@ STEXI
 ETEXI
 
 DEF("dd", img_dd,
-"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] if=input of=output")
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] [seek=blocks] if=input of=output")
 STEXI
-@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] if=@var{input} 
of=@var{output}
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] 
[seek=@var{blocks}] if=@var{input} of=@var{output}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 3adec86..600c866 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -174,7 +174,8 @@ static void QEMU_NORETURN help(void)
"  'count=N' copy only N input blocks\n"
"  'if=FILE' read from FILE\n"
"  'of=FILE' write to FILE\n"
-   "  'skip=N' skip N bs-sized blocks at the start of input\n";
+   "  'skip=N' skip N bs-sized blocks at the start of input\n"
+   "  'seek=N' seek N bs-sized blocks at the start of output\n";
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_format(format_print, NULL);
@@ -3807,6 +3808,7 @@ out:
 #define C_IF  04
 #define C_OF  010
 #define C_SKIP020
+#define C_SEEK040
 
 struct DdInfo {
 unsigned int flags;
@@ -3894,6 +3896,22 @@ static int img_dd_skip(const char *arg,
 return 0;
 }
 
+static int img_dd_seek(const char *arg,
+   struct DdIo *in, struct DdIo *out,
+   struct DdInfo *dd)
+{
+char *end;
+
+out->offset = qemu_strtosz_suffix(arg, , QEMU_STRTOSZ_DEFSUFFIX_B);
+
+if (out->offset < 0 || *end) {
+error_report("invalid number: '%s'", arg);
+return 1;
+}
+
+return 0;
+}
+
 static int img_dd(int argc, char **argv)
 {
 int ret = 0;
@@ -3901,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;
@@ -3933,6 +3953,7 @@ static int img_dd(int argc, char **argv)
 { "if", img_dd_if, C_IF },
 { "of", img_dd_of, C_OF },
 { "skip", img_dd_skip, C_SKIP },
+{ "seek", img_dd_seek, C_SEEK },
 { NULL, NULL, 0 }
 };
 const struct option long_options[] = {
@@ -3998,6 +4019,14 @@ static int img_dd(int argc, char **argv)
 arg = NULL;
 }
 
+/* Overflow check for seek */
+if (dd.flags & C_SEEK && out.offset > INT64_MAX / out.bsz) {
+error_report("seek with the block size specified is too large "
+ "for data type used");
+ret = -1;
+goto out;
+}
+
 if (!(dd.flags & C_IF && dd.flags & C_OF)) {
 error_report("Must specify both input and output files");
 ret = -1;
@@ -4052,22 +4081,61 @@ 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, _abort);
-} else {
-qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
-size - in.bsz * in.offset, _abort);
-}
+qoptions = qdict_new();
+qdict_put(qoptions, "driver", qstring_from_str(out_fmt));
 
-ret = bdrv_create(drv, out.filename, opts, _err);
-if (ret < 0) {
-error_reportf_err(local_err,
-  &qu

Re: [Qemu-devel] [PATCH v4] qemu-img: add skip option to dd

2016-08-10 Thread Reda Sallahi
On 8/10/16, Stefan Hajnoczi <stefa...@redhat.com> wrote:
> On Mon, Aug 08, 2016 at 01:34:21PM +0200, Reda Sallahi wrote:
>> @@ -4111,6 +4139,10 @@ static int img_dd(int argc, char **argv)
>>
>>  in.buf = g_new(uint8_t, in.bsz);
>>
>> +if (dd.flags & C_SKIP) {
>> +incount = in.offset * in.bsz;
>> +}
>
> Not worth changing unless there are other comments, but does this need
> to be conditional?  If in.offset = 0 because C_SKIP was not specified
> then incount = 0, which is correct.  Unconditional code is simpler.
>
> Reviewed-by: Stefan Hajnoczi <stefa...@redhat.com>
>

I had to do a rebase with some minor changes anyway so that part will be
changed as well in that version.

-- 
Reda <fullma...@gmail.com>



[Qemu-devel] [PATCH v5] qemu-img: add skip option to dd

2016-08-10 Thread Reda Sallahi
This adds the skip option which allows qemu-img dd to skip a number of blocks
before copying the input.

A test case was added to test the skip option.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
Depends on:
[PATCH v9] qemu-img: add the 'dd' subcommand

Changes from v4:
* Rebase.
Changes from v3:
* Change write command to the test image in the test case.
Changes from v2:
* Delete a tab that sneaked in (test case 160).
Changes from v1:
* Change test case output.

 qemu-img-cmds.hx   |  4 +--
 qemu-img.c | 50 
 qemu-img.texi  |  4 ++-
 tests/qemu-iotests/160 | 72 ++
 tests/qemu-iotests/160.out | 51 
 tests/qemu-iotests/group   |  1 +
 6 files changed, 174 insertions(+), 8 deletions(-)
 create mode 100755 tests/qemu-iotests/160
 create mode 100644 tests/qemu-iotests/160.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 03bdd7a..f054599 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -46,9 +46,9 @@ STEXI
 ETEXI
 
 DEF("dd", img_dd,
-"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
if=input of=output")
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] if=input of=output")
 STEXI
-@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] if=@var{input} of=@var{output}
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] if=@var{input} 
of=@var{output}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 034baf7..3adec86 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -173,7 +173,8 @@ static void QEMU_NORETURN help(void)
"(default: 512)\n"
"  'count=N' copy only N input blocks\n"
"  'if=FILE' read from FILE\n"
-   "  'of=FILE' write to FILE\n";
+   "  'of=FILE' write to FILE\n"
+   "  'skip=N' skip N bs-sized blocks at the start of input\n";
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_format(format_print, NULL);
@@ -3805,6 +3806,7 @@ out:
 #define C_COUNT   02
 #define C_IF  04
 #define C_OF  010
+#define C_SKIP020
 
 struct DdInfo {
 unsigned int flags;
@@ -3815,6 +3817,7 @@ struct DdIo {
 int bsz;/* Block size */
 char *filename;
 uint8_t *buf;
+int64_t offset;
 };
 
 struct DdOpts {
@@ -3875,6 +3878,22 @@ static int img_dd_of(const char *arg,
 return 0;
 }
 
+static int img_dd_skip(const char *arg,
+   struct DdIo *in, struct DdIo *out,
+   struct DdInfo *dd)
+{
+char *end;
+
+in->offset = qemu_strtosz_suffix(arg, , QEMU_STRTOSZ_DEFSUFFIX_B);
+
+if (in->offset < 0 || *end) {
+error_report("invalid number: '%s'", arg);
+return 1;
+}
+
+return 0;
+}
+
 static int img_dd(int argc, char **argv)
 {
 int ret = 0;
@@ -3898,12 +3917,14 @@ static int img_dd(int argc, char **argv)
 struct DdIo in = {
 .bsz = 512, /* Block size is by default 512 bytes */
 .filename = NULL,
-.buf = NULL
+.buf = NULL,
+.offset = 0
 };
 struct DdIo out = {
 .bsz = 512,
 .filename = NULL,
-.buf = NULL
+.buf = NULL,
+.offset = 0
 };
 
 const struct DdOpts options[] = {
@@ -3911,6 +3932,7 @@ static int img_dd(int argc, char **argv)
 { "count", img_dd_count, C_COUNT },
 { "if", img_dd_if, C_IF },
 { "of", img_dd_of, C_OF },
+{ "skip", img_dd_skip, C_SKIP },
 { NULL, NULL, 0 }
 };
 const struct option long_options[] = {
@@ -4030,7 +4052,14 @@ static int img_dd(int argc, char **argv)
 size = dd.count * in.bsz;
 }
 
-qemu_opt_set_number(opts, BLOCK_OPT_SIZE, size, _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.bsz * in.offset)) {
+qemu_opt_set_number(opts, BLOCK_OPT_SIZE, 0, _abort);
+} else {
+qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
+size - in.bsz * in.offset, _abort);
+}
 
 ret = bdrv_create(drv, out.filename, opts, _err);
 if (ret < 0) {
@@ -4049,9 +4078,20 @@ static int img_dd(int argc, char **argv)
 goto out;
 }
 
+if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz ||
+  size < in.offset * in.bsz)) {
+/* We give a warning if the skip option is bigger than the input
+ * size and create an empty output disk image (i.e.

[Qemu-devel] [PATCH v9] qemu-img: add the 'dd' subcommand

2016-08-09 Thread Reda Sallahi
This patch adds a basic dd subcommand analogous to dd(1) to qemu-img.

For the start, this implements the bs, if, of and count options and requires
both if and of to be specified (no stdin/stdout if not specified) and doesn't
support tty, pipes, etc.

The image format must be specified with -O for the output if the raw format
is not the intended one.

Two tests are added to test qemu-img dd.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
Changes from v8:
* Add an overflow check.
Changes from v7:
* Remove a C99-style for loop.
Changes from v6:
* Remove get_size() to use qemu_strtosz_suffix() instead.
* Type changes for some fields in DdIo and DdInfo.
Changes from v5:
* Add dd sections on qemu-img.texi.
Changes from v4:
* Fix the exit status.
Changes from v3:
* Delete an unused (so far) field in DdIo.
Changes from v2:
* Add copyright headers to new files.
Changes from v1:
* Removal of dead code.
* Fix a memory leak.
* Complete the cleanup function in the test cases.

 qemu-img-cmds.hx |   6 +
 qemu-img.c   | 303 ++-
 qemu-img.texi|  25 
 tests/qemu-iotests/158   |  67 +
 tests/qemu-iotests/158.out   |  15 ++
 tests/qemu-iotests/159   |  70 +
 tests/qemu-iotests/159.out   |  87 +++
 tests/qemu-iotests/common.filter |   9 ++
 tests/qemu-iotests/common.rc |   5 +-
 tests/qemu-iotests/group |   2 +
 10 files changed, 584 insertions(+), 5 deletions(-)
 create mode 100755 tests/qemu-iotests/158
 create mode 100644 tests/qemu-iotests/158.out
 create mode 100755 tests/qemu-iotests/159
 create mode 100644 tests/qemu-iotests/159.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 7e95b2d..03bdd7a 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -45,6 +45,12 @@ STEXI
 @item convert [--object @var{objectdef}] [--image-opts] [-c] [-p] [-q] [-n] 
[-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-o 
@var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S 
@var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
 
+DEF("dd", img_dd,
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
if=input of=output")
+STEXI
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] if=@var{input} of=@var{output}
+ETEXI
+
 DEF("info", img_info,
 "info [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] 
[--backing-chain] filename")
 STEXI
diff --git a/qemu-img.c b/qemu-img.c
index d2865a5..034baf7 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -166,7 +166,14 @@ static void QEMU_NORETURN help(void)
"Parameters to compare subcommand:\n"
"  '-f' first image format\n"
"  '-F' second image format\n"
-   "  '-s' run in Strict mode - fail on different image size or sector 
allocation\n";
+   "  '-s' run in Strict mode - fail on different image size or sector 
allocation\n"
+   "\n"
+   "Parameters to dd subcommand:\n"
+   "  'bs=BYTES' read and write up to BYTES bytes at a time "
+   "(default: 512)\n"
+   "  'count=N' copy only N input blocks\n"
+   "  'if=FILE' read from FILE\n"
+   "  'of=FILE' write to FILE\n";
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_format(format_print, NULL);
@@ -3794,6 +3801,300 @@ out:
 return 0;
 }
 
+#define C_BS  01
+#define C_COUNT   02
+#define C_IF  04
+#define C_OF  010
+
+struct DdInfo {
+unsigned int flags;
+int64_t count;
+};
+
+struct DdIo {
+int bsz;/* Block size */
+char *filename;
+uint8_t *buf;
+};
+
+struct DdOpts {
+const char *name;
+int (*f)(const char *, struct DdIo *, struct DdIo *, struct DdInfo *);
+unsigned int flag;
+};
+
+static int img_dd_bs(const char *arg,
+ struct DdIo *in, struct DdIo *out,
+ struct DdInfo *dd)
+{
+char *end;
+int64_t res;
+
+res = qemu_strtosz_suffix(arg, , QEMU_STRTOSZ_DEFSUFFIX_B);
+
+if (res <= 0 || res > INT_MAX || *end) {
+error_report("invalid number: '%s'", arg);
+return 1;
+}
+in->bsz = out->bsz = res;
+
+return 0;
+}
+
+static int img_dd_count(const char *arg,
+struct DdIo *in, struct DdIo *out,
+struct DdInfo *dd)
+{
+char *end;
+
+dd->count = qemu_strtosz_suffix(arg, , QEMU_STRTOSZ_DEFSUFFIX_B);
+
+if (dd->count < 0 || *end) {
+error_report("invalid number: '%s'", arg);
+return 1;
+}
+
+return 0;
+}
+
+static int img_dd_if(const char *arg,
+

[Qemu-devel] [PATCH v8] qemu-img: add the 'dd' subcommand

2016-08-09 Thread Reda Sallahi
This patch adds a basic dd subcommand analogous to dd(1) to qemu-img.

For the start, this implements the bs, if, of and count options and requires
both if and of to be specified (no stdin/stdout if not specified) and doesn't
support tty, pipes, etc.

The image format must be specified with -O for the output if the raw format
is not the intended one.

Two tests are added to test qemu-img dd.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
Changes from v7:
* Remove a C99-style for loop.
Changes from v6:
* Remove get_size() to use qemu_strtosz_suffix() instead.
* Type changes for some fields in DdIo and DdInfo.
Changes from v5:
* Add dd sections on qemu-img.texi.
Changes from v4:
* Fix the exit status.
Changes from v3:
* Delete an unused (so far) field in DdIo.
Changes from v2:
* Add copyright headers to new files.
Changes from v1:
* Removal of dead code.
* Fix a memory leak.
* Complete the cleanup function in the test cases.

 qemu-img-cmds.hx |   6 +
 qemu-img.c   | 302 ++-
 qemu-img.texi|  25 
 tests/qemu-iotests/158   |  68 +
 tests/qemu-iotests/158.out   |  15 ++
 tests/qemu-iotests/159   |  70 +
 tests/qemu-iotests/159.out   |  87 +++
 tests/qemu-iotests/common.filter |   9 ++
 tests/qemu-iotests/group |   2 +
 9 files changed, 583 insertions(+), 1 deletion(-)
 create mode 100755 tests/qemu-iotests/158
 create mode 100644 tests/qemu-iotests/158.out
 create mode 100755 tests/qemu-iotests/159
 create mode 100644 tests/qemu-iotests/159.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 7e95b2d..03bdd7a 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -45,6 +45,12 @@ STEXI
 @item convert [--object @var{objectdef}] [--image-opts] [-c] [-p] [-q] [-n] 
[-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-o 
@var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S 
@var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
 
+DEF("dd", img_dd,
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
if=input of=output")
+STEXI
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] if=@var{input} of=@var{output}
+ETEXI
+
 DEF("info", img_info,
 "info [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] 
[--backing-chain] filename")
 STEXI
diff --git a/qemu-img.c b/qemu-img.c
index d2865a5..10aaf0e 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -166,7 +166,14 @@ static void QEMU_NORETURN help(void)
"Parameters to compare subcommand:\n"
"  '-f' first image format\n"
"  '-F' second image format\n"
-   "  '-s' run in Strict mode - fail on different image size or sector 
allocation\n";
+   "  '-s' run in Strict mode - fail on different image size or sector 
allocation\n"
+   "\n"
+   "Parameters to dd subcommand:\n"
+   "  'bs=BYTES' read and write up to BYTES bytes at a time "
+   "(default: 512)\n"
+   "  'count=N' copy only N input blocks\n"
+   "  'if=FILE' read from FILE\n"
+   "  'of=FILE' write to FILE\n";
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_format(format_print, NULL);
@@ -3794,6 +3801,299 @@ out:
 return 0;
 }
 
+#define C_BS  01
+#define C_COUNT   02
+#define C_IF  04
+#define C_OF  010
+
+struct DdInfo {
+unsigned int flags;
+int64_t count;
+};
+
+struct DdIo {
+int bsz;/* Block size */
+char *filename;
+uint8_t *buf;
+};
+
+struct DdOpts {
+const char *name;
+int (*f)(const char *, struct DdIo *, struct DdIo *, struct DdInfo *);
+unsigned int flag;
+};
+
+static int img_dd_bs(const char *arg,
+ struct DdIo *in, struct DdIo *out,
+ struct DdInfo *dd)
+{
+char *end;
+int64_t res;
+
+res = qemu_strtosz_suffix(arg, , QEMU_STRTOSZ_DEFSUFFIX_B);
+
+if (res <= 0 || res > INT_MAX || *end) {
+error_report("invalid number: '%s'", arg);
+return 1;
+}
+in->bsz = out->bsz = res;
+
+return 0;
+}
+
+static int img_dd_count(const char *arg,
+struct DdIo *in, struct DdIo *out,
+struct DdInfo *dd)
+{
+char *end;
+
+dd->count = qemu_strtosz_suffix(arg, , QEMU_STRTOSZ_DEFSUFFIX_B);
+
+if (dd->count < 0 || *end) {
+error_report("invalid number: '%s'", arg);
+return 1;
+}
+
+return 0;
+}
+
+static int img_dd_if(const char *arg,
+ struct DdIo *in, struct DdIo *out,
+ struct DdInfo *dd)
+

[Qemu-devel] [PATCH v7] qemu-img: add the 'dd' subcommand

2016-08-09 Thread Reda Sallahi
This patch adds a basic dd subcommand analogous to dd(1) to qemu-img.

For the start, this implements the bs, if, of and count options and requires
both if and of to be specified (no stdin/stdout if not specified) and doesn't
support tty, pipes, etc.

The image format must be specified with -O for the output if the raw format
is not the intended one.

Two tests are added to test qemu-img dd.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
Changes from v6:
* Remove get_size() to use qemu_strtosz_suffix() instead.
* Type changes for some fields in DdIo and DdInfo.
Changes from v5:
* Add dd sections on qemu-img.texi.
Changes from v4:
* Fix the exit status.
Changes from v3:
* Delete an unused (so far) field in DdIo.
Changes from v2:
* Add copyright headers to new files.
Changes from v1:
* Removal of dead code.
* Fix a memory leak.
* Complete the cleanup function in the test cases.

 qemu-img-cmds.hx |   6 +
 qemu-img.c   | 302 ++-
 qemu-img.texi|  25 
 tests/qemu-iotests/158   |  68 +
 tests/qemu-iotests/158.out   |  15 ++
 tests/qemu-iotests/159   |  70 +
 tests/qemu-iotests/159.out   |  87 +++
 tests/qemu-iotests/common.filter |   9 ++
 tests/qemu-iotests/group |   2 +
 9 files changed, 583 insertions(+), 1 deletion(-)
 create mode 100755 tests/qemu-iotests/158
 create mode 100644 tests/qemu-iotests/158.out
 create mode 100755 tests/qemu-iotests/159
 create mode 100644 tests/qemu-iotests/159.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 7e95b2d..03bdd7a 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -45,6 +45,12 @@ STEXI
 @item convert [--object @var{objectdef}] [--image-opts] [-c] [-p] [-q] [-n] 
[-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-o 
@var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S 
@var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
 
+DEF("dd", img_dd,
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
if=input of=output")
+STEXI
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] if=@var{input} of=@var{output}
+ETEXI
+
 DEF("info", img_info,
 "info [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] 
[--backing-chain] filename")
 STEXI
diff --git a/qemu-img.c b/qemu-img.c
index d2865a5..5f3f2f7 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -166,7 +166,14 @@ static void QEMU_NORETURN help(void)
"Parameters to compare subcommand:\n"
"  '-f' first image format\n"
"  '-F' second image format\n"
-   "  '-s' run in Strict mode - fail on different image size or sector 
allocation\n";
+   "  '-s' run in Strict mode - fail on different image size or sector 
allocation\n"
+   "\n"
+   "Parameters to dd subcommand:\n"
+   "  'bs=BYTES' read and write up to BYTES bytes at a time "
+   "(default: 512)\n"
+   "  'count=N' copy only N input blocks\n"
+   "  'if=FILE' read from FILE\n"
+   "  'of=FILE' write to FILE\n";
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_format(format_print, NULL);
@@ -3794,6 +3801,299 @@ out:
 return 0;
 }
 
+#define C_BS  01
+#define C_COUNT   02
+#define C_IF  04
+#define C_OF  010
+
+struct DdInfo {
+unsigned int flags;
+int64_t count;
+};
+
+struct DdIo {
+int bsz;/* Block size */
+char *filename;
+uint8_t *buf;
+};
+
+struct DdOpts {
+const char *name;
+int (*f)(const char *, struct DdIo *, struct DdIo *, struct DdInfo *);
+unsigned int flag;
+};
+
+static int img_dd_bs(const char *arg,
+ struct DdIo *in, struct DdIo *out,
+ struct DdInfo *dd)
+{
+char *end;
+int64_t res;
+
+res = qemu_strtosz_suffix(arg, , QEMU_STRTOSZ_DEFSUFFIX_B);
+
+if (res <= 0 || res > INT_MAX || *end) {
+error_report("invalid number: '%s'", arg);
+return 1;
+}
+in->bsz = out->bsz = res;
+
+return 0;
+}
+
+static int img_dd_count(const char *arg,
+struct DdIo *in, struct DdIo *out,
+struct DdInfo *dd)
+{
+char *end;
+
+dd->count = qemu_strtosz_suffix(arg, , QEMU_STRTOSZ_DEFSUFFIX_B);
+
+if (dd->count < 0 || *end) {
+error_report("invalid number: '%s'", arg);
+return 1;
+}
+
+return 0;
+}
+
+static int img_dd_if(const char *arg,
+ struct DdIo *in, struct DdIo *out,
+ struct DdInfo *dd)
+{
+in->filename = g_strdup(arg);
+
+return 0;
+

Re: [Qemu-devel] [PATCH v6] qemu-img: add the 'dd' subcommand

2016-08-09 Thread Reda Sallahi
Hi Max,
Thanks for the review!

On 8/8/16, Max Reitz <mre...@redhat.com> wrote:
> On 25.07.2016 07:58, Reda Sallahi wrote:
>> +if (in->bsz == 0) {
>> +error_report("invalid number: '%s'", arg);
>
> It's not an invalid number, it's just an invalid block size. In my
> understanding, those are two different things.

I was trying to have the same error message as dd(1) for this.

>> +tmp = strchr(arg, '=');
>
> FYI, strtok() is a neat function for exactly this. I'm not saying you
> need to use it, though.

For something as simple I would rather avoid using strtok().

>> +for (; incount < size; block_count++) {
>
> Please do not initialize incount above but here. Having to jump more
> than a hundred lines up to find out what a variable is set to makes code
> very hard to read.
>
> Also, I'd rename incount to in_offset or something, because "incount" to
> me sounds like it counts a number of blocks, whereas it actually counts
> a number of bytes, independently of the block size.
>

There is already in.offset ([PATCH v4] qemu-img: add skip option to dd)
so it will just be confusing but if you have a better name I will be glad to
change it.

-- 
Reda <fullma...@gmail.com>



[Qemu-devel] [PATCH v4] qemu-img: add skip option to dd

2016-08-08 Thread Reda Sallahi
This adds the skip option which allows qemu-img dd to skip a number of blocks
before copying the input.

A test case was added to test the skip option.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
Depends on:
[PATCH v6] qemu-img: add the 'dd' subcommand

Changes from v3:
* Change write command to the test image in the test case.

Changes from v2:
* Delete a tab that sneaked in (test case 160).

Changes from v1:
* Change test case output.

 qemu-img-cmds.hx   |  4 +--
 qemu-img.c | 40 +++---
 qemu-img.texi  |  4 ++-
 tests/qemu-iotests/160 | 72 ++
 tests/qemu-iotests/160.out | 51 
 tests/qemu-iotests/group   |  1 +
 6 files changed, 165 insertions(+), 7 deletions(-)
 create mode 100755 tests/qemu-iotests/160
 create mode 100644 tests/qemu-iotests/160.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 03bdd7a..f054599 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -46,9 +46,9 @@ STEXI
 ETEXI
 
 DEF("dd", img_dd,
-"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
if=input of=output")
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] if=input of=output")
 STEXI
-@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] if=@var{input} of=@var{output}
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] if=@var{input} 
of=@var{output}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 498626b..af8f97f 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -173,7 +173,8 @@ static void QEMU_NORETURN help(void)
"(default: 512)\n"
"  'count=N' copy only N input blocks\n"
"  'if=FILE' read from FILE\n"
-   "  'of=FILE' write to FILE\n";
+   "  'of=FILE' write to FILE\n"
+   "  'skip=N' skip N bs-sized blocks at the start of input\n";
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_format(format_print, NULL);
@@ -3805,6 +3806,7 @@ out:
 #define C_COUNT   02
 #define C_IF  04
 #define C_OF  010
+#define C_SKIP020
 
 struct DdInfo {
 unsigned int flags;
@@ -3815,6 +3817,7 @@ struct DdIo {
 size_t bsz;/* Block size */
 char *filename;
 uint8_t *buf;
+int64_t offset;
 };
 
 struct DdOpts {
@@ -3940,6 +3943,19 @@ static int img_dd_of(const char *arg,
 return 0;
 }
 
+static int img_dd_skip(const char *arg,
+   struct DdIo *in, struct DdIo *out,
+   struct DdInfo *dd)
+{
+in->offset = get_size(arg);
+
+if (in->offset == 0 && (errno == EINVAL || errno == ERANGE)) {
+return 1;
+}
+
+return 0;
+}
+
 static int img_dd(int argc, char **argv)
 {
 int ret = 0;
@@ -3963,12 +3979,14 @@ static int img_dd(int argc, char **argv)
 struct DdIo in = {
 .bsz = 512, /* Block size is by default 512 bytes */
 .filename = NULL,
-.buf = NULL
+.buf = NULL,
+.offset = 0
 };
 struct DdIo out = {
 .bsz = 512,
 .filename = NULL,
-.buf = NULL
+.buf = NULL,
+.offset = 0
 };
 
 const struct DdOpts options[] = {
@@ -3976,6 +3994,7 @@ static int img_dd(int argc, char **argv)
 { "count", img_dd_count, C_COUNT },
 { "if", img_dd_if, C_IF },
 { "of", img_dd_of, C_OF },
+{ "skip", img_dd_skip, C_SKIP },
 { NULL, NULL, 0 }
 };
 const struct option long_options[] = {
@@ -4090,7 +4109,16 @@ static int img_dd(int argc, char **argv)
 size = dd.count * in.bsz;
 }
 
-qemu_opt_set_number(opts, BLOCK_OPT_SIZE, size, _abort);
+if (dd.flags & C_SKIP && size < in.bsz * in.offset) {
+/* We give a warning if the skip option is bigger than the input
+ * size and create an empty output disk image (i.e. like dd(1)).
+ */
+error_report("%s: cannot skip to specified offset", in.filename);
+qemu_opt_set_number(opts, BLOCK_OPT_SIZE, 0, _abort);
+} else {
+qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
+size - in.bsz * in.offset, _abort);
+}
 
 ret = bdrv_create(drv, out.filename, opts, _err);
 if (ret < 0) {
@@ -4111,6 +4139,10 @@ static int img_dd(int argc, char **argv)
 
 in.buf = g_new(uint8_t, in.bsz);
 
+if (dd.flags & C_SKIP) {
+incount = in.offset * in.bsz;
+}
+
 for (; incount < size; block_count++) {
 int in_ret, out_ret;
 
diff --git a/qemu-img.texi b/qemu-img.texi
index 880293a..174aae3 100644
--- a/qemu-img.texi
+++ b/qemu-img.tex

Re: [Qemu-devel] [Qemu-block] [PATCH v3] qemu-img: add skip option to dd

2016-07-28 Thread Reda Sallahi
On 7/28/16, Stefan Hajnoczi <stefa...@gmail.com> wrote:
> On Wed, Jul 27, 2016 at 3:51 PM, Reda Sallahi <fullma...@gmail.com> wrote:
>> -qemu_opt_set_number(opts, BLOCK_OPT_SIZE, size, _abort);
>> +if (dd.flags & C_SKIP && size < in.bsz * in.offset) {
>> +error_report("%s: cannot skip to specified offset",
>> in.filename);
>> +qemu_opt_set_number(opts, BLOCK_OPT_SIZE, 0, _abort);
>
> This looks odd.  What is supposed to happen in this case?  Do you have
> a test case for it?
>

We print a warning if we have specified a too big of a value for skip (bigger
than the input size) and set the size to 0 for the output disk image. It's the
same behavior on dd(1).

In the last iteration of the test case it covers such a case. Though without
checking the output on stderr.

-- 
Reda <fullma...@gmail.com>



[Qemu-devel] [PATCH v3] qemu-img: add skip option to dd

2016-07-27 Thread Reda Sallahi
This adds the skip option which allows qemu-img dd to skip a number of blocks
before copying the input.

A test case was added to test the skip option.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
Depends on:
[PATCH v6] qemu-img: add the 'dd' subcommand

Changes from v2:
* Delete a tab that sneaked in (test case 160).

Changes from v1:
* Change test case output.

 qemu-img-cmds.hx   |  4 +--
 qemu-img.c | 37 +---
 qemu-img.texi  |  4 ++-
 tests/qemu-iotests/160 | 72 ++
 tests/qemu-iotests/160.out | 51 
 tests/qemu-iotests/group   |  1 +
 6 files changed, 162 insertions(+), 7 deletions(-)
 create mode 100755 tests/qemu-iotests/160
 create mode 100644 tests/qemu-iotests/160.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 03bdd7a..f054599 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -46,9 +46,9 @@ STEXI
 ETEXI
 
 DEF("dd", img_dd,
-"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
if=input of=output")
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] if=input of=output")
 STEXI
-@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] if=@var{input} of=@var{output}
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] if=@var{input} 
of=@var{output}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 498626b..e83f838 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -173,7 +173,8 @@ static void QEMU_NORETURN help(void)
"(default: 512)\n"
"  'count=N' copy only N input blocks\n"
"  'if=FILE' read from FILE\n"
-   "  'of=FILE' write to FILE\n";
+   "  'of=FILE' write to FILE\n"
+   "  'skip=N' skip N bs-sized blocks at the start of input\n";
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_format(format_print, NULL);
@@ -3805,6 +3806,7 @@ out:
 #define C_COUNT   02
 #define C_IF  04
 #define C_OF  010
+#define C_SKIP020
 
 struct DdInfo {
 unsigned int flags;
@@ -3815,6 +3817,7 @@ struct DdIo {
 size_t bsz;/* Block size */
 char *filename;
 uint8_t *buf;
+int64_t offset;
 };
 
 struct DdOpts {
@@ -3940,6 +3943,19 @@ static int img_dd_of(const char *arg,
 return 0;
 }
 
+static int img_dd_skip(const char *arg,
+   struct DdIo *in, struct DdIo *out,
+   struct DdInfo *dd)
+{
+in->offset = get_size(arg);
+
+if (in->offset == 0 && (errno == EINVAL || errno == ERANGE)) {
+return 1;
+}
+
+return 0;
+}
+
 static int img_dd(int argc, char **argv)
 {
 int ret = 0;
@@ -3963,12 +3979,14 @@ static int img_dd(int argc, char **argv)
 struct DdIo in = {
 .bsz = 512, /* Block size is by default 512 bytes */
 .filename = NULL,
-.buf = NULL
+.buf = NULL,
+.offset = 0
 };
 struct DdIo out = {
 .bsz = 512,
 .filename = NULL,
-.buf = NULL
+.buf = NULL,
+.offset = 0
 };
 
 const struct DdOpts options[] = {
@@ -3976,6 +3994,7 @@ static int img_dd(int argc, char **argv)
 { "count", img_dd_count, C_COUNT },
 { "if", img_dd_if, C_IF },
 { "of", img_dd_of, C_OF },
+{ "skip", img_dd_skip, C_SKIP },
 { NULL, NULL, 0 }
 };
 const struct option long_options[] = {
@@ -4090,7 +4109,13 @@ static int img_dd(int argc, char **argv)
 size = dd.count * in.bsz;
 }
 
-qemu_opt_set_number(opts, BLOCK_OPT_SIZE, size, _abort);
+if (dd.flags & C_SKIP && size < in.bsz * in.offset) {
+error_report("%s: cannot skip to specified offset", in.filename);
+qemu_opt_set_number(opts, BLOCK_OPT_SIZE, 0, _abort);
+} else {
+qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
+size - in.bsz * in.offset, _abort);
+}
 
 ret = bdrv_create(drv, out.filename, opts, _err);
 if (ret < 0) {
@@ -4111,6 +4136,10 @@ static int img_dd(int argc, char **argv)
 
 in.buf = g_new(uint8_t, in.bsz);
 
+if (dd.flags & C_SKIP) {
+incount = in.offset * in.bsz;
+}
+
 for (; incount < size; block_count++) {
 int in_ret, out_ret;
 
diff --git a/qemu-img.texi b/qemu-img.texi
index 880293a..174aae3 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -151,6 +151,8 @@ sets the number of input blocks to copy
 sets the input file
 @item of=@var{output}
 sets the output file
+@item skip=@var{blocks}
+sets the number of input blocks to skip
 @end table
 
 Command description:
@@ -324,7 +3

[Qemu-devel] [PATCH v2] qemu-img: add skip option to dd

2016-07-27 Thread Reda Sallahi
This adds the skip option which allows qemu-img dd to skip a number of blocks
before copying the input.

A test case was added to test the skip option.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
Depends on:
[PATCH v6] qemu-img: add the 'dd' subcommand

Changes from v1:
* Change test case output.

 qemu-img-cmds.hx   |  4 +--
 qemu-img.c | 37 +---
 qemu-img.texi  |  4 ++-
 tests/qemu-iotests/160 | 72 ++
 tests/qemu-iotests/160.out | 51 
 tests/qemu-iotests/group   |  1 +
 6 files changed, 162 insertions(+), 7 deletions(-)
 create mode 100755 tests/qemu-iotests/160
 create mode 100644 tests/qemu-iotests/160.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 03bdd7a..f054599 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -46,9 +46,9 @@ STEXI
 ETEXI
 
 DEF("dd", img_dd,
-"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
if=input of=output")
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] if=input of=output")
 STEXI
-@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] if=@var{input} of=@var{output}
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] if=@var{input} 
of=@var{output}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 498626b..e83f838 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -173,7 +173,8 @@ static void QEMU_NORETURN help(void)
"(default: 512)\n"
"  'count=N' copy only N input blocks\n"
"  'if=FILE' read from FILE\n"
-   "  'of=FILE' write to FILE\n";
+   "  'of=FILE' write to FILE\n"
+   "  'skip=N' skip N bs-sized blocks at the start of input\n";
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_format(format_print, NULL);
@@ -3805,6 +3806,7 @@ out:
 #define C_COUNT   02
 #define C_IF  04
 #define C_OF  010
+#define C_SKIP020
 
 struct DdInfo {
 unsigned int flags;
@@ -3815,6 +3817,7 @@ struct DdIo {
 size_t bsz;/* Block size */
 char *filename;
 uint8_t *buf;
+int64_t offset;
 };
 
 struct DdOpts {
@@ -3940,6 +3943,19 @@ static int img_dd_of(const char *arg,
 return 0;
 }
 
+static int img_dd_skip(const char *arg,
+   struct DdIo *in, struct DdIo *out,
+   struct DdInfo *dd)
+{
+in->offset = get_size(arg);
+
+if (in->offset == 0 && (errno == EINVAL || errno == ERANGE)) {
+return 1;
+}
+
+return 0;
+}
+
 static int img_dd(int argc, char **argv)
 {
 int ret = 0;
@@ -3963,12 +3979,14 @@ static int img_dd(int argc, char **argv)
 struct DdIo in = {
 .bsz = 512, /* Block size is by default 512 bytes */
 .filename = NULL,
-.buf = NULL
+.buf = NULL,
+.offset = 0
 };
 struct DdIo out = {
 .bsz = 512,
 .filename = NULL,
-.buf = NULL
+.buf = NULL,
+.offset = 0
 };
 
 const struct DdOpts options[] = {
@@ -3976,6 +3994,7 @@ static int img_dd(int argc, char **argv)
 { "count", img_dd_count, C_COUNT },
 { "if", img_dd_if, C_IF },
 { "of", img_dd_of, C_OF },
+{ "skip", img_dd_skip, C_SKIP },
 { NULL, NULL, 0 }
 };
 const struct option long_options[] = {
@@ -4090,7 +4109,13 @@ static int img_dd(int argc, char **argv)
 size = dd.count * in.bsz;
 }
 
-qemu_opt_set_number(opts, BLOCK_OPT_SIZE, size, _abort);
+if (dd.flags & C_SKIP && size < in.bsz * in.offset) {
+error_report("%s: cannot skip to specified offset", in.filename);
+qemu_opt_set_number(opts, BLOCK_OPT_SIZE, 0, _abort);
+} else {
+qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
+size - in.bsz * in.offset, _abort);
+}
 
 ret = bdrv_create(drv, out.filename, opts, _err);
 if (ret < 0) {
@@ -4111,6 +4136,10 @@ static int img_dd(int argc, char **argv)
 
 in.buf = g_new(uint8_t, in.bsz);
 
+if (dd.flags & C_SKIP) {
+incount = in.offset * in.bsz;
+}
+
 for (; incount < size; block_count++) {
 int in_ret, out_ret;
 
diff --git a/qemu-img.texi b/qemu-img.texi
index 880293a..174aae3 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -151,6 +151,8 @@ sets the number of input blocks to copy
 sets the input file
 @item of=@var{output}
 sets the output file
+@item skip=@var{blocks}
+sets the number of input blocks to skip
 @end table
 
 Command description:
@@ -324,7 +326,7 @@ skipped. This is useful for formats such as @code{rbd} if 

[Qemu-devel] [PATCH] qemu-img: add skip option to dd

2016-07-27 Thread Reda Sallahi
This adds the skip option which allows qemu-img dd to skip a number of blocks
before copying the input.

A test case was added to test the skip option.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
Depends on:
[PATCH v6] qemu-img: add the 'dd' subcommand

 qemu-img-cmds.hx   |  4 +--
 qemu-img.c | 37 +---
 qemu-img.texi  |  4 ++-
 tests/qemu-iotests/160 | 71 ++
 tests/qemu-iotests/160.out | 52 +
 tests/qemu-iotests/group   |  1 +
 6 files changed, 162 insertions(+), 7 deletions(-)
 create mode 100755 tests/qemu-iotests/160
 create mode 100644 tests/qemu-iotests/160.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 03bdd7a..f054599 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -46,9 +46,9 @@ STEXI
 ETEXI
 
 DEF("dd", img_dd,
-"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
if=input of=output")
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
[skip=blocks] if=input of=output")
 STEXI
-@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] if=@var{input} of=@var{output}
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] if=@var{input} 
of=@var{output}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 498626b..e83f838 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -173,7 +173,8 @@ static void QEMU_NORETURN help(void)
"(default: 512)\n"
"  'count=N' copy only N input blocks\n"
"  'if=FILE' read from FILE\n"
-   "  'of=FILE' write to FILE\n";
+   "  'of=FILE' write to FILE\n"
+   "  'skip=N' skip N bs-sized blocks at the start of input\n";
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_format(format_print, NULL);
@@ -3805,6 +3806,7 @@ out:
 #define C_COUNT   02
 #define C_IF  04
 #define C_OF  010
+#define C_SKIP020
 
 struct DdInfo {
 unsigned int flags;
@@ -3815,6 +3817,7 @@ struct DdIo {
 size_t bsz;/* Block size */
 char *filename;
 uint8_t *buf;
+int64_t offset;
 };
 
 struct DdOpts {
@@ -3940,6 +3943,19 @@ static int img_dd_of(const char *arg,
 return 0;
 }
 
+static int img_dd_skip(const char *arg,
+   struct DdIo *in, struct DdIo *out,
+   struct DdInfo *dd)
+{
+in->offset = get_size(arg);
+
+if (in->offset == 0 && (errno == EINVAL || errno == ERANGE)) {
+return 1;
+}
+
+return 0;
+}
+
 static int img_dd(int argc, char **argv)
 {
 int ret = 0;
@@ -3963,12 +3979,14 @@ static int img_dd(int argc, char **argv)
 struct DdIo in = {
 .bsz = 512, /* Block size is by default 512 bytes */
 .filename = NULL,
-.buf = NULL
+.buf = NULL,
+.offset = 0
 };
 struct DdIo out = {
 .bsz = 512,
 .filename = NULL,
-.buf = NULL
+.buf = NULL,
+.offset = 0
 };
 
 const struct DdOpts options[] = {
@@ -3976,6 +3994,7 @@ static int img_dd(int argc, char **argv)
 { "count", img_dd_count, C_COUNT },
 { "if", img_dd_if, C_IF },
 { "of", img_dd_of, C_OF },
+{ "skip", img_dd_skip, C_SKIP },
 { NULL, NULL, 0 }
 };
 const struct option long_options[] = {
@@ -4090,7 +4109,13 @@ static int img_dd(int argc, char **argv)
 size = dd.count * in.bsz;
 }
 
-qemu_opt_set_number(opts, BLOCK_OPT_SIZE, size, _abort);
+if (dd.flags & C_SKIP && size < in.bsz * in.offset) {
+error_report("%s: cannot skip to specified offset", in.filename);
+qemu_opt_set_number(opts, BLOCK_OPT_SIZE, 0, _abort);
+} else {
+qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
+size - in.bsz * in.offset, _abort);
+}
 
 ret = bdrv_create(drv, out.filename, opts, _err);
 if (ret < 0) {
@@ -4111,6 +4136,10 @@ static int img_dd(int argc, char **argv)
 
 in.buf = g_new(uint8_t, in.bsz);
 
+if (dd.flags & C_SKIP) {
+incount = in.offset * in.bsz;
+}
+
 for (; incount < size; block_count++) {
 int in_ret, out_ret;
 
diff --git a/qemu-img.texi b/qemu-img.texi
index 880293a..174aae3 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -151,6 +151,8 @@ sets the number of input blocks to copy
 sets the input file
 @item of=@var{output}
 sets the output file
+@item skip=@var{blocks}
+sets the number of input blocks to skip
 @end table
 
 Command description:
@@ -324,7 +326,7 @@ skipped. This is useful for formats such as @code{rbd} if 
the target
 volume has already been create

[Qemu-devel] [PATCH v6] qemu-img: add the 'dd' subcommand

2016-07-25 Thread Reda Sallahi
This patch adds a basic dd subcommand analogous to dd(1) to qemu-img.

For the start, this implements the bs, if, of and count options and requires
both if and of to be specified (no stdin/stdout if not specified) and doesn't
support tty, pipes, etc.

The image format must be specified with -O for the output if the raw format
is not the intended one.

Two tests are added to test qemu-img dd.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
Changes from v5:
* Add dd sections on qemu-img.texi.
Changes from v4:
* Fix the exit status.
Changes from v3:
* Delete an unused (so far) field in DdIo.
Changes from v2:
* Add copyright headers to new files.
Changes from v1:
* Removal of dead code.
* Fix a memory leak.
* Complete the cleanup function in the test cases.

 qemu-img-cmds.hx |   6 +
 qemu-img.c   | 363 ++-
 qemu-img.texi|  25 +++
 tests/qemu-iotests/158   |  68 
 tests/qemu-iotests/158.out   |  15 ++
 tests/qemu-iotests/159   |  70 
 tests/qemu-iotests/159.out   |  87 ++
 tests/qemu-iotests/common.filter |   9 +
 tests/qemu-iotests/group |   2 +
 9 files changed, 644 insertions(+), 1 deletion(-)
 create mode 100755 tests/qemu-iotests/158
 create mode 100644 tests/qemu-iotests/158.out
 create mode 100755 tests/qemu-iotests/159
 create mode 100644 tests/qemu-iotests/159.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 7e95b2d..03bdd7a 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -45,6 +45,12 @@ STEXI
 @item convert [--object @var{objectdef}] [--image-opts] [-c] [-p] [-q] [-n] 
[-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-o 
@var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S 
@var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
 
+DEF("dd", img_dd,
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
if=input of=output")
+STEXI
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] if=@var{input} of=@var{output}
+ETEXI
+
 DEF("info", img_info,
 "info [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] 
[--backing-chain] filename")
 STEXI
diff --git a/qemu-img.c b/qemu-img.c
index 2e40e1f..498626b 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -166,7 +166,14 @@ static void QEMU_NORETURN help(void)
"Parameters to compare subcommand:\n"
"  '-f' first image format\n"
"  '-F' second image format\n"
-   "  '-s' run in Strict mode - fail on different image size or sector 
allocation\n";
+   "  '-s' run in Strict mode - fail on different image size or sector 
allocation\n"
+   "\n"
+   "Parameters to dd subcommand:\n"
+   "  'bs=BYTES' read and write up to BYTES bytes at a time "
+   "(default: 512)\n"
+   "  'count=N' copy only N input blocks\n"
+   "  'if=FILE' read from FILE\n"
+   "  'of=FILE' write to FILE\n";
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_format(format_print, NULL);
@@ -3794,6 +3801,360 @@ out:
 return 0;
 }
 
+#define C_BS  01
+#define C_COUNT   02
+#define C_IF  04
+#define C_OF  010
+
+struct DdInfo {
+unsigned int flags;
+size_t count;
+};
+
+struct DdIo {
+size_t bsz;/* Block size */
+char *filename;
+uint8_t *buf;
+};
+
+struct DdOpts {
+const char *name;
+int (*f)(const char *, struct DdIo *, struct DdIo *, struct DdInfo *);
+unsigned int flag;
+};
+
+/*
+ * get_size() was needed for the size syntax dd(1) supports which is
+ * different from qemu_strtosz_suffix()
+ *
+ */
+static size_t get_size(const char *str)
+{
+/* XXX: handle {k,m,g}B notations */
+unsigned long num;
+size_t res = 0;
+const char *buf;
+int ret;
+
+errno = 0;
+if (strchr(str, '-')) {
+error_report("invalid number: '%s'", str);
+errno = EINVAL;
+return res;
+}
+ret = qemu_strtoul(str, , 0, );
+
+if (ret < 0) {
+error_report("invalid number: '%s'", str);
+return res;
+}
+
+switch (*buf) {
+case '\0':
+case 'c':
+res = num;
+break;
+case 'w':
+res = num * 2;
+break;
+case 'b':
+res = num * 512;
+break;
+case 'K':
+res = num * 1024;
+break;
+case 'M':
+res = num * 1024 * 1024;
+break;
+case 'G':
+res = num * 1024 * 1024 * 1024;
+break;
+case 'T':
+res = num * 1024 * 1024 * 1024 * 1024;
+break;
+case 'P':
+res = num * 1024 * 1024 * 1024 * 1024 * 1024;
+   

[Qemu-devel] [PATCH] qemu-img: fix error messages emitted by img_open()

2016-07-21 Thread Reda Sallahi
img_open_file() and img_open_opts() were printing error messages with a
duplicate part because of a wrong use of error_reportf_err() (e.g.
qemu-img: Could not open 'foo': Could not open 'foo': No such file or directory)

This change uses error_report_err() instead to eliminate the duplicate part.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
 qemu-img.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 2e40e1f..dc6652d 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -268,7 +268,7 @@ static BlockBackend *img_open_opts(const char *optstr,
 options = qemu_opts_to_qdict(opts, NULL);
 blk = blk_new_open(NULL, NULL, options, flags, _err);
 if (!blk) {
-error_reportf_err(local_err, "Could not open '%s': ", optstr);
+error_report_err(local_err);
 return NULL;
 }
 blk_set_enable_write_cache(blk, !writethrough);
@@ -295,7 +295,7 @@ static BlockBackend *img_open_file(const char *filename,
 
 blk = blk_new_open(filename, NULL, options, flags, _err);
 if (!blk) {
-error_reportf_err(local_err, "Could not open '%s': ", filename);
+error_report(local_err);
 return NULL;
 }
 blk_set_enable_write_cache(blk, !writethrough);
-- 
2.9.0




[Qemu-devel] [PATCH v5] qemu-img: add the 'dd' subcommand

2016-07-20 Thread Reda Sallahi
This patch adds a basic dd subcommand analogous to dd(1) to qemu-img.

For the start, this implements the bs, if, of and count options and requires
both if and of to be specified (no stdin/stdout if not specified) and doesn't
support tty, pipes, etc.

The image format must be specified with -O for the output if the raw format
is not the intended one.

Two tests are added to test qemu-img dd.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
Changes from v4:
* Fix the exit status.

Changes from v3:
* Delete an unused (so far) field in DdIo.

Changes from v2:
* Add copyright headers to new files.

Changes from v1:
* Removal of dead code.
* Fix a memory leak.
* Complete the cleanup function in the test cases.

 qemu-img-cmds.hx |   6 +
 qemu-img.c   | 363 ++-
 tests/qemu-iotests/158   |  68 
 tests/qemu-iotests/158.out   |  15 ++
 tests/qemu-iotests/159   |  70 
 tests/qemu-iotests/159.out   |  87 ++
 tests/qemu-iotests/common.filter |   9 +
 tests/qemu-iotests/group |   2 +
 8 files changed, 619 insertions(+), 1 deletion(-)
 create mode 100755 tests/qemu-iotests/158
 create mode 100644 tests/qemu-iotests/158.out
 create mode 100755 tests/qemu-iotests/159
 create mode 100644 tests/qemu-iotests/159.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 7e95b2d..03bdd7a 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -45,6 +45,12 @@ STEXI
 @item convert [--object @var{objectdef}] [--image-opts] [-c] [-p] [-q] [-n] 
[-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-o 
@var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S 
@var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
 
+DEF("dd", img_dd,
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
if=input of=output")
+STEXI
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] if=@var{input} of=@var{output}
+ETEXI
+
 DEF("info", img_info,
 "info [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] 
[--backing-chain] filename")
 STEXI
diff --git a/qemu-img.c b/qemu-img.c
index 2e40e1f..498626b 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -166,7 +166,14 @@ static void QEMU_NORETURN help(void)
"Parameters to compare subcommand:\n"
"  '-f' first image format\n"
"  '-F' second image format\n"
-   "  '-s' run in Strict mode - fail on different image size or sector 
allocation\n";
+   "  '-s' run in Strict mode - fail on different image size or sector 
allocation\n"
+   "\n"
+   "Parameters to dd subcommand:\n"
+   "  'bs=BYTES' read and write up to BYTES bytes at a time "
+   "(default: 512)\n"
+   "  'count=N' copy only N input blocks\n"
+   "  'if=FILE' read from FILE\n"
+   "  'of=FILE' write to FILE\n";
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_format(format_print, NULL);
@@ -3794,6 +3801,360 @@ out:
 return 0;
 }
 
+#define C_BS  01
+#define C_COUNT   02
+#define C_IF  04
+#define C_OF  010
+
+struct DdInfo {
+unsigned int flags;
+size_t count;
+};
+
+struct DdIo {
+size_t bsz;/* Block size */
+char *filename;
+uint8_t *buf;
+};
+
+struct DdOpts {
+const char *name;
+int (*f)(const char *, struct DdIo *, struct DdIo *, struct DdInfo *);
+unsigned int flag;
+};
+
+/*
+ * get_size() was needed for the size syntax dd(1) supports which is
+ * different from qemu_strtosz_suffix()
+ *
+ */
+static size_t get_size(const char *str)
+{
+/* XXX: handle {k,m,g}B notations */
+unsigned long num;
+size_t res = 0;
+const char *buf;
+int ret;
+
+errno = 0;
+if (strchr(str, '-')) {
+error_report("invalid number: '%s'", str);
+errno = EINVAL;
+return res;
+}
+ret = qemu_strtoul(str, , 0, );
+
+if (ret < 0) {
+error_report("invalid number: '%s'", str);
+return res;
+}
+
+switch (*buf) {
+case '\0':
+case 'c':
+res = num;
+break;
+case 'w':
+res = num * 2;
+break;
+case 'b':
+res = num * 512;
+break;
+case 'K':
+res = num * 1024;
+break;
+case 'M':
+res = num * 1024 * 1024;
+break;
+case 'G':
+res = num * 1024 * 1024 * 1024;
+break;
+case 'T':
+res = num * 1024 * 1024 * 1024 * 1024;
+break;
+case 'P':
+res = num * 1024 * 1024 * 1024 * 1024 * 1024;
+break;
+case 'E':
+res = num * 1024 * 1024 * 1024 * 1024 * 1024 * 1024;
+ 

[Qemu-devel] [PATCH v4] qemu-img: add the 'dd' subcommand

2016-07-19 Thread Reda Sallahi
This patch adds a basic dd subcommand analogous to dd(1) to qemu-img.

For the start, this implements the bs, if, of and count options and requires
both if and of to be specified (no stdin/stdout if not specified) and doesn't
support tty, pipes, etc.

The image format must be specified with -O for the output if the raw format
is not the intended one.

Two tests are added to test qemu-img dd.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
Changes from v3:
* Delete an unused (so far) field in DdIo.

Changes from v2:
* Add copyright headers to new files.

Changes from v1:
* Removal of dead code.
* Fix a memory leak.
* Complete the cleanup function in the test cases.

 qemu-img-cmds.hx |   6 +
 qemu-img.c   | 361 ++-
 tests/qemu-iotests/158   |  68 
 tests/qemu-iotests/158.out   |  15 ++
 tests/qemu-iotests/159   |  70 
 tests/qemu-iotests/159.out   |  87 ++
 tests/qemu-iotests/common.filter |   9 +
 tests/qemu-iotests/group |   2 +
 8 files changed, 617 insertions(+), 1 deletion(-)
 create mode 100755 tests/qemu-iotests/158
 create mode 100644 tests/qemu-iotests/158.out
 create mode 100755 tests/qemu-iotests/159
 create mode 100644 tests/qemu-iotests/159.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 7e95b2d..03bdd7a 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -45,6 +45,12 @@ STEXI
 @item convert [--object @var{objectdef}] [--image-opts] [-c] [-p] [-q] [-n] 
[-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-o 
@var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S 
@var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
 
+DEF("dd", img_dd,
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
if=input of=output")
+STEXI
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] if=@var{input} of=@var{output}
+ETEXI
+
 DEF("info", img_info,
 "info [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] 
[--backing-chain] filename")
 STEXI
diff --git a/qemu-img.c b/qemu-img.c
index 2e40e1f..946d538 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -166,7 +166,14 @@ static void QEMU_NORETURN help(void)
"Parameters to compare subcommand:\n"
"  '-f' first image format\n"
"  '-F' second image format\n"
-   "  '-s' run in Strict mode - fail on different image size or sector 
allocation\n";
+   "  '-s' run in Strict mode - fail on different image size or sector 
allocation\n"
+   "\n"
+   "Parameters to dd subcommand:\n"
+   "  'bs=BYTES' read and write up to BYTES bytes at a time "
+   "(default: 512)\n"
+   "  'count=N' copy only N input blocks\n"
+   "  'if=FILE' read from FILE\n"
+   "  'of=FILE' write to FILE\n";
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_format(format_print, NULL);
@@ -3794,6 +3801,358 @@ out:
 return 0;
 }
 
+#define C_BS  01
+#define C_COUNT   02
+#define C_IF  04
+#define C_OF  010
+
+struct DdInfo {
+unsigned int flags;
+size_t count;
+};
+
+struct DdIo {
+size_t bsz;/* Block size */
+char *filename;
+uint8_t *buf;
+};
+
+struct DdOpts {
+const char *name;
+int (*f)(const char *, struct DdIo *, struct DdIo *, struct DdInfo *);
+unsigned int flag;
+};
+
+/*
+ * get_size() was needed for the size syntax dd(1) supports which is
+ * different from qemu_strtosz_suffix()
+ *
+ */
+static size_t get_size(const char *str)
+{
+/* XXX: handle {k,m,g}B notations */
+unsigned long num;
+size_t res = 0;
+const char *buf;
+int ret;
+
+errno = 0;
+if (strchr(str, '-')) {
+error_report("invalid number: '%s'", str);
+errno = EINVAL;
+return res;
+}
+ret = qemu_strtoul(str, , 0, );
+
+if (ret < 0) {
+error_report("invalid number: '%s'", str);
+return res;
+}
+
+switch (*buf) {
+case '\0':
+case 'c':
+res = num;
+break;
+case 'w':
+res = num * 2;
+break;
+case 'b':
+res = num * 512;
+break;
+case 'K':
+res = num * 1024;
+break;
+case 'M':
+res = num * 1024 * 1024;
+break;
+case 'G':
+res = num * 1024 * 1024 * 1024;
+break;
+case 'T':
+res = num * 1024 * 1024 * 1024 * 1024;
+break;
+case 'P':
+res = num * 1024 * 1024 * 1024 * 1024 * 1024;
+break;
+case 'E':
+res = num * 1024 * 1024 * 1024 * 1024 * 1024 * 1024;
+break;
+case 'Z':
+

[Qemu-devel] [PATCH v3] qemu-img: add the 'dd' subcommand

2016-07-18 Thread Reda Sallahi
This patch adds a basic dd subcommand analogous to dd(1) to qemu-img.

For the start, this implements the bs, if, of and count options and requires
both if and of to be specified (no stdin/stdout if not specified) and doesn't
support tty, pipes, etc.

The image format must be specified with -O for the output if the raw format
is not the intended one.

Two tests are added to test qemu-img dd.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
Changes from v2:
* Added copyright headers to new files.

Changes from v1:
* Removal of dead code.
* Fix a memory leak.
* Complete the cleanup function in the test cases.

 qemu-img-cmds.hx |   6 +
 qemu-img.c   | 364 ++-
 tests/qemu-iotests/158   |  68 
 tests/qemu-iotests/158.out   |  15 ++
 tests/qemu-iotests/159   |  70 
 tests/qemu-iotests/159.out   |  87 ++
 tests/qemu-iotests/common.filter |   9 +
 tests/qemu-iotests/group |   2 +
 8 files changed, 620 insertions(+), 1 deletion(-)
 create mode 100755 tests/qemu-iotests/158
 create mode 100644 tests/qemu-iotests/158.out
 create mode 100755 tests/qemu-iotests/159
 create mode 100644 tests/qemu-iotests/159.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 7e95b2d..03bdd7a 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -45,6 +45,12 @@ STEXI
 @item convert [--object @var{objectdef}] [--image-opts] [-c] [-p] [-q] [-n] 
[-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-o 
@var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S 
@var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
 
+DEF("dd", img_dd,
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
if=input of=output")
+STEXI
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] if=@var{input} of=@var{output}
+ETEXI
+
 DEF("info", img_info,
 "info [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] 
[--backing-chain] filename")
 STEXI
diff --git a/qemu-img.c b/qemu-img.c
index 2e40e1f..5a2d93c 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -166,7 +166,14 @@ static void QEMU_NORETURN help(void)
"Parameters to compare subcommand:\n"
"  '-f' first image format\n"
"  '-F' second image format\n"
-   "  '-s' run in Strict mode - fail on different image size or sector 
allocation\n";
+   "  '-s' run in Strict mode - fail on different image size or sector 
allocation\n"
+   "\n"
+   "Parameters to dd subcommand:\n"
+   "  'bs=BYTES' read and write up to BYTES bytes at a time "
+   "(default: 512)\n"
+   "  'count=N' copy only N input blocks\n"
+   "  'if=FILE' read from FILE\n"
+   "  'of=FILE' write to FILE\n";
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_format(format_print, NULL);
@@ -3794,6 +3801,361 @@ out:
 return 0;
 }
 
+#define C_BS  01
+#define C_COUNT   02
+#define C_IF  04
+#define C_OF  010
+
+struct DdInfo {
+unsigned int flags;
+size_t count;
+};
+
+struct DdIo {
+size_t bsz;/* Block size */
+off_t offset;
+char *filename;
+uint8_t *buf;
+};
+
+struct DdOpts {
+const char *name;
+int (*f)(const char *, struct DdIo *, struct DdIo *, struct DdInfo *);
+unsigned int flag;
+};
+
+/*
+ * get_size() was needed for the size syntax dd(1) supports which is
+ * different from qemu_strtosz_suffix()
+ *
+ */
+static size_t get_size(const char *str)
+{
+/* XXX: handle {k,m,g}B notations */
+unsigned long num;
+size_t res = 0;
+const char *buf;
+int ret;
+
+errno = 0;
+if (strchr(str, '-')) {
+error_report("invalid number: '%s'", str);
+errno = EINVAL;
+return res;
+}
+ret = qemu_strtoul(str, , 0, );
+
+if (ret < 0) {
+error_report("invalid number: '%s'", str);
+return res;
+}
+
+switch (*buf) {
+case '\0':
+case 'c':
+res = num;
+break;
+case 'w':
+res = num * 2;
+break;
+case 'b':
+res = num * 512;
+break;
+case 'K':
+res = num * 1024;
+break;
+case 'M':
+res = num * 1024 * 1024;
+break;
+case 'G':
+res = num * 1024 * 1024 * 1024;
+break;
+case 'T':
+res = num * 1024 * 1024 * 1024 * 1024;
+break;
+case 'P':
+res = num * 1024 * 1024 * 1024 * 1024 * 1024;
+break;
+case 'E':
+res = num * 1024 * 1024 * 1024 * 1024 * 1024 * 1024;
+break;
+case 'Z':
+res = num * 1024 * 1024 * 1024 * 1024 * 1024 * 

[Qemu-devel] [PATCH v2] qemu-img: add the 'dd' subcommand

2016-07-18 Thread Reda Sallahi
This patch adds a basic dd subcommand analogous to dd(1) to qemu-img.

For the start, this implements the bs, if, of and count options and requires
both if and of to be specified (no stdin/stdout if not specified) and doesn't
support tty, pipes, etc.

The image format must be specified with -O for the output if the raw format
is not the intended one.

Two tests are added to test qemu-img dd.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
Changes from v1:
* Removal of dead code.
* Fix a memory leak.
* Complete the cleanup function in the test cases.

 qemu-img-cmds.hx   |   6 +
 qemu-img.c | 366 -
 tests/qemu-iotests/158 |  54 +++
 tests/qemu-iotests/158.out |  15 ++
 tests/qemu-iotests/159 |  57 +++
 tests/qemu-iotests/159.out |  87 +++
 tests/qemu-iotests/group   |   2 +
 7 files changed, 586 insertions(+), 1 deletion(-)
 create mode 100755 tests/qemu-iotests/158
 create mode 100644 tests/qemu-iotests/158.out
 create mode 100755 tests/qemu-iotests/159
 create mode 100644 tests/qemu-iotests/159.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 7e95b2d..03bdd7a 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -45,6 +45,12 @@ STEXI
 @item convert [--object @var{objectdef}] [--image-opts] [-c] [-p] [-q] [-n] 
[-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-o 
@var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S 
@var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
 
+DEF("dd", img_dd,
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
if=input of=output")
+STEXI
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] if=@var{input} of=@var{output}
+ETEXI
+
 DEF("info", img_info,
 "info [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] 
[--backing-chain] filename")
 STEXI
diff --git a/qemu-img.c b/qemu-img.c
index 2e40e1f..329f01c 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -166,7 +166,14 @@ static void QEMU_NORETURN help(void)
"Parameters to compare subcommand:\n"
"  '-f' first image format\n"
"  '-F' second image format\n"
-   "  '-s' run in Strict mode - fail on different image size or sector 
allocation\n";
+   "  '-s' run in Strict mode - fail on different image size or sector 
allocation\n"
+   "\n"
+   "Parameters to dd subcommand:\n"
+   "  'bs=BYTES' read and write up to BYTES bytes at a time "
+   "(default: 512)\n"
+   "  'count=N' copy only N input blocks\n"
+   "  'if=FILE' read from FILE\n"
+   "  'of=FILE' write to FILE\n";
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_format(format_print, NULL);
@@ -3794,6 +3801,363 @@ out:
 return 0;
 }
 
+#define C_BS  01
+#define C_COUNT   02
+#define C_IF  04
+#define C_OF  010
+
+struct DdInfo {
+unsigned int flags;
+size_t count;
+};
+
+struct DdIo {
+size_t bsz;/* Block size */
+off_t offset;
+const char *filename;
+uint8_t *buf;
+};
+
+struct DdOpts {
+const char *name;
+int (*f)(const char *, struct DdIo *, struct DdIo *, struct DdInfo *);
+unsigned int flag;
+};
+
+/*
+ * get_size() was needed for the size syntax dd(1) supports which is
+ * different from qemu_strtosz_suffix()
+ *
+ */
+
+static size_t get_size(const char *str)
+{
+/* XXX: handle {k,m,g}B notations */
+unsigned long num;
+size_t res = 0;
+const char *buf;
+int ret;
+
+errno = 0;
+if (strchr(str, '-')) {
+error_report("invalid number: '%s'", str);
+errno = EINVAL;
+return res;
+}
+ret = qemu_strtoul(str, , 0, );
+
+if (ret < 0) {
+error_report("invalid number: '%s'", str);
+return res;
+}
+
+switch (*buf) {
+case '\0':
+case 'c':
+res = num;
+break;
+case 'w':
+res = num * 2;
+break;
+case 'b':
+res = num * 512;
+break;
+case 'K':
+res = num * 1024;
+break;
+case 'M':
+res = num * 1024 * 1024;
+break;
+case 'G':
+res = num * 1024 * 1024 * 1024;
+break;
+case 'T':
+res = num * 1024 * 1024 * 1024 * 1024;
+break;
+case 'P':
+res = num * 1024 * 1024 * 1024 * 1024 * 1024;
+break;
+case 'E':
+res = num * 1024 * 1024 * 1024 * 1024 * 1024 * 1024;
+break;
+case 'Z':
+res = num * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024;
+break;
+case 'Y':
+res = num * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024;
+br

[Qemu-devel] [PATCH] qemu-img: add the 'dd' subcommand

2016-07-13 Thread Reda Sallahi
This patch adds a basic dd subcommand analogous to dd(1) to qemu-img.

For the start, this implements the bs, if, of and count options and requires
both if and of to be specified (no stdin/stdout if not specified) and doesn't
support tty, pipes, etc.

The image format must be specified with -O for the output if the raw format
is not the intended one.

get_size() was needed for the size syntax dd(1) supports which is different
from qemu_strtosz_suffix().

Two tests are added to test qemu-img dd.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
 qemu-img-cmds.hx   |   6 +
 qemu-img.c | 645 -
 tests/qemu-iotests/158 |  53 
 tests/qemu-iotests/158.out |  15 ++
 tests/qemu-iotests/159 |  56 
 tests/qemu-iotests/159.out |  87 ++
 tests/qemu-iotests/group   |   2 +
 7 files changed, 863 insertions(+), 1 deletion(-)
 create mode 100755 tests/qemu-iotests/158
 create mode 100644 tests/qemu-iotests/158.out
 create mode 100755 tests/qemu-iotests/159
 create mode 100644 tests/qemu-iotests/159.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 7e95b2d..03bdd7a 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -45,6 +45,12 @@ STEXI
 @item convert [--object @var{objectdef}] [--image-opts] [-c] [-p] [-q] [-n] 
[-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-o 
@var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S 
@var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
 
+DEF("dd", img_dd,
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] 
if=input of=output")
+STEXI
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [count=@var{blocks}] if=@var{input} of=@var{output}
+ETEXI
+
 DEF("info", img_info,
 "info [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] 
[--backing-chain] filename")
 STEXI
diff --git a/qemu-img.c b/qemu-img.c
index ea5970b..d7f134d 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -166,7 +166,14 @@ static void QEMU_NORETURN help(void)
"Parameters to compare subcommand:\n"
"  '-f' first image format\n"
"  '-F' second image format\n"
-   "  '-s' run in Strict mode - fail on different image size or sector 
allocation\n";
+   "  '-s' run in Strict mode - fail on different image size or sector 
allocation\n"
+   "\n"
+   "Parameters to dd subcommand:\n"
+   "  'bs=BYTES' read and write up to BYTES bytes at a time "
+   "(default: 512)\n"
+   "  'count=N' copy only N input blocks\n"
+   "  'if=FILE' read from FILE instead of stdin\n"
+   "  'of=FILE' write to FILE instead of stdout\n";
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_format(format_print, NULL);
@@ -3794,6 +3801,642 @@ out:
 return 0;
 }
 
+#define C_BS  01
+#define C_CBS 02
+#define C_CONV04
+#define C_COUNT   010
+#define C_IBS 020
+#define C_IF  040
+#define C_IFLAG   0100
+#define C_OBS 0200
+#define C_OF  0400
+#define C_OFLAG   01000
+#define C_SEEK02000
+#define C_SKIP04000
+#define C_STATUS  01
+
+struct DdEss {
+unsigned int flags;
+unsigned int status;
+unsigned int conv;
+size_t count;
+size_t cbsz; /* Conversion block size */
+};
+
+struct DdIo {
+size_t bsz;/* Block size */
+off_t offset;
+const char *filename;
+unsigned int flags;
+uint8_t *buf;
+};
+
+struct DdOpts {
+const char *name;
+int (*f)(const char *, struct DdIo *, struct DdIo *, struct DdEss *);
+unsigned int flag;
+};
+
+static size_t get_size(const char *str)
+{
+/* XXX: handle {k,m,g}B notations */
+unsigned long num;
+size_t res = 0;
+const char *buf;
+int ret;
+
+errno = 0;
+if (strchr(str, '-')) {
+error_report("invalid number: '%s'", str);
+errno = EINVAL;
+return res;
+}
+ret = qemu_strtoul(str, , 0, );
+
+if (ret < 0) {
+error_report("invalid number: '%s'", str);
+return res;
+}
+
+switch (*buf) {
+case '\0':
+case 'c':
+res = num;
+break;
+case 'w':
+res = num * 2;
+break;
+case 'b':
+res = num * 512;
+break;
+case 'K':
+res = num * 1024;
+break;
+case 'M':
+res = num * 1024 * 1024;
+break;
+case 'G':
+res = num * 1024 * 1024 * 1024;
+break;
+case 'T':
+res = num * 1024 * 1024 * 1024 * 1024;
+break;
+case 'P':
+res = num * 1024 * 1024 * 1024 * 1024 * 1024;
+break;
+case 'E':
+res = num * 1024 * 1024 * 1024 * 1024 * 1024 

[Qemu-devel] [PATCH v2] vmdk: fix metadata write regression

2016-07-07 Thread Reda Sallahi
Commit "cdeaf1f vmdk: add bdrv_co_write_zeroes" causes a regression on
writes. It writes metadata after every write instead of doing it only once
for each cluster.

vmdk_pwritev() writes metadata whenever m_data is set as valid so this patch
sets m_data as valid only when we have a new cluster which hasn't been
allocated before or a zero grain.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
v2: Corrected the commit id referenced in the commit message.

 block/vmdk.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index d73f431..1cbd487 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1202,13 +1202,6 @@ static int get_cluster_offset(BlockDriverState *bs,
 l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size;
 cluster_sector = le32_to_cpu(l2_table[l2_index]);
 
-if (m_data) {
-m_data->valid = 1;
-m_data->l1_index = l1_index;
-m_data->l2_index = l2_index;
-m_data->l2_offset = l2_offset;
-m_data->l2_cache_entry = _table[l2_index];
-}
 if (extent->has_zero_grain && cluster_sector == VMDK_GTE_ZEROED) {
 zeroed = true;
 }
@@ -1231,6 +1224,13 @@ static int get_cluster_offset(BlockDriverState *bs,
 if (ret) {
 return ret;
 }
+if (m_data) {
+m_data->valid = 1;
+m_data->l1_index = l1_index;
+m_data->l2_index = l2_index;
+m_data->l2_offset = l2_offset;
+m_data->l2_cache_entry = _table[l2_index];
+}
 }
 *cluster_offset = cluster_sector << BDRV_SECTOR_BITS;
 return VMDK_OK;
-- 
2.9.0




[Qemu-devel] [PATCH] vmdk: fix metadata write regression

2016-07-07 Thread Reda Sallahi
Commit "cde6361 vmdk: add bdrv_co_write_zeroes" causes a regression on
writes. It writes metadata after every write instead of doing it only once
for each cluster.

vmdk_pwritev() writes metadata whenever m_data is set as valid so this patch
sets m_data as valid only when we have a new cluster which hasn't been
allocated before or a zero grain.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
 block/vmdk.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index d73f431..1cbd487 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1202,13 +1202,6 @@ static int get_cluster_offset(BlockDriverState *bs,
 l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size;
 cluster_sector = le32_to_cpu(l2_table[l2_index]);
 
-if (m_data) {
-m_data->valid = 1;
-m_data->l1_index = l1_index;
-m_data->l2_index = l2_index;
-m_data->l2_offset = l2_offset;
-m_data->l2_cache_entry = _table[l2_index];
-}
 if (extent->has_zero_grain && cluster_sector == VMDK_GTE_ZEROED) {
 zeroed = true;
 }
@@ -1231,6 +1224,13 @@ static int get_cluster_offset(BlockDriverState *bs,
 if (ret) {
 return ret;
 }
+if (m_data) {
+m_data->valid = 1;
+m_data->l1_index = l1_index;
+m_data->l2_index = l2_index;
+m_data->l2_offset = l2_offset;
+m_data->l2_cache_entry = _table[l2_index];
+}
 }
 *cluster_offset = cluster_sector << BDRV_SECTOR_BITS;
 return VMDK_OK;
-- 
2.9.0




[Qemu-devel] [PATCH RFC 1/1] qemu-img: add the 'dd' subcommand

2016-06-22 Thread Reda Sallahi
This patch adds a basic dd subcommand analogous to dd(1) to qemu-img.

For the start, this implements the bs, if, of and count options and requires
both if and of to be specified (no stdin/stdout if not specified) and doesn't
support tty, pipes, etc.

The image format must be specified with -O for the output if the raw format
is not the intended one.

get_size() and get_offset() were needed for the size syntax dd(1) supports
which is different from qemu_strtosz_suffix.

Signed-off-by: Reda Sallahi <fullma...@gmail.com>
---
 qemu-img-cmds.hx |   6 +
 qemu-img.c   | 833 ++-
 2 files changed, 838 insertions(+), 1 deletion(-)

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 7e95b2d..68f81b0 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -45,6 +45,12 @@ STEXI
 @item convert [--object @var{objectdef}] [--image-opts] [-c] [-p] [-q] [-n] 
[-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-o 
@var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S 
@var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
 
+DEF("dd", img_dd,
+"dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] 
[ibs=in_block_size] [count=blocks] if=input of=output")
+STEXI
+@item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] 
[bs=@var{block_size}] [ibs=@var{in_block_size}] [count=@var{blocks}] 
if=@var{input} of=@var{output}
+ETEXI
+
 DEF("info", img_info,
 "info [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] 
[--backing-chain] filename")
 STEXI
diff --git a/qemu-img.c b/qemu-img.c
index 14e2661..dace76b 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -159,7 +159,25 @@ static void QEMU_NORETURN help(void)
"Parameters to compare subcommand:\n"
"  '-f' first image format\n"
"  '-F' second image format\n"
-   "  '-s' run in Strict mode - fail on different image size or sector 
allocation\n";
+   "  '-s' run in Strict mode - fail on different image size or sector 
allocation\n"
+   "\n"
+   "Parameters to dd subcommand:\n"
+   "  'bs=BYTES' read and write up to BYTES bytes at a time\n"
+/* "  'cbs=BYTES' convert BYTES bytes at a time\n"
+   "  'conv=CONVS' convert the file as per the comma separated "
+   "symbol list\n" */
+   "  'count=N' copy only N input blocks\n"
+   "  'ibs=BYTES' read up to BYTES bytes at a time (default: 512)\n"
+   "  'if=FILE' read from FILE instead of stdin\n"
+   "  'obs=BYTES' write BYTES bytes at a time (default: 512)\n"
+   "  'of=FILE' write to FILE instead of stdout\n";
+/* "  'seek=N' skip N obs-sized blocks at start of output\n"
+   "  'skip=N' skip N ibs-sized blocks at start of input\n"
+   "  'status=LEVEL' The LEVEL of information to print to stderr; "
+   "'none' suppresses everything but error messages, 'noxfer' "
+   "suppresses the final transfer statistics, 'progress' shows "
+   "periodic transfer statistics\n" */
+
 
 printf("%s\nSupported formats:", help_msg);
 bdrv_iterate_format(format_print, NULL);
@@ -3788,6 +3806,819 @@ out:
 return 0;
 }
 
+#define C_BS  01
+#define C_CBS 02
+#define C_CONV04
+#define C_COUNT   010
+#define C_IBS 020
+#define C_IF  040
+#define C_IFLAG   0100
+#define C_OBS 0200
+#define C_OF  0400
+#define C_OFLAG   01000
+#define C_SEEK02000
+#define C_SKIP04000
+#define C_STATUS  01
+
+struct DdEss {
+unsigned int flags;
+unsigned int status;
+unsigned int conv;
+size_t count;
+size_t cbsz; /* Conversion block size */
+};
+
+struct DdIo {
+size_t bsz;/* Block size */
+off_t offset;
+const char *filename;
+unsigned int flags;
+uint8_t *buf;
+};
+
+struct DdOpts {
+const char *name;
+int (*f)(const char *, struct DdIo *, struct DdIo *, struct DdEss *);
+unsigned int flag;
+};
+
+static size_t get_size(const char *str)
+{
+/* XXX: handle {k,m,g}B notations */
+unsigned long num;
+size_t res = 0;
+const char *buf;
+
+errno = 0;
+qemu_strtoul(str, , 0, );
+
+if (num == ULONG_MAX && errno == ERANGE) {
+error_report("invalid number: %s", str);
+return res;
+}
+
+switch (*buf) {
+case '\0':
+case 'c':
+res = num;
+break;
+case 'w':
+res = num * 2;
+break;
+case 'b':
+res = num * 512;
+break;
+case 'K':
+res = num * 1024;
+break;
+case 'M':
+res = num * 1024 * 1024;
+brea

[Qemu-devel] [PATCH RFC 0/1] Subcommand dd for qemu-img

2016-06-22 Thread Reda Sallahi
Hi,

I have a first patch that adds a minimal subcommand dd for qemu-img that
is similar to dd(1) so this is a work-in-progress.

So far it implements the bs and count options with of course the if and of
options (e.g. ./qemu-img dd if=foo.raw of=foo.qcow2 bs=128K count=10 -O qcow2).

There is no output with statistics for now so this acts like dd status=none.


Reda Sallahi (1):
  qemu-img: add the 'dd' subcommand

 qemu-img-cmds.hx |   6 +
 qemu-img.c   | 833 ++-
 2 files changed, 838 insertions(+), 1 deletion(-)

-- 
2.9.0




[Qemu-devel] [GSoC 2016] Introduction

2016-05-23 Thread Reda Sallahi
Hello everybody,

I have been selected for this year's Google Summer of Code to
contribute to QEMU. My task will be to implement the subcommand dd for
qemu-img and to use afl-fuzz to discover security bugs on qemu-img and
fix them.

I want to thank Fam and Stefanha for taking their time to be my
mentors during this period!

It will be an exciting summer and hopefully it will only be the
beginning of my involvement on QEMU.

-- 
Reda