All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/7] qemu-img dd
@ 2016-08-22  7:55 Reda Sallahi
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 1/7] qemu-img: add seek option to dd Reda Sallahi
                   ` (6 more replies)
  0 siblings, 7 replies; 18+ messages in thread
From: Reda Sallahi @ 2016-08-22  7:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Kevin Wolf, Max Reitz, Fam Zheng, Stefan Hajnoczi,
	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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH 1/7] qemu-img: add seek option to dd
  2016-08-22  7:55 [Qemu-devel] [PATCH 0/7] qemu-img dd Reda Sallahi
@ 2016-08-22  7:55 ` Reda Sallahi
  2016-08-22 13:06   ` Stefan Hajnoczi
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 2/7] qemu-img: add iflag and oflag options " Reda Sallahi
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Reda Sallahi @ 2016-08-22  7:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Kevin Wolf, Max Reitz, Fam Zheng, Stefan Hajnoczi,
	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 <fullmanet@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_SKIP    020
-#define C_CONV    040
+#define C_SEEK    040
+#define C_CONV    0100
 
 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, &end, 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) {
+                blk_truncate(blk2, out.offset * out.bsz);
             }
+        } else if (blk2sz < out_size) {
+            blk_truncate(blk2, out_size);
         }
     }
 
@@ -4151,7 +4180,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 = out.offset * out.bsz; in_pos < size; block_count++) {
         int in_ret, out_ret;
 
         if (in_pos + in.bsz > size) {
diff --git a/qemu-img.texi b/qemu-img.texi
index 002dde2..95f603b 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -154,6 +154,8 @@ 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 seek=@var{blocks}
+sets the number of output blocks to skip
 @item conv=notrunc
 makes dd not truncate output file to zero
 @end table
@@ -329,7 +331,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}] [conv=notrunc] 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}] [seek=@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/161 b/tests/qemu-iotests/161
new file mode 100755
index 0000000..bc99102
--- /dev/null
+++ b/tests/qemu-iotests/161
@@ -0,0 +1,73 @@
+#! /bin/bash
+#
+# qemu-img dd test for the seek 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=fullmanet@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_SEEK_BLOCKS="1 2 30 30K"
+
+for seek in $TEST_SEEK_BLOCKS; do
+    echo
+    echo "== Creating image =="
+
+    size=1M
+    _make_test_img $size
+    _check_test_img
+    $QEMU_IO -c "write -P 0xa 13k 512k" "$TEST_IMG" | _filter_qemu_io
+
+    echo
+    echo "== Converting the image with dd with seek=$seek =="
+
+    $QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" seek="$seek" conv=notrunc \
+        -O "$IMGFMT" 2> /dev/null
+    TEST_IMG="$TEST_IMG.out" _check_test_img
+    dd if="$TEST_IMG" of="$TEST_IMG.out.dd" seek="$seek" conv=notrunc \
+        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/161.out b/tests/qemu-iotests/161.out
new file mode 100644
index 0000000..5dfc748
--- /dev/null
+++ b/tests/qemu-iotests/161.out
@@ -0,0 +1,51 @@
+QA output created by 161
+
+== Creating image ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
+No errors were found on the image.
+wrote 524288/524288 bytes at offset 13312
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with seek=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 524288/524288 bytes at offset 13312
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with seek=2 ==
+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 524288/524288 bytes at offset 13312
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with seek=30 ==
+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 524288/524288 bytes at offset 13312
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with seek=30K ==
+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 503eb27..28833ee 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -160,4 +160,5 @@
 158 rw auto quick
 159 rw auto quick
 160 rw auto quick
+161 rw auto quick
 162 auto quick
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH 2/7] qemu-img: add iflag and oflag options to dd
  2016-08-22  7:55 [Qemu-devel] [PATCH 0/7] qemu-img dd Reda Sallahi
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 1/7] qemu-img: add seek option to dd Reda Sallahi
@ 2016-08-22  7:55 ` Reda Sallahi
  2016-08-22 13:26   ` Stefan Hajnoczi
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 3/7] qemu-img: add more conv= conversions " Reda Sallahi
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Reda Sallahi @ 2016-08-22  7:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Kevin Wolf, Max Reitz, Fam Zheng, Stefan Hajnoczi,
	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 <fullmanet@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_SKIP    020
 #define C_SEEK    040
 #define C_CONV    0100
+#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(&tmp, ",");
+        int j;
+        for (j = 0; flags[j].name != NULL; j++) {
+            if (!strcmp(tok, flags[j].name)) {
+                in->flags |= flags[j].value;
+                break;
+            }
+        }
+        if (flags[j].name == NULL) {
+            error_report("invalid input flag: '%s'", tok);
+            ret = 1;
+        }
+    }
+
+    g_free(str);
+    return ret;
+}
+
+static int img_dd_oflag(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 },
+        { "seek_bytes", C_SEEK_BYTES },
+        { NULL, 0 }
+    };
+
+    tmp = str = g_strdup(arg);
+
+    while (tmp != NULL && !ret) {
+        tok = qemu_strsep(&tmp, ",");
+        int j;
+        for (j = 0; flags[j].name != NULL; j++) {
+            if (!strcmp(tok, flags[j].name)) {
+                out->flags |= flags[j].value;
+                break;
+            }
+        }
+        if (flags[j].name == NULL) {
+            error_report("invalid output flag: '%s'", tok);
+            ret = 1;
+        }
+    }
+
+    g_free(str);
+    return ret;
+}
+
 static int img_dd(int argc, char **argv)
 {
     int ret = 0;
@@ -3947,6 +4044,9 @@ static int img_dd(int argc, char **argv)
     const char *fmt = NULL;
     int64_t size = 0, out_size = 0;
     int64_t block_count = 0, out_pos, in_pos;
+    bool writethrough = false;
+    int flags = 0;
+    int ibsz = 0, obsz = 0;
     struct DdInfo dd = {
         .flags = 0,
         .count = 0,
@@ -3956,13 +4056,15 @@ static int img_dd(int argc, char **argv)
         .bsz = 512, /* Block size is by default 512 bytes */
         .filename = NULL,
         .buf = NULL,
-        .offset = 0
+        .offset = 0,
+        .flags = 0
     };
     struct DdIo out = {
         .bsz = 512,
         .filename = NULL,
         .buf = NULL,
-        .offset = 0
+        .offset = 0,
+        .flags = 0
     };
 
     const struct DdOpts options[] = {
@@ -3973,6 +4075,8 @@ static int img_dd(int argc, char **argv)
         { "skip", img_dd_skip, C_SKIP },
         { "seek", img_dd_seek, C_SEEK },
         { "conv", img_dd_conv, C_CONV },
+        { "iflag", img_dd_iflag, C_IFLAG },
+        { "oflag", img_dd_oflag, C_OFLAG },
         { NULL, NULL, 0 }
     };
     const struct option long_options[] = {
@@ -4038,8 +4142,13 @@ static int img_dd(int argc, char **argv)
         arg = NULL;
     }
 
+    obsz = out.bsz;
+    if (out.flags & C_SEEK_BYTES) {
+        obsz = 1;
+    }
+
     /* Overflow check for seek */
-    if (out.offset > INT64_MAX / out.bsz) {
+    if (out.offset > INT64_MAX / obsz) {
         error_report("seek with the block size specified is too large "
                      "for data type used");
         ret = -1;
@@ -4051,29 +4160,50 @@ static int img_dd(int argc, char **argv)
         ret = -1;
         goto out;
     }
-    blk1 = img_open(image_opts, in.filename, fmt, 0, false, false);
+    /* These flags make sense only for output but we're adding them anyway
+       to have something close to GNU dd(1) */
+    if (in.flags & C_DSYNC || in.flags & C_IOFLAG_SYNC) {
+        writethrough = true;
+    }
+    if (in.flags & C_DIRECT) {
+        flags |= BDRV_O_NOCACHE;
+    }
+
+    blk1 = img_open(image_opts, in.filename, fmt, flags, writethrough, false);
 
     if (!blk1) {
         ret = -1;
         goto out;
     }
+    writethrough = false; /* Reset to the default value */
 
     size = blk_getlength(blk1);
+
     if (size < 0) {
         error_report("Failed to get size for '%s'", in.filename);
         ret = -1;
         goto out;
     }
 
-    if (dd.flags & C_COUNT && dd.count <= INT64_MAX / in.bsz &&
-        dd.count * in.bsz < size) {
-        size = dd.count * in.bsz;
+    ibsz = in.bsz;
+
+    if (in.flags & C_COUNT_BYTES) {
+        ibsz = 1;
+    }
+    if (dd.flags & C_COUNT && dd.count <= INT64_MAX / ibsz &&
+        dd.count * ibsz < size) {
+        size = dd.count * ibsz;
+    }
+
+    ibsz = in.bsz; /* Reset ibsz for the skip option */
+    if (in.flags & C_SKIP_BYTES) {
+        ibsz = 1;
     }
     /* 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 = out.offset * out.bsz;
+    if (in.offset > INT64_MAX / ibsz || size < in.offset * ibsz) {
+        out_size = out.offset * obsz;
     } else {
-        out_size = size - in.offset * in.bsz + out.offset * out.bsz;
+        out_size = size - in.offset * ibsz + out.offset * obsz;
     }
 
     if (image_opts) {
@@ -4089,8 +4219,17 @@ static int img_dd(int argc, char **argv)
         qdict_put(qoptions, "driver", qstring_from_str(out_fmt));
     }
 
+    flags = BDRV_O_RDWR;
+
+    if (out.flags & C_DSYNC || out.flags & C_IOFLAG_SYNC) {
+        writethrough = true;
+    }
+    if (out.flags & C_DIRECT) {
+        flags |= BDRV_O_NOCACHE;
+    }
+
     blk2 = blk_new_open(image_opts ? NULL : out.filename,
-                        NULL, qoptions, BDRV_O_RDWR, NULL);
+                        NULL, qoptions, flags, NULL);
 
     if (!blk2) {
         drv = bdrv_find_format(out_fmt);
@@ -4133,8 +4272,10 @@ static int img_dd(int argc, char **argv)
             ret = -1;
             goto out;
         }
-        blk2 = img_open(image_opts, out.filename, out_fmt, BDRV_O_RDWR,
-                        false, false);
+
+        blk2 = img_open(image_opts, out.filename, out_fmt, flags,
+                        writethrough, false);
+
         if (!blk2) {
             ret = -1;
             goto out;
@@ -4142,6 +4283,8 @@ static int img_dd(int argc, char **argv)
     } else {
         int64_t blk2sz = 0;
 
+        blk_set_enable_write_cache(blk2, !writethrough);
+
         if (!(dd.conv & C_NOTRUNC)) {
             /* We make conv=notrunc mandatory for the moment to avoid
                accidental destruction of the output image. Needs to be
@@ -4158,29 +4301,29 @@ 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.offset * out.bsz) {
-                blk_truncate(blk2, out.offset * out.bsz);
+        if (in.offset > INT64_MAX / ibsz || size < in.offset * ibsz) {
+            if (blk2sz < out.offset * obsz) {
+                blk_truncate(blk2, out.offset * obsz);
             }
         } else if (blk2sz < out_size) {
             blk_truncate(blk2, out_size);
         }
     }
 
-    if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz ||
-                              size < in.offset * in.bsz)) {
+    if (dd.flags & C_SKIP && (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;
     } else {
-        in_pos = in.offset * in.bsz;
+        in_pos = in.offset * ibsz;
     }
 
     in.buf = g_new(uint8_t, in.bsz);
 
-    for (out_pos = out.offset * out.bsz; in_pos < size; block_count++) {
+    for (out_pos = out.offset * obsz; in_pos < size; block_count++) {
         int in_ret, out_ret;
 
         if (in_pos + in.bsz > size) {
diff --git a/qemu-img.texi b/qemu-img.texi
index 95f603b..c663cf4 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -146,18 +146,42 @@ Parameters to dd subcommand:
 @item bs=@var{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. In case 'iflags=count_bytes' is
+specified, 'blocks' is interpreted as a byte count instead of a block count.
 @item if=@var{input}
 sets the input file
 @item of=@var{output}
 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. In case 'iflags=skip_bytes' is
+specified, 'blocks' is interpreted as a byte count instead of a block count.
 @item seek=@var{blocks}
-sets the number of output blocks to skip
+sets the number of output blocks to skip. In case 'oflags=seek_bytes' is
+specified, 'blocks' is interpreted as a byte count instead of a block count.
 @item conv=notrunc
 makes dd not truncate output file to zero
+@item iflag=@var{flags}
+defines the flags used to read the input file. The flag list is seprated using
+commas.
+@item oflag=@var{flags}
+defines the flags used to write the output file. The flag list is seprated
+using commas.
+
+The flag list:
+@item direct
+direct I/O for data.
+@item dsync
+synchronised I/O for data.
+@item sync
+synchronised I/O for data.
+@item count_bytes
+interpret 'count=blocks' as a byte count. Only iflag.
+@item skip_bytes
+interpret 'skip=blocks' as a byte count. Only iflag.
+@item seek_bytes
+interpret 'seek=blocks' as a byte count. Only oflag.
+
 @end table
 
 Command description:
@@ -331,7 +355,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}] [seek=@var{blocks}] [conv=notrunc] 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}] [seek=@var{blocks}] [conv=notrunc] [iflag=@var{flags}] [oflag=@var{flags}] 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/163 b/tests/qemu-iotests/163
new file mode 100755
index 0000000..e236ea4
--- /dev/null
+++ b/tests/qemu-iotests/163
@@ -0,0 +1,103 @@
+#! /bin/bash
+#
+# qemu-img dd test for the iflag 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=fullmanet@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_SKIP_BLOCKS="1 9 37 90K 12M"
+
+for skip in $TEST_SKIP_BLOCKS; do
+    echo
+    echo "== Creating image =="
+
+    size=1M
+    _make_test_img $size
+    _check_test_img
+
+    $QEMU_IO -c "write -P 0xa 142k 512k" "$TEST_IMG" | _filter_qemu_io
+
+    echo
+    echo "== Converting the image with dd with skip=$skip iflag=skip_bytes =="
+
+    $QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" skip="$skip" \
+        iflag=skip_bytes conv=notrunc -O "$IMGFMT" 2> /dev/null
+    TEST_IMG="$TEST_IMG.out" _check_test_img
+    dd if="$TEST_IMG" of="$TEST_IMG.out.dd" skip="$skip" iflag=skip_bytes \
+        conv=notrunc status=none
+
+    echo
+    echo "== Compare the images with qemu-img compare =="
+
+    $QEMU_IMG compare "$TEST_IMG.out.dd" "$TEST_IMG.out"
+done
+
+TEST_COUNT_BLOCKS="2 19 75 24K 12M 143G"
+
+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 342k 512k" "$TEST_IMG" | _filter_qemu_io
+
+    echo
+    echo "== Converting the image with dd with count=$count" \
+	 "iflag=count_bytes =="
+
+    $QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" count="$skip" \
+        iflag=count_bytes conv=notrunc -O "$IMGFMT" 2> /dev/null
+    TEST_IMG="$TEST_IMG.out" _check_test_img
+    dd if="$TEST_IMG" of="$TEST_IMG.out.dd" count="$skip" iflag=count_bytes \
+        conv=notrunc 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/163.out b/tests/qemu-iotests/163.out
new file mode 100644
index 0000000..e1034cd
--- /dev/null
+++ b/tests/qemu-iotests/163.out
@@ -0,0 +1,135 @@
+QA output created by 163
+
+== Creating image ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
+No errors were found on the image.
+wrote 524288/524288 bytes at offset 145408
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with skip=1 iflag=skip_bytes ==
+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 524288/524288 bytes at offset 145408
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with skip=9 iflag=skip_bytes ==
+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 524288/524288 bytes at offset 145408
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with skip=37 iflag=skip_bytes ==
+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 524288/524288 bytes at offset 145408
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with skip=90K iflag=skip_bytes ==
+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 524288/524288 bytes at offset 145408
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with skip=12M iflag=skip_bytes ==
+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 524288/524288 bytes at offset 350208
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with count=2 iflag=count_bytes ==
+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 524288/524288 bytes at offset 350208
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with count=19 iflag=count_bytes ==
+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 524288/524288 bytes at offset 350208
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with count=75 iflag=count_bytes ==
+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 524288/524288 bytes at offset 350208
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with count=24K iflag=count_bytes ==
+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 524288/524288 bytes at offset 350208
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with count=12M iflag=count_bytes ==
+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 524288/524288 bytes at offset 350208
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with count=143G iflag=count_bytes ==
+No errors were found on the image.
+
+== Compare the images with qemu-img compare ==
+Images are identical.
+
+*** done
diff --git a/tests/qemu-iotests/164 b/tests/qemu-iotests/164
new file mode 100755
index 0000000..4cc69c2
--- /dev/null
+++ b/tests/qemu-iotests/164
@@ -0,0 +1,100 @@
+#! /bin/bash
+#
+# qemu-img dd test for the oflag 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=fullmanet@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_SEEK_BLOCKS="1 3 15 10K 20M"
+
+for seek in $TEST_SEEK_BLOCKS; do
+    echo
+    echo "== Creating image =="
+
+    size=1M
+    _make_test_img $size
+    _check_test_img
+
+    $QEMU_IO -c "write -P 0xa 235k 512k" "$TEST_IMG" | _filter_qemu_io
+
+    echo
+    echo "== Converting the image with dd with seek=$seek oflag=seek_bytes =="
+
+    $QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" seek="$seek" \
+        oflag=seek_bytes conv=notrunc -O "$IMGFMT" 2> /dev/null
+    TEST_IMG="$TEST_IMG.out" _check_test_img
+    dd if="$TEST_IMG" of="$TEST_IMG.out.dd" seek="$seek" \
+        oflag=seek_bytes status=none
+
+    echo
+    echo "== Compare the images with qemu-img compare =="
+
+    $QEMU_IMG compare "$TEST_IMG.out.dd" "$TEST_IMG.out"
+done
+
+echo
+echo "== Creating image =="
+
+size=1M
+_make_test_img $size
+_check_test_img
+seek=13K
+
+$QEMU_IO -c "write -P 0xa 235k 512k" "$TEST_IMG" | _filter_qemu_io
+
+echo
+echo "== Converting the image with dd with seek=$seek" \
+     "oflag=seek_bytes,direct =="
+
+$QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" seek="$seek" \
+    oflag=seek_bytes conv=notrunc -O "$IMGFMT" 2> /dev/null
+TEST_IMG="$TEST_IMG.out" _check_test_img
+dd if="$TEST_IMG" of="$TEST_IMG.out.dd" seek="$seek" \
+    oflag=seek_bytes,direct conv=notrunc status=none
+
+echo
+echo "== Compare the images with qemu-img compare =="
+
+$QEMU_IMG compare "$TEST_IMG.out.dd" "$TEST_IMG.out"
+
+
+echo
+echo "*** done"
+rm -f "$seq.full"
+status=0
diff --git a/tests/qemu-iotests/164.out b/tests/qemu-iotests/164.out
new file mode 100644
index 0000000..3951a58
--- /dev/null
+++ b/tests/qemu-iotests/164.out
@@ -0,0 +1,75 @@
+QA output created by 164
+
+== Creating image ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
+No errors were found on the image.
+wrote 524288/524288 bytes at offset 240640
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with seek=1 oflag=seek_bytes ==
+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 524288/524288 bytes at offset 240640
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with seek=3 oflag=seek_bytes ==
+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 524288/524288 bytes at offset 240640
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with seek=15 oflag=seek_bytes ==
+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 524288/524288 bytes at offset 240640
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with seek=10K oflag=seek_bytes ==
+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 524288/524288 bytes at offset 240640
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with seek=20M oflag=seek_bytes ==
+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 524288/524288 bytes at offset 240640
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with seek=13K oflag=seek_bytes,direct ==
+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 28833ee..5ba1372 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -162,3 +162,5 @@
 160 rw auto quick
 161 rw auto quick
 162 auto quick
+163 rw auto quick
+164 rw auto quick
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH 3/7] qemu-img: add more conv= conversions to dd
  2016-08-22  7:55 [Qemu-devel] [PATCH 0/7] qemu-img dd Reda Sallahi
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 1/7] qemu-img: add seek option to dd Reda Sallahi
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 2/7] qemu-img: add iflag and oflag options " Reda Sallahi
@ 2016-08-22  7:55 ` Reda Sallahi
  2016-08-22 13:35   ` Stefan Hajnoczi
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 4/7] qemu-img: delete not used variable and an unecessary check Reda Sallahi
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Reda Sallahi @ 2016-08-22  7:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Kevin Wolf, Max Reitz, Fam Zheng, Stefan Hajnoczi,
	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 <fullmanet@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_SPARSE    0200
 
 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(&tmp, ",");
+        int j;
+        for (j = 0; conv[j].name != NULL; j++) {
+            if (!strcmp(tok, conv[j].name)) {
+                if ((dd->conv | conv[j].value) & C_EXCL &&
+                    (dd->conv | conv[j].value) & C_NOCREAT) {
+                    error_report("cannot combine excl and nocreat");
+                    ret = 1;
+                    break;
+                }
+                dd->conv |= conv[j].value;
+                break;
+            }
+        }
+        if (conv[j].name == NULL) {
+            error_report("invalid conversion: '%s'", tok);
+            ret = 1;
+        }
     }
+
+    g_free(str);
+    return ret;
 }
 
 #define C_DIRECT      01
@@ -4043,10 +4093,10 @@ 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;
+    int64_t block_count = 0, out_pos, in_pos, sparse_count = 0;
     bool writethrough = false;
     int flags = 0;
-    int ibsz = 0, obsz = 0;
+    int ibsz = 0, obsz = 0, bsz;
     struct DdInfo dd = {
         .flags = 0,
         .count = 0,
@@ -4229,15 +4279,21 @@ static int img_dd(int argc, char **argv)
     }
 
     blk2 = blk_new_open(image_opts ? NULL : out.filename,
-                        NULL, qoptions, flags, NULL);
+                        NULL, qoptions, flags, &local_err);
 
     if (!blk2) {
+        if (dd.conv & C_NOCREAT) {
+            error_report_err(local_err);
+            ret = -1;
+            goto out;
+        }
         drv = bdrv_find_format(out_fmt);
         if (!drv) {
             error_report("Unknown file format");
             ret = -1;
             goto out;
         }
+        local_err = NULL;
         proto_drv = bdrv_find_protocol(out.filename, true, &local_err);
 
         if (!proto_drv) {
@@ -4283,6 +4339,13 @@ static int img_dd(int argc, char **argv)
     } else {
         int64_t blk2sz = 0;
 
+        if (dd.conv & C_EXCL) {
+            error_report("failed to open '%s': File exists", out.filename);
+            ret = -1;
+            goto out;
+        }
+
+
         blk_set_enable_write_cache(blk2, !writethrough);
 
         if (!(dd.conv & C_NOTRUNC)) {
@@ -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);
         }
+        in_ret = blk_pread(blk1, in_pos, in.buf, bsz);
+
         if (in_ret < 0) {
             error_report("error while reading from input image file: %s",
                          strerror(-in_ret));
-            ret = -1;
-            goto out;
+            if (!(dd.conv & C_NOERROR)) {
+                ret = -1;
+                goto out;
+            }
+            if (!(dd.conv & C_SYNC)) {
+                in_pos += bsz;
+                continue;
+            }
+            in_ret = bsz;
         }
         in_pos += in_ret;
 
+        if (dd.conv & C_SPARSE) {
+            if (buffer_is_zero(in.buf, bsz)) {
+                sparse_count++;
+                continue;
+            }
+            if (sparse_count > 0) {
+                out_pos += sparse_count * in.bsz;
+                sparse_count = 0;
+            }
+        }
+
         out_ret = blk_pwrite(blk2, out_pos, in.buf, in_ret, 0);
 
         if (out_ret < 0) {
@@ -4350,6 +4436,10 @@ static int img_dd(int argc, char **argv)
         out_pos += out_ret;
     }
 
+    if (dd.conv & C_FDATASYNC || dd.conv & C_FSYNC) {
+        blk_flush(blk2);
+    }
+
 out:
     g_free(arg);
     qemu_opts_del(opts);
diff --git a/qemu-img.texi b/qemu-img.texi
index c663cf4..85c3cd3 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -159,8 +159,28 @@ specified, 'blocks' is interpreted as a byte count instead of a block count.
 @item seek=@var{blocks}
 sets the number of output blocks to skip. In case 'oflags=seek_bytes' is
 specified, 'blocks' is interpreted as a byte count instead of a block count.
-@item conv=notrunc
-makes dd not truncate output file to zero
+@item conv=@var{convs}
+Converts the input according to the conversions specified. The conversion list
+is separated using commas.
+
+The conversion list:
+@item notrunc
+Make dd not truncate output file to zero.
+@item sync
+Fill every input block size with trailing zero bytes.
+@item noerror
+Continue after read failures.
+@item fdatasync
+Synchronize output data just before finishing. This forces a physical write of output data.
+@item fsync
+Synchronize output data just before finishing. This forces a physical write of output data.
+@item excl
+Err if the output file already exists.
+@item nocreat
+Do not create the output file; the output file must already exist.
+@item sparse
+Seek rather than write NUL output blocks.
+
 @item iflag=@var{flags}
 defines the flags used to read the input file. The flag list is seprated using
 commas.
@@ -355,7 +375,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}] [seek=@var{blocks}] [conv=notrunc] [iflag=@var{flags}] [oflag=@var{flags}] 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}] [seek=@var{blocks}] [conv=@var{convs}] [iflag=@var{flags}] [oflag=@var{flags}] 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/165 b/tests/qemu-iotests/165
new file mode 100755
index 0000000..749920d
--- /dev/null
+++ b/tests/qemu-iotests/165
@@ -0,0 +1,109 @@
+#! /bin/bash
+#
+# qemu-img dd test for conv 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=fullmanet@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
+
+echo
+echo "== Creating image =="
+
+size=1M
+_make_test_img $size
+_check_test_img
+
+$QEMU_IO -c "write -P 0xa 215k 212k" "$TEST_IMG" | _filter_qemu_io
+
+echo
+echo "== Converting the image with dd with conv=excl =="
+
+$QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" conv=excl,notrunc -O "$IMGFMT"
+
+TEST_IMG="$TEST_IMG.out" _check_test_img
+
+dd if="$TEST_IMG" of="$TEST_IMG.out.dd" conv=excl status=none
+
+echo
+echo "== Compare the images with qemu-img compare =="
+
+$QEMU_IMG compare "$TEST_IMG.out.dd" "$TEST_IMG.out"
+
+echo
+echo "== Converting the image with dd with conv=excl =="
+
+$QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" conv=excl,notrunc \
+          -O "$IMGFMT" 2>&1 | sed -e "s#$TEST_DIR#TEST_DIR#g" \
+                                  -e "s#$IMGFMT#IMGFMT#g"
+
+echo
+echo "== Creating image =="
+
+_make_test_img $size
+_check_test_img
+
+$QEMU_IO -c "write -P 0xa 481k 329k" "$TEST_IMG" | _filter_qemu_io
+
+echo
+echo "== Converting the image with dd with conv=nocreat =="
+
+$QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" conv=nocreat,notrunc \
+          -O "$IMGFMT"
+
+TEST_IMG="$TEST_IMG.out" _check_test_img
+
+dd if="$TEST_IMG" of="$TEST_IMG.out.dd" conv=nocreat status=none
+
+echo
+echo "== Compare the images with qemu-img compare =="
+
+$QEMU_IMG compare "$TEST_IMG.out.dd" "$TEST_IMG.out"
+
+rm -f "$TEST_IMG.out" "$TEST_IMG.out.dd"
+
+echo
+echo "== Converting the image with dd with conv=nocreat =="
+
+$QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" conv=nocreat,notrunc \
+          -O "$IMGFMT" 2>&1 | sed -e "s#$TEST_DIR#TEST_DIR#g" \
+                                  -e "s#$IMGFMT#IMGFMT#g"
+
+echo
+echo "*** done"
+rm -f "$seq.full"
+status=0
diff --git a/tests/qemu-iotests/165.out b/tests/qemu-iotests/165.out
new file mode 100644
index 0000000..bc08107
--- /dev/null
+++ b/tests/qemu-iotests/165.out
@@ -0,0 +1,33 @@
+QA output created by 165
+
+== Creating image ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
+No errors were found on the image.
+wrote 217088/217088 bytes at offset 220160
+212 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with conv=excl ==
+No errors were found on the image.
+
+== Compare the images with qemu-img compare ==
+Images are identical.
+
+== Converting the image with dd with conv=excl ==
+qemu-img: failed to open 'TEST_DIR/t.IMGFMT.out': File exists
+
+== Creating image ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
+No errors were found on the image.
+wrote 336896/336896 bytes at offset 492544
+329 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with conv=nocreat ==
+No errors were found on the image.
+
+== Compare the images with qemu-img compare ==
+Images are identical.
+
+== Converting the image with dd with conv=nocreat ==
+qemu-img: Could not open 'TEST_DIR/t.IMGFMT.out': No such file or directory
+
+*** done
diff --git a/tests/qemu-iotests/166 b/tests/qemu-iotests/166
new file mode 100755
index 0000000..409ffa8
--- /dev/null
+++ b/tests/qemu-iotests/166
@@ -0,0 +1,73 @@
+#! /bin/bash
+#
+# qemu-img dd test for conv=sparse
+#
+# 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=fullmanet@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.convert"
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+. ./common.rc
+. ./common.filter
+. ./common.pattern
+
+_supported_fmt generic
+_supported_proto file
+_supported_os Linux
+
+echo
+echo "== Creating image =="
+
+size=1M
+_make_test_img $size
+_check_test_img
+
+$QEMU_IO -c "write -P 0 0 256k" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "write -P 0xa 0 4k" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "write -P 0xa 16k 2k" "$TEST_IMG" | _filter_qemu_io
+
+echo
+echo "== Converting the image with dd with conv=sparse =="
+
+$QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" conv=sparse,notrunc \
+          -O "$IMGFMT"
+
+TEST_IMG="$TEST_IMG.out" _check_test_img
+
+$QEMU_IMG convert -S 512 "$TEST_IMG" "$TEST_IMG.out.convert" -O "$IMGFMT"
+
+echo
+echo "== Compare the images with qemu-img compare =="
+
+$QEMU_IMG compare "$TEST_IMG.out.convert" "$TEST_IMG.out"
+
+echo
+echo "*** done"
+rm -f "$seq.full"
+status=0
diff --git a/tests/qemu-iotests/166.out b/tests/qemu-iotests/166.out
new file mode 100644
index 0000000..012f545
--- /dev/null
+++ b/tests/qemu-iotests/166.out
@@ -0,0 +1,19 @@
+QA output created by 166
+
+== Creating image ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
+No errors were found on the image.
+wrote 262144/262144 bytes at offset 0
+256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 2048/2048 bytes at offset 16384
+2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd with conv=sparse ==
+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 5ba1372..9ba23e5 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -164,3 +164,5 @@
 162 auto quick
 163 rw auto quick
 164 rw auto quick
+165 rw auto quick
+166 rw auto quick
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH 4/7] qemu-img: delete not used variable and an unecessary check
  2016-08-22  7:55 [Qemu-devel] [PATCH 0/7] qemu-img dd Reda Sallahi
                   ` (2 preceding siblings ...)
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 3/7] qemu-img: add more conv= conversions " Reda Sallahi
@ 2016-08-22  7:55 ` Reda Sallahi
  2016-08-22 13:36   ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 5/7] qemu-img: add status option to dd Reda Sallahi
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Reda Sallahi @ 2016-08-22  7:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Kevin Wolf, Max Reitz, Fam Zheng, Stefan Hajnoczi,
	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 <fullmanet@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

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH 5/7] qemu-img: add status option to dd
  2016-08-22  7:55 [Qemu-devel] [PATCH 0/7] qemu-img dd Reda Sallahi
                   ` (3 preceding siblings ...)
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 4/7] qemu-img: delete not used variable and an unecessary check Reda Sallahi
@ 2016-08-22  7:55 ` Reda Sallahi
  2016-08-22 13:45   ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
  2016-08-22 13:50   ` [Qemu-devel] " Reda Sallahi
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 6/7] qemu-img: clean up dd documentation Reda Sallahi
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 7/7] qemu-img: add a test suite for the count option Reda Sallahi
  6 siblings, 2 replies; 18+ messages in thread
From: Reda Sallahi @ 2016-08-22  7:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Kevin Wolf, Max Reitz, Fam Zheng, Stefan Hajnoczi,
	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 <fullmanet@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_CONV    0100
 #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 size is by default 512 bytes */
@@ -4127,6 +4161,7 @@ static int img_dd(int argc, char **argv)
         { "conv", img_dd_conv, C_CONV },
         { "iflag", img_dd_iflag, C_IFLAG },
         { "oflag", img_dd_oflag, C_OFLAG },
+        { "status", img_dd_status, C_STATUS },
         { NULL, NULL, 0 }
     };
     const struct option long_options[] = {
@@ -4374,16 +4409,21 @@ static int img_dd(int argc, char **argv)
     }
 
     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;
+        }
     } else {
         in_pos = in.offset * ibsz;
     }
 
     in.buf = g_new(uint8_t, in.bsz);
+    if (dd.status & C_STATUS_DEFAULT) {
+        gettimeofday(&starttv, NULL);
+    }
 
     for (out_pos = out.offset * obsz; in_pos < size;) {
         int in_ret, out_ret;
@@ -4412,10 +4452,12 @@ static int img_dd(int argc, char **argv)
             in_ret = bsz;
         }
         in_pos += in_ret;
+        in_read += in_ret;
 
         if (dd.conv & C_SPARSE) {
             if (buffer_is_zero(in.buf, bsz)) {
                 sparse_count++;
+                out_wrt += bsz;
                 continue;
             }
             if (sparse_count > 0) {
@@ -4433,12 +4475,46 @@ static int img_dd(int argc, char **argv)
             goto out;
         }
         out_pos += out_ret;
+        out_wrt += out_ret;
     }
 
     if (dd.conv & C_FDATASYNC || dd.conv & C_FSYNC) {
         blk_flush(blk2);
     }
 
+    if (dd.status & C_STATUS_NOXFER || dd.status & C_STATUS_DEFAULT) {
+        fprintf(stderr, "%" PRId64 "+%" PRId64 " records in\n",
+                in_read / in.bsz, in_read % in.bsz);
+        fprintf(stderr, "%" PRId64 "+%" PRId64 " records out\n",
+                out_wrt / out.bsz, out_wrt % out.bsz);
+    }
+    if (dd.status & C_STATUS_DEFAULT) {
+        gchar *hsize;
+        double nb_microsec;
+
+        gettimeofday(&endtv, NULL);
+        timersub(&endtv, &starttv, &endtv);
+
+        if (out_wrt >= 1024) {
+            /* human-readable size in IEC format (base 1024) */
+            gchar *iecsize = g_format_size_full(out_wrt,
+                                                G_FORMAT_SIZE_IEC_UNITS);
+            /* Standard base (e.g. KB = 1000 bytes) */
+            hsize = g_format_size(out_wrt);
+            fprintf(stderr, "%" PRId64 " bytes (%s, %s) copied, ", out_wrt,
+                    hsize, iecsize);
+            g_free(hsize);
+            g_free(iecsize);
+        } else {
+            fprintf(stderr, "%" PRId64 " copied, ", out_wrt);
+        }
+        nb_microsec = (double)endtv.tv_sec * 1000000 + endtv.tv_usec;
+        hsize = g_format_size((double)out_wrt * 1000000 / nb_microsec);
+        fprintf(stderr, "%ld.%08ld s, %s/s\n", (long)endtv.tv_sec,
+                (long)endtv.tv_usec, hsize);
+        g_free(hsize);
+    }
+
 out:
     g_free(arg);
     qemu_opts_del(opts);
diff --git a/qemu-img.texi b/qemu-img.texi
index 85c3cd3..c8905c6 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -202,6 +202,13 @@ interpret 'skip=blocks' as a byte count. Only iflag.
 @item seek_bytes
 interpret 'seek=blocks' as a byte count. Only oflag.
 
+@item status=@var{level}
+Define the level of information to print to stderr.
+@item none
+Only error messages are printed.
+@item noxfer
+Do not print the final transfer rate.
+
 @end table
 
 Command description:
@@ -375,7 +382,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}] [seek=@var{blocks}] [conv=@var{convs}] [iflag=@var{flags}] [oflag=@var{flags}] 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}] [seek=@var{blocks}] [conv=@var{convs}] [iflag=@var{flags}] [oflag=@var{flags}] [status=@var{level}] 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/159 b/tests/qemu-iotests/159
index d68a19f..55f5242 100755
--- a/tests/qemu-iotests/159
+++ b/tests/qemu-iotests/159
@@ -56,7 +56,7 @@ for bs in $TEST_SIZES; do
     echo "== Converting the image with dd with a block size of $bs =="
 
     $QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" bs=$bs conv=notrunc \
-        -O "$IMGFMT"
+        -O "$IMGFMT" status=none
     TEST_IMG="$TEST_IMG.out" _check_test_img
 
     echo
diff --git a/tests/qemu-iotests/160 b/tests/qemu-iotests/160
index 53b3c30..d59228c 100755
--- a/tests/qemu-iotests/160
+++ b/tests/qemu-iotests/160
@@ -56,7 +56,7 @@ for skip in $TEST_SKIP_BLOCKS; do
     echo "== Converting the image with dd with skip=$skip =="
 
     $QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" skip="$skip" conv=notrunc  \
-        -O "$IMGFMT" 2> /dev/null
+        -O "$IMGFMT" 2> /dev/null status=none
     TEST_IMG="$TEST_IMG.out" _check_test_img
     dd if="$TEST_IMG" of="$TEST_IMG.out.dd" skip="$skip" conv=notrunc \
         status=none
diff --git a/tests/qemu-iotests/161 b/tests/qemu-iotests/161
index bc99102..27376d3 100755
--- a/tests/qemu-iotests/161
+++ b/tests/qemu-iotests/161
@@ -56,7 +56,7 @@ for seek in $TEST_SEEK_BLOCKS; do
     echo "== Converting the image with dd with seek=$seek =="
 
     $QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" seek="$seek" conv=notrunc \
-        -O "$IMGFMT" 2> /dev/null
+        -O "$IMGFMT" 2> /dev/null status=none
     TEST_IMG="$TEST_IMG.out" _check_test_img
     dd if="$TEST_IMG" of="$TEST_IMG.out.dd" seek="$seek" conv=notrunc \
         status=none
diff --git a/tests/qemu-iotests/163 b/tests/qemu-iotests/163
index e236ea4..00ebcfa 100755
--- a/tests/qemu-iotests/163
+++ b/tests/qemu-iotests/163
@@ -58,7 +58,7 @@ for skip in $TEST_SKIP_BLOCKS; do
     echo "== Converting the image with dd with skip=$skip iflag=skip_bytes =="
 
     $QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" skip="$skip" \
-        iflag=skip_bytes conv=notrunc -O "$IMGFMT" 2> /dev/null
+        iflag=skip_bytes conv=notrunc -O "$IMGFMT" status=none
     TEST_IMG="$TEST_IMG.out" _check_test_img
     dd if="$TEST_IMG" of="$TEST_IMG.out.dd" skip="$skip" iflag=skip_bytes \
         conv=notrunc status=none
@@ -86,7 +86,7 @@ for count in $TEST_COUNT_BLOCKS; do
 	 "iflag=count_bytes =="
 
     $QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" count="$skip" \
-        iflag=count_bytes conv=notrunc -O "$IMGFMT" 2> /dev/null
+        iflag=count_bytes conv=notrunc -O "$IMGFMT" status=none
     TEST_IMG="$TEST_IMG.out" _check_test_img
     dd if="$TEST_IMG" of="$TEST_IMG.out.dd" count="$skip" iflag=count_bytes \
         conv=notrunc status=none
diff --git a/tests/qemu-iotests/164 b/tests/qemu-iotests/164
index 4cc69c2..62ee766 100755
--- a/tests/qemu-iotests/164
+++ b/tests/qemu-iotests/164
@@ -57,7 +57,7 @@ for seek in $TEST_SEEK_BLOCKS; do
     echo "== Converting the image with dd with seek=$seek oflag=seek_bytes =="
 
     $QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" seek="$seek" \
-        oflag=seek_bytes conv=notrunc -O "$IMGFMT" 2> /dev/null
+        oflag=seek_bytes conv=notrunc -O "$IMGFMT" status=none
     TEST_IMG="$TEST_IMG.out" _check_test_img
     dd if="$TEST_IMG" of="$TEST_IMG.out.dd" seek="$seek" \
         oflag=seek_bytes status=none
@@ -83,7 +83,7 @@ echo "== Converting the image with dd with seek=$seek" \
      "oflag=seek_bytes,direct =="
 
 $QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" seek="$seek" \
-    oflag=seek_bytes conv=notrunc -O "$IMGFMT" 2> /dev/null
+    oflag=seek_bytes conv=notrunc -O "$IMGFMT" status=none
 TEST_IMG="$TEST_IMG.out" _check_test_img
 dd if="$TEST_IMG" of="$TEST_IMG.out.dd" seek="$seek" \
     oflag=seek_bytes,direct conv=notrunc status=none
diff --git a/tests/qemu-iotests/165 b/tests/qemu-iotests/165
index 749920d..b077322 100755
--- a/tests/qemu-iotests/165
+++ b/tests/qemu-iotests/165
@@ -53,7 +53,8 @@ $QEMU_IO -c "write -P 0xa 215k 212k" "$TEST_IMG" | _filter_qemu_io
 echo
 echo "== Converting the image with dd with conv=excl =="
 
-$QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" conv=excl,notrunc -O "$IMGFMT"
+$QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" conv=excl,notrunc \
+          -O "$IMGFMT" status=none
 
 TEST_IMG="$TEST_IMG.out" _check_test_img
 
@@ -67,7 +68,7 @@ $QEMU_IMG compare "$TEST_IMG.out.dd" "$TEST_IMG.out"
 echo
 echo "== Converting the image with dd with conv=excl =="
 
-$QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" conv=excl,notrunc \
+$QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" conv=excl,notrunc status=none \
           -O "$IMGFMT" 2>&1 | sed -e "s#$TEST_DIR#TEST_DIR#g" \
                                   -e "s#$IMGFMT#IMGFMT#g"
 
@@ -83,7 +84,7 @@ echo
 echo "== Converting the image with dd with conv=nocreat =="
 
 $QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" conv=nocreat,notrunc \
-          -O "$IMGFMT"
+          -O "$IMGFMT" status=none
 
 TEST_IMG="$TEST_IMG.out" _check_test_img
 
@@ -100,8 +101,8 @@ echo
 echo "== Converting the image with dd with conv=nocreat =="
 
 $QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" conv=nocreat,notrunc \
-          -O "$IMGFMT" 2>&1 | sed -e "s#$TEST_DIR#TEST_DIR#g" \
-                                  -e "s#$IMGFMT#IMGFMT#g"
+          -O "$IMGFMT" 2>&1 status=none | sed -e "s#$TEST_DIR#TEST_DIR#g" \
+                                              -e "s#$IMGFMT#IMGFMT#g"
 
 echo
 echo "*** done"
diff --git a/tests/qemu-iotests/166 b/tests/qemu-iotests/166
index 409ffa8..4e434f2 100755
--- a/tests/qemu-iotests/166
+++ b/tests/qemu-iotests/166
@@ -56,7 +56,7 @@ echo
 echo "== Converting the image with dd with conv=sparse =="
 
 $QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" conv=sparse,notrunc \
-          -O "$IMGFMT"
+          -O "$IMGFMT" status=none
 
 TEST_IMG="$TEST_IMG.out" _check_test_img
 
diff --git a/tests/qemu-iotests/167 b/tests/qemu-iotests/167
new file mode 100755
index 0000000..ccfd441
--- /dev/null
+++ b/tests/qemu-iotests/167
@@ -0,0 +1,77 @@
+#! /bin/bash
+#
+# qemu-img dd test for the status 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=fullmanet@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.stat" "$TEST_IMG.out.dd" \
+          "$TEST_IMG.out.dd.stat"
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+. ./common.rc
+. ./common.filter
+. ./common.pattern
+
+_supported_fmt raw
+_supported_proto file
+_supported_os Linux
+
+echo
+echo "== Creating image =="
+
+size=1M
+_make_test_img $size
+_check_test_img
+
+$QEMU_IO -c "write -P 0xa 149k 512k" "$TEST_IMG" | _filter_qemu_io
+
+echo
+echo "== Converting the image with dd status=noxfer =="
+
+$QEMU_IMG dd if="$TEST_IMG" of="$TEST_IMG.out" conv=notrunc -O "$IMGFMT" \
+	  status=noxfer 2> "$TEST_IMG.out.stat"
+TEST_IMG="$TEST_IMG.out" _check_test_img
+
+dd if="$TEST_IMG" of="$TEST_IMG.out.dd" conv=notrunc status=noxfer \
+   2> "$TEST_IMG.out.dd.stat"
+
+echo
+echo "== Compare the images with qemu-img compare =="
+
+$QEMU_IMG compare "$TEST_IMG" "$TEST_IMG.out"
+
+echo
+echo "== Compare the stat output =="
+
+diff "$TEST_IMG.out.dd.stat" "$TEST_IMG.out.stat"
+
+echo
+echo "*** done"
+rm -f "$seq.full"
+status=0
diff --git a/tests/qemu-iotests/167.out b/tests/qemu-iotests/167.out
new file mode 100644
index 0000000..39aad10
--- /dev/null
+++ b/tests/qemu-iotests/167.out
@@ -0,0 +1,17 @@
+QA output created by 167
+
+== Creating image ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
+No errors were found on the image.
+wrote 524288/524288 bytes at offset 152576
+512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== Converting the image with dd status=noxfer ==
+No errors were found on the image.
+
+== Compare the images with qemu-img compare ==
+Images are identical.
+
+== Compare the stat output ==
+
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 9ba23e5..fbe0ffe 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -166,3 +166,4 @@
 164 rw auto quick
 165 rw auto quick
 166 rw auto quick
+167 rw auto quick
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH 6/7] qemu-img: clean up dd documentation
  2016-08-22  7:55 [Qemu-devel] [PATCH 0/7] qemu-img dd Reda Sallahi
                   ` (4 preceding siblings ...)
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 5/7] qemu-img: add status option to dd Reda Sallahi
@ 2016-08-22  7:55 ` Reda Sallahi
  2016-08-22 13:46   ` Stefan Hajnoczi
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 7/7] qemu-img: add a test suite for the count option Reda Sallahi
  6 siblings, 1 reply; 18+ messages in thread
From: Reda Sallahi @ 2016-08-22  7:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Kevin Wolf, Max Reitz, Fam Zheng, Stefan Hajnoczi,
	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 <fullmanet@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_format(format_print, NULL);
diff --git a/qemu-img.texi b/qemu-img.texi
index c8905c6..a1a17f3 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -144,20 +144,20 @@ 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. In case 'iflags=count_bytes' is
+Sets the number of input blocks to copy. In case 'iflags=count_bytes' is
 specified, 'blocks' is interpreted as a byte count instead of a block count.
 @item if=@var{input}
-sets the input file
+Sets the input file
 @item of=@var{output}
-sets the output file. dd truncates the output file to zero if 'conv=notrunc'
+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. In case 'iflags=skip_bytes' is
+Sets the number of input blocks to skip. In case 'iflags=skip_bytes' is
 specified, 'blocks' is interpreted as a byte count instead of a block count.
 @item seek=@var{blocks}
-sets the number of output blocks to skip. In case 'oflags=seek_bytes' is
+Sets the number of output blocks to skip. In case 'oflags=seek_bytes' is
 specified, 'blocks' is interpreted as a byte count instead of a block count.
 @item conv=@var{convs}
 Converts the input according to the conversions specified. The conversion list
@@ -165,49 +165,49 @@ is separated using commas.
 
 The conversion list:
 @item notrunc
-Make dd not truncate output file to zero.
+Makes dd not truncate output file to zero.
 @item sync
-Fill every input block size with trailing zero bytes.
+Fills every input block size with trailing zero bytes.
 @item noerror
-Continue after read failures.
+Continues after read failures.
 @item fdatasync
-Synchronize output data just before finishing. This forces a physical write of output data.
+Synchronizes output data just before finishing. This forces a physical write of output data.
 @item fsync
-Synchronize output data just before finishing. This forces a physical write of output data.
+Synchronizes output data just before finishing. This forces a physical write of output data.
 @item excl
-Err if the output file already exists.
+Errs if the output file already exists.
 @item nocreat
-Do not create the output file; the output file must already exist.
+Does not create the output file; the output file must already exist.
 @item sparse
-Seek rather than write NUL output blocks.
+Seeks rather than write NUL output blocks.
 
 @item iflag=@var{flags}
-defines the flags used to read the input file. The flag list is seprated using
+Defines the flags used to read the input file. The flag list is seprated using
 commas.
 @item oflag=@var{flags}
-defines the flags used to write the output file. The flag list is seprated
+Defines the flags used to write the output file. The flag list is seprated
 using commas.
 
 The flag list:
 @item direct
-direct I/O for data.
+Direct I/O for data.
 @item dsync
-synchronised I/O for data.
+Synchronised I/O for data.
 @item sync
-synchronised I/O for data.
+Synchronised I/O for data.
 @item count_bytes
-interpret 'count=blocks' as a byte count. Only iflag.
+Interprets 'count=blocks' as a byte count. Only iflag.
 @item skip_bytes
-interpret 'skip=blocks' as a byte count. Only iflag.
+Interprets 'skip=blocks' as a byte count. Only iflag.
 @item seek_bytes
-interpret 'seek=blocks' as a byte count. Only oflag.
+Interprets 'seek=blocks' as a byte count. Only oflag.
 
 @item status=@var{level}
-Define the level of information to print to stderr.
+Defines the level of information to print to stderr.
 @item none
 Only error messages are printed.
 @item noxfer
-Do not print the final transfer rate.
+Does not print the final transfer rate.
 
 @end table
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH 7/7] qemu-img: add a test suite for the count option
  2016-08-22  7:55 [Qemu-devel] [PATCH 0/7] qemu-img dd Reda Sallahi
                   ` (5 preceding siblings ...)
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 6/7] qemu-img: clean up dd documentation Reda Sallahi
@ 2016-08-22  7:55 ` Reda Sallahi
  2016-08-22 13:46   ` Stefan Hajnoczi
  6 siblings, 1 reply; 18+ messages in thread
From: Reda Sallahi @ 2016-08-22  7:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-block, Kevin Wolf, Max Reitz, Fam Zheng, Stefan Hajnoczi,
	Reda Sallahi

The count option for dd lacked a test suite so this adds one with four test
cases.

Signed-off-by: Reda Sallahi <fullmanet@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 0000000..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=fullmanet@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 0000000..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

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH 1/7] qemu-img: add seek option to dd
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 1/7] qemu-img: add seek option to dd Reda Sallahi
@ 2016-08-22 13:06   ` Stefan Hajnoczi
  0 siblings, 0 replies; 18+ messages in thread
From: Stefan Hajnoczi @ 2016-08-22 13:06 UTC (permalink / raw)
  To: Reda Sallahi
  Cc: qemu-devel, Kevin Wolf, Fam Zheng, qemu-block, Max Reitz,
	Stefan Hajnoczi

[-- Attachment #1: Type: text/plain, Size: 852 bytes --]

On Mon, Aug 22, 2016 at 09:55:11AM +0200, Reda Sallahi wrote:
> 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 <fullmanet@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

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH 2/7] qemu-img: add iflag and oflag options to dd
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 2/7] qemu-img: add iflag and oflag options " Reda Sallahi
@ 2016-08-22 13:26   ` Stefan Hajnoczi
  0 siblings, 0 replies; 18+ messages in thread
From: Stefan Hajnoczi @ 2016-08-22 13:26 UTC (permalink / raw)
  To: Reda Sallahi
  Cc: qemu-devel, Kevin Wolf, Fam Zheng, qemu-block, Max Reitz,
	Stefan Hajnoczi

[-- Attachment #1: Type: text/plain, Size: 1790 bytes --]

On Mon, Aug 22, 2016 at 09:55:12AM +0200, Reda Sallahi wrote:
> +static int img_dd_oflag(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 },
> +        { "seek_bytes", C_SEEK_BYTES },
> +        { NULL, 0 }
> +    };
> +
> +    tmp = str = g_strdup(arg);
> +
> +    while (tmp != NULL && !ret) {
> +        tok = qemu_strsep(&tmp, ",");
> +        int j;
> +        for (j = 0; flags[j].name != NULL; j++) {
> +            if (!strcmp(tok, flags[j].name)) {
> +                out->flags |= flags[j].value;
> +                break;
> +            }
> +        }
> +        if (flags[j].name == NULL) {
> +            error_report("invalid output flag: '%s'", tok);
> +            ret = 1;
> +        }
> +    }
> +
> +    g_free(str);
> +    return ret;
> +}

img_dd_iflag()/img_dd_oflag() are duplicated code.  I suggest a single
helper function that parses a DdSymbols array into a DdIo->flags field.
Then you can pass in either the iflag or the oflag DdSymbols arrays.

static int img_dd_oflag(const char *arg,
                        struct DdIo *in, struct DdIo *out,
                        struct DdInfo *dd)
{
    return img_dd_xflag(arg, (DdSymbols[]){
    	{ "direct", C_DIRECT },
	{ "dsync", C_DSYNC },
	...
    }, in);
}

static int img_dd_oflag(const char *arg,
                        struct DdIo *in, struct DdIo *out,
                        struct DdInfo *dd)
{
    return img_dd_xflag(arg, (DdSymbols[]){
    	{ "direct", C_DIRECT },
	{ "dsync", C_DSYNC },
	...
    }, out);
}

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH 3/7] qemu-img: add more conv= conversions to dd
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 3/7] qemu-img: add more conv= conversions " Reda Sallahi
@ 2016-08-22 13:35   ` Stefan Hajnoczi
  2016-08-22 14:02     ` Reda Sallahi
  0 siblings, 1 reply; 18+ messages in thread
From: Stefan Hajnoczi @ 2016-08-22 13:35 UTC (permalink / raw)
  To: Reda Sallahi
  Cc: qemu-devel, Kevin Wolf, Fam Zheng, qemu-block, Max Reitz,
	Stefan Hajnoczi

[-- Attachment #1: Type: text/plain, Size: 2489 bytes --]

On Mon, Aug 22, 2016 at 09:55:13AM +0200, Reda Sallahi wrote:
>  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(&tmp, ",");
> +        int j;
> +        for (j = 0; conv[j].name != NULL; j++) {
> +            if (!strcmp(tok, conv[j].name)) {
> +                if ((dd->conv | conv[j].value) & C_EXCL &&
> +                    (dd->conv | conv[j].value) & C_NOCREAT) {
> +                    error_report("cannot combine excl and nocreat");
> +                    ret = 1;
> +                    break;
> +                }
> +                dd->conv |= conv[j].value;
> +                break;
> +            }
> +        }
> +        if (conv[j].name == NULL) {
> +            error_report("invalid conversion: '%s'", tok);
> +            ret = 1;
> +        }
>      }
> +
> +    g_free(str);
> +    return ret;
>  }

This function is very similar to img_dd_iflag/oflag.  The code
duplication can be avoided if you perform the (dd->conv | conv[j].value)
& C_EXCL && (dd->conv | conv[j].value) & C_NOCREAT later.

> @@ -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?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH 4/7] qemu-img: delete not used variable and an unecessary check
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 4/7] qemu-img: delete not used variable and an unecessary check Reda Sallahi
@ 2016-08-22 13:36   ` Stefan Hajnoczi
  0 siblings, 0 replies; 18+ messages in thread
From: Stefan Hajnoczi @ 2016-08-22 13:36 UTC (permalink / raw)
  To: Reda Sallahi
  Cc: qemu-devel, Kevin Wolf, Fam Zheng, qemu-block, Max Reitz,
	Stefan Hajnoczi

[-- Attachment #1: Type: text/plain, Size: 373 bytes --]

On Mon, Aug 22, 2016 at 09:55:14AM +0200, Reda Sallahi wrote:
> 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 <fullmanet@gmail.com>
> ---
>  qemu-img.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH 5/7] qemu-img: add status option to dd
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 5/7] qemu-img: add status option to dd Reda Sallahi
@ 2016-08-22 13:45   ` Stefan Hajnoczi
  2016-08-22 13:50   ` [Qemu-devel] " Reda Sallahi
  1 sibling, 0 replies; 18+ messages in thread
From: Stefan Hajnoczi @ 2016-08-22 13:45 UTC (permalink / raw)
  To: Reda Sallahi
  Cc: qemu-devel, Kevin Wolf, Fam Zheng, qemu-block, Max Reitz,
	Stefan Hajnoczi

[-- Attachment #1: Type: text/plain, Size: 448 bytes --]

On Mon, Aug 22, 2016 at 09:55:15AM +0200, Reda Sallahi wrote:
>  struct DdInfo {
>      unsigned int flags;
>      int64_t count;
>      unsigned int conv;
> +    unsigned status;

For consistency please use "unsigned int" like you used for the flags
and conv fields above.

>      in.buf = g_new(uint8_t, in.bsz);
> +    if (dd.status & C_STATUS_DEFAULT) {
> +        gettimeofday(&starttv, NULL);

Please use qemu_gettimeofday() for portability.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH 6/7] qemu-img: clean up dd documentation
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 6/7] qemu-img: clean up dd documentation Reda Sallahi
@ 2016-08-22 13:46   ` Stefan Hajnoczi
  0 siblings, 0 replies; 18+ messages in thread
From: Stefan Hajnoczi @ 2016-08-22 13:46 UTC (permalink / raw)
  To: Reda Sallahi
  Cc: qemu-devel, Kevin Wolf, Fam Zheng, qemu-block, Max Reitz,
	Stefan Hajnoczi

[-- Attachment #1: Type: text/plain, Size: 626 bytes --]

On Mon, Aug 22, 2016 at 09:55:16AM +0200, Reda Sallahi wrote:
> 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 <fullmanet@gmail.com>
> ---
>  qemu-img.c    | 48 +++++++++++++++++++++++++-----------------------
>  qemu-img.texi | 48 ++++++++++++++++++++++++------------------------
>  2 files changed, 49 insertions(+), 47 deletions(-)

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH 7/7] qemu-img: add a test suite for the count option
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 7/7] qemu-img: add a test suite for the count option Reda Sallahi
@ 2016-08-22 13:46   ` Stefan Hajnoczi
  0 siblings, 0 replies; 18+ messages in thread
From: Stefan Hajnoczi @ 2016-08-22 13:46 UTC (permalink / raw)
  To: Reda Sallahi
  Cc: qemu-devel, Kevin Wolf, Fam Zheng, qemu-block, Max Reitz,
	Stefan Hajnoczi

[-- Attachment #1: Type: text/plain, Size: 594 bytes --]

On Mon, Aug 22, 2016 at 09:55:17AM +0200, Reda Sallahi wrote:
> The count option for dd lacked a test suite so this adds one with four test
> cases.
> 
> Signed-off-by: Reda Sallahi <fullmanet@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

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH 5/7] qemu-img: add status option to dd
  2016-08-22  7:55 ` [Qemu-devel] [PATCH 5/7] qemu-img: add status option to dd Reda Sallahi
  2016-08-22 13:45   ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
@ 2016-08-22 13:50   ` Reda Sallahi
  1 sibling, 0 replies; 18+ messages in thread
From: Reda Sallahi @ 2016-08-22 13:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-block, Kevin Wolf, Max Reitz, Fam Zheng, Stefan Hajnoczi

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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH 3/7] qemu-img: add more conv= conversions to dd
  2016-08-22 13:35   ` Stefan Hajnoczi
@ 2016-08-22 14:02     ` Reda Sallahi
  2016-08-23 16:03       ` Stefan Hajnoczi
  0 siblings, 1 reply; 18+ messages in thread
From: Reda Sallahi @ 2016-08-22 14:02 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: qemu-devel, Kevin Wolf, Fam Zheng, qemu-block, Max Reitz,
	Stefan Hajnoczi

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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH 3/7] qemu-img: add more conv= conversions to dd
  2016-08-22 14:02     ` Reda Sallahi
@ 2016-08-23 16:03       ` Stefan Hajnoczi
  0 siblings, 0 replies; 18+ messages in thread
From: Stefan Hajnoczi @ 2016-08-23 16:03 UTC (permalink / raw)
  To: Reda Sallahi
  Cc: Stefan Hajnoczi, qemu-devel, Kevin Wolf, Fam Zheng, qemu-block,
	Max Reitz

[-- Attachment #1: Type: text/plain, Size: 1036 bytes --]

On Mon, Aug 22, 2016 at 04:02:30PM +0200, Reda Sallahi wrote:
> 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.

Ah, I see.

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2016-08-23 21:12 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-22  7:55 [Qemu-devel] [PATCH 0/7] qemu-img dd Reda Sallahi
2016-08-22  7:55 ` [Qemu-devel] [PATCH 1/7] qemu-img: add seek option to dd Reda Sallahi
2016-08-22 13:06   ` Stefan Hajnoczi
2016-08-22  7:55 ` [Qemu-devel] [PATCH 2/7] qemu-img: add iflag and oflag options " Reda Sallahi
2016-08-22 13:26   ` Stefan Hajnoczi
2016-08-22  7:55 ` [Qemu-devel] [PATCH 3/7] qemu-img: add more conv= conversions " Reda Sallahi
2016-08-22 13:35   ` Stefan Hajnoczi
2016-08-22 14:02     ` Reda Sallahi
2016-08-23 16:03       ` Stefan Hajnoczi
2016-08-22  7:55 ` [Qemu-devel] [PATCH 4/7] qemu-img: delete not used variable and an unecessary check Reda Sallahi
2016-08-22 13:36   ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
2016-08-22  7:55 ` [Qemu-devel] [PATCH 5/7] qemu-img: add status option to dd Reda Sallahi
2016-08-22 13:45   ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
2016-08-22 13:50   ` [Qemu-devel] " Reda Sallahi
2016-08-22  7:55 ` [Qemu-devel] [PATCH 6/7] qemu-img: clean up dd documentation Reda Sallahi
2016-08-22 13:46   ` Stefan Hajnoczi
2016-08-22  7:55 ` [Qemu-devel] [PATCH 7/7] qemu-img: add a test suite for the count option Reda Sallahi
2016-08-22 13:46   ` Stefan Hajnoczi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.