All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/7] qemu-img dd
@ 2016-08-26  9:16 Reda Sallahi
  2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 1/7] qemu-img: add seek option to dd Reda Sallahi
                   ` (6 more replies)
  0 siblings, 7 replies; 12+ messages in thread
From: Reda Sallahi @ 2016-08-26  9:16 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 v5] qemu-img: change opening method for the output in dd

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

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

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

-- 
2.9.3

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

* [Qemu-devel] [PATCH v2 1/7] qemu-img: add seek option to dd
  2016-08-26  9:16 [Qemu-devel] [PATCH v2 0/7] qemu-img dd Reda Sallahi
@ 2016-08-26  9:16 ` Reda Sallahi
  2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 2/7] qemu-img: add iflag and oflag options " Reda Sallahi
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Reda Sallahi @ 2016-08-26  9:16 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>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 qemu-img-cmds.hx           |  4 +--
 qemu-img.c                 | 45 +++++++++++++++++++++++-----
 qemu-img.texi              |  4 ++-
 tests/qemu-iotests/161     | 73 ++++++++++++++++++++++++++++++++++++++++++++++
 tests/qemu-iotests/161.out | 51 ++++++++++++++++++++++++++++++++
 tests/qemu-iotests/group   |  1 +
 6 files changed, 167 insertions(+), 11 deletions(-)
 create mode 100755 tests/qemu-iotests/161
 create mode 100644 tests/qemu-iotests/161.out

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

* [Qemu-devel] [PATCH v2 2/7] qemu-img: add iflag and oflag options to dd
  2016-08-26  9:16 [Qemu-devel] [PATCH v2 0/7] qemu-img dd Reda Sallahi
  2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 1/7] qemu-img: add seek option to dd Reda Sallahi
@ 2016-08-26  9:16 ` Reda Sallahi
  2016-09-13 15:48   ` Stefan Hajnoczi
  2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 3/7] qemu-img: add more conv= conversions " Reda Sallahi
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: Reda Sallahi @ 2016-08-26  9:16 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                 | 172 +++++++++++++++++++++++++++++++++++++++------
 qemu-img.texi              |  32 +++++++--
 tests/qemu-iotests/163     | 103 +++++++++++++++++++++++++++
 tests/qemu-iotests/163.out | 135 +++++++++++++++++++++++++++++++++++
 tests/qemu-iotests/164     | 100 ++++++++++++++++++++++++++
 tests/qemu-iotests/164.out |  75 ++++++++++++++++++++
 tests/qemu-iotests/group   |   2 +
 8 files changed, 595 insertions(+), 28 deletions(-)
 create mode 100755 tests/qemu-iotests/163
 create mode 100644 tests/qemu-iotests/163.out
 create mode 100755 tests/qemu-iotests/164
 create mode 100644 tests/qemu-iotests/164.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index e79a577..25eaf71 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -46,9 +46,9 @@ STEXI
 ETEXI
 
 DEF("dd", img_dd,
-    "dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] [skip=blocks] [seek=blocks] [conv=notrunc] if=input of=output")
+    "dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] [skip=blocks] [seek=blocks] [conv=notrunc] [iflag=flags] [oflag=flags] if=input of=output")
 STEXI
-    @item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] [bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] [seek=@var{blocks}] [conv=notrunc] if=@var{input} of=@var{output}
+    @item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] [bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] [seek=@var{blocks}] [conv=notrunc] [iflag=@var{flags}] [oflag=@var{flags}] if=@var{input} of=@var{output}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 7d313fd..7b2c525 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -176,7 +176,16 @@ static void QEMU_NORETURN help(void)
            "  'of=FILE' write to FILE\n"
            "  'skip=N' skip N bs-sized blocks at the start of input\n"
            "  'seek=N' seek N bs-sized blocks at the start of output\n"
-           "  'conv=notrunc' do not truncate the output file\n";
+           "  'conv=notrunc' do not truncate the output file\n"
+           "  'iflags=FLAGS' read using the comma-separated flags list\n"
+           "  'oflags=FLAGS' read using the comma-separated flags list\n\n"
+           "List of FLAGS for dd:\n"
+           "  'direct'      use direct I/O for data\n"
+           "  'dsync'       use synchronized I/O for data\n"
+           "  'sync'        use synchronized I/O for data\n"
+           "  'count_bytes' use 'count=N' as a byte count (iflag only)\n"
+           "  'skip_bytes'  use 'skip=N' as a byte count (iflag only)\n"
+           "  'seek_bytes'  use 'seek=N' as a byte count (oflag only)\n";
 
     printf("%s\nSupported formats:", help_msg);
     bdrv_iterate_format(format_print, NULL);
@@ -3811,6 +3820,8 @@ out:
 #define C_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,73 @@ static int img_dd_conv(const char *arg,
     }
 }
 
+#define C_DIRECT      01
+#define C_IOFLAG_SYNC 02
+#define C_DSYNC       04
+#define C_COUNT_BYTES 010
+#define C_SKIP_BYTES  020
+#define C_SEEK_BYTES  040
+
+static int img_dd_flag(const char *arg, struct DdIo *io,
+                       const struct DdSymbols *flags, const char *err_str)
+{
+    int ret = 0;
+    const char *tok;
+    char *str, *tmp;
+
+    tmp = str = g_strdup(arg);
+
+    while (tmp != NULL && !ret) {
+        tok = qemu_strsep(&tmp, ",");
+        int j;
+        for (j = 0; flags[j].name != NULL; j++) {
+            if (!strcmp(tok, flags[j].name)) {
+                io->flags |= flags[j].value;
+                break;
+            }
+        }
+        if (flags[j].name == NULL) {
+            error_report("%s: '%s'", err_str, tok);
+            ret = 1;
+        }
+    }
+
+    g_free(str);
+
+    return ret;
+}
+
+static int img_dd_iflag(const char *arg,
+                        struct DdIo *in, struct DdIo *out,
+                        struct DdInfo *dd)
+{
+    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}
+    };
+
+    return img_dd_flag(arg, in, flags, "invalid input flag");
+}
+
+static int img_dd_oflag(const char *arg,
+                        struct DdIo *in, struct DdIo *out,
+                        struct DdInfo *dd)
+{
+    const struct DdSymbols flags[] = {
+        { "direct", C_DIRECT },
+        { "dsync", C_DSYNC },
+        { "sync", C_IOFLAG_SYNC },
+        { "seek_bytes", C_SEEK_BYTES },
+        { NULL, 0 }
+    };
+
+    return img_dd_flag(arg, out, flags, "invalid output flag");
+}
+
 static int img_dd(int argc, char **argv)
 {
     int ret = 0;
@@ -3947,6 +4031,9 @@ static int img_dd(int argc, char **argv)
     const char *out_filename;
     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 +4043,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 +4062,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 +4129,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 +4147,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;
     }
 
     out_filename = out.filename;
@@ -4083,6 +4200,15 @@ static int img_dd(int argc, char **argv)
         out_filename = qemu_opt_get(qopts, "filename");
     }
 
+    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;
+    }
+
     ret = access(out_filename, F_OK); /* Check if file exists */
 
     if (ret == -1) {
@@ -4127,8 +4253,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;
@@ -4136,8 +4264,8 @@ static int img_dd(int argc, char **argv)
     } else {
         int64_t blk2sz = 0;
 
-        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;
@@ -4159,29 +4287,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..994b124
--- /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] 12+ messages in thread

* [Qemu-devel] [PATCH v2 3/7] qemu-img: add more conv= conversions to dd
  2016-08-26  9:16 [Qemu-devel] [PATCH v2 0/7] qemu-img dd Reda Sallahi
  2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 1/7] qemu-img: add seek option to dd Reda Sallahi
  2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 2/7] qemu-img: add iflag and oflag options " Reda Sallahi
@ 2016-08-26  9:16 ` Reda Sallahi
  2016-09-13 16:06   ` Stefan Hajnoczi
  2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 4/7] qemu-img: delete not used variable and an unecessary check Reda Sallahi
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: Reda Sallahi @ 2016-08-26  9:16 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                 | 129 +++++++++++++++++++++++++++++++++++----------
 qemu-img.texi              |  26 +++++++--
 tests/qemu-iotests/165     | 109 ++++++++++++++++++++++++++++++++++++++
 tests/qemu-iotests/165.out |  33 ++++++++++++
 tests/qemu-iotests/166     |  73 +++++++++++++++++++++++++
 tests/qemu-iotests/166.out |  19 +++++++
 tests/qemu-iotests/group   |   2 +
 8 files changed, 363 insertions(+), 32 deletions(-)
 create mode 100755 tests/qemu-iotests/165
 create mode 100644 tests/qemu-iotests/165.out
 create mode 100755 tests/qemu-iotests/166
 create mode 100644 tests/qemu-iotests/166.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 25eaf71..933ce3c 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -46,9 +46,9 @@ STEXI
 ETEXI
 
 DEF("dd", img_dd,
-    "dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] [skip=blocks] [seek=blocks] [conv=notrunc] [iflag=flags] [oflag=flags] if=input of=output")
+    "dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] [skip=blocks] [seek=blocks] [conv=convs] [iflag=flags] [oflag=flags] if=input of=output")
 STEXI
-    @item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] [bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] [seek=@var{blocks}] [conv=notrunc] [iflag=@var{flags}] [oflag=@var{flags}] if=@var{input} of=@var{output}
+    @item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] [bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] [seek=@var{blocks}] [conv=@var{convs}] [iflag=@var{flags}] [oflag=@var{flags}] if=@var{input} of=@var{output}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 7b2c525..a4d0556 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -176,9 +176,19 @@ static void QEMU_NORETURN help(void)
            "  'of=FILE' write to FILE\n"
            "  'skip=N' skip N bs-sized blocks at the start of input\n"
            "  'seek=N' seek N bs-sized blocks at the start of output\n"
-           "  'conv=notrunc' do not truncate the output file\n"
+           "  'conv=CONVS' do not truncate the output file\n"
            "  'iflags=FLAGS' read using the comma-separated flags list\n"
            "  'oflags=FLAGS' read using the comma-separated flags list\n\n"
+           "List of CONVS for dd:\n"
+           "  'notrunc'   do not truncate the output file\n"
+           "  'noerror'   continue in the event of read errors\n"
+           "  'excl'      fail if output already exists\n"
+           "  'nocreat'   do not create the output file\n"
+           "  'fsync'     physically write output file data before finishing\n"
+           "  'fdatasync' physically write output file data before finishing\n"
+           "  'sync'      pad every input block with NULs\n"
+           "  'sparse'    seek rather than write the output for NUL input"
+           " blocks\n\n"
            "List of FLAGS for dd:\n"
            "  'direct'      use direct I/O for data\n"
            "  'dsync'       use synchronized I/O for data\n"
@@ -3932,21 +3942,6 @@ static int img_dd_seek(const char *arg,
     return 0;
 }
 
-#define C_NOTRUNC 01
-
-static int img_dd_conv(const char *arg,
-                       struct DdIo *in, struct DdIo *out,
-                       struct DdInfo *dd)
-{
-    if (!strcmp(arg, "notrunc")) {
-        dd->conv |= C_NOTRUNC;
-        return 0;
-    } else {
-        error_report("invalid conversion: '%s'", arg);
-        return 1;
-    }
-}
-
 #define C_DIRECT      01
 #define C_IOFLAG_SYNC 02
 #define C_DSYNC       04
@@ -3954,7 +3949,7 @@ static int img_dd_conv(const char *arg,
 #define C_SKIP_BYTES  020
 #define C_SEEK_BYTES  040
 
-static int img_dd_flag(const char *arg, struct DdIo *io,
+static int img_dd_flag(const char *arg, struct DdIo *io, struct DdInfo *dd,
                        const struct DdSymbols *flags, const char *err_str)
 {
     int ret = 0;
@@ -3968,7 +3963,11 @@ static int img_dd_flag(const char *arg, struct DdIo *io,
         int j;
         for (j = 0; flags[j].name != NULL; j++) {
             if (!strcmp(tok, flags[j].name)) {
-                io->flags |= flags[j].value;
+                if (dd) {
+                    dd->conv |= flags[j].value;
+                } else {
+                    io->flags |= flags[j].value;
+                }
                 break;
             }
         }
@@ -3996,7 +3995,7 @@ static int img_dd_iflag(const char *arg,
         { NULL, 0}
     };
 
-    return img_dd_flag(arg, in, flags, "invalid input flag");
+    return img_dd_flag(arg, in, NULL, flags, "invalid input flag");
 }
 
 static int img_dd_oflag(const char *arg,
@@ -4011,9 +4010,46 @@ static int img_dd_oflag(const char *arg,
         { NULL, 0 }
     };
 
-    return img_dd_flag(arg, out, flags, "invalid output flag");
+    return img_dd_flag(arg, out, NULL, flags, "invalid output flag");
+}
+
+#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)
+{
+    int ret;
+    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 }
+    };
+
+    ret = img_dd_flag(arg, NULL, dd, conv, "invalid conversion");
+
+    if (ret == 0 && dd->conv & C_EXCL && dd->conv & C_NOCREAT) {
+        error_report("cannot combine excl and nocreat");
+        ret = 1;
+    }
+
+    return ret;
 }
 
+
 static int img_dd(int argc, char **argv)
 {
     int ret = 0;
@@ -4030,10 +4066,10 @@ static int img_dd(int argc, char **argv)
     const char *fmt = NULL;
     const char *out_filename;
     int64_t size = 0, out_size = 0;
-    int64_t block_count = 0, out_pos, in_pos;
+    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,
@@ -4212,6 +4248,11 @@ static int img_dd(int argc, char **argv)
     ret = access(out_filename, F_OK); /* Check if file exists */
 
     if (ret == -1) {
+        if (dd.conv & C_NOCREAT) {
+            error_report("Failed to open '%s': %s",
+                         out_filename, strerror(errno));
+            goto out;
+        }
         ret = 0; /* Reset */
         drv = bdrv_find_format(out_fmt);
         if (!drv) {
@@ -4219,6 +4260,7 @@ static int img_dd(int argc, char **argv)
             ret = -1;
             goto out;
         }
+        local_err = NULL;
         proto_drv = bdrv_find_protocol(out.filename, true, &local_err);
 
         if (!proto_drv) {
@@ -4264,6 +4306,12 @@ 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;
+        }
+
         blk2 = img_open(image_opts, out.filename, out_fmt, flags,
                         writethrough, false);
         if (!blk2) {
@@ -4311,20 +4359,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) {
@@ -4336,6 +4407,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..8db7f0a
--- /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: Failed to 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] 12+ messages in thread

* [Qemu-devel] [PATCH v2 4/7] qemu-img: delete not used variable and an unecessary check
  2016-08-26  9:16 [Qemu-devel] [PATCH v2 0/7] qemu-img dd Reda Sallahi
                   ` (2 preceding siblings ...)
  2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 3/7] qemu-img: add more conv= conversions " Reda Sallahi
@ 2016-08-26  9:16 ` Reda Sallahi
  2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 5/7] qemu-img: add status option to dd Reda Sallahi
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Reda Sallahi @ 2016-08-26  9:16 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>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 qemu-img.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

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

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

* [Qemu-devel] [PATCH v2 5/7] qemu-img: add status option to dd
  2016-08-26  9:16 [Qemu-devel] [PATCH v2 0/7] qemu-img dd Reda Sallahi
                   ` (3 preceding siblings ...)
  2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 4/7] qemu-img: delete not used variable and an unecessary check Reda Sallahi
@ 2016-08-26  9:16 ` Reda Sallahi
  2016-09-13 16:19   ` Stefan Hajnoczi
  2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 6/7] qemu-img: clean up dd documentation Reda Sallahi
  2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 7/7] qemu-img: add a test suite for the count option Reda Sallahi
  6 siblings, 1 reply; 12+ messages in thread
From: Reda Sallahi @ 2016-08-26  9:16 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                 | 87 ++++++++++++++++++++++++++++++++++++++++++----
 qemu-img.texi              |  9 ++++-
 tests/qemu-iotests/159     |  2 +-
 tests/qemu-iotests/160     |  2 +-
 tests/qemu-iotests/161     |  2 +-
 tests/qemu-iotests/163     |  4 +--
 tests/qemu-iotests/164     |  4 +--
 tests/qemu-iotests/165     | 11 +++---
 tests/qemu-iotests/166     |  2 +-
 tests/qemu-iotests/167     | 77 ++++++++++++++++++++++++++++++++++++++++
 tests/qemu-iotests/167.out | 17 +++++++++
 tests/qemu-iotests/group   |  1 +
 13 files changed, 200 insertions(+), 22 deletions(-)
 create mode 100755 tests/qemu-iotests/167
 create mode 100644 tests/qemu-iotests/167.out

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 933ce3c..6315c64 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -46,9 +46,9 @@ STEXI
 ETEXI
 
 DEF("dd", img_dd,
-    "dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] [skip=blocks] [seek=blocks] [conv=convs] [iflag=flags] [oflag=flags] if=input of=output")
+    "dd [--image-opts] [-f fmt] [-O output_fmt] [bs=block_size] [count=blocks] [skip=blocks] [seek=blocks] [conv=convs] [iflag=flags] [oflag=flags] [status=level] if=input of=output")
 STEXI
-    @item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] [bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] [seek=@var{blocks}] [conv=@var{convs}] [iflag=@var{flags}] [oflag=@var{flags}] if=@var{input} of=@var{output}
+    @item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] [bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] [seek=@var{blocks}] [conv=@var{convs}] [iflag=@var{flags}] [oflag=@var{flags}] [status=@var{level}] if=@var{input} of=@var{output}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index bd3e80d..55977ff 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -178,7 +178,11 @@ static void QEMU_NORETURN help(void)
            "  'seek=N' seek N bs-sized blocks at the start of output\n"
            "  'conv=CONVS' do not truncate the output file\n"
            "  'iflags=FLAGS' read using the comma-separated flags list\n"
-           "  'oflags=FLAGS' read using the comma-separated flags list\n\n"
+           "  'oflags=FLAGS' read using the comma-separated flags list\n"
+           "  'status=LEVEL' the LEVEL of information to print to stderr\n\n"
+           "List of LEVELS for dd:\n"
+           "  'none'   surpresses everything but error messages\n"
+           "  'noxfer' surpresses the final transfer statistics\n\n"
            "List of CONVS for dd:\n"
            "  'notrunc'   do not truncate the output file\n"
            "  'noerror'   continue in the event of read errors\n"
@@ -3832,11 +3836,13 @@ out:
 #define C_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 int status;
 };
 
 struct DdIo {
@@ -4049,6 +4055,30 @@ static int img_dd_conv(const char *arg,
     return ret;
 }
 
+#define C_STATUS_DEFAULT  00
+#define C_STATUS_NONE     01
+#define C_STATUS_NOXFER   02
+
+static int img_dd_status(const char *arg,
+                         struct DdIo *in, struct DdIo *out,
+                         struct DdInfo *dd)
+{
+    const struct DdSymbols dd_status[] = {
+        { "none", C_STATUS_NONE },
+        { "noxfer", C_STATUS_NOXFER },
+        { NULL, 0 }
+    };
+
+    for (int j = 0; dd_status[j].name != NULL; j++) {
+        if (!strcmp(arg, dd_status[j].name)) {
+            dd->status = dd_status[j].value;
+            return 0;
+        }
+    }
+
+    error_report("invalid status level: '%s'", arg);
+    return 1;
+}
 
 static int img_dd(int argc, char **argv)
 {
@@ -4067,13 +4097,16 @@ static int img_dd(int argc, char **argv)
     const char *out_filename;
     int64_t size = 0, out_size = 0;
     int64_t out_pos, in_pos, sparse_count = 0;
+    int64_t in_read = 0, out_wrt = 0; /* Read/write count for status= */
     bool writethrough = false;
     int flags = 0;
     int ibsz = 0, obsz = 0, bsz;
+    struct timeval starttv, endtv;
     struct DdInfo dd = {
         .flags = 0,
         .count = 0,
-        .conv = 0
+        .conv = 0,
+        .status = C_STATUS_DEFAULT
     };
     struct DdIo in = {
         .bsz = 512, /* Block size is by default 512 bytes */
@@ -4100,6 +4133,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[] = {
@@ -4345,16 +4379,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);
+        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) {
+        qemu_gettimeofday(&starttv);
+    }
 
     for (out_pos = out.offset * obsz; in_pos < size;) {
         int in_ret, out_ret;
@@ -4383,10 +4422,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) {
@@ -4404,12 +4445,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;
+
+        qemu_gettimeofday(&endtv);
+        qemu_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 994b124..0e4d61e 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..f158f69
--- /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" \
+          seek=10 skip=4 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 \
+   seek=10 skip=4 2> "$TEST_IMG.out.dd.stat"
+
+echo
+echo "== Compare the images with qemu-img compare =="
+
+$QEMU_IMG compare "$TEST_IMG.out" "$TEST_IMG.out.dd"
+
+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] 12+ messages in thread

* [Qemu-devel] [PATCH v2 6/7] qemu-img: clean up dd documentation
  2016-08-26  9:16 [Qemu-devel] [PATCH v2 0/7] qemu-img dd Reda Sallahi
                   ` (4 preceding siblings ...)
  2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 5/7] qemu-img: add status option to dd Reda Sallahi
@ 2016-08-26  9:16 ` Reda Sallahi
  2016-09-13 16:31   ` Eric Blake
  2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 7/7] qemu-img: add a test suite for the count option Reda Sallahi
  6 siblings, 1 reply; 12+ messages in thread
From: Reda Sallahi @ 2016-08-26  9:16 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>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 qemu-img.c    | 48 +++++++++++++++++++++++++-----------------------
 qemu-img.texi | 48 ++++++++++++++++++++++++------------------------
 2 files changed, 49 insertions(+), 47 deletions(-)

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

* [Qemu-devel] [PATCH v2 7/7] qemu-img: add a test suite for the count option
  2016-08-26  9:16 [Qemu-devel] [PATCH v2 0/7] qemu-img dd Reda Sallahi
                   ` (5 preceding siblings ...)
  2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 6/7] qemu-img: clean up dd documentation Reda Sallahi
@ 2016-08-26  9:16 ` Reda Sallahi
  6 siblings, 0 replies; 12+ messages in thread
From: Reda Sallahi @ 2016-08-26  9:16 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>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/qemu-iotests/168     | 75 ++++++++++++++++++++++++++++++++++++++++++++++
 tests/qemu-iotests/168.out | 51 +++++++++++++++++++++++++++++++
 tests/qemu-iotests/group   |  1 +
 3 files changed, 127 insertions(+)
 create mode 100755 tests/qemu-iotests/168
 create mode 100644 tests/qemu-iotests/168.out

diff --git a/tests/qemu-iotests/168 b/tests/qemu-iotests/168
new file mode 100755
index 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] 12+ messages in thread

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

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

On Fri, Aug 26, 2016 at 11:16:38AM +0200, Reda Sallahi wrote:
> 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                 | 172 +++++++++++++++++++++++++++++++++++++++------
>  qemu-img.texi              |  32 +++++++--
>  tests/qemu-iotests/163     | 103 +++++++++++++++++++++++++++
>  tests/qemu-iotests/163.out | 135 +++++++++++++++++++++++++++++++++++
>  tests/qemu-iotests/164     | 100 ++++++++++++++++++++++++++
>  tests/qemu-iotests/164.out |  75 ++++++++++++++++++++
>  tests/qemu-iotests/group   |   2 +
>  8 files changed, 595 insertions(+), 28 deletions(-)
>  create mode 100755 tests/qemu-iotests/163
>  create mode 100644 tests/qemu-iotests/163.out
>  create mode 100755 tests/qemu-iotests/164
>  create mode 100644 tests/qemu-iotests/164.out

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

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

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

* Re: [Qemu-devel] [PATCH v2 3/7] qemu-img: add more conv= conversions to dd
  2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 3/7] qemu-img: add more conv= conversions " Reda Sallahi
@ 2016-09-13 16:06   ` Stefan Hajnoczi
  0 siblings, 0 replies; 12+ messages in thread
From: Stefan Hajnoczi @ 2016-09-13 16:06 UTC (permalink / raw)
  To: Reda Sallahi; +Cc: qemu-devel, qemu-block, Kevin Wolf, Max Reitz, Fam Zheng

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

On Fri, Aug 26, 2016 at 11:16:39AM +0200, Reda Sallahi wrote:
> @@ -3968,7 +3963,11 @@ static int img_dd_flag(const char *arg, struct DdIo *io,
>          int j;
>          for (j = 0; flags[j].name != NULL; j++) {
>              if (!strcmp(tok, flags[j].name)) {
> -                io->flags |= flags[j].value;
> +                if (dd) {
> +                    dd->conv |= flags[j].value;
> +                } else {
> +                    io->flags |= flags[j].value;
> +                }
>                  break;
>              }
>          }

Does this function need to know about DdIo and DdInfo?  How about:

static int img_dd_flag(const char *arg, unsigned int *flag_bits,
                       const struct DdSymbols *flags, const char *err_str)

Then function can be called with &dd->flags or &io->flags.

If you do this then please squash the change into earlier patches in
this series using git-rebase(1).  That way the function is created with
its final prototype in the earliest patch that needs it and there is no
code churn.

> @@ -4219,6 +4260,7 @@ static int img_dd(int argc, char **argv)
>              ret = -1;
>              goto out;
>          }
> +        local_err = NULL;

Why set local_err to NULL here and not where it's declared?  If it could
possibly be non-NULL then error_free() must be used to avoid a memory
leak.

> +        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;
> +            }
> +        }

Is sparse_count needed at all?

if ((dd.conv & C_SPARSE) && buffer_is_zero(in.buf, bsz)) {
    out_pos += in.bsz;
    continue;
}

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

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

* Re: [Qemu-devel] [PATCH v2 5/7] qemu-img: add status option to dd
  2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 5/7] qemu-img: add status option to dd Reda Sallahi
@ 2016-09-13 16:19   ` Stefan Hajnoczi
  0 siblings, 0 replies; 12+ messages in thread
From: Stefan Hajnoczi @ 2016-09-13 16:19 UTC (permalink / raw)
  To: Reda Sallahi; +Cc: qemu-devel, qemu-block, Kevin Wolf, Max Reitz, Fam Zheng

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

On Fri, Aug 26, 2016 at 11:16:41AM +0200, Reda Sallahi wrote:
> +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;
> +        }
> +    }

Here you can use the existing flags parsing function if you change the
function argument to unsigned int *flags_bits as mentioned in another
reply.  Then you can pass in &dd->status.

> +
> +    error_report("invalid status level: '%s'", arg);
> +    return 1;
> +}
>  
>  static int img_dd(int argc, char **argv)
>  {
> @@ -4067,13 +4097,16 @@ static int img_dd(int argc, char **argv)
>      const char *out_filename;
>      int64_t size = 0, out_size = 0;
>      int64_t out_pos, in_pos, sparse_count = 0;
> +    int64_t in_read = 0, out_wrt = 0; /* Read/write count for status= */
>      bool writethrough = false;
>      int flags = 0;
>      int ibsz = 0, obsz = 0, bsz;
> +    struct timeval starttv, endtv;

Please use qemu_timeval instead of the system timeval type.

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

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

* Re: [Qemu-devel] [PATCH v2 6/7] qemu-img: clean up dd documentation
  2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 6/7] qemu-img: clean up dd documentation Reda Sallahi
@ 2016-09-13 16:31   ` Eric Blake
  0 siblings, 0 replies; 12+ messages in thread
From: Eric Blake @ 2016-09-13 16:31 UTC (permalink / raw)
  To: Reda Sallahi, qemu-devel
  Cc: Kevin Wolf, Fam Zheng, qemu-block, Max Reitz, Stefan Hajnoczi

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

On 08/26/2016 04:16 AM, 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).

s/conjugasion/conjugation/

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


>             "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"

s/surpress/suppress/ (twice)

> +           "  'fsync'        physically write output file data before"
> +           " finishing\n"
> +           "  'fdatasync'    physically write output file data before"
> +           " finishing\n"

What's the difference between these two? (fdatasync only flushes file
data, while fsync flushes ALL file metadata and is thus stronger. But
using the same wording for both lines doesn't make it obvious which one
is stronger, and I shouldn't have to resort to 'man fdatasync' to learn
the difference).


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

Again, mention which version is stronger.

>  @item excl
> -Err if the output file already exists.
> +Errs if the output file already exists.

s/Errs/Raises an error/

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

s/seprated/separated/

>  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

and again

>  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.

Do we have a strong preference for US (-ized) vs. UK (-ised) spelling
elsewhere in this document?

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

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

end of thread, other threads:[~2016-09-13 16:31 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-26  9:16 [Qemu-devel] [PATCH v2 0/7] qemu-img dd Reda Sallahi
2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 1/7] qemu-img: add seek option to dd Reda Sallahi
2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 2/7] qemu-img: add iflag and oflag options " Reda Sallahi
2016-09-13 15:48   ` Stefan Hajnoczi
2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 3/7] qemu-img: add more conv= conversions " Reda Sallahi
2016-09-13 16:06   ` Stefan Hajnoczi
2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 4/7] qemu-img: delete not used variable and an unecessary check Reda Sallahi
2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 5/7] qemu-img: add status option to dd Reda Sallahi
2016-09-13 16:19   ` Stefan Hajnoczi
2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 6/7] qemu-img: clean up dd documentation Reda Sallahi
2016-09-13 16:31   ` Eric Blake
2016-08-26  9:16 ` [Qemu-devel] [PATCH v2 7/7] qemu-img: add a test suite for the count option Reda Sallahi

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.