diff mbox series

[RFC] qobject: Rewrite implementation of QDict for in-order traversal

Message ID 20220705095421.2455041-1-armbru@redhat.com (mailing list archive)
State New, archived
Headers show
Series [RFC] qobject: Rewrite implementation of QDict for in-order traversal | expand

Commit Message

Markus Armbruster July 5, 2022, 9:54 a.m. UTC
QDict is implemented as a simple hash table of fixed size.  Observe:

* Slow for large n.  Not sure this matters.

* A QDict with n entries takes 4120 + n * 32 bytes on my box.  Wastes
  space for small n, which is a common case.

* Order of traversal depends on the hash function and on insertion
  order, because it iterates first over buckets, then collision
  chains.

* Special code ensures qdict_size() takes constant time.

Replace the hash table by a linked list.  Observe:

* Even slower for large n.  Might be bad enough to matter.

* A QDict with n entries takes 32 + n * 24 bytes.

* Traversal is in insertion order.

* qdict_size() is linear in the number of entries.

This is an experiment.  Do not commit to master as is.

The change of traversal order affects expected test output.  I updated
only the tests covered by "make check" so far.  I expect some more to
hide under tests/qemu-iotests/.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 include/qapi/qmp/qdict.h              |  15 +-
 qobject/qdict.c                       | 104 +--
 tests/unit/check-qdict.c              |   2 +-
 tests/unit/check-qobject.c            |   2 +-
 tests/qemu-iotests/043.out            |  22 +-
 tests/qemu-iotests/060.out            |  16 +-
 tests/qemu-iotests/061.out            |  52 +-
 tests/qemu-iotests/071.out            |   4 +-
 tests/qemu-iotests/099.out            |   4 +-
 tests/qemu-iotests/108.out            |  14 +-
 tests/qemu-iotests/117.out            |   2 +-
 tests/qemu-iotests/120.out            |   2 +-
 tests/qemu-iotests/127.out            |  20 +-
 tests/qemu-iotests/140.out            |   4 +-
 tests/qemu-iotests/141.out            |  76 +--
 tests/qemu-iotests/143.out            |   2 +-
 tests/qemu-iotests/156.out            |  20 +-
 tests/qemu-iotests/161.out            |  28 +-
 tests/qemu-iotests/176.out            |  16 +-
 tests/qemu-iotests/184.out            | 170 ++---
 tests/qemu-iotests/186.out            |  82 +--
 tests/qemu-iotests/190.out            |   4 +-
 tests/qemu-iotests/191.out            | 868 +++++++++++++-------------
 tests/qemu-iotests/195.out            |   4 +-
 tests/qemu-iotests/229.out            |  14 +-
 tests/qemu-iotests/244.out            |  12 +-
 tests/qemu-iotests/249.out            |  18 +-
 tests/qemu-iotests/tests/qsd-jobs.out |   8 +-
 28 files changed, 776 insertions(+), 809 deletions(-)

Comments

Markus Armbruster July 6, 2022, 11:35 a.m. UTC | #1
Markus Armbruster <armbru@redhat.com> writes:

> QDict is implemented as a simple hash table of fixed size.  Observe:
>
> * Slow for large n.  Not sure this matters.
>
> * A QDict with n entries takes 4120 + n * 32 bytes on my box.  Wastes
>   space for small n, which is a common case.
>
> * Order of traversal depends on the hash function and on insertion
>   order, because it iterates first over buckets, then collision
>   chains.
>
> * Special code ensures qdict_size() takes constant time.
>
> Replace the hash table by a linked list.  Observe:
>
> * Even slower for large n.  Might be bad enough to matter.
>
> * A QDict with n entries takes 32 + n * 24 bytes.
>
> * Traversal is in insertion order.
>
> * qdict_size() is linear in the number of entries.
>
> This is an experiment.  Do not commit to master as is.

Forgot to mention: see also

        Subject: Re: [PULL 14/15] qdev: Base object creation on QDict rather than QemuOpts
        Message-ID: <87wnctzdl9.fsf@pond.sub.org>
        https://lists.nongnu.org/archive/html/qemu-devel/2022-07/msg00358.html

> The change of traversal order affects expected test output.  I updated
> only the tests covered by "make check" so far.  I expect some more to
> hide under tests/qemu-iotests/.
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  include/qapi/qmp/qdict.h              |  15 +-
>  qobject/qdict.c                       | 104 +--
>  tests/unit/check-qdict.c              |   2 +-
>  tests/unit/check-qobject.c            |   2 +-
>  tests/qemu-iotests/043.out            |  22 +-
>  tests/qemu-iotests/060.out            |  16 +-
>  tests/qemu-iotests/061.out            |  52 +-
>  tests/qemu-iotests/071.out            |   4 +-
>  tests/qemu-iotests/099.out            |   4 +-
>  tests/qemu-iotests/108.out            |  14 +-
>  tests/qemu-iotests/117.out            |   2 +-
>  tests/qemu-iotests/120.out            |   2 +-
>  tests/qemu-iotests/127.out            |  20 +-
>  tests/qemu-iotests/140.out            |   4 +-
>  tests/qemu-iotests/141.out            |  76 +--
>  tests/qemu-iotests/143.out            |   2 +-
>  tests/qemu-iotests/156.out            |  20 +-
>  tests/qemu-iotests/161.out            |  28 +-
>  tests/qemu-iotests/176.out            |  16 +-
>  tests/qemu-iotests/184.out            | 170 ++---
>  tests/qemu-iotests/186.out            |  82 +--
>  tests/qemu-iotests/190.out            |   4 +-
>  tests/qemu-iotests/191.out            | 868 +++++++++++++-------------
>  tests/qemu-iotests/195.out            |   4 +-
>  tests/qemu-iotests/229.out            |  14 +-
>  tests/qemu-iotests/244.out            |  12 +-
>  tests/qemu-iotests/249.out            |  18 +-
>  tests/qemu-iotests/tests/qsd-jobs.out |   8 +-
>  28 files changed, 776 insertions(+), 809 deletions(-)
>
> diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
> index 82e90fc072..cf5c602286 100644
> --- a/include/qapi/qmp/qdict.h
> +++ b/include/qapi/qmp/qdict.h
> @@ -16,8 +16,7 @@
>  #include "qapi/qmp/qobject.h"
>  #include "qemu/queue.h"
>  
> -#define QDICT_BUCKET_MAX 512
> -
> +#if 0
>  typedef struct QDictEntry {
>      char *key;
>      QObject *value;
> @@ -29,6 +28,18 @@ struct QDict {
>      size_t size;
>      QLIST_HEAD(,QDictEntry) table[QDICT_BUCKET_MAX];
>  };
> +#else
> +typedef struct QDictEntry {
> +    char *key;
> +    QObject *value;
> +    QSIMPLEQ_ENTRY(QDictEntry) next;
> +} QDictEntry;
> +
> +struct QDict {
> +    struct QObjectBase_ base;
> +    QSIMPLEQ_HEAD(, QDictEntry) entries;
> +};
> +#endif
>  
>  void qdict_unref(QDict *q);
>  
> diff --git a/qobject/qdict.c b/qobject/qdict.c
> index 8faff230d3..444608cbc4 100644
> --- a/qobject/qdict.c
> +++ b/qobject/qdict.c
> @@ -29,27 +29,11 @@ QDict *qdict_new(void)
>  
>      qdict = g_malloc0(sizeof(*qdict));
>      qobject_init(QOBJECT(qdict), QTYPE_QDICT);
> +    QSIMPLEQ_INIT(&qdict->entries);
>  
>      return qdict;
>  }
>  
> -/**
> - * tdb_hash(): based on the hash algorithm from gdbm, via tdb
> - * (from module-init-tools)
> - */
> -static unsigned int tdb_hash(const char *name)
> -{
> -    unsigned value;    /* Used to compute the hash value.  */
> -    unsigned   i;      /* Used to cycle through random values. */
> -
> -    /* Set the initial value from the key size. */
> -    for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++) {
> -        value = (value + (((const unsigned char *)name)[i] << (i * 5 % 24)));
> -    }
> -
> -    return (1103515243 * value + 12345);
> -}
> -
>  /**
>   * alloc_entry(): allocate a new QDictEntry
>   */
> @@ -88,15 +72,14 @@ const char *qdict_entry_key(const QDictEntry *entry)
>  /**
>   * qdict_find(): List lookup function
>   */
> -static QDictEntry *qdict_find(const QDict *qdict,
> -                              const char *key, unsigned int bucket)
> +static QDictEntry *qdict_find(const QDict *qdict, const char *key)
>  {
>      QDictEntry *entry;
>  
> -    QLIST_FOREACH(entry, &qdict->table[bucket], next)
> -        if (!strcmp(entry->key, key)) {
> +    QSIMPLEQ_FOREACH(entry, &qdict->entries, next) {
> +        if (!strcmp(key, entry->key))
>              return entry;
> -        }
> +    }
>  
>      return NULL;
>  }
> @@ -114,11 +97,8 @@ static QDictEntry *qdict_find(const QDict *qdict,
>   */
>  void qdict_put_obj(QDict *qdict, const char *key, QObject *value)
>  {
> -    unsigned int bucket;
> -    QDictEntry *entry;
> +    QDictEntry *entry = qdict_find(qdict, key);
>  
> -    bucket = tdb_hash(key) % QDICT_BUCKET_MAX;
> -    entry = qdict_find(qdict, key, bucket);
>      if (entry) {
>          /* replace key's value */
>          qobject_unref(entry->value);
> @@ -126,8 +106,7 @@ void qdict_put_obj(QDict *qdict, const char *key, QObject *value)
>      } else {
>          /* allocate a new entry */
>          entry = alloc_entry(key, value);
> -        QLIST_INSERT_HEAD(&qdict->table[bucket], entry, next);
> -        qdict->size++;
> +        QSIMPLEQ_INSERT_TAIL(&qdict->entries, entry, next);
>      }
>  }
>  
> @@ -161,8 +140,8 @@ QObject *qdict_get(const QDict *qdict, const char *key)
>  {
>      QDictEntry *entry;
>  
> -    entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX);
> -    return (entry == NULL ? NULL : entry->value);
> +    entry = qdict_find(qdict, key);
> +    return entry ? entry->value : NULL;
>  }
>  
>  /**
> @@ -172,8 +151,7 @@ QObject *qdict_get(const QDict *qdict, const char *key)
>   */
>  int qdict_haskey(const QDict *qdict, const char *key)
>  {
> -    unsigned int bucket = tdb_hash(key) % QDICT_BUCKET_MAX;
> -    return (qdict_find(qdict, key, bucket) == NULL ? 0 : 1);
> +    return qdict_find(qdict, key) != NULL;
>  }
>  
>  /**
> @@ -181,7 +159,14 @@ int qdict_haskey(const QDict *qdict, const char *key)
>   */
>  size_t qdict_size(const QDict *qdict)
>  {
> -    return qdict->size;
> +    QDictEntry *entry;
> +    size_t sz = 0;
> +
> +    QSIMPLEQ_FOREACH(entry, &qdict->entries, next) {
> +        sz++;
> +    }
> +
> +    return sz;
>  }
>  
>  /**
> @@ -301,25 +286,13 @@ const char *qdict_get_try_str(const QDict *qdict, const char *key)
>      return qstr ? qstring_get_str(qstr) : NULL;
>  }
>  
> -static QDictEntry *qdict_next_entry(const QDict *qdict, int first_bucket)
> -{
> -    int i;
> -
> -    for (i = first_bucket; i < QDICT_BUCKET_MAX; i++) {
> -        if (!QLIST_EMPTY(&qdict->table[i])) {
> -            return QLIST_FIRST(&qdict->table[i]);
> -        }
> -    }
> -
> -    return NULL;
> -}
> -
>  /**
>   * qdict_first(): Return first qdict entry for iteration.
>   */
>  const QDictEntry *qdict_first(const QDict *qdict)
>  {
> -    return qdict_next_entry(qdict, 0);
> +    return QSIMPLEQ_FIRST(&qdict->entries);
> +
>  }
>  
>  /**
> @@ -327,15 +300,7 @@ const QDictEntry *qdict_first(const QDict *qdict)
>   */
>  const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry)
>  {
> -    QDictEntry *ret;
> -
> -    ret = QLIST_NEXT(entry, next);
> -    if (!ret) {
> -        unsigned int bucket = tdb_hash(entry->key) % QDICT_BUCKET_MAX;
> -        ret = qdict_next_entry(qdict, bucket + 1);
> -    }
> -
> -    return ret;
> +    return QSIMPLEQ_NEXT(entry, next);
>  }
>  
>  /**
> @@ -346,14 +311,11 @@ QDict *qdict_clone_shallow(const QDict *src)
>  {
>      QDict *dest;
>      QDictEntry *entry;
> -    int i;
>  
>      dest = qdict_new();
>  
> -    for (i = 0; i < QDICT_BUCKET_MAX; i++) {
> -        QLIST_FOREACH(entry, &src->table[i], next) {
> -            qdict_put_obj(dest, entry->key, qobject_ref(entry->value));
> -        }
> +    QSIMPLEQ_FOREACH(entry, &src->entries, next) {
> +        qdict_put_obj(dest, entry->key, qobject_ref(entry->value));
>      }
>  
>      return dest;
> @@ -380,13 +342,11 @@ static void qentry_destroy(QDictEntry *e)
>   */
>  void qdict_del(QDict *qdict, const char *key)
>  {
> -    QDictEntry *entry;
> +    QDictEntry *entry = qdict_find(qdict, key);
>  
> -    entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX);
>      if (entry) {
> -        QLIST_REMOVE(entry, next);
> +        QSIMPLEQ_REMOVE(&qdict->entries, entry, QDictEntry, next);
>          qentry_destroy(entry);
> -        qdict->size--;
>      }
>  }
>  
> @@ -424,20 +384,16 @@ bool qdict_is_equal(const QObject *x, const QObject *y)
>   */
>  void qdict_destroy_obj(QObject *obj)
>  {
> -    int i;
>      QDict *qdict;
>  
>      assert(obj != NULL);
>      qdict = qobject_to(QDict, obj);
>  
> -    for (i = 0; i < QDICT_BUCKET_MAX; i++) {
> -        QDictEntry *entry = QLIST_FIRST(&qdict->table[i]);
> -        while (entry) {
> -            QDictEntry *tmp = QLIST_NEXT(entry, next);
> -            QLIST_REMOVE(entry, next);
> -            qentry_destroy(entry);
> -            entry = tmp;
> -        }
> +    while (!QSIMPLEQ_EMPTY(&qdict->entries)) {
> +        QDictEntry *entry = QSIMPLEQ_FIRST(&qdict->entries);
> +
> +        QSIMPLEQ_REMOVE_HEAD(&qdict->entries, next);
> +        qentry_destroy(entry);
>      }
>  
>      g_free(qdict);
> diff --git a/tests/unit/check-qdict.c b/tests/unit/check-qdict.c
> index b5efa859b0..d7d3df5efb 100644
> --- a/tests/unit/check-qdict.c
> +++ b/tests/unit/check-qdict.c
> @@ -47,7 +47,7 @@ static void qdict_put_obj_test(void)
>      qdict_put_int(qdict, "", num);
>  
>      g_assert(qdict_size(qdict) == 1);
> -    ent = QLIST_FIRST(&qdict->table[12345 % QDICT_BUCKET_MAX]);
> +    ent = QSIMPLEQ_FIRST(&qdict->entries);
>      qn = qobject_to(QNum, ent->value);
>      g_assert_cmpint(qnum_get_int(qn), ==, num);
>  
> diff --git a/tests/unit/check-qobject.c b/tests/unit/check-qobject.c
> index 022b7c74fe..0416762f80 100644
> --- a/tests/unit/check-qobject.c
> +++ b/tests/unit/check-qobject.c
> @@ -192,10 +192,10 @@ static void qobject_is_equal_dict_test(void)
>      qdict_put_int(dict_0, "baz", 3);
>      qdict_put_null(dict_0, "null");
>  
> -    qdict_put_int(dict_1, "f.o", 1);
>      qdict_put_int(dict_1, "bar", 2);
>      qdict_put_int(dict_1, "baz", 3);
>      qdict_put_null(dict_1, "null");
> +    qdict_put_int(dict_1, "f.o", 1);
>  
>      qdict_put_int(dict_different_key, "F.o", 1);
>      qdict_put_int(dict_different_key, "bar", 2);
> diff --git a/tests/qemu-iotests/043.out b/tests/qemu-iotests/043.out
> index 63ecb21816..d8fcff24e9 100644
> --- a/tests/qemu-iotests/043.out
> +++ b/tests/qemu-iotests/043.out
> @@ -40,29 +40,29 @@ cluster_size: 65536
>  == finite chain of length 3 (json) ==
>  [
>      {
> -        "virtual-size": 134217728,
>          "filename": "TEST_DIR/t.IMGFMT",
> -        "cluster-size": 65536,
>          "format": "IMGFMT",
> -        "full-backing-filename": "TEST_DIR/t.IMGFMT.2.base",
> +        "dirty-flag": false,
> +        "virtual-size": 134217728,
> +        "cluster-size": 65536,
>          "backing-filename": "TEST_DIR/t.IMGFMT.2.base",
> -        "dirty-flag": false
> +        "full-backing-filename": "TEST_DIR/t.IMGFMT.2.base",
>      },
>      {
> -        "virtual-size": 134217728,
>          "filename": "TEST_DIR/t.IMGFMT.2.base",
> -        "cluster-size": 65536,
>          "format": "IMGFMT",
> -        "full-backing-filename": "TEST_DIR/t.IMGFMT.1.base",
> +        "dirty-flag": false,
> +        "virtual-size": 134217728,
> +        "cluster-size": 65536,
>          "backing-filename": "TEST_DIR/t.IMGFMT.1.base",
> -        "dirty-flag": false
> +        "full-backing-filename": "TEST_DIR/t.IMGFMT.1.base",
>      },
>      {
> -        "virtual-size": 134217728,
>          "filename": "TEST_DIR/t.IMGFMT.1.base",
> -        "cluster-size": 65536,
>          "format": "IMGFMT",
> -        "dirty-flag": false
> +        "dirty-flag": false,
> +        "virtual-size": 134217728,
> +        "cluster-size": 65536,
>      }
>  ]
>  *** done
> diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out
> index 329977d9b9..f654a6579c 100644
> --- a/tests/qemu-iotests/060.out
> +++ b/tests/qemu-iotests/060.out
> @@ -17,11 +17,11 @@ virtual size: 64 MiB (67108864 bytes)
>  cluster_size: 65536
>  Format specific information:
>      compat: 1.1
> -    compression type: COMPRESSION_TYPE
> -    lazy refcounts: false
> -    refcount bits: 16
> -    corrupt: true
>      extended l2: false
> +    lazy refcounts: false
> +    corrupt: true
> +    refcount bits: 16
> +    compression type: COMPRESSION_TYPE
>  qemu-io: can't open device TEST_DIR/t.IMGFMT: IMGFMT: Image is corrupt; cannot be opened read/write
>  no file open, try 'help open'
>  read 512/512 bytes at offset 0
> @@ -418,11 +418,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
>  qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with refcount table); further corruption events will be suppressed
>  QMP_VERSION
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_IMAGE_CORRUPTED", "data": {"device": "none0", "msg": "Preventing invalid write on metadata (overlaps with refcount table)", "offset": 65536, "node-name": "drive", "fatal": true, "size": 65536}}
> +{"event": "BLOCK_IMAGE_CORRUPTED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"device": "none0", "node-name": "drive", "msg": "Preventing invalid write on metadata (overlaps with refcount table)", "offset": 65536, "size": 65536, "fatal": true}}
>  write failed: Input/output error
>  {"return": ""}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  
>  === Testing incoming inactive corrupted image ===
>  
> @@ -430,10 +430,10 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
>  QMP_VERSION
>  {"return": {}}
>  qcow2: Image is corrupt: L2 table offset 0x2a2a2a00 unaligned (L1 index: 0); further non-fatal corruption events will be suppressed
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_IMAGE_CORRUPTED", "data": {"device": "", "msg": "L2 table offset 0x2a2a2a00 unaligned (L1 index: 0)", "node-name": "drive", "fatal": false}}
> +{"event": "BLOCK_IMAGE_CORRUPTED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"device": "", "node-name": "drive", "msg": "L2 table offset 0x2a2a2a00 unaligned (L1 index: 0)", "fatal": false}}
>  {"return": ""}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  
>      corrupt: false
>  *** done
> diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
> index 139fc68177..6a05d67378 100644
> --- a/tests/qemu-iotests/061.out
> +++ b/tests/qemu-iotests/061.out
> @@ -497,7 +497,7 @@ wrote 65536/65536 bytes at offset 2147483648
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  wrote 65536/65536 bytes at offset 3221225472
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> -    (0.00/100%)
>     (12.50/100%)
>     (25.00/100%)
>     (37.50/100%)
>     (50.00/100%)
>     (62.50/100%)
>     (75.00/100%)
>     (87.50/100%)
>     (100.00/100%)
>     (100.00/100%)
> +    (0.00/100%)
>     (12.50/100%)
>     (25.00/100%)
>     (37.50/100%)
>     (50.00/100%)
>     (62.50/100%)
>     (75.00/100%)
>     (87.50/100%)
>     (100.00/100%)
>     (100.00/100%)
>  No errors were found on the image.
>  
>  === Testing progress report with snapshot ===
> @@ -512,7 +512,7 @@ wrote 65536/65536 bytes at offset 2147483648
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  wrote 65536/65536 bytes at offset 3221225472
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> -    (0.00/100%)
>     (6.25/100%)
>     (12.50/100%)
>     (18.75/100%)
>     (25.00/100%)
>     (31.25/100%)
>     (37.50/100%)
>     (43.75/100%)
>     (50.00/100%)
>     (56.25/100%)
>     (62.50/100%)
>     (68.75/100%)
>     (75.00/100%)
>     (81.25/100%)
>     (87.50/100%)
>     (93.75/100%)
>     (100.00/100%)
>     (100.00/100%)
> +    (0.00/100%)
>     (6.25/100%)
>     (12.50/100%)
>     (18.75/100%)
>     (25.00/100%)
>     (31.25/100%)
>     (37.50/100%)
>     (43.75/100%)
>     (50.00/100%)
>     (56.25/100%)
>     (62.50/100%)
>     (68.75/100%)
>     (75.00/100%)
>     (81.25/100%)
>     (87.50/100%)
>     (93.75/100%)
>     (100.00/100%)
>     (100.00/100%)
>  No errors were found on the image.
>  
>  === Testing version downgrade with external data file ===
> @@ -525,13 +525,13 @@ virtual size: 64 MiB (67108864 bytes)
>  cluster_size: 65536
>  Format specific information:
>      compat: 1.1
> -    compression type: COMPRESSION_TYPE
> -    lazy refcounts: false
> -    refcount bits: 16
>      data file: TEST_DIR/t.IMGFMT.data
>      data file raw: false
> -    corrupt: false
>      extended l2: false
> +    lazy refcounts: false
> +    corrupt: false
> +    refcount bits: 16
> +    compression type: COMPRESSION_TYPE
>  No errors were found on the image.
>  
>  === Testing version downgrade with extended L2 entries ===
> @@ -552,13 +552,13 @@ virtual size: 64 MiB (67108864 bytes)
>  cluster_size: 65536
>  Format specific information:
>      compat: 1.1
> -    compression type: COMPRESSION_TYPE
> -    lazy refcounts: false
> -    refcount bits: 16
>      data file: foo
>      data file raw: false
> -    corrupt: false
>      extended l2: false
> +    lazy refcounts: false
> +    corrupt: false
> +    refcount bits: 16
> +    compression type: COMPRESSION_TYPE
>  
>  qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'data-file' is required for this image
>  image: TEST_DIR/t.IMGFMT
> @@ -567,12 +567,12 @@ virtual size: 64 MiB (67108864 bytes)
>  cluster_size: 65536
>  Format specific information:
>      compat: 1.1
> -    compression type: COMPRESSION_TYPE
> -    lazy refcounts: false
> -    refcount bits: 16
>      data file raw: false
> -    corrupt: false
>      extended l2: false
> +    lazy refcounts: false
> +    corrupt: false
> +    refcount bits: 16
> +    compression type: COMPRESSION_TYPE
>  
>  === Clearing and setting data-file-raw ===
>  
> @@ -583,13 +583,13 @@ virtual size: 64 MiB (67108864 bytes)
>  cluster_size: 65536
>  Format specific information:
>      compat: 1.1
> -    compression type: COMPRESSION_TYPE
> -    lazy refcounts: false
> -    refcount bits: 16
>      data file: TEST_DIR/t.IMGFMT.data
>      data file raw: true
> -    corrupt: false
>      extended l2: false
> +    lazy refcounts: false
> +    corrupt: false
> +    refcount bits: 16
> +    compression type: COMPRESSION_TYPE
>  No errors were found on the image.
>  image: TEST_DIR/t.IMGFMT
>  file format: IMGFMT
> @@ -597,13 +597,13 @@ virtual size: 64 MiB (67108864 bytes)
>  cluster_size: 65536
>  Format specific information:
>      compat: 1.1
> -    compression type: COMPRESSION_TYPE
> -    lazy refcounts: false
> -    refcount bits: 16
>      data file: TEST_DIR/t.IMGFMT.data
>      data file raw: false
> -    corrupt: false
>      extended l2: false
> +    lazy refcounts: false
> +    corrupt: false
> +    refcount bits: 16
> +    compression type: COMPRESSION_TYPE
>  No errors were found on the image.
>  qemu-img: data-file-raw cannot be set on existing images
>  image: TEST_DIR/t.IMGFMT
> @@ -612,12 +612,12 @@ virtual size: 64 MiB (67108864 bytes)
>  cluster_size: 65536
>  Format specific information:
>      compat: 1.1
> -    compression type: COMPRESSION_TYPE
> -    lazy refcounts: false
> -    refcount bits: 16
>      data file: TEST_DIR/t.IMGFMT.data
>      data file raw: false
> -    corrupt: false
>      extended l2: false
> +    lazy refcounts: false
> +    corrupt: false
> +    refcount bits: 16
> +    compression type: COMPRESSION_TYPE
>  No errors were found on the image.
>  *** done
> diff --git a/tests/qemu-iotests/071.out b/tests/qemu-iotests/071.out
> index bca0c02f5c..ff00da1ad1 100644
> --- a/tests/qemu-iotests/071.out
> +++ b/tests/qemu-iotests/071.out
> @@ -46,7 +46,7 @@ QMP_VERSION
>  read failed: Input/output error
>  {"return": ""}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  
>  
>  === Testing blkverify on existing block device ===
> @@ -85,7 +85,7 @@ wrote 512/512 bytes at offset 0
>  read failed: Input/output error
>  {"return": ""}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  QEMU_PROG: Failed to flush the L2 table cache: Input/output error
>  QEMU_PROG: Failed to flush the refcount block cache: Input/output error
>  
> diff --git a/tests/qemu-iotests/099.out b/tests/qemu-iotests/099.out
> index 8cce627529..5726466bc6 100644
> --- a/tests/qemu-iotests/099.out
> +++ b/tests/qemu-iotests/099.out
> @@ -12,11 +12,11 @@ blkverify:TEST_DIR/t.IMGFMT.compare:TEST_DIR/t.IMGFMT
>  
>  === Testing JSON filename for blkdebug ===
>  
> -json:{"driver": "IMGFMT", "file": {"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "l1_update"}}
> +json:{"driver": "IMGFMT", "file": {"driver": "blkdebug", "inject-error.0.event": "l1_update", "image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}}}
>  
>  === Testing indirectly enforced JSON filename ===
>  
> -json:{"driver": "raw", "file": {"test": {"driver": "IMGFMT", "file": {"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "l1_update"}}, "driver": "blkverify", "raw": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.compare"}}}
> +json:{"driver": "raw", "file": {"driver": "blkverify", "test": {"driver": "IMGFMT", "file": {"driver": "blkdebug", "inject-error.0.event": "l1_update", "image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}}}, "raw": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.compare"}}}
>  
>  === Testing plain filename for blkdebug ===
>  
> diff --git a/tests/qemu-iotests/108.out b/tests/qemu-iotests/108.out
> index b5401d788d..faaabbcdf3 100644
> --- a/tests/qemu-iotests/108.out
> +++ b/tests/qemu-iotests/108.out
> @@ -163,18 +163,18 @@ OK: Reftable is where we expect it
>                 "size": 67108864,
>                 "cluster-size": 512
>             } } }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "create"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "create"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "running"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "create"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "create"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "create"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "waiting"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "pending"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "concluded"}}
>  { "execute": "job-dismiss", "arguments": { "id": "create" } }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "create"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "null"}}
>  {"return": {}}
>  { "execute": "quit" }
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  
>  wrote 65536/65536 bytes at offset 0
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> diff --git a/tests/qemu-iotests/117.out b/tests/qemu-iotests/117.out
> index 735ffd25c6..015c971197 100644
> --- a/tests/qemu-iotests/117.out
> +++ b/tests/qemu-iotests/117.out
> @@ -19,7 +19,7 @@ wrote 65536/65536 bytes at offset 0
>  {"return": ""}
>  { 'execute': 'quit' }
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  No errors were found on the image.
>  read 65536/65536 bytes at offset 0
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> diff --git a/tests/qemu-iotests/120.out b/tests/qemu-iotests/120.out
> index 0744c1f136..d677c72599 100644
> --- a/tests/qemu-iotests/120.out
> +++ b/tests/qemu-iotests/120.out
> @@ -6,7 +6,7 @@ wrote 65536/65536 bytes at offset 0
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  {"return": ""}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  read 65536/65536 bytes at offset 0
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  read 65536/65536 bytes at offset 0
> diff --git a/tests/qemu-iotests/127.out b/tests/qemu-iotests/127.out
> index 1685c4850a..863832d162 100644
> --- a/tests/qemu-iotests/127.out
> +++ b/tests/qemu-iotests/127.out
> @@ -14,20 +14,20 @@ wrote 42/42 bytes at offset 0
>             'mode':   'existing',
>             'sync':   'top'
>         } }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "mirror"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "mirror"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "running"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "mirror"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "mirror", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "ready"}}
> +{"event": "BLOCK_JOB_READY", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "mirror", "len": 65536, "offset": 65536, "speed": 0}}
>  { 'execute': 'block-job-complete',
>         'arguments': { 'device': 'mirror' } }
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "mirror"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "mirror"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "mirror", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "waiting"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "pending"}}
> +{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "mirror", "len": 65536, "offset": 65536, "speed": 0}}
>  { 'execute': 'quit' }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "mirror"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "mirror"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "concluded"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "null"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  *** done
> diff --git a/tests/qemu-iotests/140.out b/tests/qemu-iotests/140.out
> index 312f76d5da..586b64b24e 100644
> --- a/tests/qemu-iotests/140.out
> +++ b/tests/qemu-iotests/140.out
> @@ -15,10 +15,10 @@ read 65536/65536 bytes at offset 0
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  { 'execute': 'eject',
>         'arguments': { 'device': 'drv' }}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "drv"}}
> +{"event": "BLOCK_EXPORT_DELETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "drv"}}
>  qemu-io: can't open device nbd+unix:///drv?socket=SOCK_DIR/nbd: Requested export not available
>  server reported: export 'drv' not present
>  { 'execute': 'quit' }
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  *** done
> diff --git a/tests/qemu-iotests/141.out b/tests/qemu-iotests/141.out
> index 63203d9944..4d8c7b598c 100644
> --- a/tests/qemu-iotests/141.out
> +++ b/tests/qemu-iotests/141.out
> @@ -23,20 +23,20 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/m.
>  'format': 'IMGFMT',
>  'sync': 'none'}}
>  Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT backing_fmt=IMGFMT
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "paused"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
>  {'execute': 'blockdev-del',
>            'arguments': {'node-name': 'drv0'}}
>  {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: node is used as backing hd of 'NODE_NAME'"}}
>  {'execute': 'block-job-cancel',
>            'arguments': {'device': 'job0'}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 0, "speed": 0, "type": "backup"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "aborting"}}
> +{"event": "BLOCK_JOB_CANCELLED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "backup", "device": "job0", "len": 1048576, "offset": 0, "speed": 0}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>  {'execute': 'blockdev-del',
>            'arguments': {'node-name': 'drv0'}}
>  {"return": {}}
> @@ -59,21 +59,21 @@ Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
>  'format': 'IMGFMT',
>  'sync': 'none'}}
>  Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT backing_fmt=IMGFMT
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "ready"}}
> +{"event": "BLOCK_JOB_READY", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "job0", "len": 0, "offset": 0, "speed": 0}}
>  {'execute': 'blockdev-del',
>            'arguments': {'node-name': 'drv0'}}
>  {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: mirror"}}
>  {'execute': 'block-job-cancel',
>            'arguments': {'device': 'job0'}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "waiting"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "pending"}}
> +{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "job0", "len": 0, "offset": 0, "speed": 0}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>  {'execute': 'blockdev-del',
>            'arguments': {'node-name': 'drv0'}}
>  {"return": {}}
> @@ -91,21 +91,21 @@ Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
>  {"return": {}}
>  {'execute': 'block-commit',
>  'arguments': {'job-id': 'job0', 'device': 'drv0'}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "ready"}}
> +{"event": "BLOCK_JOB_READY", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "job0", "len": 0, "offset": 0, "speed": 0}}
>  {'execute': 'blockdev-del',
>            'arguments': {'node-name': 'drv0'}}
>  {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: commit"}}
>  {'execute': 'block-job-cancel',
>            'arguments': {'device': 'job0'}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "waiting"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "pending"}}
> +{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "job0", "len": 0, "offset": 0, "speed": 0}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>  {'execute': 'blockdev-del',
>            'arguments': {'node-name': 'drv0'}}
>  {"return": {}}
> @@ -128,18 +128,18 @@ wrote 1048576/1048576 bytes at offset 0
>  'device': 'drv0',
>  'top':    'TEST_DIR/m.IMGFMT',
>  'speed':  1}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
>  {'execute': 'blockdev-del',
>            'arguments': {'node-name': 'drv0'}}
>  {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: commit"}}
>  {'execute': 'block-job-cancel',
>            'arguments': {'device': 'job0'}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, "type": "commit"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "aborting"}}
> +{"event": "BLOCK_JOB_CANCELLED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "job0", "len": 1048576, "offset": 524288, "speed": 1}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>  {'execute': 'blockdev-del',
>            'arguments': {'node-name': 'drv0'}}
>  {"return": {}}
> @@ -161,18 +161,18 @@ wrote 1048576/1048576 bytes at offset 0
>  'arguments': {'job-id': 'job0',
>  'device': 'drv0',
>  'speed': 1}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
>  {'execute': 'blockdev-del',
>            'arguments': {'node-name': 'drv0'}}
>  {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: stream"}}
>  {'execute': 'block-job-cancel',
>            'arguments': {'device': 'job0'}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, "type": "stream"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "aborting"}}
> +{"event": "BLOCK_JOB_CANCELLED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "stream", "device": "job0", "len": 1048576, "offset": 524288, "speed": 1}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>  {'execute': 'blockdev-del',
>            'arguments': {'node-name': 'drv0'}}
>  {"return": {}}
> diff --git a/tests/qemu-iotests/143.out b/tests/qemu-iotests/143.out
> index 9ec5888e0e..ec58b08e43 100644
> --- a/tests/qemu-iotests/143.out
> +++ b/tests/qemu-iotests/143.out
> @@ -11,5 +11,5 @@ qemu-io: can't open device nbd+unix:///aa--aa1?socket=SOCK_DIR/nbd: Requested ex
>  server reported: export 'aa--aa...' not present
>  { 'execute': 'quit' }
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  *** done
> diff --git a/tests/qemu-iotests/156.out b/tests/qemu-iotests/156.out
> index 4a22f0c41a..bb01818fc7 100644
> --- a/tests/qemu-iotests/156.out
> +++ b/tests/qemu-iotests/156.out
> @@ -26,11 +26,11 @@ Formatting 'TEST_DIR/t.IMGFMT.target.overlay', fmt=IMGFMT size=1048576 backing_f
>                        'target': 'TEST_DIR/t.IMGFMT.target.overlay',
>                        'mode': 'existing',
>                        'sync': 'top' } }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "source"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "source"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "running"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "source"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "source", "len": 131072, "offset": 131072, "speed": 0, "type": "mirror"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "ready"}}
> +{"event": "BLOCK_JOB_READY", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "source", "len": 131072, "offset": 131072, "speed": 0}}
>  { 'execute': 'human-monitor-command',
>         'arguments': { 'command-line':
>                        'qemu-io source "write -P 4 192k 64k"' } }
> @@ -40,11 +40,11 @@ wrote 65536/65536 bytes at offset 196608
>  { 'execute': 'block-job-complete',
>         'arguments': { 'device': 'source' } }
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "source"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "source"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "source", "len": 196608, "offset": 196608, "speed": 0, "type": "mirror"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "source"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "source"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "waiting"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "pending"}}
> +{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "source", "len": 196608, "offset": 196608, "speed": 0}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "concluded"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "null"}}
>  
>  { 'execute': 'human-monitor-command',
>         'arguments': { 'command-line':
> @@ -73,7 +73,7 @@ read 65536/65536 bytes at offset 196608
>  
>  { 'execute': 'quit' }
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  
>  read 65536/65536 bytes at offset 0
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> diff --git a/tests/qemu-iotests/161.out b/tests/qemu-iotests/161.out
> index 6cc285afcf..c62657639a 100644
> --- a/tests/qemu-iotests/161.out
> +++ b/tests/qemu-iotests/161.out
> @@ -18,17 +18,17 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
>  {"return": {}}
>  { 'execute': 'block-stream',        'arguments': { 'device': 'none0',
>                        'base': 'TEST_DIR/t.IMGFMT.base' } }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "none0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "none0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "running"}}
>  {"return": {}}
>  { 'execute': 'human-monitor-command',
>         'arguments': { 'command-line':
>                        'qemu-io none0 "reopen -o backing.detect-zeroes=on"' } }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "none0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "none0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "none0", "len": 1048576, "offset": 1048576, "speed": 0, "type": "stream"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "none0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "none0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "waiting"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "pending"}}
> +{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "stream", "device": "none0", "len": 1048576, "offset": 1048576, "speed": 0}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "concluded"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "null"}}
>  {"return": ""}
>  
>  *** Commit and then change an option on the backing file
> @@ -40,16 +40,16 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
>  {"return": {}}
>  { 'execute': 'block-commit',        'arguments': { 'device': 'none0',
>                        'top': 'TEST_DIR/t.IMGFMT.int' } }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "none0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "none0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "running"}}
>  {"return": {}}
>  { 'execute': 'human-monitor-command',
>         'arguments': { 'command-line':
>                        'qemu-io none0 "reopen -o backing.detect-zeroes=on"' } }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "none0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "none0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "none0", "len": 1048576, "offset": 1048576, "speed": 0, "type": "commit"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "none0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "none0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "waiting"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "pending"}}
> +{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "none0", "len": 1048576, "offset": 1048576, "speed": 0}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "concluded"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "null"}}
>  {"return": ""}
>  *** done
> diff --git a/tests/qemu-iotests/176.out b/tests/qemu-iotests/176.out
> index 9d09b60452..b46b743850 100644
> --- a/tests/qemu-iotests/176.out
> +++ b/tests/qemu-iotests/176.out
> @@ -170,7 +170,7 @@ QMP_VERSION
>  {"return": {}}
>  {"return": {}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  wrote 196608/196608 bytes at offset 2147287040
>  192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  wrote 131072/131072 bytes at offset 2147352576
> @@ -207,7 +207,7 @@ QMP_VERSION
>  {"return": {}}
>  {"return": {"sha256": HASH}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  
>  === Test pass bitmap.1 ===
>  
> @@ -219,7 +219,7 @@ QMP_VERSION
>  {"return": {}}
>  {"return": {}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  wrote 196608/196608 bytes at offset 2147287040
>  192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  wrote 131072/131072 bytes at offset 2147352576
> @@ -257,7 +257,7 @@ QMP_VERSION
>  {"return": {}}
>  {"return": {"sha256": HASH}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  
>  === Test pass bitmap.2 ===
>  
> @@ -269,7 +269,7 @@ QMP_VERSION
>  {"return": {}}
>  {"return": {}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  wrote 196608/196608 bytes at offset 2147287040
>  192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  wrote 131072/131072 bytes at offset 2147352576
> @@ -307,7 +307,7 @@ QMP_VERSION
>  {"return": {}}
>  {"return": {"sha256": HASH}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  
>  === Test pass bitmap.3 ===
>  
> @@ -319,7 +319,7 @@ QMP_VERSION
>  {"return": {}}
>  {"return": {}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  wrote 196608/196608 bytes at offset 2147287040
>  192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  wrote 131072/131072 bytes at offset 2147352576
> @@ -354,5 +354,5 @@ QMP_VERSION
>  {"return": {}}
>  {"return": {"sha256": HASH}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  *** done
> diff --git a/tests/qemu-iotests/184.out b/tests/qemu-iotests/184.out
> index 77e5489d65..93e33ba20a 100644
> --- a/tests/qemu-iotests/184.out
> +++ b/tests/qemu-iotests/184.out
> @@ -24,64 +24,64 @@ Testing:
>  {
>      "return": [
>          {
> -            "iops_rd": 0,
> +            "file": "json:{\"driver\": \"throttle\", \"throttle-group\": \"group0\", \"file\": {\"driver\": \"null-co\"}}",
> +            "node-name": "throttle0",
> +            "ro": false,
> +            "drv": "throttle",
> +            "backing_file_depth": 1,
> +            "encrypted": false,
>              "detect_zeroes": "off",
> +            "bps": 0,
> +            "bps_rd": 0,
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
>              "image": {
> +                "filename": "json:{\"driver\": \"throttle\", \"throttle-group\": \"group0\", \"file\": {\"driver\": \"null-co\"}}",
> +                "format": "throttle",
> +                "actual-size": 0,
> +                "virtual-size": 1073741824,
>                  "backing-image": {
> -                    "virtual-size": 1073741824,
>                      "filename": "null-co://",
>                      "format": "null-co",
> -                    "actual-size": 0
> -                },
> -                "virtual-size": 1073741824,
> -                "filename": "json:{\"throttle-group\": \"group0\", \"driver\": \"throttle\", \"file\": {\"driver\": \"null-co\"}}",
> -                "format": "throttle",
> -                "actual-size": 0
> +                    "actual-size": 0,
> +                    "virtual-size": 1073741824
> +                }
>              },
> -            "iops_wr": 0,
> -            "ro": false,
> -            "node-name": "throttle0",
> -            "backing_file_depth": 1,
> -            "drv": "throttle",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> -            "encrypted": false,
> -            "bps": 0,
> -            "bps_rd": 0,
>              "cache": {
> -                "no-flush": false,
> +                "writeback": true,
>                  "direct": false,
> -                "writeback": true
> +                "no-flush": false
>              },
> -            "file": "json:{\"throttle-group\": \"group0\", \"driver\": \"throttle\", \"file\": {\"driver\": \"null-co\"}}"
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> -            "detect_zeroes": "off",
> -            "image": {
> -                "virtual-size": 1073741824,
> -                "filename": "null-co://",
> -                "format": "null-co",
> -                "actual-size": 0
> -            },
> -            "iops_wr": 0,
> -            "ro": false,
> +            "file": "null-co://",
>              "node-name": "disk0",
> -            "backing_file_depth": 0,
> +            "ro": false,
>              "drv": "null-co",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> +            "backing_file_depth": 0,
>              "encrypted": false,
> +            "detect_zeroes": "off",
>              "bps": 0,
>              "bps_rd": 0,
> -            "cache": {
> -                "no-flush": false,
> -                "direct": false,
> -                "writeback": true
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
> +            "image": {
> +                "filename": "null-co://",
> +                "format": "null-co",
> +                "actual-size": 0,
> +                "virtual-size": 1073741824
>              },
> -            "file": "null-co://"
> +            "cache": {
> +                "writeback": true,
> +                "direct": false,
> +                "no-flush": false
> +            },
> +            "write_threshold": 0
>          }
>      ]
>  }
> @@ -94,11 +94,11 @@ Testing:
>      }
>  }
>  {
> +    "event": "SHUTDOWN",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "SHUTDOWN",
>      "data": {
>          "guest": false,
>          "reason": "host-qmp-quit"
> @@ -121,52 +121,25 @@ Testing:
>  }
>  {
>      "return": {
> -        "bps-read-max-length": 1,
> -        "iops-read-max-length": 1,
> -        "bps-read-max": 0,
> -        "bps-total": 0,
> -        "iops-total-max-length": 1,
>          "iops-total": 1000,
> -        "iops-write-max": 0,
> -        "bps-write": 0,
> -        "bps-total-max": 0,
> -        "bps-write-max": 0,
> -        "iops-size": 0,
> -        "iops-read": 0,
> -        "iops-write-max-length": 1,
> -        "iops-write": 0,
> -        "bps-total-max-length": 1,
> -        "iops-read-max": 0,
> -        "bps-read": 0,
> -        "bps-write-max-length": 1,
> -        "iops-total-max": 0
> -    }
> -}
> -{
> -    "return": {
> -    }
> -}
> -{
> -    "return": {
> -        "bps-read-max-length": 1,
> -        "iops-read-max-length": 1,
> -        "bps-read-max": 0,
> -        "bps-total": 0,
> +        "iops-total-max": 0,
>          "iops-total-max-length": 1,
> -        "iops-total": 0,
> -        "iops-write-max": 0,
> -        "bps-write": 0,
> -        "bps-total-max": 0,
> -        "bps-write-max": 0,
> -        "iops-size": 0,
>          "iops-read": 0,
> -        "iops-write-max-length": 1,
> -        "iops-write": 0,
> -        "bps-total-max-length": 1,
>          "iops-read-max": 0,
> +        "iops-read-max-length": 1,
> +        "iops-write": 0,
> +        "iops-write-max": 0,
> +        "iops-write-max-length": 1,
> +        "bps-total": 0,
> +        "bps-total-max": 0,
> +        "bps-total-max-length": 1,
>          "bps-read": 0,
> +        "bps-read-max": 0,
> +        "bps-read-max-length": 1,
> +        "bps-write": 0,
> +        "bps-write-max": 0,
>          "bps-write-max-length": 1,
> -        "iops-total-max": 0
> +        "iops-size": 0
>      }
>  }
>  {
> @@ -174,11 +147,38 @@ Testing:
>      }
>  }
>  {
> +    "return": {
> +        "iops-total": 0,
> +        "iops-total-max": 0,
> +        "iops-total-max-length": 1,
> +        "iops-read": 0,
> +        "iops-read-max": 0,
> +        "iops-read-max-length": 1,
> +        "iops-write": 0,
> +        "iops-write-max": 0,
> +        "iops-write-max-length": 1,
> +        "bps-total": 0,
> +        "bps-total-max": 0,
> +        "bps-total-max-length": 1,
> +        "bps-read": 0,
> +        "bps-read-max": 0,
> +        "bps-read-max-length": 1,
> +        "bps-write": 0,
> +        "bps-write-max": 0,
> +        "bps-write-max-length": 1,
> +        "iops-size": 0
> +    }
> +}
> +{
> +    "return": {
> +    }
> +}
> +{
> +    "event": "SHUTDOWN",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "SHUTDOWN",
>      "data": {
>          "guest": false,
>          "reason": "host-qmp-quit"
> @@ -216,11 +216,11 @@ Testing:
>      }
>  }
>  {
> +    "event": "SHUTDOWN",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "SHUTDOWN",
>      "data": {
>          "guest": false,
>          "reason": "host-qmp-quit"
> @@ -252,11 +252,11 @@ Testing:
>      }
>  }
>  {
> +    "event": "SHUTDOWN",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "SHUTDOWN",
>      "data": {
>          "guest": false,
>          "reason": "host-qmp-quit"
> diff --git a/tests/qemu-iotests/186.out b/tests/qemu-iotests/186.out
> index 01530040e5..12ea630222 100644
> --- a/tests/qemu-iotests/186.out
> +++ b/tests/qemu-iotests/186.out
> @@ -57,7 +57,7 @@ qdev_id: [not inserted]
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device ide-hd,drive=null
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]
>      Cache mode:       writeback
>  (qemu) quit
> @@ -65,7 +65,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device ide-hd,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      qdev_id
>      Cache mode:       writeback
>  (qemu) quit
> @@ -73,7 +73,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device scsi-hd,drive=null
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]
>      Cache mode:       writeback
>  (qemu) quit
> @@ -81,7 +81,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device scsi-hd,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      qdev_id
>      Cache mode:       writeback
>  (qemu) quit
> @@ -89,7 +89,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device virtio-blk-pci,drive=null
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]/virtio-backend
>      Cache mode:       writeback
>  (qemu) quit
> @@ -97,7 +97,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device virtio-blk-pci,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      /machine/peripheral/qdev_id/virtio-backend
>      Cache mode:       writeback
>  (qemu) quit
> @@ -105,7 +105,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device floppy,drive=null
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -114,7 +114,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device floppy,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      qdev_id
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -123,7 +123,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device ide-cd,drive=null
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -132,7 +132,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device ide-cd,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      qdev_id
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -141,7 +141,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device scsi-cd,drive=null
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -150,7 +150,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device scsi-cd,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      qdev_id
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -162,11 +162,11 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-hd,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
>  
> -null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      qdev_id
>      Cache mode:       writeback
>  (qemu) quit
> @@ -174,11 +174,11 @@ null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-hd,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
>  
> -null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      qdev_id
>      Cache mode:       writeback
>  (qemu) quit
> @@ -186,11 +186,11 @@ null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device virtio-blk-pci,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
>  
> -null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/peripheral/qdev_id/virtio-backend
>      Cache mode:       writeback
>  (qemu) quit
> @@ -198,11 +198,11 @@ null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device floppy,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
>  
> -null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      qdev_id
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -211,11 +211,11 @@ null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-cd,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
>  
> -null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      qdev_id
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -224,11 +224,11 @@ null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-cd,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
>  
> -null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      qdev_id
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -240,7 +240,7 @@ null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-hd,drive=none0
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]
>      Cache mode:       writeback
>  (qemu) quit
> @@ -248,7 +248,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-hd,drive=none0,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      qdev_id
>      Cache mode:       writeback
>  (qemu) quit
> @@ -256,7 +256,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-hd,drive=none0
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]
>      Cache mode:       writeback
>  (qemu) quit
> @@ -264,7 +264,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-hd,drive=none0,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      qdev_id
>      Cache mode:       writeback
>  (qemu) quit
> @@ -272,7 +272,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device virtio-blk-pci,drive=none0
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]/virtio-backend
>      Cache mode:       writeback
>  (qemu) quit
> @@ -280,7 +280,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device virtio-blk-pci,drive=none0,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/peripheral/qdev_id/virtio-backend
>      Cache mode:       writeback
>  (qemu) quit
> @@ -288,7 +288,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device floppy,drive=none0
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -297,7 +297,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device floppy,drive=none0,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      qdev_id
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -306,7 +306,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-cd,drive=none0
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -315,7 +315,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-cd,drive=none0,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      qdev_id
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -324,7 +324,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-cd,drive=none0
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -333,7 +333,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-cd,drive=none0,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      qdev_id
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -411,7 +411,7 @@ floppy0: [not inserted]
>  Testing: -drive if=floppy,driver=null-co,read-zeroes=on
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -floppy0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +floppy0 (NODE_NAME): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/unattached/device[N]
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -420,7 +420,7 @@ floppy0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=ide,driver=null-co,read-zeroes=on
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -ide0-hd0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +ide0-hd0 (NODE_NAME): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/unattached/device[N]
>      Cache mode:       writeback
>  (qemu) quit
> @@ -436,7 +436,7 @@ ide0-cd0: [not inserted]
>  Testing: -drive if=ide,driver=null-co,read-zeroes=on,media=cdrom
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -ide0-cd0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co, read-only)
> +ide0-cd0 (NODE_NAME): json:{"driver": "null-co", "read-zeroes": "on"} (null-co, read-only)
>      Attached to:      /machine/unattached/device[N]
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -445,7 +445,7 @@ ide0-cd0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co,
>  Testing: -drive if=virtio,driver=null-co,read-zeroes=on
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -virtio0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +virtio0 (NODE_NAME): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]/virtio-backend
>      Cache mode:       writeback
>  (qemu) quit
> @@ -453,7 +453,7 @@ virtio0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=pflash,driver=null-co,read-zeroes=on,size=1M
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -pflash0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co", "size": "1M"} (null-co)
> +pflash0 (NODE_NAME): json:{"driver": "null-co", "size": "1M", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/system.flash0
>      Cache mode:       writeback
>  (qemu) quit
> diff --git a/tests/qemu-iotests/190.out b/tests/qemu-iotests/190.out
> index ed9d8214eb..2acea9982c 100644
> --- a/tests/qemu-iotests/190.out
> +++ b/tests/qemu-iotests/190.out
> @@ -29,8 +29,8 @@ bitmaps size: 537198592
>  
>  expected bitmap 545259520
>  {
> -    "bitmaps": 545259520,
>      "required": 18874368,
> -    "fully-allocated": 2199042129920
> +    "fully-allocated": 2199042129920,
> +    "bitmaps": 545259520
>  }
>  *** done
> diff --git a/tests/qemu-iotests/191.out b/tests/qemu-iotests/191.out
> index ea88777374..a7dfb22080 100644
> --- a/tests/qemu-iotests/191.out
> +++ b/tests/qemu-iotests/191.out
> @@ -22,25 +22,25 @@ wrote 65536/65536 bytes at offset 1048576
>                        'base':'TEST_DIR/t.IMGFMT.base',
>                        'top': 'TEST_DIR/t.IMGFMT.mid' } }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "created",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "created"
>      }
>  }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "running",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "running"
>      }
>  }
>  {
> @@ -48,61 +48,61 @@ wrote 65536/65536 bytes at offset 1048576
>      }
>  }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "waiting",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "waiting"
>      }
>  }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "pending",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "pending"
>      }
>  }
>  {
> -    "timestamp": {
> -        "seconds":  TIMESTAMP,
> -        "microseconds":  TIMESTAMP
> -    },
>      "event": "BLOCK_JOB_COMPLETED",
> +    "timestamp": {
> +        "seconds":  TIMESTAMP,
> +        "microseconds":  TIMESTAMP
> +    },
>      "data": {
> +        "type": "commit",
>          "device": "commit0",
>          "len": 67108864,
>          "offset": 67108864,
> -        "speed": 0,
> -        "type": "commit"
> +        "speed": 0
>      }
>  }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "concluded",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "concluded"
>      }
>  }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "null",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "null"
>      }
>  }
>  
> @@ -112,268 +112,268 @@ wrote 65536/65536 bytes at offset 1048576
>  {
>      "return": [
>          {
> -            "iops_rd": 0,
> -            "detect_zeroes": "off",
> -            "image": {
> -                "backing-image": {
> -                    "virtual-size": 67108864,
> -                    "filename": "TEST_DIR/t.IMGFMT.base",
> -                    "cluster-size": 65536,
> -                    "format": "IMGFMT",
> -                    "actual-size": SIZE,
> -                    "dirty-flag": false
> -                },
> -                "backing-filename-format": "IMGFMT",
> -                "virtual-size": 67108864,
> -                "filename": "TEST_DIR/t.IMGFMT.ovl2",
> -                "cluster-size": 65536,
> -                "format": "IMGFMT",
> -                "actual-size": SIZE,
> -                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                "backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                "dirty-flag": false
> -            },
> -            "iops_wr": 0,
> -            "ro": false,
> +            "file": "TEST_DIR/t.IMGFMT.ovl2",
>              "node-name": "top2",
> -            "backing_file_depth": 1,
> +            "ro": false,
>              "drv": "IMGFMT",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
>              "backing_file": "TEST_DIR/t.IMGFMT.base",
> +            "backing_file_depth": 1,
>              "encrypted": false,
> +            "detect_zeroes": "off",
>              "bps": 0,
>              "bps_rd": 0,
> -            "cache": {
> -                "no-flush": false,
> -                "direct": false,
> -                "writeback": true
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
> +            "image": {
> +                "filename": "TEST_DIR/t.IMGFMT.ovl2",
> +                "format": "IMGFMT",
> +                "dirty-flag": false,
> +                "actual-size": SIZE,
> +                "virtual-size": 67108864,
> +                "cluster-size": 65536,
> +                "backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                "backing-filename-format": "IMGFMT",
> +                "backing-image": {
> +                    "filename": "TEST_DIR/t.IMGFMT.base",
> +                    "format": "IMGFMT",
> +                    "dirty-flag": false,
> +                    "actual-size": SIZE,
> +                    "virtual-size": 67108864,
> +                    "cluster-size": 65536,
> +                },
>              },
> -            "file": "TEST_DIR/t.IMGFMT.ovl2"
> +            "cache": {
> +                "writeback": true,
> +                "direct": false,
> +                "no-flush": false
> +            },
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> +            "file": "TEST_DIR/t.IMGFMT.ovl2",
> +            "node-name": "NODE_NAME",
> +            "ro": false,
> +            "drv": "file",
> +            "backing_file_depth": 0,
> +            "encrypted": false,
>              "detect_zeroes": "off",
> +            "bps": 0,
> +            "bps_rd": 0,
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
>              "image": {
> -                "virtual-size": 197120,
>                  "filename": "TEST_DIR/t.IMGFMT.ovl2",
>                  "format": "file",
> +                "dirty-flag": false,
>                  "actual-size": SIZE,
> -                "dirty-flag": false
> +                "virtual-size": 197120
>              },
> -            "iops_wr": 0,
> -            "ro": false,
> -            "node-name": "NODE_NAME",
> -            "backing_file_depth": 0,
> -            "drv": "file",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> -            "encrypted": false,
> -            "bps": 0,
> -            "bps_rd": 0,
>              "cache": {
> -                "no-flush": false,
> +                "writeback": true,
>                  "direct": false,
> -                "writeback": true
> +                "no-flush": false
>              },
> -            "file": "TEST_DIR/t.IMGFMT.ovl2"
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> -            "detect_zeroes": "off",
> -            "image": {
> -                "backing-image": {
> -                    "virtual-size": 67108864,
> -                    "filename": "TEST_DIR/t.IMGFMT.base",
> -                    "cluster-size": 65536,
> -                    "format": "IMGFMT",
> -                    "actual-size": SIZE,
> -                    "dirty-flag": false
> -                },
> -                "backing-filename-format": "IMGFMT",
> -                "virtual-size": 67108864,
> -                "filename": "TEST_DIR/t.IMGFMT",
> -                "cluster-size": 65536,
> -                "format": "IMGFMT",
> -                "actual-size": SIZE,
> -                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                "backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                "dirty-flag": false
> -            },
> -            "iops_wr": 0,
> -            "ro": false,
> +            "file": "TEST_DIR/t.IMGFMT",
>              "node-name": "top",
> -            "backing_file_depth": 1,
> +            "ro": false,
>              "drv": "IMGFMT",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
>              "backing_file": "TEST_DIR/t.IMGFMT.base",
> +            "backing_file_depth": 1,
>              "encrypted": false,
> +            "detect_zeroes": "off",
>              "bps": 0,
>              "bps_rd": 0,
> -            "cache": {
> -                "no-flush": false,
> -                "direct": false,
> -                "writeback": true
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
> +            "image": {
> +                "filename": "TEST_DIR/t.IMGFMT",
> +                "format": "IMGFMT",
> +                "dirty-flag": false,
> +                "actual-size": SIZE,
> +                "virtual-size": 67108864,
> +                "cluster-size": 65536,
> +                "backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                "backing-filename-format": "IMGFMT",
> +                "backing-image": {
> +                    "filename": "TEST_DIR/t.IMGFMT.base",
> +                    "format": "IMGFMT",
> +                    "dirty-flag": false,
> +                    "actual-size": SIZE,
> +                    "virtual-size": 67108864,
> +                    "cluster-size": 65536,
> +                },
>              },
> -            "file": "TEST_DIR/t.IMGFMT"
> +            "cache": {
> +                "writeback": true,
> +                "direct": false,
> +                "no-flush": false
> +            },
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> +            "file": "TEST_DIR/t.IMGFMT",
> +            "node-name": "NODE_NAME",
> +            "ro": false,
> +            "drv": "file",
> +            "backing_file_depth": 0,
> +            "encrypted": false,
>              "detect_zeroes": "off",
> +            "bps": 0,
> +            "bps_rd": 0,
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
>              "image": {
> -                "virtual-size": 197120,
>                  "filename": "TEST_DIR/t.IMGFMT",
>                  "format": "file",
> +                "dirty-flag": false,
>                  "actual-size": SIZE,
> -                "dirty-flag": false
> +                "virtual-size": 197120
>              },
> -            "iops_wr": 0,
> -            "ro": false,
> -            "node-name": "NODE_NAME",
> -            "backing_file_depth": 0,
> -            "drv": "file",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> -            "encrypted": false,
> -            "bps": 0,
> -            "bps_rd": 0,
>              "cache": {
> -                "no-flush": false,
> +                "writeback": true,
>                  "direct": false,
> -                "writeback": true
> +                "no-flush": false
>              },
> -            "file": "TEST_DIR/t.IMGFMT"
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> -            "detect_zeroes": "off",
> -            "image": {
> -                "backing-image": {
> -                    "virtual-size": 67108864,
> -                    "filename": "TEST_DIR/t.IMGFMT.base",
> -                    "cluster-size": 65536,
> -                    "format": "IMGFMT",
> -                    "actual-size": SIZE,
> -                    "dirty-flag": false
> -                },
> -                "backing-filename-format": "IMGFMT",
> -                "virtual-size": 67108864,
> -                "filename": "TEST_DIR/t.IMGFMT.mid",
> -                "cluster-size": 65536,
> -                "format": "IMGFMT",
> -                "actual-size": SIZE,
> -                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                "backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                "dirty-flag": false
> -            },
> -            "iops_wr": 0,
> -            "ro": false,
> +            "file": "TEST_DIR/t.IMGFMT.mid",
>              "node-name": "mid",
> -            "backing_file_depth": 1,
> +            "ro": false,
>              "drv": "IMGFMT",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
>              "backing_file": "TEST_DIR/t.IMGFMT.base",
> +            "backing_file_depth": 1,
>              "encrypted": false,
> +            "detect_zeroes": "off",
>              "bps": 0,
>              "bps_rd": 0,
> -            "cache": {
> -                "no-flush": false,
> -                "direct": false,
> -                "writeback": true
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
> +            "image": {
> +                "filename": "TEST_DIR/t.IMGFMT.mid",
> +                "format": "IMGFMT",
> +                "dirty-flag": false,
> +                "actual-size": SIZE,
> +                "virtual-size": 67108864,
> +                "cluster-size": 65536,
> +                "backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                "backing-filename-format": "IMGFMT",
> +                "backing-image": {
> +                    "filename": "TEST_DIR/t.IMGFMT.base",
> +                    "format": "IMGFMT",
> +                    "dirty-flag": false,
> +                    "actual-size": SIZE,
> +                    "virtual-size": 67108864,
> +                    "cluster-size": 65536,
> +                },
>              },
> -            "file": "TEST_DIR/t.IMGFMT.mid"
> +            "cache": {
> +                "writeback": true,
> +                "direct": false,
> +                "no-flush": false
> +            },
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> +            "file": "TEST_DIR/t.IMGFMT.mid",
> +            "node-name": "NODE_NAME",
> +            "ro": false,
> +            "drv": "file",
> +            "backing_file_depth": 0,
> +            "encrypted": false,
>              "detect_zeroes": "off",
> +            "bps": 0,
> +            "bps_rd": 0,
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
>              "image": {
> -                "virtual-size": 393216,
>                  "filename": "TEST_DIR/t.IMGFMT.mid",
>                  "format": "file",
> +                "dirty-flag": false,
>                  "actual-size": SIZE,
> -                "dirty-flag": false
> +                "virtual-size": 393216
>              },
> -            "iops_wr": 0,
> -            "ro": false,
> -            "node-name": "NODE_NAME",
> -            "backing_file_depth": 0,
> -            "drv": "file",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> -            "encrypted": false,
> -            "bps": 0,
> -            "bps_rd": 0,
>              "cache": {
> -                "no-flush": false,
> +                "writeback": true,
>                  "direct": false,
> -                "writeback": true
> +                "no-flush": false
>              },
> -            "file": "TEST_DIR/t.IMGFMT.mid"
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> -            "detect_zeroes": "off",
> -            "image": {
> -                "virtual-size": 67108864,
> -                "filename": "TEST_DIR/t.IMGFMT.base",
> -                "cluster-size": 65536,
> -                "format": "IMGFMT",
> -                "actual-size": SIZE,
> -                "dirty-flag": false
> -            },
> -            "iops_wr": 0,
> -            "ro": false,
> +            "file": "TEST_DIR/t.IMGFMT.base",
>              "node-name": "base",
> -            "backing_file_depth": 0,
> +            "ro": false,
>              "drv": "IMGFMT",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> +            "backing_file_depth": 0,
>              "encrypted": false,
> +            "detect_zeroes": "off",
>              "bps": 0,
>              "bps_rd": 0,
> -            "cache": {
> -                "no-flush": false,
> -                "direct": false,
> -                "writeback": true
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
> +            "image": {
> +                "filename": "TEST_DIR/t.IMGFMT.base",
> +                "format": "IMGFMT",
> +                "dirty-flag": false,
> +                "actual-size": SIZE,
> +                "virtual-size": 67108864,
> +                "cluster-size": 65536,
>              },
> -            "file": "TEST_DIR/t.IMGFMT.base"
> +            "cache": {
> +                "writeback": true,
> +                "direct": false,
> +                "no-flush": false
> +            },
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> +            "file": "TEST_DIR/t.IMGFMT.base",
> +            "node-name": "NODE_NAME",
> +            "ro": false,
> +            "drv": "file",
> +            "backing_file_depth": 0,
> +            "encrypted": false,
>              "detect_zeroes": "off",
> +            "bps": 0,
> +            "bps_rd": 0,
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
>              "image": {
> -                "virtual-size": 393216,
>                  "filename": "TEST_DIR/t.IMGFMT.base",
>                  "format": "file",
> +                "dirty-flag": false,
>                  "actual-size": SIZE,
> -                "dirty-flag": false
> +                "virtual-size": 393216
>              },
> -            "iops_wr": 0,
> -            "ro": false,
> -            "node-name": "NODE_NAME",
> -            "backing_file_depth": 0,
> -            "drv": "file",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> -            "encrypted": false,
> -            "bps": 0,
> -            "bps_rd": 0,
>              "cache": {
> -                "no-flush": false,
> +                "writeback": true,
>                  "direct": false,
> -                "writeback": true
> +                "no-flush": false
>              },
> -            "file": "TEST_DIR/t.IMGFMT.base"
> +            "write_threshold": 0
>          }
>      ]
>  }
> @@ -383,11 +383,11 @@ wrote 65536/65536 bytes at offset 1048576
>      }
>  }
>  {
> +    "event": "SHUTDOWN",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "SHUTDOWN",
>      "data": {
>          "guest": false,
>          "reason": "host-qmp-quit"
> @@ -429,25 +429,25 @@ wrote 65536/65536 bytes at offset 1048576
>                        'base':'TEST_DIR/t.IMGFMT.base',
>                        'top': 'TEST_DIR/t.IMGFMT.mid' } }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "created",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "created"
>      }
>  }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "running",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "running"
>      }
>  }
>  {
> @@ -455,61 +455,61 @@ wrote 65536/65536 bytes at offset 1048576
>      }
>  }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "waiting",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "waiting"
>      }
>  }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "pending",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "pending"
>      }
>  }
>  {
> -    "timestamp": {
> -        "seconds":  TIMESTAMP,
> -        "microseconds":  TIMESTAMP
> -    },
>      "event": "BLOCK_JOB_COMPLETED",
> +    "timestamp": {
> +        "seconds":  TIMESTAMP,
> +        "microseconds":  TIMESTAMP
> +    },
>      "data": {
> +        "type": "commit",
>          "device": "commit0",
>          "len": 67108864,
>          "offset": 67108864,
> -        "speed": 0,
> -        "type": "commit"
> +        "speed": 0
>      }
>  }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "concluded",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "concluded"
>      }
>  }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "null",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "null"
>      }
>  }
>  
> @@ -519,279 +519,279 @@ wrote 65536/65536 bytes at offset 1048576
>  {
>      "return": [
>          {
> -            "iops_rd": 0,
> -            "detect_zeroes": "off",
> -            "image": {
> -                "backing-image": {
> -                    "virtual-size": 67108864,
> -                    "filename": "TEST_DIR/t.IMGFMT.base",
> -                    "cluster-size": 65536,
> -                    "format": "IMGFMT",
> -                    "actual-size": SIZE,
> -                    "dirty-flag": false
> -                },
> -                "backing-filename-format": "IMGFMT",
> -                "virtual-size": 67108864,
> -                "filename": "TEST_DIR/t.IMGFMT.ovl2",
> -                "cluster-size": 65536,
> -                "format": "IMGFMT",
> -                "actual-size": SIZE,
> -                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                "backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                "dirty-flag": false
> -            },
> -            "iops_wr": 0,
> -            "ro": true,
> +            "file": "TEST_DIR/t.IMGFMT.ovl2",
>              "node-name": "NODE_NAME",
> -            "backing_file_depth": 1,
> +            "ro": true,
>              "drv": "IMGFMT",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
>              "backing_file": "TEST_DIR/t.IMGFMT.base",
> +            "backing_file_depth": 1,
>              "encrypted": false,
> +            "detect_zeroes": "off",
>              "bps": 0,
>              "bps_rd": 0,
> -            "cache": {
> -                "no-flush": false,
> -                "direct": false,
> -                "writeback": true
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
> +            "image": {
> +                "filename": "TEST_DIR/t.IMGFMT.ovl2",
> +                "format": "IMGFMT",
> +                "dirty-flag": false,
> +                "actual-size": SIZE,
> +                "virtual-size": 67108864,
> +                "cluster-size": 65536,
> +                "backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                "backing-filename-format": "IMGFMT",
> +                "backing-image": {
> +                    "filename": "TEST_DIR/t.IMGFMT.base",
> +                    "format": "IMGFMT",
> +                    "dirty-flag": false,
> +                    "actual-size": SIZE,
> +                    "virtual-size": 67108864,
> +                    "cluster-size": 65536,
> +                },
>              },
> -            "file": "TEST_DIR/t.IMGFMT.ovl2"
> +            "cache": {
> +                "writeback": true,
> +                "direct": false,
> +                "no-flush": false
> +            },
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> +            "file": "TEST_DIR/t.IMGFMT.ovl2",
> +            "node-name": "NODE_NAME",
> +            "ro": true,
> +            "drv": "file",
> +            "backing_file_depth": 0,
> +            "encrypted": false,
>              "detect_zeroes": "off",
> +            "bps": 0,
> +            "bps_rd": 0,
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
>              "image": {
> -                "virtual-size": 197120,
>                  "filename": "TEST_DIR/t.IMGFMT.ovl2",
>                  "format": "file",
> +                "dirty-flag": false,
>                  "actual-size": SIZE,
> -                "dirty-flag": false
> +                "virtual-size": 197120
>              },
> -            "iops_wr": 0,
> -            "ro": true,
> -            "node-name": "NODE_NAME",
> -            "backing_file_depth": 0,
> -            "drv": "file",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> -            "encrypted": false,
> -            "bps": 0,
> -            "bps_rd": 0,
>              "cache": {
> -                "no-flush": false,
> +                "writeback": true,
>                  "direct": false,
> -                "writeback": true
> +                "no-flush": false
>              },
> -            "file": "TEST_DIR/t.IMGFMT.ovl2"
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> -            "detect_zeroes": "off",
> -            "image": {
> -                "backing-image": {
> -                    "backing-image": {
> -                        "virtual-size": 67108864,
> -                        "filename": "TEST_DIR/t.IMGFMT.base",
> -                        "cluster-size": 65536,
> -                        "format": "IMGFMT",
> -                        "actual-size": SIZE,
> -                        "dirty-flag": false
> -                    },
> -                    "backing-filename-format": "IMGFMT",
> -                    "virtual-size": 67108864,
> -                    "filename": "TEST_DIR/t.IMGFMT.ovl2",
> -                    "cluster-size": 65536,
> -                    "format": "IMGFMT",
> -                    "actual-size": SIZE,
> -                    "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                    "backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                    "dirty-flag": false
> -                },
> -                "backing-filename-format": "IMGFMT",
> -                "virtual-size": 67108864,
> -                "filename": "TEST_DIR/t.IMGFMT.ovl3",
> -                "cluster-size": 65536,
> -                "format": "IMGFMT",
> -                "actual-size": SIZE,
> -                "full-backing-filename": "TEST_DIR/t.IMGFMT.ovl2",
> -                "backing-filename": "TEST_DIR/t.IMGFMT.ovl2",
> -                "dirty-flag": false
> -            },
> -            "iops_wr": 0,
> -            "ro": false,
> +            "file": "TEST_DIR/t.IMGFMT.ovl3",
>              "node-name": "top2",
> -            "backing_file_depth": 2,
> +            "ro": false,
>              "drv": "IMGFMT",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
>              "backing_file": "TEST_DIR/t.IMGFMT.ovl2",
> +            "backing_file_depth": 2,
>              "encrypted": false,
> +            "detect_zeroes": "off",
>              "bps": 0,
>              "bps_rd": 0,
> -            "cache": {
> -                "no-flush": false,
> -                "direct": false,
> -                "writeback": true
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
> +            "image": {
> +                "filename": "TEST_DIR/t.IMGFMT.ovl3",
> +                "format": "IMGFMT",
> +                "dirty-flag": false,
> +                "actual-size": SIZE,
> +                "virtual-size": 67108864,
> +                "cluster-size": 65536,
> +                "backing-filename": "TEST_DIR/t.IMGFMT.ovl2",
> +                "full-backing-filename": "TEST_DIR/t.IMGFMT.ovl2",
> +                "backing-filename-format": "IMGFMT",
> +                "backing-image": {
> +                    "filename": "TEST_DIR/t.IMGFMT.ovl2",
> +                    "format": "IMGFMT",
> +                    "dirty-flag": false,
> +                    "actual-size": SIZE,
> +                    "virtual-size": 67108864,
> +                    "cluster-size": 65536,
> +                    "backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                    "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                    "backing-filename-format": "IMGFMT",
> +                    "backing-image": {
> +                        "filename": "TEST_DIR/t.IMGFMT.base",
> +                        "format": "IMGFMT",
> +                        "dirty-flag": false,
> +                        "actual-size": SIZE,
> +                        "virtual-size": 67108864,
> +                        "cluster-size": 65536,
> +                    },
> +                },
>              },
> -            "file": "TEST_DIR/t.IMGFMT.ovl3"
> +            "cache": {
> +                "writeback": true,
> +                "direct": false,
> +                "no-flush": false
> +            },
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> +            "file": "TEST_DIR/t.IMGFMT.ovl3",
> +            "node-name": "NODE_NAME",
> +            "ro": false,
> +            "drv": "file",
> +            "backing_file_depth": 0,
> +            "encrypted": false,
>              "detect_zeroes": "off",
> +            "bps": 0,
> +            "bps_rd": 0,
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
>              "image": {
> -                "virtual-size": 197120,
>                  "filename": "TEST_DIR/t.IMGFMT.ovl3",
>                  "format": "file",
> +                "dirty-flag": false,
>                  "actual-size": SIZE,
> -                "dirty-flag": false
> +                "virtual-size": 197120
>              },
> -            "iops_wr": 0,
> -            "ro": false,
> -            "node-name": "NODE_NAME",
> -            "backing_file_depth": 0,
> -            "drv": "file",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> -            "encrypted": false,
> -            "bps": 0,
> -            "bps_rd": 0,
>              "cache": {
> -                "no-flush": false,
> +                "writeback": true,
>                  "direct": false,
> -                "writeback": true
> +                "no-flush": false
>              },
> -            "file": "TEST_DIR/t.IMGFMT.ovl3"
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> -            "detect_zeroes": "off",
> -            "image": {
> -                "virtual-size": 67108864,
> -                "filename": "TEST_DIR/t.IMGFMT.base",
> -                "cluster-size": 65536,
> -                "format": "IMGFMT",
> -                "actual-size": SIZE,
> -                "dirty-flag": false
> -            },
> -            "iops_wr": 0,
> +            "file": "TEST_DIR/t.IMGFMT.base",
> +            "node-name": "NODE_NAME",
>              "ro": true,
> -            "node-name": "NODE_NAME",
> -            "backing_file_depth": 0,
>              "drv": "IMGFMT",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> +            "backing_file_depth": 0,
>              "encrypted": false,
> +            "detect_zeroes": "off",
>              "bps": 0,
>              "bps_rd": 0,
> -            "cache": {
> -                "no-flush": false,
> -                "direct": false,
> -                "writeback": true
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
> +            "image": {
> +                "filename": "TEST_DIR/t.IMGFMT.base",
> +                "format": "IMGFMT",
> +                "dirty-flag": false,
> +                "actual-size": SIZE,
> +                "virtual-size": 67108864,
> +                "cluster-size": 65536,
>              },
> -            "file": "TEST_DIR/t.IMGFMT.base"
> +            "cache": {
> +                "writeback": true,
> +                "direct": false,
> +                "no-flush": false
> +            },
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> +            "file": "TEST_DIR/t.IMGFMT.base",
> +            "node-name": "NODE_NAME",
> +            "ro": true,
> +            "drv": "file",
> +            "backing_file_depth": 0,
> +            "encrypted": false,
>              "detect_zeroes": "off",
> +            "bps": 0,
> +            "bps_rd": 0,
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
>              "image": {
> -                "virtual-size": 393216,
>                  "filename": "TEST_DIR/t.IMGFMT.base",
>                  "format": "file",
> +                "dirty-flag": false,
>                  "actual-size": SIZE,
> -                "dirty-flag": false
> +                "virtual-size": 393216
>              },
> -            "iops_wr": 0,
> -            "ro": true,
> -            "node-name": "NODE_NAME",
> -            "backing_file_depth": 0,
> -            "drv": "file",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> -            "encrypted": false,
> -            "bps": 0,
> -            "bps_rd": 0,
>              "cache": {
> -                "no-flush": false,
> +                "writeback": true,
>                  "direct": false,
> -                "writeback": true
> +                "no-flush": false
>              },
> -            "file": "TEST_DIR/t.IMGFMT.base"
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> -            "detect_zeroes": "off",
> -            "image": {
> -                "backing-image": {
> -                    "virtual-size": 67108864,
> -                    "filename": "TEST_DIR/t.IMGFMT.base",
> -                    "cluster-size": 65536,
> -                    "format": "IMGFMT",
> -                    "actual-size": SIZE,
> -                    "dirty-flag": false
> -                },
> -                "backing-filename-format": "IMGFMT",
> -                "virtual-size": 67108864,
> -                "filename": "TEST_DIR/t.IMGFMT",
> -                "cluster-size": 65536,
> -                "format": "IMGFMT",
> -                "actual-size": SIZE,
> -                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                "backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                "dirty-flag": false
> -            },
> -            "iops_wr": 0,
> -            "ro": false,
> +            "file": "TEST_DIR/t.IMGFMT",
>              "node-name": "top",
> -            "backing_file_depth": 1,
> +            "ro": false,
>              "drv": "IMGFMT",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
>              "backing_file": "TEST_DIR/t.IMGFMT.base",
> +            "backing_file_depth": 1,
>              "encrypted": false,
> +            "detect_zeroes": "off",
>              "bps": 0,
>              "bps_rd": 0,
> -            "cache": {
> -                "no-flush": false,
> -                "direct": false,
> -                "writeback": true
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
> +            "image": {
> +                "filename": "TEST_DIR/t.IMGFMT",
> +                "format": "IMGFMT",
> +                "dirty-flag": false,
> +                "actual-size": SIZE,
> +                "virtual-size": 67108864,
> +                "cluster-size": 65536,
> +                "backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                "backing-filename-format": "IMGFMT",
> +                "backing-image": {
> +                    "filename": "TEST_DIR/t.IMGFMT.base",
> +                    "format": "IMGFMT",
> +                    "dirty-flag": false,
> +                    "actual-size": SIZE,
> +                    "virtual-size": 67108864,
> +                    "cluster-size": 65536,
> +                },
>              },
> -            "file": "TEST_DIR/t.IMGFMT"
> +            "cache": {
> +                "writeback": true,
> +                "direct": false,
> +                "no-flush": false
> +            },
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> -            "detect_zeroes": "off",
> -            "image": {
> -                "virtual-size": 197120,
> -                "filename": "TEST_DIR/t.IMGFMT",
> -                "format": "file",
> -                "actual-size": SIZE,
> -                "dirty-flag": false
> -            },
> -            "iops_wr": 0,
> -            "ro": false,
> +            "file": "TEST_DIR/t.IMGFMT",
>              "node-name": "NODE_NAME",
> -            "backing_file_depth": 0,
> +            "ro": false,
>              "drv": "file",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> +            "backing_file_depth": 0,
>              "encrypted": false,
> +            "detect_zeroes": "off",
>              "bps": 0,
>              "bps_rd": 0,
> -            "cache": {
> -                "no-flush": false,
> -                "direct": false,
> -                "writeback": true
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
> +            "image": {
> +                "filename": "TEST_DIR/t.IMGFMT",
> +                "format": "file",
> +                "dirty-flag": false,
> +                "actual-size": SIZE,
> +                "virtual-size": 197120
>              },
> -            "file": "TEST_DIR/t.IMGFMT"
> +            "cache": {
> +                "writeback": true,
> +                "direct": false,
> +                "no-flush": false
> +            },
> +            "write_threshold": 0
>          }
>      ]
>  }
> @@ -801,11 +801,11 @@ wrote 65536/65536 bytes at offset 1048576
>      }
>  }
>  {
> +    "event": "SHUTDOWN",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "SHUTDOWN",
>      "data": {
>          "guest": false,
>          "reason": "host-qmp-quit"
> diff --git a/tests/qemu-iotests/195.out b/tests/qemu-iotests/195.out
> index ec84df5012..485d7a1115 100644
> --- a/tests/qemu-iotests/195.out
> +++ b/tests/qemu-iotests/195.out
> @@ -22,11 +22,11 @@ Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,backing.node-name=mid
>      }
>  }
>  {
> +    "event": "SHUTDOWN",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "SHUTDOWN",
>      "data": {
>          "guest": false,
>          "reason": "host-qmp-quit"
> @@ -60,11 +60,11 @@ Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,node-name=top
>      }
>  }
>  {
> +    "event": "SHUTDOWN",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "SHUTDOWN",
>      "data": {
>          "guest": false,
>          "reason": "host-qmp-quit"
> diff --git a/tests/qemu-iotests/229.out b/tests/qemu-iotests/229.out
> index 7d2bfbfbe6..3f4391df6e 100644
> --- a/tests/qemu-iotests/229.out
> +++ b/tests/qemu-iotests/229.out
> @@ -16,19 +16,19 @@ wrote 2097152/2097152 bytes at offset 0
>                                 'mode':   'existing',
>                                 'on-source-error': 'stop',
>                                 'on-target-error': 'stop' }}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "testdisk"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "testdisk", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "testdisk", "status": "running"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "testdisk", "operation": "write", "action": "stop"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "testdisk"}}
> +{"event": "BLOCK_JOB_ERROR", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"device": "testdisk", "operation": "write", "action": "stop"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "testdisk", "status": "paused"}}
>  
>  === Force cancel job paused in error state  ===
>  
>  {'execute': 'block-job-cancel',
>                   'arguments': { 'device': 'testdisk',
>                                  'force': true}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "testdisk", "status": "running"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "testdisk"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "testdisk", "len": 2097152, "offset": OFFSET, "speed": 0, "type": "mirror"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "testdisk", "status": "aborting"}}
> +{"event": "BLOCK_JOB_CANCELLED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "testdisk", "len": 2097152, "offset": OFFSET, "speed": 0}}
>  *** done
> diff --git a/tests/qemu-iotests/244.out b/tests/qemu-iotests/244.out
> index 5e03add054..57cffee1ea 100644
> --- a/tests/qemu-iotests/244.out
> +++ b/tests/qemu-iotests/244.out
> @@ -156,14 +156,14 @@ wrote 1048576/1048576 bytes at offset 0
>                 "data-file": "data",
>                 "data-file-raw": true
>             } } }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "create"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "create"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "running"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "create"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "create"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "create"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "waiting"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "pending"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "concluded"}}
>  { "execute": "job-dismiss", "arguments": { "id": "create" } }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "create"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "null"}}
>  {"return": {}}
>  
>  Comparing pattern:
> diff --git a/tests/qemu-iotests/249.out b/tests/qemu-iotests/249.out
> index d2bf9be85e..a1a1a1b851 100644
> --- a/tests/qemu-iotests/249.out
> +++ b/tests/qemu-iotests/249.out
> @@ -16,8 +16,8 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
>  { 'execute': 'block-commit',
>         'arguments': {'job-id': 'job0', 'device': 'none1', 'top-node': 'int',
>                       'filter-node-name': '1234'}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>  {"error": {"class": "GenericError", "desc": "Invalid node-name: '1234'"}}
>  
>  === Send a write command to a drive opened in read-only mode (2)
> @@ -30,14 +30,14 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
>  
>  { 'execute': 'block-commit',
>         'arguments': {'job-id': 'job0', 'device': 'none1', 'top-node': 'int'}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 1048576, "offset": 1048576, "speed": 0, "type": "commit"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "waiting"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "pending"}}
> +{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "job0", "len": 1048576, "offset": 1048576, "speed": 0}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>  
>  === Send a write command to a drive opened in read-only mode (3)
>  
> diff --git a/tests/qemu-iotests/tests/qsd-jobs.out b/tests/qemu-iotests/tests/qsd-jobs.out
> index c1bc9b8356..336a5c3946 100644
> --- a/tests/qemu-iotests/tests/qsd-jobs.out
> +++ b/tests/qemu-iotests/tests/qsd-jobs.out
> @@ -8,15 +8,15 @@ QMP_VERSION
>  {"return": {}}
>  {"return": {}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
> +{"event": "BLOCK_JOB_CANCELLED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "job0", "len": 0, "offset": 0, "speed": 0}}
>  
>  === Streaming can't get permission on base node ===
>  
>  QMP_VERSION
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>  {"error": {"class": "GenericError", "desc": "Permission conflict on node 'fmt_base': permissions 'write' are both required by an unnamed block device (uses node 'fmt_base' as 'root' child) and unshared by stream job 'job0' (uses node 'fmt_base' as 'intermediate node' child)."}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export1"}}
> +{"event": "BLOCK_EXPORT_DELETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "export1"}}
>  *** done
Mark Cave-Ayland July 6, 2022, 11:49 a.m. UTC | #2
On 06/07/2022 12:35, Markus Armbruster wrote:

> Markus Armbruster <armbru@redhat.com> writes:
> 
>> QDict is implemented as a simple hash table of fixed size.  Observe:
>>
>> * Slow for large n.  Not sure this matters.
>>
>> * A QDict with n entries takes 4120 + n * 32 bytes on my box.  Wastes
>>    space for small n, which is a common case.
>>
>> * Order of traversal depends on the hash function and on insertion
>>    order, because it iterates first over buckets, then collision
>>    chains.
>>
>> * Special code ensures qdict_size() takes constant time.
>>
>> Replace the hash table by a linked list.  Observe:
>>
>> * Even slower for large n.  Might be bad enough to matter.
>>
>> * A QDict with n entries takes 32 + n * 24 bytes.
>>
>> * Traversal is in insertion order.
>>
>> * qdict_size() is linear in the number of entries.
>>
>> This is an experiment.  Do not commit to master as is.
> 
> Forgot to mention: see also
> 
>          Subject: Re: [PULL 14/15] qdev: Base object creation on QDict rather than QemuOpts
>          Message-ID: <87wnctzdl9.fsf@pond.sub.org>
>          https://lists.nongnu.org/archive/html/qemu-devel/2022-07/msg00358.html

It looks like the reporter also reported the issue on gitlab so you could also add:

Fixes: #1090

as well as posting a link to the proposed patch to get some more feedback.

>> The change of traversal order affects expected test output.  I updated
>> only the tests covered by "make check" so far.  I expect some more to
>> hide under tests/qemu-iotests/.
>>
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> ---
>>   include/qapi/qmp/qdict.h              |  15 +-
>>   qobject/qdict.c                       | 104 +--
>>   tests/unit/check-qdict.c              |   2 +-
>>   tests/unit/check-qobject.c            |   2 +-
>>   tests/qemu-iotests/043.out            |  22 +-
>>   tests/qemu-iotests/060.out            |  16 +-
>>   tests/qemu-iotests/061.out            |  52 +-
>>   tests/qemu-iotests/071.out            |   4 +-
>>   tests/qemu-iotests/099.out            |   4 +-
>>   tests/qemu-iotests/108.out            |  14 +-
>>   tests/qemu-iotests/117.out            |   2 +-
>>   tests/qemu-iotests/120.out            |   2 +-
>>   tests/qemu-iotests/127.out            |  20 +-
>>   tests/qemu-iotests/140.out            |   4 +-
>>   tests/qemu-iotests/141.out            |  76 +--
>>   tests/qemu-iotests/143.out            |   2 +-
>>   tests/qemu-iotests/156.out            |  20 +-
>>   tests/qemu-iotests/161.out            |  28 +-
>>   tests/qemu-iotests/176.out            |  16 +-
>>   tests/qemu-iotests/184.out            | 170 ++---
>>   tests/qemu-iotests/186.out            |  82 +--
>>   tests/qemu-iotests/190.out            |   4 +-
>>   tests/qemu-iotests/191.out            | 868 +++++++++++++-------------
>>   tests/qemu-iotests/195.out            |   4 +-
>>   tests/qemu-iotests/229.out            |  14 +-
>>   tests/qemu-iotests/244.out            |  12 +-
>>   tests/qemu-iotests/249.out            |  18 +-
>>   tests/qemu-iotests/tests/qsd-jobs.out |   8 +-
>>   28 files changed, 776 insertions(+), 809 deletions(-)
>>
>> diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
>> index 82e90fc072..cf5c602286 100644
>> --- a/include/qapi/qmp/qdict.h
>> +++ b/include/qapi/qmp/qdict.h
>> @@ -16,8 +16,7 @@
>>   #include "qapi/qmp/qobject.h"
>>   #include "qemu/queue.h"
>>   
>> -#define QDICT_BUCKET_MAX 512
>> -
>> +#if 0
>>   typedef struct QDictEntry {
>>       char *key;
>>       QObject *value;
>> @@ -29,6 +28,18 @@ struct QDict {
>>       size_t size;
>>       QLIST_HEAD(,QDictEntry) table[QDICT_BUCKET_MAX];
>>   };
>> +#else
>> +typedef struct QDictEntry {
>> +    char *key;
>> +    QObject *value;
>> +    QSIMPLEQ_ENTRY(QDictEntry) next;
>> +} QDictEntry;
>> +
>> +struct QDict {
>> +    struct QObjectBase_ base;
>> +    QSIMPLEQ_HEAD(, QDictEntry) entries;
>> +};
>> +#endif
>>   
>>   void qdict_unref(QDict *q);
>>   
>> diff --git a/qobject/qdict.c b/qobject/qdict.c
>> index 8faff230d3..444608cbc4 100644
>> --- a/qobject/qdict.c
>> +++ b/qobject/qdict.c
>> @@ -29,27 +29,11 @@ QDict *qdict_new(void)
>>   
>>       qdict = g_malloc0(sizeof(*qdict));
>>       qobject_init(QOBJECT(qdict), QTYPE_QDICT);
>> +    QSIMPLEQ_INIT(&qdict->entries);
>>   
>>       return qdict;
>>   }
>>   
>> -/**
>> - * tdb_hash(): based on the hash algorithm from gdbm, via tdb
>> - * (from module-init-tools)
>> - */
>> -static unsigned int tdb_hash(const char *name)
>> -{
>> -    unsigned value;    /* Used to compute the hash value.  */
>> -    unsigned   i;      /* Used to cycle through random values. */
>> -
>> -    /* Set the initial value from the key size. */
>> -    for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++) {
>> -        value = (value + (((const unsigned char *)name)[i] << (i * 5 % 24)));
>> -    }
>> -
>> -    return (1103515243 * value + 12345);
>> -}
>> -
>>   /**
>>    * alloc_entry(): allocate a new QDictEntry
>>    */
>> @@ -88,15 +72,14 @@ const char *qdict_entry_key(const QDictEntry *entry)
>>   /**
>>    * qdict_find(): List lookup function
>>    */
>> -static QDictEntry *qdict_find(const QDict *qdict,
>> -                              const char *key, unsigned int bucket)
>> +static QDictEntry *qdict_find(const QDict *qdict, const char *key)
>>   {
>>       QDictEntry *entry;
>>   
>> -    QLIST_FOREACH(entry, &qdict->table[bucket], next)
>> -        if (!strcmp(entry->key, key)) {
>> +    QSIMPLEQ_FOREACH(entry, &qdict->entries, next) {
>> +        if (!strcmp(key, entry->key))
>>               return entry;
>> -        }
>> +    }
>>   
>>       return NULL;
>>   }
>> @@ -114,11 +97,8 @@ static QDictEntry *qdict_find(const QDict *qdict,
>>    */
>>   void qdict_put_obj(QDict *qdict, const char *key, QObject *value)
>>   {
>> -    unsigned int bucket;
>> -    QDictEntry *entry;
>> +    QDictEntry *entry = qdict_find(qdict, key);
>>   
>> -    bucket = tdb_hash(key) % QDICT_BUCKET_MAX;
>> -    entry = qdict_find(qdict, key, bucket);
>>       if (entry) {
>>           /* replace key's value */
>>           qobject_unref(entry->value);
>> @@ -126,8 +106,7 @@ void qdict_put_obj(QDict *qdict, const char *key, QObject *value)
>>       } else {
>>           /* allocate a new entry */
>>           entry = alloc_entry(key, value);
>> -        QLIST_INSERT_HEAD(&qdict->table[bucket], entry, next);
>> -        qdict->size++;
>> +        QSIMPLEQ_INSERT_TAIL(&qdict->entries, entry, next);
>>       }
>>   }
>>   
>> @@ -161,8 +140,8 @@ QObject *qdict_get(const QDict *qdict, const char *key)
>>   {
>>       QDictEntry *entry;
>>   
>> -    entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX);
>> -    return (entry == NULL ? NULL : entry->value);
>> +    entry = qdict_find(qdict, key);
>> +    return entry ? entry->value : NULL;
>>   }
>>   
>>   /**
>> @@ -172,8 +151,7 @@ QObject *qdict_get(const QDict *qdict, const char *key)
>>    */
>>   int qdict_haskey(const QDict *qdict, const char *key)
>>   {
>> -    unsigned int bucket = tdb_hash(key) % QDICT_BUCKET_MAX;
>> -    return (qdict_find(qdict, key, bucket) == NULL ? 0 : 1);
>> +    return qdict_find(qdict, key) != NULL;
>>   }
>>   
>>   /**
>> @@ -181,7 +159,14 @@ int qdict_haskey(const QDict *qdict, const char *key)
>>    */
>>   size_t qdict_size(const QDict *qdict)
>>   {
>> -    return qdict->size;
>> +    QDictEntry *entry;
>> +    size_t sz = 0;
>> +
>> +    QSIMPLEQ_FOREACH(entry, &qdict->entries, next) {
>> +        sz++;
>> +    }
>> +
>> +    return sz;
>>   }
>>   
>>   /**
>> @@ -301,25 +286,13 @@ const char *qdict_get_try_str(const QDict *qdict, const char *key)
>>       return qstr ? qstring_get_str(qstr) : NULL;
>>   }
>>   
>> -static QDictEntry *qdict_next_entry(const QDict *qdict, int first_bucket)
>> -{
>> -    int i;
>> -
>> -    for (i = first_bucket; i < QDICT_BUCKET_MAX; i++) {
>> -        if (!QLIST_EMPTY(&qdict->table[i])) {
>> -            return QLIST_FIRST(&qdict->table[i]);
>> -        }
>> -    }
>> -
>> -    return NULL;
>> -}
>> -
>>   /**
>>    * qdict_first(): Return first qdict entry for iteration.
>>    */
>>   const QDictEntry *qdict_first(const QDict *qdict)
>>   {
>> -    return qdict_next_entry(qdict, 0);
>> +    return QSIMPLEQ_FIRST(&qdict->entries);
>> +
>>   }
>>   
>>   /**
>> @@ -327,15 +300,7 @@ const QDictEntry *qdict_first(const QDict *qdict)
>>    */
>>   const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry)
>>   {
>> -    QDictEntry *ret;
>> -
>> -    ret = QLIST_NEXT(entry, next);
>> -    if (!ret) {
>> -        unsigned int bucket = tdb_hash(entry->key) % QDICT_BUCKET_MAX;
>> -        ret = qdict_next_entry(qdict, bucket + 1);
>> -    }
>> -
>> -    return ret;
>> +    return QSIMPLEQ_NEXT(entry, next);
>>   }
>>   
>>   /**
>> @@ -346,14 +311,11 @@ QDict *qdict_clone_shallow(const QDict *src)
>>   {
>>       QDict *dest;
>>       QDictEntry *entry;
>> -    int i;
>>   
>>       dest = qdict_new();
>>   
>> -    for (i = 0; i < QDICT_BUCKET_MAX; i++) {
>> -        QLIST_FOREACH(entry, &src->table[i], next) {
>> -            qdict_put_obj(dest, entry->key, qobject_ref(entry->value));
>> -        }
>> +    QSIMPLEQ_FOREACH(entry, &src->entries, next) {
>> +        qdict_put_obj(dest, entry->key, qobject_ref(entry->value));
>>       }
>>   
>>       return dest;
>> @@ -380,13 +342,11 @@ static void qentry_destroy(QDictEntry *e)
>>    */
>>   void qdict_del(QDict *qdict, const char *key)
>>   {
>> -    QDictEntry *entry;
>> +    QDictEntry *entry = qdict_find(qdict, key);
>>   
>> -    entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX);
>>       if (entry) {
>> -        QLIST_REMOVE(entry, next);
>> +        QSIMPLEQ_REMOVE(&qdict->entries, entry, QDictEntry, next);
>>           qentry_destroy(entry);
>> -        qdict->size--;
>>       }
>>   }
>>   
>> @@ -424,20 +384,16 @@ bool qdict_is_equal(const QObject *x, const QObject *y)
>>    */
>>   void qdict_destroy_obj(QObject *obj)
>>   {
>> -    int i;
>>       QDict *qdict;
>>   
>>       assert(obj != NULL);
>>       qdict = qobject_to(QDict, obj);
>>   
>> -    for (i = 0; i < QDICT_BUCKET_MAX; i++) {
>> -        QDictEntry *entry = QLIST_FIRST(&qdict->table[i]);
>> -        while (entry) {
>> -            QDictEntry *tmp = QLIST_NEXT(entry, next);
>> -            QLIST_REMOVE(entry, next);
>> -            qentry_destroy(entry);
>> -            entry = tmp;
>> -        }
>> +    while (!QSIMPLEQ_EMPTY(&qdict->entries)) {
>> +        QDictEntry *entry = QSIMPLEQ_FIRST(&qdict->entries);
>> +
>> +        QSIMPLEQ_REMOVE_HEAD(&qdict->entries, next);
>> +        qentry_destroy(entry);
>>       }
>>   
>>       g_free(qdict);
>> diff --git a/tests/unit/check-qdict.c b/tests/unit/check-qdict.c
>> index b5efa859b0..d7d3df5efb 100644
>> --- a/tests/unit/check-qdict.c
>> +++ b/tests/unit/check-qdict.c
>> @@ -47,7 +47,7 @@ static void qdict_put_obj_test(void)
>>       qdict_put_int(qdict, "", num);
>>   
>>       g_assert(qdict_size(qdict) == 1);
>> -    ent = QLIST_FIRST(&qdict->table[12345 % QDICT_BUCKET_MAX]);
>> +    ent = QSIMPLEQ_FIRST(&qdict->entries);
>>       qn = qobject_to(QNum, ent->value);
>>       g_assert_cmpint(qnum_get_int(qn), ==, num);
>>   
>> diff --git a/tests/unit/check-qobject.c b/tests/unit/check-qobject.c
>> index 022b7c74fe..0416762f80 100644
>> --- a/tests/unit/check-qobject.c
>> +++ b/tests/unit/check-qobject.c
>> @@ -192,10 +192,10 @@ static void qobject_is_equal_dict_test(void)
>>       qdict_put_int(dict_0, "baz", 3);
>>       qdict_put_null(dict_0, "null");
>>   
>> -    qdict_put_int(dict_1, "f.o", 1);
>>       qdict_put_int(dict_1, "bar", 2);
>>       qdict_put_int(dict_1, "baz", 3);
>>       qdict_put_null(dict_1, "null");
>> +    qdict_put_int(dict_1, "f.o", 1);
>>   
>>       qdict_put_int(dict_different_key, "F.o", 1);
>>       qdict_put_int(dict_different_key, "bar", 2);
>> diff --git a/tests/qemu-iotests/043.out b/tests/qemu-iotests/043.out
>> index 63ecb21816..d8fcff24e9 100644
>> --- a/tests/qemu-iotests/043.out
>> +++ b/tests/qemu-iotests/043.out
>> @@ -40,29 +40,29 @@ cluster_size: 65536
>>   == finite chain of length 3 (json) ==
>>   [
>>       {
>> -        "virtual-size": 134217728,
>>           "filename": "TEST_DIR/t.IMGFMT",
>> -        "cluster-size": 65536,
>>           "format": "IMGFMT",
>> -        "full-backing-filename": "TEST_DIR/t.IMGFMT.2.base",
>> +        "dirty-flag": false,
>> +        "virtual-size": 134217728,
>> +        "cluster-size": 65536,
>>           "backing-filename": "TEST_DIR/t.IMGFMT.2.base",
>> -        "dirty-flag": false
>> +        "full-backing-filename": "TEST_DIR/t.IMGFMT.2.base",
>>       },
>>       {
>> -        "virtual-size": 134217728,
>>           "filename": "TEST_DIR/t.IMGFMT.2.base",
>> -        "cluster-size": 65536,
>>           "format": "IMGFMT",
>> -        "full-backing-filename": "TEST_DIR/t.IMGFMT.1.base",
>> +        "dirty-flag": false,
>> +        "virtual-size": 134217728,
>> +        "cluster-size": 65536,
>>           "backing-filename": "TEST_DIR/t.IMGFMT.1.base",
>> -        "dirty-flag": false
>> +        "full-backing-filename": "TEST_DIR/t.IMGFMT.1.base",
>>       },
>>       {
>> -        "virtual-size": 134217728,
>>           "filename": "TEST_DIR/t.IMGFMT.1.base",
>> -        "cluster-size": 65536,
>>           "format": "IMGFMT",
>> -        "dirty-flag": false
>> +        "dirty-flag": false,
>> +        "virtual-size": 134217728,
>> +        "cluster-size": 65536,
>>       }
>>   ]
>>   *** done
>> diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out
>> index 329977d9b9..f654a6579c 100644
>> --- a/tests/qemu-iotests/060.out
>> +++ b/tests/qemu-iotests/060.out
>> @@ -17,11 +17,11 @@ virtual size: 64 MiB (67108864 bytes)
>>   cluster_size: 65536
>>   Format specific information:
>>       compat: 1.1
>> -    compression type: COMPRESSION_TYPE
>> -    lazy refcounts: false
>> -    refcount bits: 16
>> -    corrupt: true
>>       extended l2: false
>> +    lazy refcounts: false
>> +    corrupt: true
>> +    refcount bits: 16
>> +    compression type: COMPRESSION_TYPE
>>   qemu-io: can't open device TEST_DIR/t.IMGFMT: IMGFMT: Image is corrupt; cannot be opened read/write
>>   no file open, try 'help open'
>>   read 512/512 bytes at offset 0
>> @@ -418,11 +418,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
>>   qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with refcount table); further corruption events will be suppressed
>>   QMP_VERSION
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_IMAGE_CORRUPTED", "data": {"device": "none0", "msg": "Preventing invalid write on metadata (overlaps with refcount table)", "offset": 65536, "node-name": "drive", "fatal": true, "size": 65536}}
>> +{"event": "BLOCK_IMAGE_CORRUPTED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"device": "none0", "node-name": "drive", "msg": "Preventing invalid write on metadata (overlaps with refcount table)", "offset": 65536, "size": 65536, "fatal": true}}
>>   write failed: Input/output error
>>   {"return": ""}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
>> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>>   
>>   === Testing incoming inactive corrupted image ===
>>   
>> @@ -430,10 +430,10 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
>>   QMP_VERSION
>>   {"return": {}}
>>   qcow2: Image is corrupt: L2 table offset 0x2a2a2a00 unaligned (L1 index: 0); further non-fatal corruption events will be suppressed
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_IMAGE_CORRUPTED", "data": {"device": "", "msg": "L2 table offset 0x2a2a2a00 unaligned (L1 index: 0)", "node-name": "drive", "fatal": false}}
>> +{"event": "BLOCK_IMAGE_CORRUPTED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"device": "", "node-name": "drive", "msg": "L2 table offset 0x2a2a2a00 unaligned (L1 index: 0)", "fatal": false}}
>>   {"return": ""}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
>> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>>   
>>       corrupt: false
>>   *** done
>> diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
>> index 139fc68177..6a05d67378 100644
>> --- a/tests/qemu-iotests/061.out
>> +++ b/tests/qemu-iotests/061.out
>> @@ -497,7 +497,7 @@ wrote 65536/65536 bytes at offset 2147483648
>>   64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>>   wrote 65536/65536 bytes at offset 3221225472
>>   64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>> -    (0.00/100%)
>>      (12.50/100%)
>>      (25.00/100%)
>>      (37.50/100%)
>>      (50.00/100%)
>>      (62.50/100%)
>>      (75.00/100%)
>>      (87.50/100%)
>>      (100.00/100%)
>>      (100.00/100%)
>> +    (0.00/100%)
>>      (12.50/100%)
>>      (25.00/100%)
>>      (37.50/100%)
>>      (50.00/100%)
>>      (62.50/100%)
>>      (75.00/100%)
>>      (87.50/100%)
>>      (100.00/100%)
>>      (100.00/100%)
>>   No errors were found on the image.
>>   
>>   === Testing progress report with snapshot ===
>> @@ -512,7 +512,7 @@ wrote 65536/65536 bytes at offset 2147483648
>>   64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>>   wrote 65536/65536 bytes at offset 3221225472
>>   64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>> -    (0.00/100%)
>>      (6.25/100%)
>>      (12.50/100%)
>>      (18.75/100%)
>>      (25.00/100%)
>>      (31.25/100%)
>>      (37.50/100%)
>>      (43.75/100%)
>>      (50.00/100%)
>>      (56.25/100%)
>>      (62.50/100%)
>>      (68.75/100%)
>>      (75.00/100%)
>>      (81.25/100%)
>>      (87.50/100%)
>>      (93.75/100%)
>>      (100.00/100%)
>>      (100.00/100%)
>> +    (0.00/100%)
>>      (6.25/100%)
>>      (12.50/100%)
>>      (18.75/100%)
>>      (25.00/100%)
>>      (31.25/100%)
>>      (37.50/100%)
>>      (43.75/100%)
>>      (50.00/100%)
>>      (56.25/100%)
>>      (62.50/100%)
>>      (68.75/100%)
>>      (75.00/100%)
>>      (81.25/100%)
>>      (87.50/100%)
>>      (93.75/100%)
>>      (100.00/100%)
>>      (100.00/100%)
>>   No errors were found on the image.
>>   
>>   === Testing version downgrade with external data file ===
>> @@ -525,13 +525,13 @@ virtual size: 64 MiB (67108864 bytes)
>>   cluster_size: 65536
>>   Format specific information:
>>       compat: 1.1
>> -    compression type: COMPRESSION_TYPE
>> -    lazy refcounts: false
>> -    refcount bits: 16
>>       data file: TEST_DIR/t.IMGFMT.data
>>       data file raw: false
>> -    corrupt: false
>>       extended l2: false
>> +    lazy refcounts: false
>> +    corrupt: false
>> +    refcount bits: 16
>> +    compression type: COMPRESSION_TYPE
>>   No errors were found on the image.
>>   
>>   === Testing version downgrade with extended L2 entries ===
>> @@ -552,13 +552,13 @@ virtual size: 64 MiB (67108864 bytes)
>>   cluster_size: 65536
>>   Format specific information:
>>       compat: 1.1
>> -    compression type: COMPRESSION_TYPE
>> -    lazy refcounts: false
>> -    refcount bits: 16
>>       data file: foo
>>       data file raw: false
>> -    corrupt: false
>>       extended l2: false
>> +    lazy refcounts: false
>> +    corrupt: false
>> +    refcount bits: 16
>> +    compression type: COMPRESSION_TYPE
>>   
>>   qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'data-file' is required for this image
>>   image: TEST_DIR/t.IMGFMT
>> @@ -567,12 +567,12 @@ virtual size: 64 MiB (67108864 bytes)
>>   cluster_size: 65536
>>   Format specific information:
>>       compat: 1.1
>> -    compression type: COMPRESSION_TYPE
>> -    lazy refcounts: false
>> -    refcount bits: 16
>>       data file raw: false
>> -    corrupt: false
>>       extended l2: false
>> +    lazy refcounts: false
>> +    corrupt: false
>> +    refcount bits: 16
>> +    compression type: COMPRESSION_TYPE
>>   
>>   === Clearing and setting data-file-raw ===
>>   
>> @@ -583,13 +583,13 @@ virtual size: 64 MiB (67108864 bytes)
>>   cluster_size: 65536
>>   Format specific information:
>>       compat: 1.1
>> -    compression type: COMPRESSION_TYPE
>> -    lazy refcounts: false
>> -    refcount bits: 16
>>       data file: TEST_DIR/t.IMGFMT.data
>>       data file raw: true
>> -    corrupt: false
>>       extended l2: false
>> +    lazy refcounts: false
>> +    corrupt: false
>> +    refcount bits: 16
>> +    compression type: COMPRESSION_TYPE
>>   No errors were found on the image.
>>   image: TEST_DIR/t.IMGFMT
>>   file format: IMGFMT
>> @@ -597,13 +597,13 @@ virtual size: 64 MiB (67108864 bytes)
>>   cluster_size: 65536
>>   Format specific information:
>>       compat: 1.1
>> -    compression type: COMPRESSION_TYPE
>> -    lazy refcounts: false
>> -    refcount bits: 16
>>       data file: TEST_DIR/t.IMGFMT.data
>>       data file raw: false
>> -    corrupt: false
>>       extended l2: false
>> +    lazy refcounts: false
>> +    corrupt: false
>> +    refcount bits: 16
>> +    compression type: COMPRESSION_TYPE
>>   No errors were found on the image.
>>   qemu-img: data-file-raw cannot be set on existing images
>>   image: TEST_DIR/t.IMGFMT
>> @@ -612,12 +612,12 @@ virtual size: 64 MiB (67108864 bytes)
>>   cluster_size: 65536
>>   Format specific information:
>>       compat: 1.1
>> -    compression type: COMPRESSION_TYPE
>> -    lazy refcounts: false
>> -    refcount bits: 16
>>       data file: TEST_DIR/t.IMGFMT.data
>>       data file raw: false
>> -    corrupt: false
>>       extended l2: false
>> +    lazy refcounts: false
>> +    corrupt: false
>> +    refcount bits: 16
>> +    compression type: COMPRESSION_TYPE
>>   No errors were found on the image.
>>   *** done
>> diff --git a/tests/qemu-iotests/071.out b/tests/qemu-iotests/071.out
>> index bca0c02f5c..ff00da1ad1 100644
>> --- a/tests/qemu-iotests/071.out
>> +++ b/tests/qemu-iotests/071.out
>> @@ -46,7 +46,7 @@ QMP_VERSION
>>   read failed: Input/output error
>>   {"return": ""}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
>> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>>   
>>   
>>   === Testing blkverify on existing block device ===
>> @@ -85,7 +85,7 @@ wrote 512/512 bytes at offset 0
>>   read failed: Input/output error
>>   {"return": ""}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
>> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>>   QEMU_PROG: Failed to flush the L2 table cache: Input/output error
>>   QEMU_PROG: Failed to flush the refcount block cache: Input/output error
>>   
>> diff --git a/tests/qemu-iotests/099.out b/tests/qemu-iotests/099.out
>> index 8cce627529..5726466bc6 100644
>> --- a/tests/qemu-iotests/099.out
>> +++ b/tests/qemu-iotests/099.out
>> @@ -12,11 +12,11 @@ blkverify:TEST_DIR/t.IMGFMT.compare:TEST_DIR/t.IMGFMT
>>   
>>   === Testing JSON filename for blkdebug ===
>>   
>> -json:{"driver": "IMGFMT", "file": {"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "l1_update"}}
>> +json:{"driver": "IMGFMT", "file": {"driver": "blkdebug", "inject-error.0.event": "l1_update", "image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}}}
>>   
>>   === Testing indirectly enforced JSON filename ===
>>   
>> -json:{"driver": "raw", "file": {"test": {"driver": "IMGFMT", "file": {"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "l1_update"}}, "driver": "blkverify", "raw": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.compare"}}}
>> +json:{"driver": "raw", "file": {"driver": "blkverify", "test": {"driver": "IMGFMT", "file": {"driver": "blkdebug", "inject-error.0.event": "l1_update", "image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}}}, "raw": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.compare"}}}
>>   
>>   === Testing plain filename for blkdebug ===
>>   
>> diff --git a/tests/qemu-iotests/108.out b/tests/qemu-iotests/108.out
>> index b5401d788d..faaabbcdf3 100644
>> --- a/tests/qemu-iotests/108.out
>> +++ b/tests/qemu-iotests/108.out
>> @@ -163,18 +163,18 @@ OK: Reftable is where we expect it
>>                  "size": 67108864,
>>                  "cluster-size": 512
>>              } } }
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "create"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "create"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "created"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "running"}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "create"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "create"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "create"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "waiting"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "pending"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "concluded"}}
>>   { "execute": "job-dismiss", "arguments": { "id": "create" } }
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "create"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "null"}}
>>   {"return": {}}
>>   { "execute": "quit" }
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
>> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>>   
>>   wrote 65536/65536 bytes at offset 0
>>   64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>> diff --git a/tests/qemu-iotests/117.out b/tests/qemu-iotests/117.out
>> index 735ffd25c6..015c971197 100644
>> --- a/tests/qemu-iotests/117.out
>> +++ b/tests/qemu-iotests/117.out
>> @@ -19,7 +19,7 @@ wrote 65536/65536 bytes at offset 0
>>   {"return": ""}
>>   { 'execute': 'quit' }
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
>> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>>   No errors were found on the image.
>>   read 65536/65536 bytes at offset 0
>>   64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>> diff --git a/tests/qemu-iotests/120.out b/tests/qemu-iotests/120.out
>> index 0744c1f136..d677c72599 100644
>> --- a/tests/qemu-iotests/120.out
>> +++ b/tests/qemu-iotests/120.out
>> @@ -6,7 +6,7 @@ wrote 65536/65536 bytes at offset 0
>>   64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>>   {"return": ""}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
>> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>>   read 65536/65536 bytes at offset 0
>>   64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>>   read 65536/65536 bytes at offset 0
>> diff --git a/tests/qemu-iotests/127.out b/tests/qemu-iotests/127.out
>> index 1685c4850a..863832d162 100644
>> --- a/tests/qemu-iotests/127.out
>> +++ b/tests/qemu-iotests/127.out
>> @@ -14,20 +14,20 @@ wrote 42/42 bytes at offset 0
>>              'mode':   'existing',
>>              'sync':   'top'
>>          } }
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "mirror"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "mirror"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "created"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "running"}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "mirror"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "mirror", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "ready"}}
>> +{"event": "BLOCK_JOB_READY", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "mirror", "len": 65536, "offset": 65536, "speed": 0}}
>>   { 'execute': 'block-job-complete',
>>          'arguments': { 'device': 'mirror' } }
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "mirror"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "mirror"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "mirror", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "waiting"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "pending"}}
>> +{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "mirror", "len": 65536, "offset": 65536, "speed": 0}}
>>   { 'execute': 'quit' }
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "mirror"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "mirror"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "concluded"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "null"}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
>> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>>   *** done
>> diff --git a/tests/qemu-iotests/140.out b/tests/qemu-iotests/140.out
>> index 312f76d5da..586b64b24e 100644
>> --- a/tests/qemu-iotests/140.out
>> +++ b/tests/qemu-iotests/140.out
>> @@ -15,10 +15,10 @@ read 65536/65536 bytes at offset 0
>>   64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>>   { 'execute': 'eject',
>>          'arguments': { 'device': 'drv' }}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "drv"}}
>> +{"event": "BLOCK_EXPORT_DELETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "drv"}}
>>   qemu-io: can't open device nbd+unix:///drv?socket=SOCK_DIR/nbd: Requested export not available
>>   server reported: export 'drv' not present
>>   { 'execute': 'quit' }
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
>> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>>   *** done
>> diff --git a/tests/qemu-iotests/141.out b/tests/qemu-iotests/141.out
>> index 63203d9944..4d8c7b598c 100644
>> --- a/tests/qemu-iotests/141.out
>> +++ b/tests/qemu-iotests/141.out
>> @@ -23,20 +23,20 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/m.
>>   'format': 'IMGFMT',
>>   'sync': 'none'}}
>>   Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT backing_fmt=IMGFMT
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "paused"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
>>   {'execute': 'blockdev-del',
>>             'arguments': {'node-name': 'drv0'}}
>>   {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: node is used as backing hd of 'NODE_NAME'"}}
>>   {'execute': 'block-job-cancel',
>>             'arguments': {'device': 'job0'}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 0, "speed": 0, "type": "backup"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "aborting"}}
>> +{"event": "BLOCK_JOB_CANCELLED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "backup", "device": "job0", "len": 1048576, "offset": 0, "speed": 0}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>>   {'execute': 'blockdev-del',
>>             'arguments': {'node-name': 'drv0'}}
>>   {"return": {}}
>> @@ -59,21 +59,21 @@ Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
>>   'format': 'IMGFMT',
>>   'sync': 'none'}}
>>   Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT backing_fmt=IMGFMT
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "ready"}}
>> +{"event": "BLOCK_JOB_READY", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "job0", "len": 0, "offset": 0, "speed": 0}}
>>   {'execute': 'blockdev-del',
>>             'arguments': {'node-name': 'drv0'}}
>>   {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: mirror"}}
>>   {'execute': 'block-job-cancel',
>>             'arguments': {'device': 'job0'}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "waiting"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "pending"}}
>> +{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "job0", "len": 0, "offset": 0, "speed": 0}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>>   {'execute': 'blockdev-del',
>>             'arguments': {'node-name': 'drv0'}}
>>   {"return": {}}
>> @@ -91,21 +91,21 @@ Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
>>   {"return": {}}
>>   {'execute': 'block-commit',
>>   'arguments': {'job-id': 'job0', 'device': 'drv0'}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "ready"}}
>> +{"event": "BLOCK_JOB_READY", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "job0", "len": 0, "offset": 0, "speed": 0}}
>>   {'execute': 'blockdev-del',
>>             'arguments': {'node-name': 'drv0'}}
>>   {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: commit"}}
>>   {'execute': 'block-job-cancel',
>>             'arguments': {'device': 'job0'}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "waiting"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "pending"}}
>> +{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "job0", "len": 0, "offset": 0, "speed": 0}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>>   {'execute': 'blockdev-del',
>>             'arguments': {'node-name': 'drv0'}}
>>   {"return": {}}
>> @@ -128,18 +128,18 @@ wrote 1048576/1048576 bytes at offset 0
>>   'device': 'drv0',
>>   'top':    'TEST_DIR/m.IMGFMT',
>>   'speed':  1}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
>>   {'execute': 'blockdev-del',
>>             'arguments': {'node-name': 'drv0'}}
>>   {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: commit"}}
>>   {'execute': 'block-job-cancel',
>>             'arguments': {'device': 'job0'}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, "type": "commit"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "aborting"}}
>> +{"event": "BLOCK_JOB_CANCELLED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "job0", "len": 1048576, "offset": 524288, "speed": 1}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>>   {'execute': 'blockdev-del',
>>             'arguments': {'node-name': 'drv0'}}
>>   {"return": {}}
>> @@ -161,18 +161,18 @@ wrote 1048576/1048576 bytes at offset 0
>>   'arguments': {'job-id': 'job0',
>>   'device': 'drv0',
>>   'speed': 1}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
>>   {'execute': 'blockdev-del',
>>             'arguments': {'node-name': 'drv0'}}
>>   {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: stream"}}
>>   {'execute': 'block-job-cancel',
>>             'arguments': {'device': 'job0'}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, "type": "stream"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "aborting"}}
>> +{"event": "BLOCK_JOB_CANCELLED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "stream", "device": "job0", "len": 1048576, "offset": 524288, "speed": 1}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>>   {'execute': 'blockdev-del',
>>             'arguments': {'node-name': 'drv0'}}
>>   {"return": {}}
>> diff --git a/tests/qemu-iotests/143.out b/tests/qemu-iotests/143.out
>> index 9ec5888e0e..ec58b08e43 100644
>> --- a/tests/qemu-iotests/143.out
>> +++ b/tests/qemu-iotests/143.out
>> @@ -11,5 +11,5 @@ qemu-io: can't open device nbd+unix:///aa--aa1?socket=SOCK_DIR/nbd: Requested ex
>>   server reported: export 'aa--aa...' not present
>>   { 'execute': 'quit' }
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
>> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>>   *** done
>> diff --git a/tests/qemu-iotests/156.out b/tests/qemu-iotests/156.out
>> index 4a22f0c41a..bb01818fc7 100644
>> --- a/tests/qemu-iotests/156.out
>> +++ b/tests/qemu-iotests/156.out
>> @@ -26,11 +26,11 @@ Formatting 'TEST_DIR/t.IMGFMT.target.overlay', fmt=IMGFMT size=1048576 backing_f
>>                         'target': 'TEST_DIR/t.IMGFMT.target.overlay',
>>                         'mode': 'existing',
>>                         'sync': 'top' } }
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "source"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "source"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "created"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "running"}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "source"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "source", "len": 131072, "offset": 131072, "speed": 0, "type": "mirror"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "ready"}}
>> +{"event": "BLOCK_JOB_READY", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "source", "len": 131072, "offset": 131072, "speed": 0}}
>>   { 'execute': 'human-monitor-command',
>>          'arguments': { 'command-line':
>>                         'qemu-io source "write -P 4 192k 64k"' } }
>> @@ -40,11 +40,11 @@ wrote 65536/65536 bytes at offset 196608
>>   { 'execute': 'block-job-complete',
>>          'arguments': { 'device': 'source' } }
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "source"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "source"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "source", "len": 196608, "offset": 196608, "speed": 0, "type": "mirror"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "source"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "source"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "waiting"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "pending"}}
>> +{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "source", "len": 196608, "offset": 196608, "speed": 0}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "concluded"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "null"}}
>>   
>>   { 'execute': 'human-monitor-command',
>>          'arguments': { 'command-line':
>> @@ -73,7 +73,7 @@ read 65536/65536 bytes at offset 196608
>>   
>>   { 'execute': 'quit' }
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
>> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>>   
>>   read 65536/65536 bytes at offset 0
>>   64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>> diff --git a/tests/qemu-iotests/161.out b/tests/qemu-iotests/161.out
>> index 6cc285afcf..c62657639a 100644
>> --- a/tests/qemu-iotests/161.out
>> +++ b/tests/qemu-iotests/161.out
>> @@ -18,17 +18,17 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
>>   {"return": {}}
>>   { 'execute': 'block-stream',        'arguments': { 'device': 'none0',
>>                         'base': 'TEST_DIR/t.IMGFMT.base' } }
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "none0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "none0"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "created"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "running"}}
>>   {"return": {}}
>>   { 'execute': 'human-monitor-command',
>>          'arguments': { 'command-line':
>>                         'qemu-io none0 "reopen -o backing.detect-zeroes=on"' } }
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "none0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "none0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "none0", "len": 1048576, "offset": 1048576, "speed": 0, "type": "stream"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "none0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "none0"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "waiting"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "pending"}}
>> +{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "stream", "device": "none0", "len": 1048576, "offset": 1048576, "speed": 0}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "concluded"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "null"}}
>>   {"return": ""}
>>   
>>   *** Commit and then change an option on the backing file
>> @@ -40,16 +40,16 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
>>   {"return": {}}
>>   { 'execute': 'block-commit',        'arguments': { 'device': 'none0',
>>                         'top': 'TEST_DIR/t.IMGFMT.int' } }
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "none0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "none0"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "created"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "running"}}
>>   {"return": {}}
>>   { 'execute': 'human-monitor-command',
>>          'arguments': { 'command-line':
>>                         'qemu-io none0 "reopen -o backing.detect-zeroes=on"' } }
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "none0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "none0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "none0", "len": 1048576, "offset": 1048576, "speed": 0, "type": "commit"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "none0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "none0"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "waiting"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "pending"}}
>> +{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "none0", "len": 1048576, "offset": 1048576, "speed": 0}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "concluded"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "null"}}
>>   {"return": ""}
>>   *** done
>> diff --git a/tests/qemu-iotests/176.out b/tests/qemu-iotests/176.out
>> index 9d09b60452..b46b743850 100644
>> --- a/tests/qemu-iotests/176.out
>> +++ b/tests/qemu-iotests/176.out
>> @@ -170,7 +170,7 @@ QMP_VERSION
>>   {"return": {}}
>>   {"return": {}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
>> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>>   wrote 196608/196608 bytes at offset 2147287040
>>   192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>>   wrote 131072/131072 bytes at offset 2147352576
>> @@ -207,7 +207,7 @@ QMP_VERSION
>>   {"return": {}}
>>   {"return": {"sha256": HASH}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
>> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>>   
>>   === Test pass bitmap.1 ===
>>   
>> @@ -219,7 +219,7 @@ QMP_VERSION
>>   {"return": {}}
>>   {"return": {}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
>> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>>   wrote 196608/196608 bytes at offset 2147287040
>>   192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>>   wrote 131072/131072 bytes at offset 2147352576
>> @@ -257,7 +257,7 @@ QMP_VERSION
>>   {"return": {}}
>>   {"return": {"sha256": HASH}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
>> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>>   
>>   === Test pass bitmap.2 ===
>>   
>> @@ -269,7 +269,7 @@ QMP_VERSION
>>   {"return": {}}
>>   {"return": {}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
>> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>>   wrote 196608/196608 bytes at offset 2147287040
>>   192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>>   wrote 131072/131072 bytes at offset 2147352576
>> @@ -307,7 +307,7 @@ QMP_VERSION
>>   {"return": {}}
>>   {"return": {"sha256": HASH}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
>> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>>   
>>   === Test pass bitmap.3 ===
>>   
>> @@ -319,7 +319,7 @@ QMP_VERSION
>>   {"return": {}}
>>   {"return": {}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
>> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>>   wrote 196608/196608 bytes at offset 2147287040
>>   192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>>   wrote 131072/131072 bytes at offset 2147352576
>> @@ -354,5 +354,5 @@ QMP_VERSION
>>   {"return": {}}
>>   {"return": {"sha256": HASH}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
>> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>>   *** done
>> diff --git a/tests/qemu-iotests/184.out b/tests/qemu-iotests/184.out
>> index 77e5489d65..93e33ba20a 100644
>> --- a/tests/qemu-iotests/184.out
>> +++ b/tests/qemu-iotests/184.out
>> @@ -24,64 +24,64 @@ Testing:
>>   {
>>       "return": [
>>           {
>> -            "iops_rd": 0,
>> +            "file": "json:{\"driver\": \"throttle\", \"throttle-group\": \"group0\", \"file\": {\"driver\": \"null-co\"}}",
>> +            "node-name": "throttle0",
>> +            "ro": false,
>> +            "drv": "throttle",
>> +            "backing_file_depth": 1,
>> +            "encrypted": false,
>>               "detect_zeroes": "off",
>> +            "bps": 0,
>> +            "bps_rd": 0,
>> +            "bps_wr": 0,
>> +            "iops": 0,
>> +            "iops_rd": 0,
>> +            "iops_wr": 0,
>>               "image": {
>> +                "filename": "json:{\"driver\": \"throttle\", \"throttle-group\": \"group0\", \"file\": {\"driver\": \"null-co\"}}",
>> +                "format": "throttle",
>> +                "actual-size": 0,
>> +                "virtual-size": 1073741824,
>>                   "backing-image": {
>> -                    "virtual-size": 1073741824,
>>                       "filename": "null-co://",
>>                       "format": "null-co",
>> -                    "actual-size": 0
>> -                },
>> -                "virtual-size": 1073741824,
>> -                "filename": "json:{\"throttle-group\": \"group0\", \"driver\": \"throttle\", \"file\": {\"driver\": \"null-co\"}}",
>> -                "format": "throttle",
>> -                "actual-size": 0
>> +                    "actual-size": 0,
>> +                    "virtual-size": 1073741824
>> +                }
>>               },
>> -            "iops_wr": 0,
>> -            "ro": false,
>> -            "node-name": "throttle0",
>> -            "backing_file_depth": 1,
>> -            "drv": "throttle",
>> -            "iops": 0,
>> -            "bps_wr": 0,
>> -            "write_threshold": 0,
>> -            "encrypted": false,
>> -            "bps": 0,
>> -            "bps_rd": 0,
>>               "cache": {
>> -                "no-flush": false,
>> +                "writeback": true,
>>                   "direct": false,
>> -                "writeback": true
>> +                "no-flush": false
>>               },
>> -            "file": "json:{\"throttle-group\": \"group0\", \"driver\": \"throttle\", \"file\": {\"driver\": \"null-co\"}}"
>> +            "write_threshold": 0
>>           },
>>           {
>> -            "iops_rd": 0,
>> -            "detect_zeroes": "off",
>> -            "image": {
>> -                "virtual-size": 1073741824,
>> -                "filename": "null-co://",
>> -                "format": "null-co",
>> -                "actual-size": 0
>> -            },
>> -            "iops_wr": 0,
>> -            "ro": false,
>> +            "file": "null-co://",
>>               "node-name": "disk0",
>> -            "backing_file_depth": 0,
>> +            "ro": false,
>>               "drv": "null-co",
>> -            "iops": 0,
>> -            "bps_wr": 0,
>> -            "write_threshold": 0,
>> +            "backing_file_depth": 0,
>>               "encrypted": false,
>> +            "detect_zeroes": "off",
>>               "bps": 0,
>>               "bps_rd": 0,
>> -            "cache": {
>> -                "no-flush": false,
>> -                "direct": false,
>> -                "writeback": true
>> +            "bps_wr": 0,
>> +            "iops": 0,
>> +            "iops_rd": 0,
>> +            "iops_wr": 0,
>> +            "image": {
>> +                "filename": "null-co://",
>> +                "format": "null-co",
>> +                "actual-size": 0,
>> +                "virtual-size": 1073741824
>>               },
>> -            "file": "null-co://"
>> +            "cache": {
>> +                "writeback": true,
>> +                "direct": false,
>> +                "no-flush": false
>> +            },
>> +            "write_threshold": 0
>>           }
>>       ]
>>   }
>> @@ -94,11 +94,11 @@ Testing:
>>       }
>>   }
>>   {
>> +    "event": "SHUTDOWN",
>>       "timestamp": {
>>           "seconds":  TIMESTAMP,
>>           "microseconds":  TIMESTAMP
>>       },
>> -    "event": "SHUTDOWN",
>>       "data": {
>>           "guest": false,
>>           "reason": "host-qmp-quit"
>> @@ -121,52 +121,25 @@ Testing:
>>   }
>>   {
>>       "return": {
>> -        "bps-read-max-length": 1,
>> -        "iops-read-max-length": 1,
>> -        "bps-read-max": 0,
>> -        "bps-total": 0,
>> -        "iops-total-max-length": 1,
>>           "iops-total": 1000,
>> -        "iops-write-max": 0,
>> -        "bps-write": 0,
>> -        "bps-total-max": 0,
>> -        "bps-write-max": 0,
>> -        "iops-size": 0,
>> -        "iops-read": 0,
>> -        "iops-write-max-length": 1,
>> -        "iops-write": 0,
>> -        "bps-total-max-length": 1,
>> -        "iops-read-max": 0,
>> -        "bps-read": 0,
>> -        "bps-write-max-length": 1,
>> -        "iops-total-max": 0
>> -    }
>> -}
>> -{
>> -    "return": {
>> -    }
>> -}
>> -{
>> -    "return": {
>> -        "bps-read-max-length": 1,
>> -        "iops-read-max-length": 1,
>> -        "bps-read-max": 0,
>> -        "bps-total": 0,
>> +        "iops-total-max": 0,
>>           "iops-total-max-length": 1,
>> -        "iops-total": 0,
>> -        "iops-write-max": 0,
>> -        "bps-write": 0,
>> -        "bps-total-max": 0,
>> -        "bps-write-max": 0,
>> -        "iops-size": 0,
>>           "iops-read": 0,
>> -        "iops-write-max-length": 1,
>> -        "iops-write": 0,
>> -        "bps-total-max-length": 1,
>>           "iops-read-max": 0,
>> +        "iops-read-max-length": 1,
>> +        "iops-write": 0,
>> +        "iops-write-max": 0,
>> +        "iops-write-max-length": 1,
>> +        "bps-total": 0,
>> +        "bps-total-max": 0,
>> +        "bps-total-max-length": 1,
>>           "bps-read": 0,
>> +        "bps-read-max": 0,
>> +        "bps-read-max-length": 1,
>> +        "bps-write": 0,
>> +        "bps-write-max": 0,
>>           "bps-write-max-length": 1,
>> -        "iops-total-max": 0
>> +        "iops-size": 0
>>       }
>>   }
>>   {
>> @@ -174,11 +147,38 @@ Testing:
>>       }
>>   }
>>   {
>> +    "return": {
>> +        "iops-total": 0,
>> +        "iops-total-max": 0,
>> +        "iops-total-max-length": 1,
>> +        "iops-read": 0,
>> +        "iops-read-max": 0,
>> +        "iops-read-max-length": 1,
>> +        "iops-write": 0,
>> +        "iops-write-max": 0,
>> +        "iops-write-max-length": 1,
>> +        "bps-total": 0,
>> +        "bps-total-max": 0,
>> +        "bps-total-max-length": 1,
>> +        "bps-read": 0,
>> +        "bps-read-max": 0,
>> +        "bps-read-max-length": 1,
>> +        "bps-write": 0,
>> +        "bps-write-max": 0,
>> +        "bps-write-max-length": 1,
>> +        "iops-size": 0
>> +    }
>> +}
>> +{
>> +    "return": {
>> +    }
>> +}
>> +{
>> +    "event": "SHUTDOWN",
>>       "timestamp": {
>>           "seconds":  TIMESTAMP,
>>           "microseconds":  TIMESTAMP
>>       },
>> -    "event": "SHUTDOWN",
>>       "data": {
>>           "guest": false,
>>           "reason": "host-qmp-quit"
>> @@ -216,11 +216,11 @@ Testing:
>>       }
>>   }
>>   {
>> +    "event": "SHUTDOWN",
>>       "timestamp": {
>>           "seconds":  TIMESTAMP,
>>           "microseconds":  TIMESTAMP
>>       },
>> -    "event": "SHUTDOWN",
>>       "data": {
>>           "guest": false,
>>           "reason": "host-qmp-quit"
>> @@ -252,11 +252,11 @@ Testing:
>>       }
>>   }
>>   {
>> +    "event": "SHUTDOWN",
>>       "timestamp": {
>>           "seconds":  TIMESTAMP,
>>           "microseconds":  TIMESTAMP
>>       },
>> -    "event": "SHUTDOWN",
>>       "data": {
>>           "guest": false,
>>           "reason": "host-qmp-quit"
>> diff --git a/tests/qemu-iotests/186.out b/tests/qemu-iotests/186.out
>> index 01530040e5..12ea630222 100644
>> --- a/tests/qemu-iotests/186.out
>> +++ b/tests/qemu-iotests/186.out
>> @@ -57,7 +57,7 @@ qdev_id: [not inserted]
>>   Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device ide-hd,drive=null
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>>       Attached to:      /machine/peripheral-anon/device[N]
>>       Cache mode:       writeback
>>   (qemu) quit
>> @@ -65,7 +65,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>>   Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device ide-hd,drive=null,id=qdev_id
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>>       Attached to:      qdev_id
>>       Cache mode:       writeback
>>   (qemu) quit
>> @@ -73,7 +73,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>>   Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device scsi-hd,drive=null
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>>       Attached to:      /machine/peripheral-anon/device[N]
>>       Cache mode:       writeback
>>   (qemu) quit
>> @@ -81,7 +81,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>>   Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device scsi-hd,drive=null,id=qdev_id
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>>       Attached to:      qdev_id
>>       Cache mode:       writeback
>>   (qemu) quit
>> @@ -89,7 +89,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>>   Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device virtio-blk-pci,drive=null
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>>       Attached to:      /machine/peripheral-anon/device[N]/virtio-backend
>>       Cache mode:       writeback
>>   (qemu) quit
>> @@ -97,7 +97,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>>   Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device virtio-blk-pci,drive=null,id=qdev_id
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>>       Attached to:      /machine/peripheral/qdev_id/virtio-backend
>>       Cache mode:       writeback
>>   (qemu) quit
>> @@ -105,7 +105,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>>   Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device floppy,drive=null
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>>       Attached to:      /machine/peripheral-anon/device[N]
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>> @@ -114,7 +114,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>>   Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device floppy,drive=null,id=qdev_id
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>>       Attached to:      qdev_id
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>> @@ -123,7 +123,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>>   Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device ide-cd,drive=null
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>>       Attached to:      /machine/peripheral-anon/device[N]
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>> @@ -132,7 +132,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>>   Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device ide-cd,drive=null,id=qdev_id
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>>       Attached to:      qdev_id
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>> @@ -141,7 +141,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>>   Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device scsi-cd,drive=null
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>>       Attached to:      /machine/peripheral-anon/device[N]
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>> @@ -150,7 +150,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>>   Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device scsi-cd,drive=null,id=qdev_id
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>>       Attached to:      qdev_id
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>> @@ -162,11 +162,11 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>>   Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-hd,drive=null,id=qdev_id
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>>   
>> -null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Attached to:      qdev_id
>>       Cache mode:       writeback
>>   (qemu) quit
>> @@ -174,11 +174,11 @@ null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>>   Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-hd,drive=null,id=qdev_id
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>>   
>> -null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Attached to:      qdev_id
>>       Cache mode:       writeback
>>   (qemu) quit
>> @@ -186,11 +186,11 @@ null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>>   Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device virtio-blk-pci,drive=null,id=qdev_id
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>>   
>> -null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Attached to:      /machine/peripheral/qdev_id/virtio-backend
>>       Cache mode:       writeback
>>   (qemu) quit
>> @@ -198,11 +198,11 @@ null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>>   Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device floppy,drive=null,id=qdev_id
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>>   
>> -null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Attached to:      qdev_id
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>> @@ -211,11 +211,11 @@ null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>>   Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-cd,drive=null,id=qdev_id
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>>   
>> -null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Attached to:      qdev_id
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>> @@ -224,11 +224,11 @@ null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>>   Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-cd,drive=null,id=qdev_id
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>>   
>> -null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Attached to:      qdev_id
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>> @@ -240,7 +240,7 @@ null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>>   Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-hd,drive=none0
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Attached to:      /machine/peripheral-anon/device[N]
>>       Cache mode:       writeback
>>   (qemu) quit
>> @@ -248,7 +248,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>>   Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-hd,drive=none0,id=qdev_id
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Attached to:      qdev_id
>>       Cache mode:       writeback
>>   (qemu) quit
>> @@ -256,7 +256,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>>   Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-hd,drive=none0
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Attached to:      /machine/peripheral-anon/device[N]
>>       Cache mode:       writeback
>>   (qemu) quit
>> @@ -264,7 +264,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>>   Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-hd,drive=none0,id=qdev_id
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Attached to:      qdev_id
>>       Cache mode:       writeback
>>   (qemu) quit
>> @@ -272,7 +272,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>>   Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device virtio-blk-pci,drive=none0
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Attached to:      /machine/peripheral-anon/device[N]/virtio-backend
>>       Cache mode:       writeback
>>   (qemu) quit
>> @@ -280,7 +280,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>>   Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device virtio-blk-pci,drive=none0,id=qdev_id
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Attached to:      /machine/peripheral/qdev_id/virtio-backend
>>       Cache mode:       writeback
>>   (qemu) quit
>> @@ -288,7 +288,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>>   Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device floppy,drive=none0
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Attached to:      /machine/peripheral-anon/device[N]
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>> @@ -297,7 +297,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>>   Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device floppy,drive=none0,id=qdev_id
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Attached to:      qdev_id
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>> @@ -306,7 +306,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>>   Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-cd,drive=none0
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Attached to:      /machine/peripheral-anon/device[N]
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>> @@ -315,7 +315,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>>   Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-cd,drive=none0,id=qdev_id
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Attached to:      qdev_id
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>> @@ -324,7 +324,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>>   Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-cd,drive=none0
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Attached to:      /machine/peripheral-anon/device[N]
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>> @@ -333,7 +333,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>>   Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-cd,drive=none0,id=qdev_id
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Attached to:      qdev_id
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>> @@ -411,7 +411,7 @@ floppy0: [not inserted]
>>   Testing: -drive if=floppy,driver=null-co,read-zeroes=on
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -floppy0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +floppy0 (NODE_NAME): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Attached to:      /machine/unattached/device[N]
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>> @@ -420,7 +420,7 @@ floppy0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>>   Testing: -drive if=ide,driver=null-co,read-zeroes=on
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -ide0-hd0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +ide0-hd0 (NODE_NAME): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Attached to:      /machine/unattached/device[N]
>>       Cache mode:       writeback
>>   (qemu) quit
>> @@ -436,7 +436,7 @@ ide0-cd0: [not inserted]
>>   Testing: -drive if=ide,driver=null-co,read-zeroes=on,media=cdrom
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -ide0-cd0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co, read-only)
>> +ide0-cd0 (NODE_NAME): json:{"driver": "null-co", "read-zeroes": "on"} (null-co, read-only)
>>       Attached to:      /machine/unattached/device[N]
>>       Removable device: not locked, tray closed
>>       Cache mode:       writeback
>> @@ -445,7 +445,7 @@ ide0-cd0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co,
>>   Testing: -drive if=virtio,driver=null-co,read-zeroes=on
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -virtio0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>> +virtio0 (NODE_NAME): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>>       Attached to:      /machine/peripheral-anon/device[N]/virtio-backend
>>       Cache mode:       writeback
>>   (qemu) quit
>> @@ -453,7 +453,7 @@ virtio0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>>   Testing: -drive if=pflash,driver=null-co,read-zeroes=on,size=1M
>>   QEMU X.Y.Z monitor - type 'help' for more information
>>   (qemu) info block
>> -pflash0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co", "size": "1M"} (null-co)
>> +pflash0 (NODE_NAME): json:{"driver": "null-co", "size": "1M", "read-zeroes": "on"} (null-co)
>>       Attached to:      /machine/system.flash0
>>       Cache mode:       writeback
>>   (qemu) quit
>> diff --git a/tests/qemu-iotests/190.out b/tests/qemu-iotests/190.out
>> index ed9d8214eb..2acea9982c 100644
>> --- a/tests/qemu-iotests/190.out
>> +++ b/tests/qemu-iotests/190.out
>> @@ -29,8 +29,8 @@ bitmaps size: 537198592
>>   
>>   expected bitmap 545259520
>>   {
>> -    "bitmaps": 545259520,
>>       "required": 18874368,
>> -    "fully-allocated": 2199042129920
>> +    "fully-allocated": 2199042129920,
>> +    "bitmaps": 545259520
>>   }
>>   *** done
>> diff --git a/tests/qemu-iotests/191.out b/tests/qemu-iotests/191.out
>> index ea88777374..a7dfb22080 100644
>> --- a/tests/qemu-iotests/191.out
>> +++ b/tests/qemu-iotests/191.out
>> @@ -22,25 +22,25 @@ wrote 65536/65536 bytes at offset 1048576
>>                         'base':'TEST_DIR/t.IMGFMT.base',
>>                         'top': 'TEST_DIR/t.IMGFMT.mid' } }
>>   {
>> +    "event": "JOB_STATUS_CHANGE",
>>       "timestamp": {
>>           "seconds":  TIMESTAMP,
>>           "microseconds":  TIMESTAMP
>>       },
>> -    "event": "JOB_STATUS_CHANGE",
>>       "data": {
>> -        "status": "created",
>> -        "id": "commit0"
>> +        "id": "commit0",
>> +        "status": "created"
>>       }
>>   }
>>   {
>> +    "event": "JOB_STATUS_CHANGE",
>>       "timestamp": {
>>           "seconds":  TIMESTAMP,
>>           "microseconds":  TIMESTAMP
>>       },
>> -    "event": "JOB_STATUS_CHANGE",
>>       "data": {
>> -        "status": "running",
>> -        "id": "commit0"
>> +        "id": "commit0",
>> +        "status": "running"
>>       }
>>   }
>>   {
>> @@ -48,61 +48,61 @@ wrote 65536/65536 bytes at offset 1048576
>>       }
>>   }
>>   {
>> +    "event": "JOB_STATUS_CHANGE",
>>       "timestamp": {
>>           "seconds":  TIMESTAMP,
>>           "microseconds":  TIMESTAMP
>>       },
>> -    "event": "JOB_STATUS_CHANGE",
>>       "data": {
>> -        "status": "waiting",
>> -        "id": "commit0"
>> +        "id": "commit0",
>> +        "status": "waiting"
>>       }
>>   }
>>   {
>> +    "event": "JOB_STATUS_CHANGE",
>>       "timestamp": {
>>           "seconds":  TIMESTAMP,
>>           "microseconds":  TIMESTAMP
>>       },
>> -    "event": "JOB_STATUS_CHANGE",
>>       "data": {
>> -        "status": "pending",
>> -        "id": "commit0"
>> +        "id": "commit0",
>> +        "status": "pending"
>>       }
>>   }
>>   {
>> -    "timestamp": {
>> -        "seconds":  TIMESTAMP,
>> -        "microseconds":  TIMESTAMP
>> -    },
>>       "event": "BLOCK_JOB_COMPLETED",
>> +    "timestamp": {
>> +        "seconds":  TIMESTAMP,
>> +        "microseconds":  TIMESTAMP
>> +    },
>>       "data": {
>> +        "type": "commit",
>>           "device": "commit0",
>>           "len": 67108864,
>>           "offset": 67108864,
>> -        "speed": 0,
>> -        "type": "commit"
>> +        "speed": 0
>>       }
>>   }
>>   {
>> +    "event": "JOB_STATUS_CHANGE",
>>       "timestamp": {
>>           "seconds":  TIMESTAMP,
>>           "microseconds":  TIMESTAMP
>>       },
>> -    "event": "JOB_STATUS_CHANGE",
>>       "data": {
>> -        "status": "concluded",
>> -        "id": "commit0"
>> +        "id": "commit0",
>> +        "status": "concluded"
>>       }
>>   }
>>   {
>> +    "event": "JOB_STATUS_CHANGE",
>>       "timestamp": {
>>           "seconds":  TIMESTAMP,
>>           "microseconds":  TIMESTAMP
>>       },
>> -    "event": "JOB_STATUS_CHANGE",
>>       "data": {
>> -        "status": "null",
>> -        "id": "commit0"
>> +        "id": "commit0",
>> +        "status": "null"
>>       }
>>   }
>>   
>> @@ -112,268 +112,268 @@ wrote 65536/65536 bytes at offset 1048576
>>   {
>>       "return": [
>>           {
>> -            "iops_rd": 0,
>> -            "detect_zeroes": "off",
>> -            "image": {
>> -                "backing-image": {
>> -                    "virtual-size": 67108864,
>> -                    "filename": "TEST_DIR/t.IMGFMT.base",
>> -                    "cluster-size": 65536,
>> -                    "format": "IMGFMT",
>> -                    "actual-size": SIZE,
>> -                    "dirty-flag": false
>> -                },
>> -                "backing-filename-format": "IMGFMT",
>> -                "virtual-size": 67108864,
>> -                "filename": "TEST_DIR/t.IMGFMT.ovl2",
>> -                "cluster-size": 65536,
>> -                "format": "IMGFMT",
>> -                "actual-size": SIZE,
>> -                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
>> -                "backing-filename": "TEST_DIR/t.IMGFMT.base",
>> -                "dirty-flag": false
>> -            },
>> -            "iops_wr": 0,
>> -            "ro": false,
>> +            "file": "TEST_DIR/t.IMGFMT.ovl2",
>>               "node-name": "top2",
>> -            "backing_file_depth": 1,
>> +            "ro": false,
>>               "drv": "IMGFMT",
>> -            "iops": 0,
>> -            "bps_wr": 0,
>> -            "write_threshold": 0,
>>               "backing_file": "TEST_DIR/t.IMGFMT.base",
>> +            "backing_file_depth": 1,
>>               "encrypted": false,
>> +            "detect_zeroes": "off",
>>               "bps": 0,
>>               "bps_rd": 0,
>> -            "cache": {
>> -                "no-flush": false,
>> -                "direct": false,
>> -                "writeback": true
>> +            "bps_wr": 0,
>> +            "iops": 0,
>> +            "iops_rd": 0,
>> +            "iops_wr": 0,
>> +            "image": {
>> +                "filename": "TEST_DIR/t.IMGFMT.ovl2",
>> +                "format": "IMGFMT",
>> +                "dirty-flag": false,
>> +                "actual-size": SIZE,
>> +                "virtual-size": 67108864,
>> +                "cluster-size": 65536,
>> +                "backing-filename": "TEST_DIR/t.IMGFMT.base",
>> +                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
>> +                "backing-filename-format": "IMGFMT",
>> +                "backing-image": {
>> +                    "filename": "TEST_DIR/t.IMGFMT.base",
>> +                    "format": "IMGFMT",
>> +                    "dirty-flag": false,
>> +                    "actual-size": SIZE,
>> +                    "virtual-size": 67108864,
>> +                    "cluster-size": 65536,
>> +                },
>>               },
>> -            "file": "TEST_DIR/t.IMGFMT.ovl2"
>> +            "cache": {
>> +                "writeback": true,
>> +                "direct": false,
>> +                "no-flush": false
>> +            },
>> +            "write_threshold": 0
>>           },
>>           {
>> -            "iops_rd": 0,
>> +            "file": "TEST_DIR/t.IMGFMT.ovl2",
>> +            "node-name": "NODE_NAME",
>> +            "ro": false,
>> +            "drv": "file",
>> +            "backing_file_depth": 0,
>> +            "encrypted": false,
>>               "detect_zeroes": "off",
>> +            "bps": 0,
>> +            "bps_rd": 0,
>> +            "bps_wr": 0,
>> +            "iops": 0,
>> +            "iops_rd": 0,
>> +            "iops_wr": 0,
>>               "image": {
>> -                "virtual-size": 197120,
>>                   "filename": "TEST_DIR/t.IMGFMT.ovl2",
>>                   "format": "file",
>> +                "dirty-flag": false,
>>                   "actual-size": SIZE,
>> -                "dirty-flag": false
>> +                "virtual-size": 197120
>>               },
>> -            "iops_wr": 0,
>> -            "ro": false,
>> -            "node-name": "NODE_NAME",
>> -            "backing_file_depth": 0,
>> -            "drv": "file",
>> -            "iops": 0,
>> -            "bps_wr": 0,
>> -            "write_threshold": 0,
>> -            "encrypted": false,
>> -            "bps": 0,
>> -            "bps_rd": 0,
>>               "cache": {
>> -                "no-flush": false,
>> +                "writeback": true,
>>                   "direct": false,
>> -                "writeback": true
>> +                "no-flush": false
>>               },
>> -            "file": "TEST_DIR/t.IMGFMT.ovl2"
>> +            "write_threshold": 0
>>           },
>>           {
>> -            "iops_rd": 0,
>> -            "detect_zeroes": "off",
>> -            "image": {
>> -                "backing-image": {
>> -                    "virtual-size": 67108864,
>> -                    "filename": "TEST_DIR/t.IMGFMT.base",
>> -                    "cluster-size": 65536,
>> -                    "format": "IMGFMT",
>> -                    "actual-size": SIZE,
>> -                    "dirty-flag": false
>> -                },
>> -                "backing-filename-format": "IMGFMT",
>> -                "virtual-size": 67108864,
>> -                "filename": "TEST_DIR/t.IMGFMT",
>> -                "cluster-size": 65536,
>> -                "format": "IMGFMT",
>> -                "actual-size": SIZE,
>> -                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
>> -                "backing-filename": "TEST_DIR/t.IMGFMT.base",
>> -                "dirty-flag": false
>> -            },
>> -            "iops_wr": 0,
>> -            "ro": false,
>> +            "file": "TEST_DIR/t.IMGFMT",
>>               "node-name": "top",
>> -            "backing_file_depth": 1,
>> +            "ro": false,
>>               "drv": "IMGFMT",
>> -            "iops": 0,
>> -            "bps_wr": 0,
>> -            "write_threshold": 0,
>>               "backing_file": "TEST_DIR/t.IMGFMT.base",
>> +            "backing_file_depth": 1,
>>               "encrypted": false,
>> +            "detect_zeroes": "off",
>>               "bps": 0,
>>               "bps_rd": 0,
>> -            "cache": {
>> -                "no-flush": false,
>> -                "direct": false,
>> -                "writeback": true
>> +            "bps_wr": 0,
>> +            "iops": 0,
>> +            "iops_rd": 0,
>> +            "iops_wr": 0,
>> +            "image": {
>> +                "filename": "TEST_DIR/t.IMGFMT",
>> +                "format": "IMGFMT",
>> +                "dirty-flag": false,
>> +                "actual-size": SIZE,
>> +                "virtual-size": 67108864,
>> +                "cluster-size": 65536,
>> +                "backing-filename": "TEST_DIR/t.IMGFMT.base",
>> +                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
>> +                "backing-filename-format": "IMGFMT",
>> +                "backing-image": {
>> +                    "filename": "TEST_DIR/t.IMGFMT.base",
>> +                    "format": "IMGFMT",
>> +                    "dirty-flag": false,
>> +                    "actual-size": SIZE,
>> +                    "virtual-size": 67108864,
>> +                    "cluster-size": 65536,
>> +                },
>>               },
>> -            "file": "TEST_DIR/t.IMGFMT"
>> +            "cache": {
>> +                "writeback": true,
>> +                "direct": false,
>> +                "no-flush": false
>> +            },
>> +            "write_threshold": 0
>>           },
>>           {
>> -            "iops_rd": 0,
>> +            "file": "TEST_DIR/t.IMGFMT",
>> +            "node-name": "NODE_NAME",
>> +            "ro": false,
>> +            "drv": "file",
>> +            "backing_file_depth": 0,
>> +            "encrypted": false,
>>               "detect_zeroes": "off",
>> +            "bps": 0,
>> +            "bps_rd": 0,
>> +            "bps_wr": 0,
>> +            "iops": 0,
>> +            "iops_rd": 0,
>> +            "iops_wr": 0,
>>               "image": {
>> -                "virtual-size": 197120,
>>                   "filename": "TEST_DIR/t.IMGFMT",
>>                   "format": "file",
>> +                "dirty-flag": false,
>>                   "actual-size": SIZE,
>> -                "dirty-flag": false
>> +                "virtual-size": 197120
>>               },
>> -            "iops_wr": 0,
>> -            "ro": false,
>> -            "node-name": "NODE_NAME",
>> -            "backing_file_depth": 0,
>> -            "drv": "file",
>> -            "iops": 0,
>> -            "bps_wr": 0,
>> -            "write_threshold": 0,
>> -            "encrypted": false,
>> -            "bps": 0,
>> -            "bps_rd": 0,
>>               "cache": {
>> -                "no-flush": false,
>> +                "writeback": true,
>>                   "direct": false,
>> -                "writeback": true
>> +                "no-flush": false
>>               },
>> -            "file": "TEST_DIR/t.IMGFMT"
>> +            "write_threshold": 0
>>           },
>>           {
>> -            "iops_rd": 0,
>> -            "detect_zeroes": "off",
>> -            "image": {
>> -                "backing-image": {
>> -                    "virtual-size": 67108864,
>> -                    "filename": "TEST_DIR/t.IMGFMT.base",
>> -                    "cluster-size": 65536,
>> -                    "format": "IMGFMT",
>> -                    "actual-size": SIZE,
>> -                    "dirty-flag": false
>> -                },
>> -                "backing-filename-format": "IMGFMT",
>> -                "virtual-size": 67108864,
>> -                "filename": "TEST_DIR/t.IMGFMT.mid",
>> -                "cluster-size": 65536,
>> -                "format": "IMGFMT",
>> -                "actual-size": SIZE,
>> -                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
>> -                "backing-filename": "TEST_DIR/t.IMGFMT.base",
>> -                "dirty-flag": false
>> -            },
>> -            "iops_wr": 0,
>> -            "ro": false,
>> +            "file": "TEST_DIR/t.IMGFMT.mid",
>>               "node-name": "mid",
>> -            "backing_file_depth": 1,
>> +            "ro": false,
>>               "drv": "IMGFMT",
>> -            "iops": 0,
>> -            "bps_wr": 0,
>> -            "write_threshold": 0,
>>               "backing_file": "TEST_DIR/t.IMGFMT.base",
>> +            "backing_file_depth": 1,
>>               "encrypted": false,
>> +            "detect_zeroes": "off",
>>               "bps": 0,
>>               "bps_rd": 0,
>> -            "cache": {
>> -                "no-flush": false,
>> -                "direct": false,
>> -                "writeback": true
>> +            "bps_wr": 0,
>> +            "iops": 0,
>> +            "iops_rd": 0,
>> +            "iops_wr": 0,
>> +            "image": {
>> +                "filename": "TEST_DIR/t.IMGFMT.mid",
>> +                "format": "IMGFMT",
>> +                "dirty-flag": false,
>> +                "actual-size": SIZE,
>> +                "virtual-size": 67108864,
>> +                "cluster-size": 65536,
>> +                "backing-filename": "TEST_DIR/t.IMGFMT.base",
>> +                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
>> +                "backing-filename-format": "IMGFMT",
>> +                "backing-image": {
>> +                    "filename": "TEST_DIR/t.IMGFMT.base",
>> +                    "format": "IMGFMT",
>> +                    "dirty-flag": false,
>> +                    "actual-size": SIZE,
>> +                    "virtual-size": 67108864,
>> +                    "cluster-size": 65536,
>> +                },
>>               },
>> -            "file": "TEST_DIR/t.IMGFMT.mid"
>> +            "cache": {
>> +                "writeback": true,
>> +                "direct": false,
>> +                "no-flush": false
>> +            },
>> +            "write_threshold": 0
>>           },
>>           {
>> -            "iops_rd": 0,
>> +            "file": "TEST_DIR/t.IMGFMT.mid",
>> +            "node-name": "NODE_NAME",
>> +            "ro": false,
>> +            "drv": "file",
>> +            "backing_file_depth": 0,
>> +            "encrypted": false,
>>               "detect_zeroes": "off",
>> +            "bps": 0,
>> +            "bps_rd": 0,
>> +            "bps_wr": 0,
>> +            "iops": 0,
>> +            "iops_rd": 0,
>> +            "iops_wr": 0,
>>               "image": {
>> -                "virtual-size": 393216,
>>                   "filename": "TEST_DIR/t.IMGFMT.mid",
>>                   "format": "file",
>> +                "dirty-flag": false,
>>                   "actual-size": SIZE,
>> -                "dirty-flag": false
>> +                "virtual-size": 393216
>>               },
>> -            "iops_wr": 0,
>> -            "ro": false,
>> -            "node-name": "NODE_NAME",
>> -            "backing_file_depth": 0,
>> -            "drv": "file",
>> -            "iops": 0,
>> -            "bps_wr": 0,
>> -            "write_threshold": 0,
>> -            "encrypted": false,
>> -            "bps": 0,
>> -            "bps_rd": 0,
>>               "cache": {
>> -                "no-flush": false,
>> +                "writeback": true,
>>                   "direct": false,
>> -                "writeback": true
>> +                "no-flush": false
>>               },
>> -            "file": "TEST_DIR/t.IMGFMT.mid"
>> +            "write_threshold": 0
>>           },
>>           {
>> -            "iops_rd": 0,
>> -            "detect_zeroes": "off",
>> -            "image": {
>> -                "virtual-size": 67108864,
>> -                "filename": "TEST_DIR/t.IMGFMT.base",
>> -                "cluster-size": 65536,
>> -                "format": "IMGFMT",
>> -                "actual-size": SIZE,
>> -                "dirty-flag": false
>> -            },
>> -            "iops_wr": 0,
>> -            "ro": false,
>> +            "file": "TEST_DIR/t.IMGFMT.base",
>>               "node-name": "base",
>> -            "backing_file_depth": 0,
>> +            "ro": false,
>>               "drv": "IMGFMT",
>> -            "iops": 0,
>> -            "bps_wr": 0,
>> -            "write_threshold": 0,
>> +            "backing_file_depth": 0,
>>               "encrypted": false,
>> +            "detect_zeroes": "off",
>>               "bps": 0,
>>               "bps_rd": 0,
>> -            "cache": {
>> -                "no-flush": false,
>> -                "direct": false,
>> -                "writeback": true
>> +            "bps_wr": 0,
>> +            "iops": 0,
>> +            "iops_rd": 0,
>> +            "iops_wr": 0,
>> +            "image": {
>> +                "filename": "TEST_DIR/t.IMGFMT.base",
>> +                "format": "IMGFMT",
>> +                "dirty-flag": false,
>> +                "actual-size": SIZE,
>> +                "virtual-size": 67108864,
>> +                "cluster-size": 65536,
>>               },
>> -            "file": "TEST_DIR/t.IMGFMT.base"
>> +            "cache": {
>> +                "writeback": true,
>> +                "direct": false,
>> +                "no-flush": false
>> +            },
>> +            "write_threshold": 0
>>           },
>>           {
>> -            "iops_rd": 0,
>> +            "file": "TEST_DIR/t.IMGFMT.base",
>> +            "node-name": "NODE_NAME",
>> +            "ro": false,
>> +            "drv": "file",
>> +            "backing_file_depth": 0,
>> +            "encrypted": false,
>>               "detect_zeroes": "off",
>> +            "bps": 0,
>> +            "bps_rd": 0,
>> +            "bps_wr": 0,
>> +            "iops": 0,
>> +            "iops_rd": 0,
>> +            "iops_wr": 0,
>>               "image": {
>> -                "virtual-size": 393216,
>>                   "filename": "TEST_DIR/t.IMGFMT.base",
>>                   "format": "file",
>> +                "dirty-flag": false,
>>                   "actual-size": SIZE,
>> -                "dirty-flag": false
>> +                "virtual-size": 393216
>>               },
>> -            "iops_wr": 0,
>> -            "ro": false,
>> -            "node-name": "NODE_NAME",
>> -            "backing_file_depth": 0,
>> -            "drv": "file",
>> -            "iops": 0,
>> -            "bps_wr": 0,
>> -            "write_threshold": 0,
>> -            "encrypted": false,
>> -            "bps": 0,
>> -            "bps_rd": 0,
>>               "cache": {
>> -                "no-flush": false,
>> +                "writeback": true,
>>                   "direct": false,
>> -                "writeback": true
>> +                "no-flush": false
>>               },
>> -            "file": "TEST_DIR/t.IMGFMT.base"
>> +            "write_threshold": 0
>>           }
>>       ]
>>   }
>> @@ -383,11 +383,11 @@ wrote 65536/65536 bytes at offset 1048576
>>       }
>>   }
>>   {
>> +    "event": "SHUTDOWN",
>>       "timestamp": {
>>           "seconds":  TIMESTAMP,
>>           "microseconds":  TIMESTAMP
>>       },
>> -    "event": "SHUTDOWN",
>>       "data": {
>>           "guest": false,
>>           "reason": "host-qmp-quit"
>> @@ -429,25 +429,25 @@ wrote 65536/65536 bytes at offset 1048576
>>                         'base':'TEST_DIR/t.IMGFMT.base',
>>                         'top': 'TEST_DIR/t.IMGFMT.mid' } }
>>   {
>> +    "event": "JOB_STATUS_CHANGE",
>>       "timestamp": {
>>           "seconds":  TIMESTAMP,
>>           "microseconds":  TIMESTAMP
>>       },
>> -    "event": "JOB_STATUS_CHANGE",
>>       "data": {
>> -        "status": "created",
>> -        "id": "commit0"
>> +        "id": "commit0",
>> +        "status": "created"
>>       }
>>   }
>>   {
>> +    "event": "JOB_STATUS_CHANGE",
>>       "timestamp": {
>>           "seconds":  TIMESTAMP,
>>           "microseconds":  TIMESTAMP
>>       },
>> -    "event": "JOB_STATUS_CHANGE",
>>       "data": {
>> -        "status": "running",
>> -        "id": "commit0"
>> +        "id": "commit0",
>> +        "status": "running"
>>       }
>>   }
>>   {
>> @@ -455,61 +455,61 @@ wrote 65536/65536 bytes at offset 1048576
>>       }
>>   }
>>   {
>> +    "event": "JOB_STATUS_CHANGE",
>>       "timestamp": {
>>           "seconds":  TIMESTAMP,
>>           "microseconds":  TIMESTAMP
>>       },
>> -    "event": "JOB_STATUS_CHANGE",
>>       "data": {
>> -        "status": "waiting",
>> -        "id": "commit0"
>> +        "id": "commit0",
>> +        "status": "waiting"
>>       }
>>   }
>>   {
>> +    "event": "JOB_STATUS_CHANGE",
>>       "timestamp": {
>>           "seconds":  TIMESTAMP,
>>           "microseconds":  TIMESTAMP
>>       },
>> -    "event": "JOB_STATUS_CHANGE",
>>       "data": {
>> -        "status": "pending",
>> -        "id": "commit0"
>> +        "id": "commit0",
>> +        "status": "pending"
>>       }
>>   }
>>   {
>> -    "timestamp": {
>> -        "seconds":  TIMESTAMP,
>> -        "microseconds":  TIMESTAMP
>> -    },
>>       "event": "BLOCK_JOB_COMPLETED",
>> +    "timestamp": {
>> +        "seconds":  TIMESTAMP,
>> +        "microseconds":  TIMESTAMP
>> +    },
>>       "data": {
>> +        "type": "commit",
>>           "device": "commit0",
>>           "len": 67108864,
>>           "offset": 67108864,
>> -        "speed": 0,
>> -        "type": "commit"
>> +        "speed": 0
>>       }
>>   }
>>   {
>> +    "event": "JOB_STATUS_CHANGE",
>>       "timestamp": {
>>           "seconds":  TIMESTAMP,
>>           "microseconds":  TIMESTAMP
>>       },
>> -    "event": "JOB_STATUS_CHANGE",
>>       "data": {
>> -        "status": "concluded",
>> -        "id": "commit0"
>> +        "id": "commit0",
>> +        "status": "concluded"
>>       }
>>   }
>>   {
>> +    "event": "JOB_STATUS_CHANGE",
>>       "timestamp": {
>>           "seconds":  TIMESTAMP,
>>           "microseconds":  TIMESTAMP
>>       },
>> -    "event": "JOB_STATUS_CHANGE",
>>       "data": {
>> -        "status": "null",
>> -        "id": "commit0"
>> +        "id": "commit0",
>> +        "status": "null"
>>       }
>>   }
>>   
>> @@ -519,279 +519,279 @@ wrote 65536/65536 bytes at offset 1048576
>>   {
>>       "return": [
>>           {
>> -            "iops_rd": 0,
>> -            "detect_zeroes": "off",
>> -            "image": {
>> -                "backing-image": {
>> -                    "virtual-size": 67108864,
>> -                    "filename": "TEST_DIR/t.IMGFMT.base",
>> -                    "cluster-size": 65536,
>> -                    "format": "IMGFMT",
>> -                    "actual-size": SIZE,
>> -                    "dirty-flag": false
>> -                },
>> -                "backing-filename-format": "IMGFMT",
>> -                "virtual-size": 67108864,
>> -                "filename": "TEST_DIR/t.IMGFMT.ovl2",
>> -                "cluster-size": 65536,
>> -                "format": "IMGFMT",
>> -                "actual-size": SIZE,
>> -                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
>> -                "backing-filename": "TEST_DIR/t.IMGFMT.base",
>> -                "dirty-flag": false
>> -            },
>> -            "iops_wr": 0,
>> -            "ro": true,
>> +            "file": "TEST_DIR/t.IMGFMT.ovl2",
>>               "node-name": "NODE_NAME",
>> -            "backing_file_depth": 1,
>> +            "ro": true,
>>               "drv": "IMGFMT",
>> -            "iops": 0,
>> -            "bps_wr": 0,
>> -            "write_threshold": 0,
>>               "backing_file": "TEST_DIR/t.IMGFMT.base",
>> +            "backing_file_depth": 1,
>>               "encrypted": false,
>> +            "detect_zeroes": "off",
>>               "bps": 0,
>>               "bps_rd": 0,
>> -            "cache": {
>> -                "no-flush": false,
>> -                "direct": false,
>> -                "writeback": true
>> +            "bps_wr": 0,
>> +            "iops": 0,
>> +            "iops_rd": 0,
>> +            "iops_wr": 0,
>> +            "image": {
>> +                "filename": "TEST_DIR/t.IMGFMT.ovl2",
>> +                "format": "IMGFMT",
>> +                "dirty-flag": false,
>> +                "actual-size": SIZE,
>> +                "virtual-size": 67108864,
>> +                "cluster-size": 65536,
>> +                "backing-filename": "TEST_DIR/t.IMGFMT.base",
>> +                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
>> +                "backing-filename-format": "IMGFMT",
>> +                "backing-image": {
>> +                    "filename": "TEST_DIR/t.IMGFMT.base",
>> +                    "format": "IMGFMT",
>> +                    "dirty-flag": false,
>> +                    "actual-size": SIZE,
>> +                    "virtual-size": 67108864,
>> +                    "cluster-size": 65536,
>> +                },
>>               },
>> -            "file": "TEST_DIR/t.IMGFMT.ovl2"
>> +            "cache": {
>> +                "writeback": true,
>> +                "direct": false,
>> +                "no-flush": false
>> +            },
>> +            "write_threshold": 0
>>           },
>>           {
>> -            "iops_rd": 0,
>> +            "file": "TEST_DIR/t.IMGFMT.ovl2",
>> +            "node-name": "NODE_NAME",
>> +            "ro": true,
>> +            "drv": "file",
>> +            "backing_file_depth": 0,
>> +            "encrypted": false,
>>               "detect_zeroes": "off",
>> +            "bps": 0,
>> +            "bps_rd": 0,
>> +            "bps_wr": 0,
>> +            "iops": 0,
>> +            "iops_rd": 0,
>> +            "iops_wr": 0,
>>               "image": {
>> -                "virtual-size": 197120,
>>                   "filename": "TEST_DIR/t.IMGFMT.ovl2",
>>                   "format": "file",
>> +                "dirty-flag": false,
>>                   "actual-size": SIZE,
>> -                "dirty-flag": false
>> +                "virtual-size": 197120
>>               },
>> -            "iops_wr": 0,
>> -            "ro": true,
>> -            "node-name": "NODE_NAME",
>> -            "backing_file_depth": 0,
>> -            "drv": "file",
>> -            "iops": 0,
>> -            "bps_wr": 0,
>> -            "write_threshold": 0,
>> -            "encrypted": false,
>> -            "bps": 0,
>> -            "bps_rd": 0,
>>               "cache": {
>> -                "no-flush": false,
>> +                "writeback": true,
>>                   "direct": false,
>> -                "writeback": true
>> +                "no-flush": false
>>               },
>> -            "file": "TEST_DIR/t.IMGFMT.ovl2"
>> +            "write_threshold": 0
>>           },
>>           {
>> -            "iops_rd": 0,
>> -            "detect_zeroes": "off",
>> -            "image": {
>> -                "backing-image": {
>> -                    "backing-image": {
>> -                        "virtual-size": 67108864,
>> -                        "filename": "TEST_DIR/t.IMGFMT.base",
>> -                        "cluster-size": 65536,
>> -                        "format": "IMGFMT",
>> -                        "actual-size": SIZE,
>> -                        "dirty-flag": false
>> -                    },
>> -                    "backing-filename-format": "IMGFMT",
>> -                    "virtual-size": 67108864,
>> -                    "filename": "TEST_DIR/t.IMGFMT.ovl2",
>> -                    "cluster-size": 65536,
>> -                    "format": "IMGFMT",
>> -                    "actual-size": SIZE,
>> -                    "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
>> -                    "backing-filename": "TEST_DIR/t.IMGFMT.base",
>> -                    "dirty-flag": false
>> -                },
>> -                "backing-filename-format": "IMGFMT",
>> -                "virtual-size": 67108864,
>> -                "filename": "TEST_DIR/t.IMGFMT.ovl3",
>> -                "cluster-size": 65536,
>> -                "format": "IMGFMT",
>> -                "actual-size": SIZE,
>> -                "full-backing-filename": "TEST_DIR/t.IMGFMT.ovl2",
>> -                "backing-filename": "TEST_DIR/t.IMGFMT.ovl2",
>> -                "dirty-flag": false
>> -            },
>> -            "iops_wr": 0,
>> -            "ro": false,
>> +            "file": "TEST_DIR/t.IMGFMT.ovl3",
>>               "node-name": "top2",
>> -            "backing_file_depth": 2,
>> +            "ro": false,
>>               "drv": "IMGFMT",
>> -            "iops": 0,
>> -            "bps_wr": 0,
>> -            "write_threshold": 0,
>>               "backing_file": "TEST_DIR/t.IMGFMT.ovl2",
>> +            "backing_file_depth": 2,
>>               "encrypted": false,
>> +            "detect_zeroes": "off",
>>               "bps": 0,
>>               "bps_rd": 0,
>> -            "cache": {
>> -                "no-flush": false,
>> -                "direct": false,
>> -                "writeback": true
>> +            "bps_wr": 0,
>> +            "iops": 0,
>> +            "iops_rd": 0,
>> +            "iops_wr": 0,
>> +            "image": {
>> +                "filename": "TEST_DIR/t.IMGFMT.ovl3",
>> +                "format": "IMGFMT",
>> +                "dirty-flag": false,
>> +                "actual-size": SIZE,
>> +                "virtual-size": 67108864,
>> +                "cluster-size": 65536,
>> +                "backing-filename": "TEST_DIR/t.IMGFMT.ovl2",
>> +                "full-backing-filename": "TEST_DIR/t.IMGFMT.ovl2",
>> +                "backing-filename-format": "IMGFMT",
>> +                "backing-image": {
>> +                    "filename": "TEST_DIR/t.IMGFMT.ovl2",
>> +                    "format": "IMGFMT",
>> +                    "dirty-flag": false,
>> +                    "actual-size": SIZE,
>> +                    "virtual-size": 67108864,
>> +                    "cluster-size": 65536,
>> +                    "backing-filename": "TEST_DIR/t.IMGFMT.base",
>> +                    "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
>> +                    "backing-filename-format": "IMGFMT",
>> +                    "backing-image": {
>> +                        "filename": "TEST_DIR/t.IMGFMT.base",
>> +                        "format": "IMGFMT",
>> +                        "dirty-flag": false,
>> +                        "actual-size": SIZE,
>> +                        "virtual-size": 67108864,
>> +                        "cluster-size": 65536,
>> +                    },
>> +                },
>>               },
>> -            "file": "TEST_DIR/t.IMGFMT.ovl3"
>> +            "cache": {
>> +                "writeback": true,
>> +                "direct": false,
>> +                "no-flush": false
>> +            },
>> +            "write_threshold": 0
>>           },
>>           {
>> -            "iops_rd": 0,
>> +            "file": "TEST_DIR/t.IMGFMT.ovl3",
>> +            "node-name": "NODE_NAME",
>> +            "ro": false,
>> +            "drv": "file",
>> +            "backing_file_depth": 0,
>> +            "encrypted": false,
>>               "detect_zeroes": "off",
>> +            "bps": 0,
>> +            "bps_rd": 0,
>> +            "bps_wr": 0,
>> +            "iops": 0,
>> +            "iops_rd": 0,
>> +            "iops_wr": 0,
>>               "image": {
>> -                "virtual-size": 197120,
>>                   "filename": "TEST_DIR/t.IMGFMT.ovl3",
>>                   "format": "file",
>> +                "dirty-flag": false,
>>                   "actual-size": SIZE,
>> -                "dirty-flag": false
>> +                "virtual-size": 197120
>>               },
>> -            "iops_wr": 0,
>> -            "ro": false,
>> -            "node-name": "NODE_NAME",
>> -            "backing_file_depth": 0,
>> -            "drv": "file",
>> -            "iops": 0,
>> -            "bps_wr": 0,
>> -            "write_threshold": 0,
>> -            "encrypted": false,
>> -            "bps": 0,
>> -            "bps_rd": 0,
>>               "cache": {
>> -                "no-flush": false,
>> +                "writeback": true,
>>                   "direct": false,
>> -                "writeback": true
>> +                "no-flush": false
>>               },
>> -            "file": "TEST_DIR/t.IMGFMT.ovl3"
>> +            "write_threshold": 0
>>           },
>>           {
>> -            "iops_rd": 0,
>> -            "detect_zeroes": "off",
>> -            "image": {
>> -                "virtual-size": 67108864,
>> -                "filename": "TEST_DIR/t.IMGFMT.base",
>> -                "cluster-size": 65536,
>> -                "format": "IMGFMT",
>> -                "actual-size": SIZE,
>> -                "dirty-flag": false
>> -            },
>> -            "iops_wr": 0,
>> +            "file": "TEST_DIR/t.IMGFMT.base",
>> +            "node-name": "NODE_NAME",
>>               "ro": true,
>> -            "node-name": "NODE_NAME",
>> -            "backing_file_depth": 0,
>>               "drv": "IMGFMT",
>> -            "iops": 0,
>> -            "bps_wr": 0,
>> -            "write_threshold": 0,
>> +            "backing_file_depth": 0,
>>               "encrypted": false,
>> +            "detect_zeroes": "off",
>>               "bps": 0,
>>               "bps_rd": 0,
>> -            "cache": {
>> -                "no-flush": false,
>> -                "direct": false,
>> -                "writeback": true
>> +            "bps_wr": 0,
>> +            "iops": 0,
>> +            "iops_rd": 0,
>> +            "iops_wr": 0,
>> +            "image": {
>> +                "filename": "TEST_DIR/t.IMGFMT.base",
>> +                "format": "IMGFMT",
>> +                "dirty-flag": false,
>> +                "actual-size": SIZE,
>> +                "virtual-size": 67108864,
>> +                "cluster-size": 65536,
>>               },
>> -            "file": "TEST_DIR/t.IMGFMT.base"
>> +            "cache": {
>> +                "writeback": true,
>> +                "direct": false,
>> +                "no-flush": false
>> +            },
>> +            "write_threshold": 0
>>           },
>>           {
>> -            "iops_rd": 0,
>> +            "file": "TEST_DIR/t.IMGFMT.base",
>> +            "node-name": "NODE_NAME",
>> +            "ro": true,
>> +            "drv": "file",
>> +            "backing_file_depth": 0,
>> +            "encrypted": false,
>>               "detect_zeroes": "off",
>> +            "bps": 0,
>> +            "bps_rd": 0,
>> +            "bps_wr": 0,
>> +            "iops": 0,
>> +            "iops_rd": 0,
>> +            "iops_wr": 0,
>>               "image": {
>> -                "virtual-size": 393216,
>>                   "filename": "TEST_DIR/t.IMGFMT.base",
>>                   "format": "file",
>> +                "dirty-flag": false,
>>                   "actual-size": SIZE,
>> -                "dirty-flag": false
>> +                "virtual-size": 393216
>>               },
>> -            "iops_wr": 0,
>> -            "ro": true,
>> -            "node-name": "NODE_NAME",
>> -            "backing_file_depth": 0,
>> -            "drv": "file",
>> -            "iops": 0,
>> -            "bps_wr": 0,
>> -            "write_threshold": 0,
>> -            "encrypted": false,
>> -            "bps": 0,
>> -            "bps_rd": 0,
>>               "cache": {
>> -                "no-flush": false,
>> +                "writeback": true,
>>                   "direct": false,
>> -                "writeback": true
>> +                "no-flush": false
>>               },
>> -            "file": "TEST_DIR/t.IMGFMT.base"
>> +            "write_threshold": 0
>>           },
>>           {
>> -            "iops_rd": 0,
>> -            "detect_zeroes": "off",
>> -            "image": {
>> -                "backing-image": {
>> -                    "virtual-size": 67108864,
>> -                    "filename": "TEST_DIR/t.IMGFMT.base",
>> -                    "cluster-size": 65536,
>> -                    "format": "IMGFMT",
>> -                    "actual-size": SIZE,
>> -                    "dirty-flag": false
>> -                },
>> -                "backing-filename-format": "IMGFMT",
>> -                "virtual-size": 67108864,
>> -                "filename": "TEST_DIR/t.IMGFMT",
>> -                "cluster-size": 65536,
>> -                "format": "IMGFMT",
>> -                "actual-size": SIZE,
>> -                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
>> -                "backing-filename": "TEST_DIR/t.IMGFMT.base",
>> -                "dirty-flag": false
>> -            },
>> -            "iops_wr": 0,
>> -            "ro": false,
>> +            "file": "TEST_DIR/t.IMGFMT",
>>               "node-name": "top",
>> -            "backing_file_depth": 1,
>> +            "ro": false,
>>               "drv": "IMGFMT",
>> -            "iops": 0,
>> -            "bps_wr": 0,
>> -            "write_threshold": 0,
>>               "backing_file": "TEST_DIR/t.IMGFMT.base",
>> +            "backing_file_depth": 1,
>>               "encrypted": false,
>> +            "detect_zeroes": "off",
>>               "bps": 0,
>>               "bps_rd": 0,
>> -            "cache": {
>> -                "no-flush": false,
>> -                "direct": false,
>> -                "writeback": true
>> +            "bps_wr": 0,
>> +            "iops": 0,
>> +            "iops_rd": 0,
>> +            "iops_wr": 0,
>> +            "image": {
>> +                "filename": "TEST_DIR/t.IMGFMT",
>> +                "format": "IMGFMT",
>> +                "dirty-flag": false,
>> +                "actual-size": SIZE,
>> +                "virtual-size": 67108864,
>> +                "cluster-size": 65536,
>> +                "backing-filename": "TEST_DIR/t.IMGFMT.base",
>> +                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
>> +                "backing-filename-format": "IMGFMT",
>> +                "backing-image": {
>> +                    "filename": "TEST_DIR/t.IMGFMT.base",
>> +                    "format": "IMGFMT",
>> +                    "dirty-flag": false,
>> +                    "actual-size": SIZE,
>> +                    "virtual-size": 67108864,
>> +                    "cluster-size": 65536,
>> +                },
>>               },
>> -            "file": "TEST_DIR/t.IMGFMT"
>> +            "cache": {
>> +                "writeback": true,
>> +                "direct": false,
>> +                "no-flush": false
>> +            },
>> +            "write_threshold": 0
>>           },
>>           {
>> -            "iops_rd": 0,
>> -            "detect_zeroes": "off",
>> -            "image": {
>> -                "virtual-size": 197120,
>> -                "filename": "TEST_DIR/t.IMGFMT",
>> -                "format": "file",
>> -                "actual-size": SIZE,
>> -                "dirty-flag": false
>> -            },
>> -            "iops_wr": 0,
>> -            "ro": false,
>> +            "file": "TEST_DIR/t.IMGFMT",
>>               "node-name": "NODE_NAME",
>> -            "backing_file_depth": 0,
>> +            "ro": false,
>>               "drv": "file",
>> -            "iops": 0,
>> -            "bps_wr": 0,
>> -            "write_threshold": 0,
>> +            "backing_file_depth": 0,
>>               "encrypted": false,
>> +            "detect_zeroes": "off",
>>               "bps": 0,
>>               "bps_rd": 0,
>> -            "cache": {
>> -                "no-flush": false,
>> -                "direct": false,
>> -                "writeback": true
>> +            "bps_wr": 0,
>> +            "iops": 0,
>> +            "iops_rd": 0,
>> +            "iops_wr": 0,
>> +            "image": {
>> +                "filename": "TEST_DIR/t.IMGFMT",
>> +                "format": "file",
>> +                "dirty-flag": false,
>> +                "actual-size": SIZE,
>> +                "virtual-size": 197120
>>               },
>> -            "file": "TEST_DIR/t.IMGFMT"
>> +            "cache": {
>> +                "writeback": true,
>> +                "direct": false,
>> +                "no-flush": false
>> +            },
>> +            "write_threshold": 0
>>           }
>>       ]
>>   }
>> @@ -801,11 +801,11 @@ wrote 65536/65536 bytes at offset 1048576
>>       }
>>   }
>>   {
>> +    "event": "SHUTDOWN",
>>       "timestamp": {
>>           "seconds":  TIMESTAMP,
>>           "microseconds":  TIMESTAMP
>>       },
>> -    "event": "SHUTDOWN",
>>       "data": {
>>           "guest": false,
>>           "reason": "host-qmp-quit"
>> diff --git a/tests/qemu-iotests/195.out b/tests/qemu-iotests/195.out
>> index ec84df5012..485d7a1115 100644
>> --- a/tests/qemu-iotests/195.out
>> +++ b/tests/qemu-iotests/195.out
>> @@ -22,11 +22,11 @@ Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,backing.node-name=mid
>>       }
>>   }
>>   {
>> +    "event": "SHUTDOWN",
>>       "timestamp": {
>>           "seconds":  TIMESTAMP,
>>           "microseconds":  TIMESTAMP
>>       },
>> -    "event": "SHUTDOWN",
>>       "data": {
>>           "guest": false,
>>           "reason": "host-qmp-quit"
>> @@ -60,11 +60,11 @@ Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,node-name=top
>>       }
>>   }
>>   {
>> +    "event": "SHUTDOWN",
>>       "timestamp": {
>>           "seconds":  TIMESTAMP,
>>           "microseconds":  TIMESTAMP
>>       },
>> -    "event": "SHUTDOWN",
>>       "data": {
>>           "guest": false,
>>           "reason": "host-qmp-quit"
>> diff --git a/tests/qemu-iotests/229.out b/tests/qemu-iotests/229.out
>> index 7d2bfbfbe6..3f4391df6e 100644
>> --- a/tests/qemu-iotests/229.out
>> +++ b/tests/qemu-iotests/229.out
>> @@ -16,19 +16,19 @@ wrote 2097152/2097152 bytes at offset 0
>>                                  'mode':   'existing',
>>                                  'on-source-error': 'stop',
>>                                  'on-target-error': 'stop' }}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "testdisk"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "testdisk", "status": "created"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "testdisk", "status": "running"}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "testdisk", "operation": "write", "action": "stop"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "testdisk"}}
>> +{"event": "BLOCK_JOB_ERROR", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"device": "testdisk", "operation": "write", "action": "stop"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "testdisk", "status": "paused"}}
>>   
>>   === Force cancel job paused in error state  ===
>>   
>>   {'execute': 'block-job-cancel',
>>                    'arguments': { 'device': 'testdisk',
>>                                   'force': true}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "testdisk", "status": "running"}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "testdisk"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "testdisk", "len": 2097152, "offset": OFFSET, "speed": 0, "type": "mirror"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "testdisk", "status": "aborting"}}
>> +{"event": "BLOCK_JOB_CANCELLED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "testdisk", "len": 2097152, "offset": OFFSET, "speed": 0}}
>>   *** done
>> diff --git a/tests/qemu-iotests/244.out b/tests/qemu-iotests/244.out
>> index 5e03add054..57cffee1ea 100644
>> --- a/tests/qemu-iotests/244.out
>> +++ b/tests/qemu-iotests/244.out
>> @@ -156,14 +156,14 @@ wrote 1048576/1048576 bytes at offset 0
>>                  "data-file": "data",
>>                  "data-file-raw": true
>>              } } }
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "create"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "create"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "created"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "running"}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "create"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "create"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "create"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "waiting"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "pending"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "concluded"}}
>>   { "execute": "job-dismiss", "arguments": { "id": "create" } }
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "create"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "null"}}
>>   {"return": {}}
>>   
>>   Comparing pattern:
>> diff --git a/tests/qemu-iotests/249.out b/tests/qemu-iotests/249.out
>> index d2bf9be85e..a1a1a1b851 100644
>> --- a/tests/qemu-iotests/249.out
>> +++ b/tests/qemu-iotests/249.out
>> @@ -16,8 +16,8 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
>>   { 'execute': 'block-commit',
>>          'arguments': {'job-id': 'job0', 'device': 'none1', 'top-node': 'int',
>>                        'filter-node-name': '1234'}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>>   {"error": {"class": "GenericError", "desc": "Invalid node-name: '1234'"}}
>>   
>>   === Send a write command to a drive opened in read-only mode (2)
>> @@ -30,14 +30,14 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
>>   
>>   { 'execute': 'block-commit',
>>          'arguments': {'job-id': 'job0', 'device': 'none1', 'top-node': 'int'}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 1048576, "offset": 1048576, "speed": 0, "type": "commit"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "waiting"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "pending"}}
>> +{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "job0", "len": 1048576, "offset": 1048576, "speed": 0}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>>   
>>   === Send a write command to a drive opened in read-only mode (3)
>>   
>> diff --git a/tests/qemu-iotests/tests/qsd-jobs.out b/tests/qemu-iotests/tests/qsd-jobs.out
>> index c1bc9b8356..336a5c3946 100644
>> --- a/tests/qemu-iotests/tests/qsd-jobs.out
>> +++ b/tests/qemu-iotests/tests/qsd-jobs.out
>> @@ -8,15 +8,15 @@ QMP_VERSION
>>   {"return": {}}
>>   {"return": {}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
>> +{"event": "BLOCK_JOB_CANCELLED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "job0", "len": 0, "offset": 0, "speed": 0}}
>>   
>>   === Streaming can't get permission on base node ===
>>   
>>   QMP_VERSION
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
>> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>>   {"error": {"class": "GenericError", "desc": "Permission conflict on node 'fmt_base': permissions 'write' are both required by an unnamed block device (uses node 'fmt_base' as 'root' child) and unshared by stream job 'job0' (uses node 'fmt_base' as 'intermediate node' child)."}}
>>   {"return": {}}
>> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export1"}}
>> +{"event": "BLOCK_EXPORT_DELETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "export1"}}
>>   *** done


ATB,

Mark.
Peter Maydell July 7, 2022, 12:57 p.m. UTC | #3
On Tue, 5 Jul 2022 at 10:54, Markus Armbruster <armbru@redhat.com> wrote:
>
> QDict is implemented as a simple hash table of fixed size.  Observe:
>
> * Slow for large n.  Not sure this matters.
>
> * A QDict with n entries takes 4120 + n * 32 bytes on my box.  Wastes
>   space for small n, which is a common case.
>
> * Order of traversal depends on the hash function and on insertion
>   order, because it iterates first over buckets, then collision
>   chains.
>
> * Special code ensures qdict_size() takes constant time.
>
> Replace the hash table by a linked list.  Observe:
>
> * Even slower for large n.  Might be bad enough to matter.
>
> * A QDict with n entries takes 32 + n * 24 bytes.
>
> * Traversal is in insertion order.
>
> * qdict_size() is linear in the number of entries.
>
> This is an experiment.  Do not commit to master as is.
>
> The change of traversal order affects expected test output.  I updated
> only the tests covered by "make check" so far.  I expect some more to
> hide under tests/qemu-iotests/.

Seems to fix the 'rocker' device regression, at least in that
it no longer gives an error message on startup.

The amount of patching you had to do to expected-output files
in 'tests' suggests we have quite a lot of test cases that
are currently implicitly reliant on the hash table traversal
order, which is not guaranteed to remain stable. Regardless of
what we do with this patch it would probably be a good idea
for whatever is outputting the text these tests are comparing
against to be made to use a stable output order (alphabetical??).

-- PMM
Markus Armbruster July 7, 2022, 2:27 p.m. UTC | #4
Peter Maydell <peter.maydell@linaro.org> writes:

> On Tue, 5 Jul 2022 at 10:54, Markus Armbruster <armbru@redhat.com> wrote:
>>
>> QDict is implemented as a simple hash table of fixed size.  Observe:
>>
>> * Slow for large n.  Not sure this matters.
>>
>> * A QDict with n entries takes 4120 + n * 32 bytes on my box.  Wastes
>>   space for small n, which is a common case.
>>
>> * Order of traversal depends on the hash function and on insertion
>>   order, because it iterates first over buckets, then collision
>>   chains.
>>
>> * Special code ensures qdict_size() takes constant time.
>>
>> Replace the hash table by a linked list.  Observe:
>>
>> * Even slower for large n.  Might be bad enough to matter.
>>
>> * A QDict with n entries takes 32 + n * 24 bytes.
>>
>> * Traversal is in insertion order.
>>
>> * qdict_size() is linear in the number of entries.
>>
>> This is an experiment.  Do not commit to master as is.
>>
>> The change of traversal order affects expected test output.  I updated
>> only the tests covered by "make check" so far.  I expect some more to
>> hide under tests/qemu-iotests/.
>
> Seems to fix the 'rocker' device regression, at least in that
> it no longer gives an error message on startup.
>
> The amount of patching you had to do to expected-output files
> in 'tests' suggests we have quite a lot of test cases that
> are currently implicitly reliant on the hash table traversal
> order, which is not guaranteed to remain stable.

Correct.

I expect to find a few more in tests not run by "make check".

>                                                  Regardless of
> what we do with this patch it would probably be a good idea
> for whatever is outputting the text these tests are comparing
> against to be made to use a stable output order (alphabetical??).

Traversal order before the patch depends on the (fixed) size of the hash
table and the has function for (string) keys.  Both have remained
unchanged since the initial commit (2009), which is why we've gotten
away with relying on it in tests.

Traversal order after the patch depends on insertion order.  I think
this is already an improvement for the tests: now the expected output
depends on what the test does, not on how qdict.c does its job.

If we think this still isn't good enough, we can investigate how to get
test output where the keys are in alphabetical order.
Daniel P. Berrangé July 7, 2022, 2:43 p.m. UTC | #5
On Tue, Jul 05, 2022 at 11:54:21AM +0200, Markus Armbruster wrote:
> QDict is implemented as a simple hash table of fixed size.  Observe:
> 
> * Slow for large n.  Not sure this matters.
> 
> * A QDict with n entries takes 4120 + n * 32 bytes on my box.  Wastes
>   space for small n, which is a common case.
> 
> * Order of traversal depends on the hash function and on insertion
>   order, because it iterates first over buckets, then collision
>   chains.
> 
> * Special code ensures qdict_size() takes constant time.
> 
> Replace the hash table by a linked list.  Observe:
> 
> * Even slower for large n.  Might be bad enough to matter.
> 
> * A QDict with n entries takes 32 + n * 24 bytes.
> 
> * Traversal is in insertion order.
> 
> * qdict_size() is linear in the number of entries.
> 
> This is an experiment.  Do not commit to master as is.
> 
> The change of traversal order affects expected test output.  I updated
> only the tests covered by "make check" so far.  I expect some more to
> hide under tests/qemu-iotests/.
> 
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  include/qapi/qmp/qdict.h              |  15 +-
>  qobject/qdict.c                       | 104 +--
>  tests/unit/check-qdict.c              |   2 +-
>  tests/unit/check-qobject.c            |   2 +-
>  tests/qemu-iotests/043.out            |  22 +-
>  tests/qemu-iotests/060.out            |  16 +-
>  tests/qemu-iotests/061.out            |  52 +-
>  tests/qemu-iotests/071.out            |   4 +-
>  tests/qemu-iotests/099.out            |   4 +-
>  tests/qemu-iotests/108.out            |  14 +-
>  tests/qemu-iotests/117.out            |   2 +-
>  tests/qemu-iotests/120.out            |   2 +-
>  tests/qemu-iotests/127.out            |  20 +-
>  tests/qemu-iotests/140.out            |   4 +-
>  tests/qemu-iotests/141.out            |  76 +--
>  tests/qemu-iotests/143.out            |   2 +-
>  tests/qemu-iotests/156.out            |  20 +-
>  tests/qemu-iotests/161.out            |  28 +-
>  tests/qemu-iotests/176.out            |  16 +-
>  tests/qemu-iotests/184.out            | 170 ++---
>  tests/qemu-iotests/186.out            |  82 +--
>  tests/qemu-iotests/190.out            |   4 +-
>  tests/qemu-iotests/191.out            | 868 +++++++++++++-------------
>  tests/qemu-iotests/195.out            |   4 +-
>  tests/qemu-iotests/229.out            |  14 +-
>  tests/qemu-iotests/244.out            |  12 +-
>  tests/qemu-iotests/249.out            |  18 +-
>  tests/qemu-iotests/tests/qsd-jobs.out |   8 +-
>  28 files changed, 776 insertions(+), 809 deletions(-)


> diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
> index 139fc68177..6a05d67378 100644
> --- a/tests/qemu-iotests/061.out
> +++ b/tests/qemu-iotests/061.out

>  === Testing version downgrade with external data file ===
> @@ -525,13 +525,13 @@ virtual size: 64 MiB (67108864 bytes)
>  cluster_size: 65536
>  Format specific information:
>      compat: 1.1
> -    compression type: COMPRESSION_TYPE
> -    lazy refcounts: false
> -    refcount bits: 16
>      data file: TEST_DIR/t.IMGFMT.data
>      data file raw: false
> -    corrupt: false
>      extended l2: false
> +    lazy refcounts: false
> +    corrupt: false
> +    refcount bits: 16
> +    compression type: COMPRESSION_TYPE
>  No errors were found on the image.

For this qemu-immg info output, I'd suggest that both the original
and new output orderings are undesirable.

Given it is human targetted, it would be better if this was emitted
in alphabetical order. This ought to be addressed in a separate
stanadlone patch though, since its unrelated to the QDict ordering,
just a pre-existing flaw.


With regards,
Daniel
Daniel P. Berrangé July 7, 2022, 3:07 p.m. UTC | #6
On Thu, Jul 07, 2022 at 04:27:35PM +0200, Markus Armbruster wrote:
> Peter Maydell <peter.maydell@linaro.org> writes:
> 
> > On Tue, 5 Jul 2022 at 10:54, Markus Armbruster <armbru@redhat.com> wrote:
> >>
> >> QDict is implemented as a simple hash table of fixed size.  Observe:
> >>
> >> * Slow for large n.  Not sure this matters.
> >>
> >> * A QDict with n entries takes 4120 + n * 32 bytes on my box.  Wastes
> >>   space for small n, which is a common case.
> >>
> >> * Order of traversal depends on the hash function and on insertion
> >>   order, because it iterates first over buckets, then collision
> >>   chains.
> >>
> >> * Special code ensures qdict_size() takes constant time.
> >>
> >> Replace the hash table by a linked list.  Observe:
> >>
> >> * Even slower for large n.  Might be bad enough to matter.
> >>
> >> * A QDict with n entries takes 32 + n * 24 bytes.
> >>
> >> * Traversal is in insertion order.
> >>
> >> * qdict_size() is linear in the number of entries.
> >>
> >> This is an experiment.  Do not commit to master as is.
> >>
> >> The change of traversal order affects expected test output.  I updated
> >> only the tests covered by "make check" so far.  I expect some more to
> >> hide under tests/qemu-iotests/.
> >
> > Seems to fix the 'rocker' device regression, at least in that
> > it no longer gives an error message on startup.
> >
> > The amount of patching you had to do to expected-output files
> > in 'tests' suggests we have quite a lot of test cases that
> > are currently implicitly reliant on the hash table traversal
> > order, which is not guaranteed to remain stable.
> 
> Correct.
> 
> I expect to find a few more in tests not run by "make check".
> 
> >                                                  Regardless of
> > what we do with this patch it would probably be a good idea
> > for whatever is outputting the text these tests are comparing
> > against to be made to use a stable output order (alphabetical??).
> 
> Traversal order before the patch depends on the (fixed) size of the hash
> table and the has function for (string) keys.  Both have remained
> unchanged since the initial commit (2009), which is why we've gotten
> away with relying on it in tests.

We're lucky to have got away with such a crude hash table impl without
anyone (to our knowledge) identifying a way to abuse it for a denial
of service. For robustness, string key hashing functions really ought
to be non-deterministic between invokations of the program at the very
least, even better if non-deterministic across each hashtable instance.
If hashing is deterministic then a malicious user can sometimes abuse
this to force the hash table performance to degrade from O(log(n)) to
O(n). A fast cryptographic hash function is the gold standard.

See also https://lwn.net/Articles/474912/

I recall we discussed this back in the day when that LWN article came
out and decided QEMU was safe-ish. The believe was that QEMU doesn't
take JSON input from any source that is less trustworthy than itself.
Or when it does, it is already expected that the upper level mgmt
layer will have santised input before passing it to QEMU. eg a qcow2
file can contain JSON backing store, but if an app gets a random disk
image from untrusted source, it must already validate that a backing
store absent or sane, before invoking QEMU (eg to  avoid telling
QEMU to open /dev/shadow as its backing store).

None the less, I would still be more comfortable if we have a robust
non-determinstic hashing function, if we have even the slighest feeling
that that O(1) lookup is important for any part of QEMU's QDict usage.

The QMP communication of course is all betwween QEMU and libvirt, where
QEMU is the untrusted party, so libvirt needs protection aaginst
malicious QEMU, but QEMU trustes libvirt.  QEMU doesn't talk to the
guest agent itself, so ok in that area too, and of course the CLI argv
is trusted.

Particular with the multi-process QEMU work though, and/or vhostuser
backends, etc, we are probably moving to a world where some parts of
QEMU are less trusted than other parts of QEMU. So this kind of thing
may yet become important to some degree.

> Traversal order after the patch depends on insertion order.  I think
> this is already an improvement for the tests: now the expected output
> depends on what the test does, not on how qdict.c does its job.

For machine targetted output it is a saner. For human targetted
output I'd say no significant win.

> If we think this still isn't good enough, we can investigate how to get
> test output where the keys are in alphabetical order.

This essentially comes down to the JSON serializer, which iterates over
the keys when outputting json objects. The serializer could apply sorting
of keys itself based on any criteria it chooses, regardless of what the
QDict impl provides. Probably make JSON serializer marginally less
efficient but not neccessarily the end of the world.

Co-incidentally it'd make libvirt a little happier, as we store the
output of many QMP commands for our test suite, and those output docs
can change wildly as we update them for new QEMU versions / git snapshots


With regards,
Daniel
Daniel P. Berrangé July 7, 2022, 3:37 p.m. UTC | #7
On Tue, Jul 05, 2022 at 11:54:21AM +0200, Markus Armbruster wrote:
> QDict is implemented as a simple hash table of fixed size.  Observe:
> 
> * Slow for large n.  Not sure this matters.

I presume you're referring qdict_find() here, which would
ideally be O(1).

Our bucket size is 512, so for hash tables less than say
2000, it is close enough to O(1) that it likely doesn't
matter (except for our deterministic hash function which
can be abused to overfill specific buckets).

Ignoring the latter attack though, the fixed hash bucket
count isn't likely a speed issue for normal usage as our
QDict element counts are just not that big typically. So
it is mostly a memory wastage issue.


Historically QEMU's JSON input has come from sources that
are more trusted than QEMU itself, so didn't matter. As
we split up QEMU into co-operating processes with potentially
varying privileges, this may cease to be a safe assumption.

For pre-emptive robustness though I'd favour a guaranteed
O(1) impl, which would mean a dynamically resizing bucket
count, along with a non-deterministic (ideally cryptographically
strong) key hash function.

> * A QDict with n entries takes 4120 + n * 32 bytes on my box.  Wastes
>   space for small n, which is a common case.

So effectively 8k usage for every QDict instance at a minimum.
This is not so great with widespread QDict usage.

> * Order of traversal depends on the hash function and on insertion
>   order, because it iterates first over buckets, then collision
>   chains.
> 
> * Special code ensures qdict_size() takes constant time.
> 
> Replace the hash table by a linked list.  Observe:
> 
> * Even slower for large n.  Might be bad enough to matter.

Guaranteed O(n) every time, even for small values of 'n'.
Just feels like a bad idea to me.

> * A QDict with n entries takes 32 + n * 24 bytes.
> 
> * Traversal is in insertion order.
> 
> * qdict_size() is linear in the number of entries.
> 
> This is an experiment.  Do not commit to master as is.

Two alternative ideas.

 * Implement it is both a hashtable and a linked list.
   Hashtable to get O(1) lookup, linked list to get
   stable iteration order based on insertion order.
   Makes the insert/delete operations more expensive,
   and slightly greater memory overhead.

 * Merely change the users to apply the ordering they
   require when iterating.

In both those cases, I'd suggest we consider use of GHashTable, to give
us a more dynamic hash table impl with resizing buckets, so it is more
memory efficient and stronger guarantee of O(1) lookups. It also quite
simple to iterate over the keys in a fixed order, as you can get a GList
of keys, and invoke g_list_sort with any comparator. While we could add
more APIs to do this with QDict and QLIST, re-inventing the wheel feels
dubious unless there's a compelling benefit to our existing impl.


With regards,
Daniel
Alex Bennée July 7, 2022, 3:52 p.m. UTC | #8
Markus Armbruster <armbru@redhat.com> writes:

> QDict is implemented as a simple hash table of fixed size.  Observe:
>
> * Slow for large n.  Not sure this matters.
>
> * A QDict with n entries takes 4120 + n * 32 bytes on my box.  Wastes
>   space for small n, which is a common case.
>
> * Order of traversal depends on the hash function and on insertion
>   order, because it iterates first over buckets, then collision
>   chains.
>
> * Special code ensures qdict_size() takes constant time.
>
> Replace the hash table by a linked list.  Observe:
>
> * Even slower for large n.  Might be bad enough to matter.
>
> * A QDict with n entries takes 32 + n * 24 bytes.
>
> * Traversal is in insertion order.
>
> * qdict_size() is linear in the number of entries.
>
> This is an experiment.  Do not commit to master as is.

Did you consider just using a straight array? What is the usual size of
a QDict - how many entries do you expect to scale to?

> The change of traversal order affects expected test output.  I updated
> only the tests covered by "make check" so far.  I expect some more to
> hide under tests/qemu-iotests/.
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
>  include/qapi/qmp/qdict.h              |  15 +-
>  qobject/qdict.c                       | 104 +--
>  tests/unit/check-qdict.c              |   2 +-
>  tests/unit/check-qobject.c            |   2 +-
>  tests/qemu-iotests/043.out            |  22 +-
>  tests/qemu-iotests/060.out            |  16 +-
>  tests/qemu-iotests/061.out            |  52 +-
>  tests/qemu-iotests/071.out            |   4 +-
>  tests/qemu-iotests/099.out            |   4 +-
>  tests/qemu-iotests/108.out            |  14 +-
>  tests/qemu-iotests/117.out            |   2 +-
>  tests/qemu-iotests/120.out            |   2 +-
>  tests/qemu-iotests/127.out            |  20 +-
>  tests/qemu-iotests/140.out            |   4 +-
>  tests/qemu-iotests/141.out            |  76 +--
>  tests/qemu-iotests/143.out            |   2 +-
>  tests/qemu-iotests/156.out            |  20 +-
>  tests/qemu-iotests/161.out            |  28 +-
>  tests/qemu-iotests/176.out            |  16 +-
>  tests/qemu-iotests/184.out            | 170 ++---
>  tests/qemu-iotests/186.out            |  82 +--
>  tests/qemu-iotests/190.out            |   4 +-
>  tests/qemu-iotests/191.out            | 868 +++++++++++++-------------
>  tests/qemu-iotests/195.out            |   4 +-
>  tests/qemu-iotests/229.out            |  14 +-
>  tests/qemu-iotests/244.out            |  12 +-
>  tests/qemu-iotests/249.out            |  18 +-
>  tests/qemu-iotests/tests/qsd-jobs.out |   8 +-
>  28 files changed, 776 insertions(+), 809 deletions(-)
>
> diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
> index 82e90fc072..cf5c602286 100644
> --- a/include/qapi/qmp/qdict.h
> +++ b/include/qapi/qmp/qdict.h
> @@ -16,8 +16,7 @@
>  #include "qapi/qmp/qobject.h"
>  #include "qemu/queue.h"
>  
> -#define QDICT_BUCKET_MAX 512
> -
> +#if 0
>  typedef struct QDictEntry {
>      char *key;
>      QObject *value;
> @@ -29,6 +28,18 @@ struct QDict {
>      size_t size;
>      QLIST_HEAD(,QDictEntry) table[QDICT_BUCKET_MAX];
>  };
> +#else
> +typedef struct QDictEntry {
> +    char *key;
> +    QObject *value;
> +    QSIMPLEQ_ENTRY(QDictEntry) next;
> +} QDictEntry;
> +
> +struct QDict {
> +    struct QObjectBase_ base;
> +    QSIMPLEQ_HEAD(, QDictEntry) entries;
> +};
> +#endif
>  
>  void qdict_unref(QDict *q);
>  
> diff --git a/qobject/qdict.c b/qobject/qdict.c
> index 8faff230d3..444608cbc4 100644
> --- a/qobject/qdict.c
> +++ b/qobject/qdict.c
> @@ -29,27 +29,11 @@ QDict *qdict_new(void)
>  
>      qdict = g_malloc0(sizeof(*qdict));
>      qobject_init(QOBJECT(qdict), QTYPE_QDICT);
> +    QSIMPLEQ_INIT(&qdict->entries);
>  
>      return qdict;
>  }
>  
> -/**
> - * tdb_hash(): based on the hash algorithm from gdbm, via tdb
> - * (from module-init-tools)
> - */
> -static unsigned int tdb_hash(const char *name)
> -{
> -    unsigned value;    /* Used to compute the hash value.  */
> -    unsigned   i;      /* Used to cycle through random values. */
> -
> -    /* Set the initial value from the key size. */
> -    for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++) {
> -        value = (value + (((const unsigned char *)name)[i] << (i * 5 % 24)));
> -    }
> -
> -    return (1103515243 * value + 12345);
> -}
> -
>  /**
>   * alloc_entry(): allocate a new QDictEntry
>   */
> @@ -88,15 +72,14 @@ const char *qdict_entry_key(const QDictEntry *entry)
>  /**
>   * qdict_find(): List lookup function
>   */
> -static QDictEntry *qdict_find(const QDict *qdict,
> -                              const char *key, unsigned int bucket)
> +static QDictEntry *qdict_find(const QDict *qdict, const char *key)
>  {
>      QDictEntry *entry;
>  
> -    QLIST_FOREACH(entry, &qdict->table[bucket], next)
> -        if (!strcmp(entry->key, key)) {
> +    QSIMPLEQ_FOREACH(entry, &qdict->entries, next) {
> +        if (!strcmp(key, entry->key))
>              return entry;
> -        }
> +    }
>  
>      return NULL;
>  }
> @@ -114,11 +97,8 @@ static QDictEntry *qdict_find(const QDict *qdict,
>   */
>  void qdict_put_obj(QDict *qdict, const char *key, QObject *value)
>  {
> -    unsigned int bucket;
> -    QDictEntry *entry;
> +    QDictEntry *entry = qdict_find(qdict, key);
>  
> -    bucket = tdb_hash(key) % QDICT_BUCKET_MAX;
> -    entry = qdict_find(qdict, key, bucket);
>      if (entry) {
>          /* replace key's value */
>          qobject_unref(entry->value);
> @@ -126,8 +106,7 @@ void qdict_put_obj(QDict *qdict, const char *key, QObject *value)
>      } else {
>          /* allocate a new entry */
>          entry = alloc_entry(key, value);
> -        QLIST_INSERT_HEAD(&qdict->table[bucket], entry, next);
> -        qdict->size++;
> +        QSIMPLEQ_INSERT_TAIL(&qdict->entries, entry, next);
>      }
>  }
>  
> @@ -161,8 +140,8 @@ QObject *qdict_get(const QDict *qdict, const char *key)
>  {
>      QDictEntry *entry;
>  
> -    entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX);
> -    return (entry == NULL ? NULL : entry->value);
> +    entry = qdict_find(qdict, key);
> +    return entry ? entry->value : NULL;
>  }
>  
>  /**
> @@ -172,8 +151,7 @@ QObject *qdict_get(const QDict *qdict, const char *key)
>   */
>  int qdict_haskey(const QDict *qdict, const char *key)
>  {
> -    unsigned int bucket = tdb_hash(key) % QDICT_BUCKET_MAX;
> -    return (qdict_find(qdict, key, bucket) == NULL ? 0 : 1);
> +    return qdict_find(qdict, key) != NULL;
>  }
>  
>  /**
> @@ -181,7 +159,14 @@ int qdict_haskey(const QDict *qdict, const char *key)
>   */
>  size_t qdict_size(const QDict *qdict)
>  {
> -    return qdict->size;
> +    QDictEntry *entry;
> +    size_t sz = 0;
> +
> +    QSIMPLEQ_FOREACH(entry, &qdict->entries, next) {
> +        sz++;
> +    }
> +
> +    return sz;
>  }
>  
>  /**
> @@ -301,25 +286,13 @@ const char *qdict_get_try_str(const QDict *qdict, const char *key)
>      return qstr ? qstring_get_str(qstr) : NULL;
>  }
>  
> -static QDictEntry *qdict_next_entry(const QDict *qdict, int first_bucket)
> -{
> -    int i;
> -
> -    for (i = first_bucket; i < QDICT_BUCKET_MAX; i++) {
> -        if (!QLIST_EMPTY(&qdict->table[i])) {
> -            return QLIST_FIRST(&qdict->table[i]);
> -        }
> -    }
> -
> -    return NULL;
> -}
> -
>  /**
>   * qdict_first(): Return first qdict entry for iteration.
>   */
>  const QDictEntry *qdict_first(const QDict *qdict)
>  {
> -    return qdict_next_entry(qdict, 0);
> +    return QSIMPLEQ_FIRST(&qdict->entries);
> +
>  }
>  
>  /**
> @@ -327,15 +300,7 @@ const QDictEntry *qdict_first(const QDict *qdict)
>   */
>  const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry)
>  {
> -    QDictEntry *ret;
> -
> -    ret = QLIST_NEXT(entry, next);
> -    if (!ret) {
> -        unsigned int bucket = tdb_hash(entry->key) % QDICT_BUCKET_MAX;
> -        ret = qdict_next_entry(qdict, bucket + 1);
> -    }
> -
> -    return ret;
> +    return QSIMPLEQ_NEXT(entry, next);
>  }
>  
>  /**
> @@ -346,14 +311,11 @@ QDict *qdict_clone_shallow(const QDict *src)
>  {
>      QDict *dest;
>      QDictEntry *entry;
> -    int i;
>  
>      dest = qdict_new();
>  
> -    for (i = 0; i < QDICT_BUCKET_MAX; i++) {
> -        QLIST_FOREACH(entry, &src->table[i], next) {
> -            qdict_put_obj(dest, entry->key, qobject_ref(entry->value));
> -        }
> +    QSIMPLEQ_FOREACH(entry, &src->entries, next) {
> +        qdict_put_obj(dest, entry->key, qobject_ref(entry->value));
>      }
>  
>      return dest;
> @@ -380,13 +342,11 @@ static void qentry_destroy(QDictEntry *e)
>   */
>  void qdict_del(QDict *qdict, const char *key)
>  {
> -    QDictEntry *entry;
> +    QDictEntry *entry = qdict_find(qdict, key);
>  
> -    entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX);
>      if (entry) {
> -        QLIST_REMOVE(entry, next);
> +        QSIMPLEQ_REMOVE(&qdict->entries, entry, QDictEntry, next);
>          qentry_destroy(entry);
> -        qdict->size--;
>      }
>  }
>  
> @@ -424,20 +384,16 @@ bool qdict_is_equal(const QObject *x, const QObject *y)
>   */
>  void qdict_destroy_obj(QObject *obj)
>  {
> -    int i;
>      QDict *qdict;
>  
>      assert(obj != NULL);
>      qdict = qobject_to(QDict, obj);
>  
> -    for (i = 0; i < QDICT_BUCKET_MAX; i++) {
> -        QDictEntry *entry = QLIST_FIRST(&qdict->table[i]);
> -        while (entry) {
> -            QDictEntry *tmp = QLIST_NEXT(entry, next);
> -            QLIST_REMOVE(entry, next);
> -            qentry_destroy(entry);
> -            entry = tmp;
> -        }
> +    while (!QSIMPLEQ_EMPTY(&qdict->entries)) {
> +        QDictEntry *entry = QSIMPLEQ_FIRST(&qdict->entries);
> +
> +        QSIMPLEQ_REMOVE_HEAD(&qdict->entries, next);
> +        qentry_destroy(entry);
>      }
>  
>      g_free(qdict);
> diff --git a/tests/unit/check-qdict.c b/tests/unit/check-qdict.c
> index b5efa859b0..d7d3df5efb 100644
> --- a/tests/unit/check-qdict.c
> +++ b/tests/unit/check-qdict.c
> @@ -47,7 +47,7 @@ static void qdict_put_obj_test(void)
>      qdict_put_int(qdict, "", num);
>  
>      g_assert(qdict_size(qdict) == 1);
> -    ent = QLIST_FIRST(&qdict->table[12345 % QDICT_BUCKET_MAX]);
> +    ent = QSIMPLEQ_FIRST(&qdict->entries);
>      qn = qobject_to(QNum, ent->value);
>      g_assert_cmpint(qnum_get_int(qn), ==, num);
>  
> diff --git a/tests/unit/check-qobject.c b/tests/unit/check-qobject.c
> index 022b7c74fe..0416762f80 100644
> --- a/tests/unit/check-qobject.c
> +++ b/tests/unit/check-qobject.c
> @@ -192,10 +192,10 @@ static void qobject_is_equal_dict_test(void)
>      qdict_put_int(dict_0, "baz", 3);
>      qdict_put_null(dict_0, "null");
>  
> -    qdict_put_int(dict_1, "f.o", 1);
>      qdict_put_int(dict_1, "bar", 2);
>      qdict_put_int(dict_1, "baz", 3);
>      qdict_put_null(dict_1, "null");
> +    qdict_put_int(dict_1, "f.o", 1);
>  
>      qdict_put_int(dict_different_key, "F.o", 1);
>      qdict_put_int(dict_different_key, "bar", 2);
> diff --git a/tests/qemu-iotests/043.out b/tests/qemu-iotests/043.out
> index 63ecb21816..d8fcff24e9 100644
> --- a/tests/qemu-iotests/043.out
> +++ b/tests/qemu-iotests/043.out
> @@ -40,29 +40,29 @@ cluster_size: 65536
>  == finite chain of length 3 (json) ==
>  [
>      {
> -        "virtual-size": 134217728,
>          "filename": "TEST_DIR/t.IMGFMT",
> -        "cluster-size": 65536,
>          "format": "IMGFMT",
> -        "full-backing-filename": "TEST_DIR/t.IMGFMT.2.base",
> +        "dirty-flag": false,
> +        "virtual-size": 134217728,
> +        "cluster-size": 65536,
>          "backing-filename": "TEST_DIR/t.IMGFMT.2.base",
> -        "dirty-flag": false
> +        "full-backing-filename": "TEST_DIR/t.IMGFMT.2.base",
>      },
>      {
> -        "virtual-size": 134217728,
>          "filename": "TEST_DIR/t.IMGFMT.2.base",
> -        "cluster-size": 65536,
>          "format": "IMGFMT",
> -        "full-backing-filename": "TEST_DIR/t.IMGFMT.1.base",
> +        "dirty-flag": false,
> +        "virtual-size": 134217728,
> +        "cluster-size": 65536,
>          "backing-filename": "TEST_DIR/t.IMGFMT.1.base",
> -        "dirty-flag": false
> +        "full-backing-filename": "TEST_DIR/t.IMGFMT.1.base",
>      },
>      {
> -        "virtual-size": 134217728,
>          "filename": "TEST_DIR/t.IMGFMT.1.base",
> -        "cluster-size": 65536,
>          "format": "IMGFMT",
> -        "dirty-flag": false
> +        "dirty-flag": false,
> +        "virtual-size": 134217728,
> +        "cluster-size": 65536,
>      }
>  ]
>  *** done
> diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out
> index 329977d9b9..f654a6579c 100644
> --- a/tests/qemu-iotests/060.out
> +++ b/tests/qemu-iotests/060.out
> @@ -17,11 +17,11 @@ virtual size: 64 MiB (67108864 bytes)
>  cluster_size: 65536
>  Format specific information:
>      compat: 1.1
> -    compression type: COMPRESSION_TYPE
> -    lazy refcounts: false
> -    refcount bits: 16
> -    corrupt: true
>      extended l2: false
> +    lazy refcounts: false
> +    corrupt: true
> +    refcount bits: 16
> +    compression type: COMPRESSION_TYPE
>  qemu-io: can't open device TEST_DIR/t.IMGFMT: IMGFMT: Image is corrupt; cannot be opened read/write
>  no file open, try 'help open'
>  read 512/512 bytes at offset 0
> @@ -418,11 +418,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
>  qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with refcount table); further corruption events will be suppressed
>  QMP_VERSION
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_IMAGE_CORRUPTED", "data": {"device": "none0", "msg": "Preventing invalid write on metadata (overlaps with refcount table)", "offset": 65536, "node-name": "drive", "fatal": true, "size": 65536}}
> +{"event": "BLOCK_IMAGE_CORRUPTED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"device": "none0", "node-name": "drive", "msg": "Preventing invalid write on metadata (overlaps with refcount table)", "offset": 65536, "size": 65536, "fatal": true}}
>  write failed: Input/output error
>  {"return": ""}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  
>  === Testing incoming inactive corrupted image ===
>  
> @@ -430,10 +430,10 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
>  QMP_VERSION
>  {"return": {}}
>  qcow2: Image is corrupt: L2 table offset 0x2a2a2a00 unaligned (L1 index: 0); further non-fatal corruption events will be suppressed
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_IMAGE_CORRUPTED", "data": {"device": "", "msg": "L2 table offset 0x2a2a2a00 unaligned (L1 index: 0)", "node-name": "drive", "fatal": false}}
> +{"event": "BLOCK_IMAGE_CORRUPTED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"device": "", "node-name": "drive", "msg": "L2 table offset 0x2a2a2a00 unaligned (L1 index: 0)", "fatal": false}}
>  {"return": ""}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  
>      corrupt: false
>  *** done
> diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
> index 139fc68177..6a05d67378 100644
> --- a/tests/qemu-iotests/061.out
> +++ b/tests/qemu-iotests/061.out
> @@ -497,7 +497,7 @@ wrote 65536/65536 bytes at offset 2147483648
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  wrote 65536/65536 bytes at offset 3221225472
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> -    (0.00/100%)
>     (12.50/100%)
>     (25.00/100%)
>     (37.50/100%)
>     (50.00/100%)
>     (62.50/100%)
>     (75.00/100%)
>     (87.50/100%)
>     (100.00/100%)
>     (100.00/100%)
> +    (0.00/100%)
>     (12.50/100%)
>     (25.00/100%)
>     (37.50/100%)
>     (50.00/100%)
>     (62.50/100%)
>     (75.00/100%)
>     (87.50/100%)
>     (100.00/100%)
>     (100.00/100%)
>  No errors were found on the image.
>  
>  === Testing progress report with snapshot ===
> @@ -512,7 +512,7 @@ wrote 65536/65536 bytes at offset 2147483648
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  wrote 65536/65536 bytes at offset 3221225472
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> -    (0.00/100%)
>     (6.25/100%)
>     (12.50/100%)
>     (18.75/100%)
>     (25.00/100%)
>     (31.25/100%)
>     (37.50/100%)
>     (43.75/100%)
>     (50.00/100%)
>     (56.25/100%)
>     (62.50/100%)
>     (68.75/100%)
>     (75.00/100%)
>     (81.25/100%)
>     (87.50/100%)
>     (93.75/100%)
>     (100.00/100%)
>     (100.00/100%)
> +    (0.00/100%)
>     (6.25/100%)
>     (12.50/100%)
>     (18.75/100%)
>     (25.00/100%)
>     (31.25/100%)
>     (37.50/100%)
>     (43.75/100%)
>     (50.00/100%)
>     (56.25/100%)
>     (62.50/100%)
>     (68.75/100%)
>     (75.00/100%)
>     (81.25/100%)
>     (87.50/100%)
>     (93.75/100%)
>     (100.00/100%)
>     (100.00/100%)
>  No errors were found on the image.
>  
>  === Testing version downgrade with external data file ===
> @@ -525,13 +525,13 @@ virtual size: 64 MiB (67108864 bytes)
>  cluster_size: 65536
>  Format specific information:
>      compat: 1.1
> -    compression type: COMPRESSION_TYPE
> -    lazy refcounts: false
> -    refcount bits: 16
>      data file: TEST_DIR/t.IMGFMT.data
>      data file raw: false
> -    corrupt: false
>      extended l2: false
> +    lazy refcounts: false
> +    corrupt: false
> +    refcount bits: 16
> +    compression type: COMPRESSION_TYPE
>  No errors were found on the image.
>  
>  === Testing version downgrade with extended L2 entries ===
> @@ -552,13 +552,13 @@ virtual size: 64 MiB (67108864 bytes)
>  cluster_size: 65536
>  Format specific information:
>      compat: 1.1
> -    compression type: COMPRESSION_TYPE
> -    lazy refcounts: false
> -    refcount bits: 16
>      data file: foo
>      data file raw: false
> -    corrupt: false
>      extended l2: false
> +    lazy refcounts: false
> +    corrupt: false
> +    refcount bits: 16
> +    compression type: COMPRESSION_TYPE
>  
>  qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'data-file' is required for this image
>  image: TEST_DIR/t.IMGFMT
> @@ -567,12 +567,12 @@ virtual size: 64 MiB (67108864 bytes)
>  cluster_size: 65536
>  Format specific information:
>      compat: 1.1
> -    compression type: COMPRESSION_TYPE
> -    lazy refcounts: false
> -    refcount bits: 16
>      data file raw: false
> -    corrupt: false
>      extended l2: false
> +    lazy refcounts: false
> +    corrupt: false
> +    refcount bits: 16
> +    compression type: COMPRESSION_TYPE
>  
>  === Clearing and setting data-file-raw ===
>  
> @@ -583,13 +583,13 @@ virtual size: 64 MiB (67108864 bytes)
>  cluster_size: 65536
>  Format specific information:
>      compat: 1.1
> -    compression type: COMPRESSION_TYPE
> -    lazy refcounts: false
> -    refcount bits: 16
>      data file: TEST_DIR/t.IMGFMT.data
>      data file raw: true
> -    corrupt: false
>      extended l2: false
> +    lazy refcounts: false
> +    corrupt: false
> +    refcount bits: 16
> +    compression type: COMPRESSION_TYPE
>  No errors were found on the image.
>  image: TEST_DIR/t.IMGFMT
>  file format: IMGFMT
> @@ -597,13 +597,13 @@ virtual size: 64 MiB (67108864 bytes)
>  cluster_size: 65536
>  Format specific information:
>      compat: 1.1
> -    compression type: COMPRESSION_TYPE
> -    lazy refcounts: false
> -    refcount bits: 16
>      data file: TEST_DIR/t.IMGFMT.data
>      data file raw: false
> -    corrupt: false
>      extended l2: false
> +    lazy refcounts: false
> +    corrupt: false
> +    refcount bits: 16
> +    compression type: COMPRESSION_TYPE
>  No errors were found on the image.
>  qemu-img: data-file-raw cannot be set on existing images
>  image: TEST_DIR/t.IMGFMT
> @@ -612,12 +612,12 @@ virtual size: 64 MiB (67108864 bytes)
>  cluster_size: 65536
>  Format specific information:
>      compat: 1.1
> -    compression type: COMPRESSION_TYPE
> -    lazy refcounts: false
> -    refcount bits: 16
>      data file: TEST_DIR/t.IMGFMT.data
>      data file raw: false
> -    corrupt: false
>      extended l2: false
> +    lazy refcounts: false
> +    corrupt: false
> +    refcount bits: 16
> +    compression type: COMPRESSION_TYPE
>  No errors were found on the image.
>  *** done
> diff --git a/tests/qemu-iotests/071.out b/tests/qemu-iotests/071.out
> index bca0c02f5c..ff00da1ad1 100644
> --- a/tests/qemu-iotests/071.out
> +++ b/tests/qemu-iotests/071.out
> @@ -46,7 +46,7 @@ QMP_VERSION
>  read failed: Input/output error
>  {"return": ""}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  
>  
>  === Testing blkverify on existing block device ===
> @@ -85,7 +85,7 @@ wrote 512/512 bytes at offset 0
>  read failed: Input/output error
>  {"return": ""}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  QEMU_PROG: Failed to flush the L2 table cache: Input/output error
>  QEMU_PROG: Failed to flush the refcount block cache: Input/output error
>  
> diff --git a/tests/qemu-iotests/099.out b/tests/qemu-iotests/099.out
> index 8cce627529..5726466bc6 100644
> --- a/tests/qemu-iotests/099.out
> +++ b/tests/qemu-iotests/099.out
> @@ -12,11 +12,11 @@ blkverify:TEST_DIR/t.IMGFMT.compare:TEST_DIR/t.IMGFMT
>  
>  === Testing JSON filename for blkdebug ===
>  
> -json:{"driver": "IMGFMT", "file": {"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "l1_update"}}
> +json:{"driver": "IMGFMT", "file": {"driver": "blkdebug", "inject-error.0.event": "l1_update", "image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}}}
>  
>  === Testing indirectly enforced JSON filename ===
>  
> -json:{"driver": "raw", "file": {"test": {"driver": "IMGFMT", "file": {"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "l1_update"}}, "driver": "blkverify", "raw": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.compare"}}}
> +json:{"driver": "raw", "file": {"driver": "blkverify", "test": {"driver": "IMGFMT", "file": {"driver": "blkdebug", "inject-error.0.event": "l1_update", "image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}}}, "raw": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.compare"}}}
>  
>  === Testing plain filename for blkdebug ===
>  
> diff --git a/tests/qemu-iotests/108.out b/tests/qemu-iotests/108.out
> index b5401d788d..faaabbcdf3 100644
> --- a/tests/qemu-iotests/108.out
> +++ b/tests/qemu-iotests/108.out
> @@ -163,18 +163,18 @@ OK: Reftable is where we expect it
>                 "size": 67108864,
>                 "cluster-size": 512
>             } } }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "create"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "create"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "running"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "create"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "create"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "create"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "waiting"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "pending"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "concluded"}}
>  { "execute": "job-dismiss", "arguments": { "id": "create" } }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "create"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "null"}}
>  {"return": {}}
>  { "execute": "quit" }
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  
>  wrote 65536/65536 bytes at offset 0
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> diff --git a/tests/qemu-iotests/117.out b/tests/qemu-iotests/117.out
> index 735ffd25c6..015c971197 100644
> --- a/tests/qemu-iotests/117.out
> +++ b/tests/qemu-iotests/117.out
> @@ -19,7 +19,7 @@ wrote 65536/65536 bytes at offset 0
>  {"return": ""}
>  { 'execute': 'quit' }
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  No errors were found on the image.
>  read 65536/65536 bytes at offset 0
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> diff --git a/tests/qemu-iotests/120.out b/tests/qemu-iotests/120.out
> index 0744c1f136..d677c72599 100644
> --- a/tests/qemu-iotests/120.out
> +++ b/tests/qemu-iotests/120.out
> @@ -6,7 +6,7 @@ wrote 65536/65536 bytes at offset 0
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  {"return": ""}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  read 65536/65536 bytes at offset 0
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  read 65536/65536 bytes at offset 0
> diff --git a/tests/qemu-iotests/127.out b/tests/qemu-iotests/127.out
> index 1685c4850a..863832d162 100644
> --- a/tests/qemu-iotests/127.out
> +++ b/tests/qemu-iotests/127.out
> @@ -14,20 +14,20 @@ wrote 42/42 bytes at offset 0
>             'mode':   'existing',
>             'sync':   'top'
>         } }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "mirror"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "mirror"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "running"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "mirror"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "mirror", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "ready"}}
> +{"event": "BLOCK_JOB_READY", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "mirror", "len": 65536, "offset": 65536, "speed": 0}}
>  { 'execute': 'block-job-complete',
>         'arguments': { 'device': 'mirror' } }
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "mirror"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "mirror"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "mirror", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "waiting"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "pending"}}
> +{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "mirror", "len": 65536, "offset": 65536, "speed": 0}}
>  { 'execute': 'quit' }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "mirror"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "mirror"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "concluded"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "null"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  *** done
> diff --git a/tests/qemu-iotests/140.out b/tests/qemu-iotests/140.out
> index 312f76d5da..586b64b24e 100644
> --- a/tests/qemu-iotests/140.out
> +++ b/tests/qemu-iotests/140.out
> @@ -15,10 +15,10 @@ read 65536/65536 bytes at offset 0
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  { 'execute': 'eject',
>         'arguments': { 'device': 'drv' }}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "drv"}}
> +{"event": "BLOCK_EXPORT_DELETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "drv"}}
>  qemu-io: can't open device nbd+unix:///drv?socket=SOCK_DIR/nbd: Requested export not available
>  server reported: export 'drv' not present
>  { 'execute': 'quit' }
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  *** done
> diff --git a/tests/qemu-iotests/141.out b/tests/qemu-iotests/141.out
> index 63203d9944..4d8c7b598c 100644
> --- a/tests/qemu-iotests/141.out
> +++ b/tests/qemu-iotests/141.out
> @@ -23,20 +23,20 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/m.
>  'format': 'IMGFMT',
>  'sync': 'none'}}
>  Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT backing_fmt=IMGFMT
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "paused"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
>  {'execute': 'blockdev-del',
>            'arguments': {'node-name': 'drv0'}}
>  {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: node is used as backing hd of 'NODE_NAME'"}}
>  {'execute': 'block-job-cancel',
>            'arguments': {'device': 'job0'}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 0, "speed": 0, "type": "backup"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "aborting"}}
> +{"event": "BLOCK_JOB_CANCELLED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "backup", "device": "job0", "len": 1048576, "offset": 0, "speed": 0}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>  {'execute': 'blockdev-del',
>            'arguments': {'node-name': 'drv0'}}
>  {"return": {}}
> @@ -59,21 +59,21 @@ Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
>  'format': 'IMGFMT',
>  'sync': 'none'}}
>  Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT backing_fmt=IMGFMT
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "ready"}}
> +{"event": "BLOCK_JOB_READY", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "job0", "len": 0, "offset": 0, "speed": 0}}
>  {'execute': 'blockdev-del',
>            'arguments': {'node-name': 'drv0'}}
>  {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: mirror"}}
>  {'execute': 'block-job-cancel',
>            'arguments': {'device': 'job0'}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "waiting"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "pending"}}
> +{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "job0", "len": 0, "offset": 0, "speed": 0}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>  {'execute': 'blockdev-del',
>            'arguments': {'node-name': 'drv0'}}
>  {"return": {}}
> @@ -91,21 +91,21 @@ Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
>  {"return": {}}
>  {'execute': 'block-commit',
>  'arguments': {'job-id': 'job0', 'device': 'drv0'}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "ready"}}
> +{"event": "BLOCK_JOB_READY", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "job0", "len": 0, "offset": 0, "speed": 0}}
>  {'execute': 'blockdev-del',
>            'arguments': {'node-name': 'drv0'}}
>  {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: commit"}}
>  {'execute': 'block-job-cancel',
>            'arguments': {'device': 'job0'}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "waiting"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "pending"}}
> +{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "job0", "len": 0, "offset": 0, "speed": 0}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>  {'execute': 'blockdev-del',
>            'arguments': {'node-name': 'drv0'}}
>  {"return": {}}
> @@ -128,18 +128,18 @@ wrote 1048576/1048576 bytes at offset 0
>  'device': 'drv0',
>  'top':    'TEST_DIR/m.IMGFMT',
>  'speed':  1}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
>  {'execute': 'blockdev-del',
>            'arguments': {'node-name': 'drv0'}}
>  {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: commit"}}
>  {'execute': 'block-job-cancel',
>            'arguments': {'device': 'job0'}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, "type": "commit"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "aborting"}}
> +{"event": "BLOCK_JOB_CANCELLED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "job0", "len": 1048576, "offset": 524288, "speed": 1}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>  {'execute': 'blockdev-del',
>            'arguments': {'node-name': 'drv0'}}
>  {"return": {}}
> @@ -161,18 +161,18 @@ wrote 1048576/1048576 bytes at offset 0
>  'arguments': {'job-id': 'job0',
>  'device': 'drv0',
>  'speed': 1}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
>  {'execute': 'blockdev-del',
>            'arguments': {'node-name': 'drv0'}}
>  {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: stream"}}
>  {'execute': 'block-job-cancel',
>            'arguments': {'device': 'job0'}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, "type": "stream"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "aborting"}}
> +{"event": "BLOCK_JOB_CANCELLED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "stream", "device": "job0", "len": 1048576, "offset": 524288, "speed": 1}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>  {'execute': 'blockdev-del',
>            'arguments': {'node-name': 'drv0'}}
>  {"return": {}}
> diff --git a/tests/qemu-iotests/143.out b/tests/qemu-iotests/143.out
> index 9ec5888e0e..ec58b08e43 100644
> --- a/tests/qemu-iotests/143.out
> +++ b/tests/qemu-iotests/143.out
> @@ -11,5 +11,5 @@ qemu-io: can't open device nbd+unix:///aa--aa1?socket=SOCK_DIR/nbd: Requested ex
>  server reported: export 'aa--aa...' not present
>  { 'execute': 'quit' }
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  *** done
> diff --git a/tests/qemu-iotests/156.out b/tests/qemu-iotests/156.out
> index 4a22f0c41a..bb01818fc7 100644
> --- a/tests/qemu-iotests/156.out
> +++ b/tests/qemu-iotests/156.out
> @@ -26,11 +26,11 @@ Formatting 'TEST_DIR/t.IMGFMT.target.overlay', fmt=IMGFMT size=1048576 backing_f
>                        'target': 'TEST_DIR/t.IMGFMT.target.overlay',
>                        'mode': 'existing',
>                        'sync': 'top' } }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "source"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "source"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "running"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "source"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "source", "len": 131072, "offset": 131072, "speed": 0, "type": "mirror"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "ready"}}
> +{"event": "BLOCK_JOB_READY", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "source", "len": 131072, "offset": 131072, "speed": 0}}
>  { 'execute': 'human-monitor-command',
>         'arguments': { 'command-line':
>                        'qemu-io source "write -P 4 192k 64k"' } }
> @@ -40,11 +40,11 @@ wrote 65536/65536 bytes at offset 196608
>  { 'execute': 'block-job-complete',
>         'arguments': { 'device': 'source' } }
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "source"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "source"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "source", "len": 196608, "offset": 196608, "speed": 0, "type": "mirror"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "source"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "source"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "waiting"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "pending"}}
> +{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "source", "len": 196608, "offset": 196608, "speed": 0}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "concluded"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "null"}}
>  
>  { 'execute': 'human-monitor-command',
>         'arguments': { 'command-line':
> @@ -73,7 +73,7 @@ read 65536/65536 bytes at offset 196608
>  
>  { 'execute': 'quit' }
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  
>  read 65536/65536 bytes at offset 0
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> diff --git a/tests/qemu-iotests/161.out b/tests/qemu-iotests/161.out
> index 6cc285afcf..c62657639a 100644
> --- a/tests/qemu-iotests/161.out
> +++ b/tests/qemu-iotests/161.out
> @@ -18,17 +18,17 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
>  {"return": {}}
>  { 'execute': 'block-stream',        'arguments': { 'device': 'none0',
>                        'base': 'TEST_DIR/t.IMGFMT.base' } }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "none0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "none0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "running"}}
>  {"return": {}}
>  { 'execute': 'human-monitor-command',
>         'arguments': { 'command-line':
>                        'qemu-io none0 "reopen -o backing.detect-zeroes=on"' } }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "none0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "none0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "none0", "len": 1048576, "offset": 1048576, "speed": 0, "type": "stream"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "none0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "none0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "waiting"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "pending"}}
> +{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "stream", "device": "none0", "len": 1048576, "offset": 1048576, "speed": 0}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "concluded"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "null"}}
>  {"return": ""}
>  
>  *** Commit and then change an option on the backing file
> @@ -40,16 +40,16 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
>  {"return": {}}
>  { 'execute': 'block-commit',        'arguments': { 'device': 'none0',
>                        'top': 'TEST_DIR/t.IMGFMT.int' } }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "none0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "none0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "running"}}
>  {"return": {}}
>  { 'execute': 'human-monitor-command',
>         'arguments': { 'command-line':
>                        'qemu-io none0 "reopen -o backing.detect-zeroes=on"' } }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "none0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "none0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "none0", "len": 1048576, "offset": 1048576, "speed": 0, "type": "commit"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "none0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "none0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "waiting"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "pending"}}
> +{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "none0", "len": 1048576, "offset": 1048576, "speed": 0}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "concluded"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "null"}}
>  {"return": ""}
>  *** done
> diff --git a/tests/qemu-iotests/176.out b/tests/qemu-iotests/176.out
> index 9d09b60452..b46b743850 100644
> --- a/tests/qemu-iotests/176.out
> +++ b/tests/qemu-iotests/176.out
> @@ -170,7 +170,7 @@ QMP_VERSION
>  {"return": {}}
>  {"return": {}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  wrote 196608/196608 bytes at offset 2147287040
>  192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  wrote 131072/131072 bytes at offset 2147352576
> @@ -207,7 +207,7 @@ QMP_VERSION
>  {"return": {}}
>  {"return": {"sha256": HASH}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  
>  === Test pass bitmap.1 ===
>  
> @@ -219,7 +219,7 @@ QMP_VERSION
>  {"return": {}}
>  {"return": {}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  wrote 196608/196608 bytes at offset 2147287040
>  192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  wrote 131072/131072 bytes at offset 2147352576
> @@ -257,7 +257,7 @@ QMP_VERSION
>  {"return": {}}
>  {"return": {"sha256": HASH}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  
>  === Test pass bitmap.2 ===
>  
> @@ -269,7 +269,7 @@ QMP_VERSION
>  {"return": {}}
>  {"return": {}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  wrote 196608/196608 bytes at offset 2147287040
>  192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  wrote 131072/131072 bytes at offset 2147352576
> @@ -307,7 +307,7 @@ QMP_VERSION
>  {"return": {}}
>  {"return": {"sha256": HASH}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  
>  === Test pass bitmap.3 ===
>  
> @@ -319,7 +319,7 @@ QMP_VERSION
>  {"return": {}}
>  {"return": {}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  wrote 196608/196608 bytes at offset 2147287040
>  192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  wrote 131072/131072 bytes at offset 2147352576
> @@ -354,5 +354,5 @@ QMP_VERSION
>  {"return": {}}
>  {"return": {"sha256": HASH}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
> +{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
>  *** done
> diff --git a/tests/qemu-iotests/184.out b/tests/qemu-iotests/184.out
> index 77e5489d65..93e33ba20a 100644
> --- a/tests/qemu-iotests/184.out
> +++ b/tests/qemu-iotests/184.out
> @@ -24,64 +24,64 @@ Testing:
>  {
>      "return": [
>          {
> -            "iops_rd": 0,
> +            "file": "json:{\"driver\": \"throttle\", \"throttle-group\": \"group0\", \"file\": {\"driver\": \"null-co\"}}",
> +            "node-name": "throttle0",
> +            "ro": false,
> +            "drv": "throttle",
> +            "backing_file_depth": 1,
> +            "encrypted": false,
>              "detect_zeroes": "off",
> +            "bps": 0,
> +            "bps_rd": 0,
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
>              "image": {
> +                "filename": "json:{\"driver\": \"throttle\", \"throttle-group\": \"group0\", \"file\": {\"driver\": \"null-co\"}}",
> +                "format": "throttle",
> +                "actual-size": 0,
> +                "virtual-size": 1073741824,
>                  "backing-image": {
> -                    "virtual-size": 1073741824,
>                      "filename": "null-co://",
>                      "format": "null-co",
> -                    "actual-size": 0
> -                },
> -                "virtual-size": 1073741824,
> -                "filename": "json:{\"throttle-group\": \"group0\", \"driver\": \"throttle\", \"file\": {\"driver\": \"null-co\"}}",
> -                "format": "throttle",
> -                "actual-size": 0
> +                    "actual-size": 0,
> +                    "virtual-size": 1073741824
> +                }
>              },
> -            "iops_wr": 0,
> -            "ro": false,
> -            "node-name": "throttle0",
> -            "backing_file_depth": 1,
> -            "drv": "throttle",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> -            "encrypted": false,
> -            "bps": 0,
> -            "bps_rd": 0,
>              "cache": {
> -                "no-flush": false,
> +                "writeback": true,
>                  "direct": false,
> -                "writeback": true
> +                "no-flush": false
>              },
> -            "file": "json:{\"throttle-group\": \"group0\", \"driver\": \"throttle\", \"file\": {\"driver\": \"null-co\"}}"
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> -            "detect_zeroes": "off",
> -            "image": {
> -                "virtual-size": 1073741824,
> -                "filename": "null-co://",
> -                "format": "null-co",
> -                "actual-size": 0
> -            },
> -            "iops_wr": 0,
> -            "ro": false,
> +            "file": "null-co://",
>              "node-name": "disk0",
> -            "backing_file_depth": 0,
> +            "ro": false,
>              "drv": "null-co",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> +            "backing_file_depth": 0,
>              "encrypted": false,
> +            "detect_zeroes": "off",
>              "bps": 0,
>              "bps_rd": 0,
> -            "cache": {
> -                "no-flush": false,
> -                "direct": false,
> -                "writeback": true
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
> +            "image": {
> +                "filename": "null-co://",
> +                "format": "null-co",
> +                "actual-size": 0,
> +                "virtual-size": 1073741824
>              },
> -            "file": "null-co://"
> +            "cache": {
> +                "writeback": true,
> +                "direct": false,
> +                "no-flush": false
> +            },
> +            "write_threshold": 0
>          }
>      ]
>  }
> @@ -94,11 +94,11 @@ Testing:
>      }
>  }
>  {
> +    "event": "SHUTDOWN",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "SHUTDOWN",
>      "data": {
>          "guest": false,
>          "reason": "host-qmp-quit"
> @@ -121,52 +121,25 @@ Testing:
>  }
>  {
>      "return": {
> -        "bps-read-max-length": 1,
> -        "iops-read-max-length": 1,
> -        "bps-read-max": 0,
> -        "bps-total": 0,
> -        "iops-total-max-length": 1,
>          "iops-total": 1000,
> -        "iops-write-max": 0,
> -        "bps-write": 0,
> -        "bps-total-max": 0,
> -        "bps-write-max": 0,
> -        "iops-size": 0,
> -        "iops-read": 0,
> -        "iops-write-max-length": 1,
> -        "iops-write": 0,
> -        "bps-total-max-length": 1,
> -        "iops-read-max": 0,
> -        "bps-read": 0,
> -        "bps-write-max-length": 1,
> -        "iops-total-max": 0
> -    }
> -}
> -{
> -    "return": {
> -    }
> -}
> -{
> -    "return": {
> -        "bps-read-max-length": 1,
> -        "iops-read-max-length": 1,
> -        "bps-read-max": 0,
> -        "bps-total": 0,
> +        "iops-total-max": 0,
>          "iops-total-max-length": 1,
> -        "iops-total": 0,
> -        "iops-write-max": 0,
> -        "bps-write": 0,
> -        "bps-total-max": 0,
> -        "bps-write-max": 0,
> -        "iops-size": 0,
>          "iops-read": 0,
> -        "iops-write-max-length": 1,
> -        "iops-write": 0,
> -        "bps-total-max-length": 1,
>          "iops-read-max": 0,
> +        "iops-read-max-length": 1,
> +        "iops-write": 0,
> +        "iops-write-max": 0,
> +        "iops-write-max-length": 1,
> +        "bps-total": 0,
> +        "bps-total-max": 0,
> +        "bps-total-max-length": 1,
>          "bps-read": 0,
> +        "bps-read-max": 0,
> +        "bps-read-max-length": 1,
> +        "bps-write": 0,
> +        "bps-write-max": 0,
>          "bps-write-max-length": 1,
> -        "iops-total-max": 0
> +        "iops-size": 0
>      }
>  }
>  {
> @@ -174,11 +147,38 @@ Testing:
>      }
>  }
>  {
> +    "return": {
> +        "iops-total": 0,
> +        "iops-total-max": 0,
> +        "iops-total-max-length": 1,
> +        "iops-read": 0,
> +        "iops-read-max": 0,
> +        "iops-read-max-length": 1,
> +        "iops-write": 0,
> +        "iops-write-max": 0,
> +        "iops-write-max-length": 1,
> +        "bps-total": 0,
> +        "bps-total-max": 0,
> +        "bps-total-max-length": 1,
> +        "bps-read": 0,
> +        "bps-read-max": 0,
> +        "bps-read-max-length": 1,
> +        "bps-write": 0,
> +        "bps-write-max": 0,
> +        "bps-write-max-length": 1,
> +        "iops-size": 0
> +    }
> +}
> +{
> +    "return": {
> +    }
> +}
> +{
> +    "event": "SHUTDOWN",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "SHUTDOWN",
>      "data": {
>          "guest": false,
>          "reason": "host-qmp-quit"
> @@ -216,11 +216,11 @@ Testing:
>      }
>  }
>  {
> +    "event": "SHUTDOWN",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "SHUTDOWN",
>      "data": {
>          "guest": false,
>          "reason": "host-qmp-quit"
> @@ -252,11 +252,11 @@ Testing:
>      }
>  }
>  {
> +    "event": "SHUTDOWN",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "SHUTDOWN",
>      "data": {
>          "guest": false,
>          "reason": "host-qmp-quit"
> diff --git a/tests/qemu-iotests/186.out b/tests/qemu-iotests/186.out
> index 01530040e5..12ea630222 100644
> --- a/tests/qemu-iotests/186.out
> +++ b/tests/qemu-iotests/186.out
> @@ -57,7 +57,7 @@ qdev_id: [not inserted]
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device ide-hd,drive=null
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]
>      Cache mode:       writeback
>  (qemu) quit
> @@ -65,7 +65,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device ide-hd,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      qdev_id
>      Cache mode:       writeback
>  (qemu) quit
> @@ -73,7 +73,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device scsi-hd,drive=null
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]
>      Cache mode:       writeback
>  (qemu) quit
> @@ -81,7 +81,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device scsi-hd,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      qdev_id
>      Cache mode:       writeback
>  (qemu) quit
> @@ -89,7 +89,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device virtio-blk-pci,drive=null
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]/virtio-backend
>      Cache mode:       writeback
>  (qemu) quit
> @@ -97,7 +97,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device virtio-blk-pci,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      /machine/peripheral/qdev_id/virtio-backend
>      Cache mode:       writeback
>  (qemu) quit
> @@ -105,7 +105,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device floppy,drive=null
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -114,7 +114,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device floppy,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      qdev_id
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -123,7 +123,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device ide-cd,drive=null
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -132,7 +132,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device ide-cd,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      qdev_id
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -141,7 +141,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device scsi-cd,drive=null
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -150,7 +150,7 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device scsi-cd,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
>      Attached to:      qdev_id
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -162,11 +162,11 @@ null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-hd,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
>  
> -null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      qdev_id
>      Cache mode:       writeback
>  (qemu) quit
> @@ -174,11 +174,11 @@ null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-hd,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
>  
> -null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      qdev_id
>      Cache mode:       writeback
>  (qemu) quit
> @@ -186,11 +186,11 @@ null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device virtio-blk-pci,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
>  
> -null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/peripheral/qdev_id/virtio-backend
>      Cache mode:       writeback
>  (qemu) quit
> @@ -198,11 +198,11 @@ null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device floppy,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
>  
> -null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      qdev_id
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -211,11 +211,11 @@ null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-cd,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
>  
> -null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      qdev_id
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -224,11 +224,11 @@ null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-cd,drive=null,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
>  
> -null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      qdev_id
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -240,7 +240,7 @@ null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-hd,drive=none0
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]
>      Cache mode:       writeback
>  (qemu) quit
> @@ -248,7 +248,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-hd,drive=none0,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      qdev_id
>      Cache mode:       writeback
>  (qemu) quit
> @@ -256,7 +256,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-hd,drive=none0
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]
>      Cache mode:       writeback
>  (qemu) quit
> @@ -264,7 +264,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-hd,drive=none0,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      qdev_id
>      Cache mode:       writeback
>  (qemu) quit
> @@ -272,7 +272,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device virtio-blk-pci,drive=none0
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]/virtio-backend
>      Cache mode:       writeback
>  (qemu) quit
> @@ -280,7 +280,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device virtio-blk-pci,drive=none0,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/peripheral/qdev_id/virtio-backend
>      Cache mode:       writeback
>  (qemu) quit
> @@ -288,7 +288,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device floppy,drive=none0
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -297,7 +297,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device floppy,drive=none0,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      qdev_id
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -306,7 +306,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-cd,drive=none0
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -315,7 +315,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-cd,drive=none0,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      qdev_id
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -324,7 +324,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-cd,drive=none0
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -333,7 +333,7 @@ none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-cd,drive=none0,id=qdev_id
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      qdev_id
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -411,7 +411,7 @@ floppy0: [not inserted]
>  Testing: -drive if=floppy,driver=null-co,read-zeroes=on
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -floppy0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +floppy0 (NODE_NAME): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/unattached/device[N]
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -420,7 +420,7 @@ floppy0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=ide,driver=null-co,read-zeroes=on
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -ide0-hd0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +ide0-hd0 (NODE_NAME): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/unattached/device[N]
>      Cache mode:       writeback
>  (qemu) quit
> @@ -436,7 +436,7 @@ ide0-cd0: [not inserted]
>  Testing: -drive if=ide,driver=null-co,read-zeroes=on,media=cdrom
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -ide0-cd0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co, read-only)
> +ide0-cd0 (NODE_NAME): json:{"driver": "null-co", "read-zeroes": "on"} (null-co, read-only)
>      Attached to:      /machine/unattached/device[N]
>      Removable device: not locked, tray closed
>      Cache mode:       writeback
> @@ -445,7 +445,7 @@ ide0-cd0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co,
>  Testing: -drive if=virtio,driver=null-co,read-zeroes=on
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -virtio0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
> +virtio0 (NODE_NAME): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/peripheral-anon/device[N]/virtio-backend
>      Cache mode:       writeback
>  (qemu) quit
> @@ -453,7 +453,7 @@ virtio0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
>  Testing: -drive if=pflash,driver=null-co,read-zeroes=on,size=1M
>  QEMU X.Y.Z monitor - type 'help' for more information
>  (qemu) info block
> -pflash0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co", "size": "1M"} (null-co)
> +pflash0 (NODE_NAME): json:{"driver": "null-co", "size": "1M", "read-zeroes": "on"} (null-co)
>      Attached to:      /machine/system.flash0
>      Cache mode:       writeback
>  (qemu) quit
> diff --git a/tests/qemu-iotests/190.out b/tests/qemu-iotests/190.out
> index ed9d8214eb..2acea9982c 100644
> --- a/tests/qemu-iotests/190.out
> +++ b/tests/qemu-iotests/190.out
> @@ -29,8 +29,8 @@ bitmaps size: 537198592
>  
>  expected bitmap 545259520
>  {
> -    "bitmaps": 545259520,
>      "required": 18874368,
> -    "fully-allocated": 2199042129920
> +    "fully-allocated": 2199042129920,
> +    "bitmaps": 545259520
>  }
>  *** done
> diff --git a/tests/qemu-iotests/191.out b/tests/qemu-iotests/191.out
> index ea88777374..a7dfb22080 100644
> --- a/tests/qemu-iotests/191.out
> +++ b/tests/qemu-iotests/191.out
> @@ -22,25 +22,25 @@ wrote 65536/65536 bytes at offset 1048576
>                        'base':'TEST_DIR/t.IMGFMT.base',
>                        'top': 'TEST_DIR/t.IMGFMT.mid' } }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "created",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "created"
>      }
>  }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "running",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "running"
>      }
>  }
>  {
> @@ -48,61 +48,61 @@ wrote 65536/65536 bytes at offset 1048576
>      }
>  }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "waiting",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "waiting"
>      }
>  }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "pending",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "pending"
>      }
>  }
>  {
> -    "timestamp": {
> -        "seconds":  TIMESTAMP,
> -        "microseconds":  TIMESTAMP
> -    },
>      "event": "BLOCK_JOB_COMPLETED",
> +    "timestamp": {
> +        "seconds":  TIMESTAMP,
> +        "microseconds":  TIMESTAMP
> +    },
>      "data": {
> +        "type": "commit",
>          "device": "commit0",
>          "len": 67108864,
>          "offset": 67108864,
> -        "speed": 0,
> -        "type": "commit"
> +        "speed": 0
>      }
>  }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "concluded",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "concluded"
>      }
>  }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "null",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "null"
>      }
>  }
>  
> @@ -112,268 +112,268 @@ wrote 65536/65536 bytes at offset 1048576
>  {
>      "return": [
>          {
> -            "iops_rd": 0,
> -            "detect_zeroes": "off",
> -            "image": {
> -                "backing-image": {
> -                    "virtual-size": 67108864,
> -                    "filename": "TEST_DIR/t.IMGFMT.base",
> -                    "cluster-size": 65536,
> -                    "format": "IMGFMT",
> -                    "actual-size": SIZE,
> -                    "dirty-flag": false
> -                },
> -                "backing-filename-format": "IMGFMT",
> -                "virtual-size": 67108864,
> -                "filename": "TEST_DIR/t.IMGFMT.ovl2",
> -                "cluster-size": 65536,
> -                "format": "IMGFMT",
> -                "actual-size": SIZE,
> -                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                "backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                "dirty-flag": false
> -            },
> -            "iops_wr": 0,
> -            "ro": false,
> +            "file": "TEST_DIR/t.IMGFMT.ovl2",
>              "node-name": "top2",
> -            "backing_file_depth": 1,
> +            "ro": false,
>              "drv": "IMGFMT",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
>              "backing_file": "TEST_DIR/t.IMGFMT.base",
> +            "backing_file_depth": 1,
>              "encrypted": false,
> +            "detect_zeroes": "off",
>              "bps": 0,
>              "bps_rd": 0,
> -            "cache": {
> -                "no-flush": false,
> -                "direct": false,
> -                "writeback": true
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
> +            "image": {
> +                "filename": "TEST_DIR/t.IMGFMT.ovl2",
> +                "format": "IMGFMT",
> +                "dirty-flag": false,
> +                "actual-size": SIZE,
> +                "virtual-size": 67108864,
> +                "cluster-size": 65536,
> +                "backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                "backing-filename-format": "IMGFMT",
> +                "backing-image": {
> +                    "filename": "TEST_DIR/t.IMGFMT.base",
> +                    "format": "IMGFMT",
> +                    "dirty-flag": false,
> +                    "actual-size": SIZE,
> +                    "virtual-size": 67108864,
> +                    "cluster-size": 65536,
> +                },
>              },
> -            "file": "TEST_DIR/t.IMGFMT.ovl2"
> +            "cache": {
> +                "writeback": true,
> +                "direct": false,
> +                "no-flush": false
> +            },
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> +            "file": "TEST_DIR/t.IMGFMT.ovl2",
> +            "node-name": "NODE_NAME",
> +            "ro": false,
> +            "drv": "file",
> +            "backing_file_depth": 0,
> +            "encrypted": false,
>              "detect_zeroes": "off",
> +            "bps": 0,
> +            "bps_rd": 0,
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
>              "image": {
> -                "virtual-size": 197120,
>                  "filename": "TEST_DIR/t.IMGFMT.ovl2",
>                  "format": "file",
> +                "dirty-flag": false,
>                  "actual-size": SIZE,
> -                "dirty-flag": false
> +                "virtual-size": 197120
>              },
> -            "iops_wr": 0,
> -            "ro": false,
> -            "node-name": "NODE_NAME",
> -            "backing_file_depth": 0,
> -            "drv": "file",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> -            "encrypted": false,
> -            "bps": 0,
> -            "bps_rd": 0,
>              "cache": {
> -                "no-flush": false,
> +                "writeback": true,
>                  "direct": false,
> -                "writeback": true
> +                "no-flush": false
>              },
> -            "file": "TEST_DIR/t.IMGFMT.ovl2"
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> -            "detect_zeroes": "off",
> -            "image": {
> -                "backing-image": {
> -                    "virtual-size": 67108864,
> -                    "filename": "TEST_DIR/t.IMGFMT.base",
> -                    "cluster-size": 65536,
> -                    "format": "IMGFMT",
> -                    "actual-size": SIZE,
> -                    "dirty-flag": false
> -                },
> -                "backing-filename-format": "IMGFMT",
> -                "virtual-size": 67108864,
> -                "filename": "TEST_DIR/t.IMGFMT",
> -                "cluster-size": 65536,
> -                "format": "IMGFMT",
> -                "actual-size": SIZE,
> -                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                "backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                "dirty-flag": false
> -            },
> -            "iops_wr": 0,
> -            "ro": false,
> +            "file": "TEST_DIR/t.IMGFMT",
>              "node-name": "top",
> -            "backing_file_depth": 1,
> +            "ro": false,
>              "drv": "IMGFMT",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
>              "backing_file": "TEST_DIR/t.IMGFMT.base",
> +            "backing_file_depth": 1,
>              "encrypted": false,
> +            "detect_zeroes": "off",
>              "bps": 0,
>              "bps_rd": 0,
> -            "cache": {
> -                "no-flush": false,
> -                "direct": false,
> -                "writeback": true
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
> +            "image": {
> +                "filename": "TEST_DIR/t.IMGFMT",
> +                "format": "IMGFMT",
> +                "dirty-flag": false,
> +                "actual-size": SIZE,
> +                "virtual-size": 67108864,
> +                "cluster-size": 65536,
> +                "backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                "backing-filename-format": "IMGFMT",
> +                "backing-image": {
> +                    "filename": "TEST_DIR/t.IMGFMT.base",
> +                    "format": "IMGFMT",
> +                    "dirty-flag": false,
> +                    "actual-size": SIZE,
> +                    "virtual-size": 67108864,
> +                    "cluster-size": 65536,
> +                },
>              },
> -            "file": "TEST_DIR/t.IMGFMT"
> +            "cache": {
> +                "writeback": true,
> +                "direct": false,
> +                "no-flush": false
> +            },
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> +            "file": "TEST_DIR/t.IMGFMT",
> +            "node-name": "NODE_NAME",
> +            "ro": false,
> +            "drv": "file",
> +            "backing_file_depth": 0,
> +            "encrypted": false,
>              "detect_zeroes": "off",
> +            "bps": 0,
> +            "bps_rd": 0,
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
>              "image": {
> -                "virtual-size": 197120,
>                  "filename": "TEST_DIR/t.IMGFMT",
>                  "format": "file",
> +                "dirty-flag": false,
>                  "actual-size": SIZE,
> -                "dirty-flag": false
> +                "virtual-size": 197120
>              },
> -            "iops_wr": 0,
> -            "ro": false,
> -            "node-name": "NODE_NAME",
> -            "backing_file_depth": 0,
> -            "drv": "file",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> -            "encrypted": false,
> -            "bps": 0,
> -            "bps_rd": 0,
>              "cache": {
> -                "no-flush": false,
> +                "writeback": true,
>                  "direct": false,
> -                "writeback": true
> +                "no-flush": false
>              },
> -            "file": "TEST_DIR/t.IMGFMT"
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> -            "detect_zeroes": "off",
> -            "image": {
> -                "backing-image": {
> -                    "virtual-size": 67108864,
> -                    "filename": "TEST_DIR/t.IMGFMT.base",
> -                    "cluster-size": 65536,
> -                    "format": "IMGFMT",
> -                    "actual-size": SIZE,
> -                    "dirty-flag": false
> -                },
> -                "backing-filename-format": "IMGFMT",
> -                "virtual-size": 67108864,
> -                "filename": "TEST_DIR/t.IMGFMT.mid",
> -                "cluster-size": 65536,
> -                "format": "IMGFMT",
> -                "actual-size": SIZE,
> -                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                "backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                "dirty-flag": false
> -            },
> -            "iops_wr": 0,
> -            "ro": false,
> +            "file": "TEST_DIR/t.IMGFMT.mid",
>              "node-name": "mid",
> -            "backing_file_depth": 1,
> +            "ro": false,
>              "drv": "IMGFMT",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
>              "backing_file": "TEST_DIR/t.IMGFMT.base",
> +            "backing_file_depth": 1,
>              "encrypted": false,
> +            "detect_zeroes": "off",
>              "bps": 0,
>              "bps_rd": 0,
> -            "cache": {
> -                "no-flush": false,
> -                "direct": false,
> -                "writeback": true
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
> +            "image": {
> +                "filename": "TEST_DIR/t.IMGFMT.mid",
> +                "format": "IMGFMT",
> +                "dirty-flag": false,
> +                "actual-size": SIZE,
> +                "virtual-size": 67108864,
> +                "cluster-size": 65536,
> +                "backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                "backing-filename-format": "IMGFMT",
> +                "backing-image": {
> +                    "filename": "TEST_DIR/t.IMGFMT.base",
> +                    "format": "IMGFMT",
> +                    "dirty-flag": false,
> +                    "actual-size": SIZE,
> +                    "virtual-size": 67108864,
> +                    "cluster-size": 65536,
> +                },
>              },
> -            "file": "TEST_DIR/t.IMGFMT.mid"
> +            "cache": {
> +                "writeback": true,
> +                "direct": false,
> +                "no-flush": false
> +            },
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> +            "file": "TEST_DIR/t.IMGFMT.mid",
> +            "node-name": "NODE_NAME",
> +            "ro": false,
> +            "drv": "file",
> +            "backing_file_depth": 0,
> +            "encrypted": false,
>              "detect_zeroes": "off",
> +            "bps": 0,
> +            "bps_rd": 0,
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
>              "image": {
> -                "virtual-size": 393216,
>                  "filename": "TEST_DIR/t.IMGFMT.mid",
>                  "format": "file",
> +                "dirty-flag": false,
>                  "actual-size": SIZE,
> -                "dirty-flag": false
> +                "virtual-size": 393216
>              },
> -            "iops_wr": 0,
> -            "ro": false,
> -            "node-name": "NODE_NAME",
> -            "backing_file_depth": 0,
> -            "drv": "file",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> -            "encrypted": false,
> -            "bps": 0,
> -            "bps_rd": 0,
>              "cache": {
> -                "no-flush": false,
> +                "writeback": true,
>                  "direct": false,
> -                "writeback": true
> +                "no-flush": false
>              },
> -            "file": "TEST_DIR/t.IMGFMT.mid"
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> -            "detect_zeroes": "off",
> -            "image": {
> -                "virtual-size": 67108864,
> -                "filename": "TEST_DIR/t.IMGFMT.base",
> -                "cluster-size": 65536,
> -                "format": "IMGFMT",
> -                "actual-size": SIZE,
> -                "dirty-flag": false
> -            },
> -            "iops_wr": 0,
> -            "ro": false,
> +            "file": "TEST_DIR/t.IMGFMT.base",
>              "node-name": "base",
> -            "backing_file_depth": 0,
> +            "ro": false,
>              "drv": "IMGFMT",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> +            "backing_file_depth": 0,
>              "encrypted": false,
> +            "detect_zeroes": "off",
>              "bps": 0,
>              "bps_rd": 0,
> -            "cache": {
> -                "no-flush": false,
> -                "direct": false,
> -                "writeback": true
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
> +            "image": {
> +                "filename": "TEST_DIR/t.IMGFMT.base",
> +                "format": "IMGFMT",
> +                "dirty-flag": false,
> +                "actual-size": SIZE,
> +                "virtual-size": 67108864,
> +                "cluster-size": 65536,
>              },
> -            "file": "TEST_DIR/t.IMGFMT.base"
> +            "cache": {
> +                "writeback": true,
> +                "direct": false,
> +                "no-flush": false
> +            },
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> +            "file": "TEST_DIR/t.IMGFMT.base",
> +            "node-name": "NODE_NAME",
> +            "ro": false,
> +            "drv": "file",
> +            "backing_file_depth": 0,
> +            "encrypted": false,
>              "detect_zeroes": "off",
> +            "bps": 0,
> +            "bps_rd": 0,
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
>              "image": {
> -                "virtual-size": 393216,
>                  "filename": "TEST_DIR/t.IMGFMT.base",
>                  "format": "file",
> +                "dirty-flag": false,
>                  "actual-size": SIZE,
> -                "dirty-flag": false
> +                "virtual-size": 393216
>              },
> -            "iops_wr": 0,
> -            "ro": false,
> -            "node-name": "NODE_NAME",
> -            "backing_file_depth": 0,
> -            "drv": "file",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> -            "encrypted": false,
> -            "bps": 0,
> -            "bps_rd": 0,
>              "cache": {
> -                "no-flush": false,
> +                "writeback": true,
>                  "direct": false,
> -                "writeback": true
> +                "no-flush": false
>              },
> -            "file": "TEST_DIR/t.IMGFMT.base"
> +            "write_threshold": 0
>          }
>      ]
>  }
> @@ -383,11 +383,11 @@ wrote 65536/65536 bytes at offset 1048576
>      }
>  }
>  {
> +    "event": "SHUTDOWN",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "SHUTDOWN",
>      "data": {
>          "guest": false,
>          "reason": "host-qmp-quit"
> @@ -429,25 +429,25 @@ wrote 65536/65536 bytes at offset 1048576
>                        'base':'TEST_DIR/t.IMGFMT.base',
>                        'top': 'TEST_DIR/t.IMGFMT.mid' } }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "created",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "created"
>      }
>  }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "running",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "running"
>      }
>  }
>  {
> @@ -455,61 +455,61 @@ wrote 65536/65536 bytes at offset 1048576
>      }
>  }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "waiting",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "waiting"
>      }
>  }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "pending",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "pending"
>      }
>  }
>  {
> -    "timestamp": {
> -        "seconds":  TIMESTAMP,
> -        "microseconds":  TIMESTAMP
> -    },
>      "event": "BLOCK_JOB_COMPLETED",
> +    "timestamp": {
> +        "seconds":  TIMESTAMP,
> +        "microseconds":  TIMESTAMP
> +    },
>      "data": {
> +        "type": "commit",
>          "device": "commit0",
>          "len": 67108864,
>          "offset": 67108864,
> -        "speed": 0,
> -        "type": "commit"
> +        "speed": 0
>      }
>  }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "concluded",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "concluded"
>      }
>  }
>  {
> +    "event": "JOB_STATUS_CHANGE",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "JOB_STATUS_CHANGE",
>      "data": {
> -        "status": "null",
> -        "id": "commit0"
> +        "id": "commit0",
> +        "status": "null"
>      }
>  }
>  
> @@ -519,279 +519,279 @@ wrote 65536/65536 bytes at offset 1048576
>  {
>      "return": [
>          {
> -            "iops_rd": 0,
> -            "detect_zeroes": "off",
> -            "image": {
> -                "backing-image": {
> -                    "virtual-size": 67108864,
> -                    "filename": "TEST_DIR/t.IMGFMT.base",
> -                    "cluster-size": 65536,
> -                    "format": "IMGFMT",
> -                    "actual-size": SIZE,
> -                    "dirty-flag": false
> -                },
> -                "backing-filename-format": "IMGFMT",
> -                "virtual-size": 67108864,
> -                "filename": "TEST_DIR/t.IMGFMT.ovl2",
> -                "cluster-size": 65536,
> -                "format": "IMGFMT",
> -                "actual-size": SIZE,
> -                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                "backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                "dirty-flag": false
> -            },
> -            "iops_wr": 0,
> -            "ro": true,
> +            "file": "TEST_DIR/t.IMGFMT.ovl2",
>              "node-name": "NODE_NAME",
> -            "backing_file_depth": 1,
> +            "ro": true,
>              "drv": "IMGFMT",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
>              "backing_file": "TEST_DIR/t.IMGFMT.base",
> +            "backing_file_depth": 1,
>              "encrypted": false,
> +            "detect_zeroes": "off",
>              "bps": 0,
>              "bps_rd": 0,
> -            "cache": {
> -                "no-flush": false,
> -                "direct": false,
> -                "writeback": true
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
> +            "image": {
> +                "filename": "TEST_DIR/t.IMGFMT.ovl2",
> +                "format": "IMGFMT",
> +                "dirty-flag": false,
> +                "actual-size": SIZE,
> +                "virtual-size": 67108864,
> +                "cluster-size": 65536,
> +                "backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                "backing-filename-format": "IMGFMT",
> +                "backing-image": {
> +                    "filename": "TEST_DIR/t.IMGFMT.base",
> +                    "format": "IMGFMT",
> +                    "dirty-flag": false,
> +                    "actual-size": SIZE,
> +                    "virtual-size": 67108864,
> +                    "cluster-size": 65536,
> +                },
>              },
> -            "file": "TEST_DIR/t.IMGFMT.ovl2"
> +            "cache": {
> +                "writeback": true,
> +                "direct": false,
> +                "no-flush": false
> +            },
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> +            "file": "TEST_DIR/t.IMGFMT.ovl2",
> +            "node-name": "NODE_NAME",
> +            "ro": true,
> +            "drv": "file",
> +            "backing_file_depth": 0,
> +            "encrypted": false,
>              "detect_zeroes": "off",
> +            "bps": 0,
> +            "bps_rd": 0,
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
>              "image": {
> -                "virtual-size": 197120,
>                  "filename": "TEST_DIR/t.IMGFMT.ovl2",
>                  "format": "file",
> +                "dirty-flag": false,
>                  "actual-size": SIZE,
> -                "dirty-flag": false
> +                "virtual-size": 197120
>              },
> -            "iops_wr": 0,
> -            "ro": true,
> -            "node-name": "NODE_NAME",
> -            "backing_file_depth": 0,
> -            "drv": "file",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> -            "encrypted": false,
> -            "bps": 0,
> -            "bps_rd": 0,
>              "cache": {
> -                "no-flush": false,
> +                "writeback": true,
>                  "direct": false,
> -                "writeback": true
> +                "no-flush": false
>              },
> -            "file": "TEST_DIR/t.IMGFMT.ovl2"
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> -            "detect_zeroes": "off",
> -            "image": {
> -                "backing-image": {
> -                    "backing-image": {
> -                        "virtual-size": 67108864,
> -                        "filename": "TEST_DIR/t.IMGFMT.base",
> -                        "cluster-size": 65536,
> -                        "format": "IMGFMT",
> -                        "actual-size": SIZE,
> -                        "dirty-flag": false
> -                    },
> -                    "backing-filename-format": "IMGFMT",
> -                    "virtual-size": 67108864,
> -                    "filename": "TEST_DIR/t.IMGFMT.ovl2",
> -                    "cluster-size": 65536,
> -                    "format": "IMGFMT",
> -                    "actual-size": SIZE,
> -                    "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                    "backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                    "dirty-flag": false
> -                },
> -                "backing-filename-format": "IMGFMT",
> -                "virtual-size": 67108864,
> -                "filename": "TEST_DIR/t.IMGFMT.ovl3",
> -                "cluster-size": 65536,
> -                "format": "IMGFMT",
> -                "actual-size": SIZE,
> -                "full-backing-filename": "TEST_DIR/t.IMGFMT.ovl2",
> -                "backing-filename": "TEST_DIR/t.IMGFMT.ovl2",
> -                "dirty-flag": false
> -            },
> -            "iops_wr": 0,
> -            "ro": false,
> +            "file": "TEST_DIR/t.IMGFMT.ovl3",
>              "node-name": "top2",
> -            "backing_file_depth": 2,
> +            "ro": false,
>              "drv": "IMGFMT",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
>              "backing_file": "TEST_DIR/t.IMGFMT.ovl2",
> +            "backing_file_depth": 2,
>              "encrypted": false,
> +            "detect_zeroes": "off",
>              "bps": 0,
>              "bps_rd": 0,
> -            "cache": {
> -                "no-flush": false,
> -                "direct": false,
> -                "writeback": true
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
> +            "image": {
> +                "filename": "TEST_DIR/t.IMGFMT.ovl3",
> +                "format": "IMGFMT",
> +                "dirty-flag": false,
> +                "actual-size": SIZE,
> +                "virtual-size": 67108864,
> +                "cluster-size": 65536,
> +                "backing-filename": "TEST_DIR/t.IMGFMT.ovl2",
> +                "full-backing-filename": "TEST_DIR/t.IMGFMT.ovl2",
> +                "backing-filename-format": "IMGFMT",
> +                "backing-image": {
> +                    "filename": "TEST_DIR/t.IMGFMT.ovl2",
> +                    "format": "IMGFMT",
> +                    "dirty-flag": false,
> +                    "actual-size": SIZE,
> +                    "virtual-size": 67108864,
> +                    "cluster-size": 65536,
> +                    "backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                    "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                    "backing-filename-format": "IMGFMT",
> +                    "backing-image": {
> +                        "filename": "TEST_DIR/t.IMGFMT.base",
> +                        "format": "IMGFMT",
> +                        "dirty-flag": false,
> +                        "actual-size": SIZE,
> +                        "virtual-size": 67108864,
> +                        "cluster-size": 65536,
> +                    },
> +                },
>              },
> -            "file": "TEST_DIR/t.IMGFMT.ovl3"
> +            "cache": {
> +                "writeback": true,
> +                "direct": false,
> +                "no-flush": false
> +            },
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> +            "file": "TEST_DIR/t.IMGFMT.ovl3",
> +            "node-name": "NODE_NAME",
> +            "ro": false,
> +            "drv": "file",
> +            "backing_file_depth": 0,
> +            "encrypted": false,
>              "detect_zeroes": "off",
> +            "bps": 0,
> +            "bps_rd": 0,
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
>              "image": {
> -                "virtual-size": 197120,
>                  "filename": "TEST_DIR/t.IMGFMT.ovl3",
>                  "format": "file",
> +                "dirty-flag": false,
>                  "actual-size": SIZE,
> -                "dirty-flag": false
> +                "virtual-size": 197120
>              },
> -            "iops_wr": 0,
> -            "ro": false,
> -            "node-name": "NODE_NAME",
> -            "backing_file_depth": 0,
> -            "drv": "file",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> -            "encrypted": false,
> -            "bps": 0,
> -            "bps_rd": 0,
>              "cache": {
> -                "no-flush": false,
> +                "writeback": true,
>                  "direct": false,
> -                "writeback": true
> +                "no-flush": false
>              },
> -            "file": "TEST_DIR/t.IMGFMT.ovl3"
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> -            "detect_zeroes": "off",
> -            "image": {
> -                "virtual-size": 67108864,
> -                "filename": "TEST_DIR/t.IMGFMT.base",
> -                "cluster-size": 65536,
> -                "format": "IMGFMT",
> -                "actual-size": SIZE,
> -                "dirty-flag": false
> -            },
> -            "iops_wr": 0,
> +            "file": "TEST_DIR/t.IMGFMT.base",
> +            "node-name": "NODE_NAME",
>              "ro": true,
> -            "node-name": "NODE_NAME",
> -            "backing_file_depth": 0,
>              "drv": "IMGFMT",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> +            "backing_file_depth": 0,
>              "encrypted": false,
> +            "detect_zeroes": "off",
>              "bps": 0,
>              "bps_rd": 0,
> -            "cache": {
> -                "no-flush": false,
> -                "direct": false,
> -                "writeback": true
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
> +            "image": {
> +                "filename": "TEST_DIR/t.IMGFMT.base",
> +                "format": "IMGFMT",
> +                "dirty-flag": false,
> +                "actual-size": SIZE,
> +                "virtual-size": 67108864,
> +                "cluster-size": 65536,
>              },
> -            "file": "TEST_DIR/t.IMGFMT.base"
> +            "cache": {
> +                "writeback": true,
> +                "direct": false,
> +                "no-flush": false
> +            },
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> +            "file": "TEST_DIR/t.IMGFMT.base",
> +            "node-name": "NODE_NAME",
> +            "ro": true,
> +            "drv": "file",
> +            "backing_file_depth": 0,
> +            "encrypted": false,
>              "detect_zeroes": "off",
> +            "bps": 0,
> +            "bps_rd": 0,
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
>              "image": {
> -                "virtual-size": 393216,
>                  "filename": "TEST_DIR/t.IMGFMT.base",
>                  "format": "file",
> +                "dirty-flag": false,
>                  "actual-size": SIZE,
> -                "dirty-flag": false
> +                "virtual-size": 393216
>              },
> -            "iops_wr": 0,
> -            "ro": true,
> -            "node-name": "NODE_NAME",
> -            "backing_file_depth": 0,
> -            "drv": "file",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> -            "encrypted": false,
> -            "bps": 0,
> -            "bps_rd": 0,
>              "cache": {
> -                "no-flush": false,
> +                "writeback": true,
>                  "direct": false,
> -                "writeback": true
> +                "no-flush": false
>              },
> -            "file": "TEST_DIR/t.IMGFMT.base"
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> -            "detect_zeroes": "off",
> -            "image": {
> -                "backing-image": {
> -                    "virtual-size": 67108864,
> -                    "filename": "TEST_DIR/t.IMGFMT.base",
> -                    "cluster-size": 65536,
> -                    "format": "IMGFMT",
> -                    "actual-size": SIZE,
> -                    "dirty-flag": false
> -                },
> -                "backing-filename-format": "IMGFMT",
> -                "virtual-size": 67108864,
> -                "filename": "TEST_DIR/t.IMGFMT",
> -                "cluster-size": 65536,
> -                "format": "IMGFMT",
> -                "actual-size": SIZE,
> -                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                "backing-filename": "TEST_DIR/t.IMGFMT.base",
> -                "dirty-flag": false
> -            },
> -            "iops_wr": 0,
> -            "ro": false,
> +            "file": "TEST_DIR/t.IMGFMT",
>              "node-name": "top",
> -            "backing_file_depth": 1,
> +            "ro": false,
>              "drv": "IMGFMT",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
>              "backing_file": "TEST_DIR/t.IMGFMT.base",
> +            "backing_file_depth": 1,
>              "encrypted": false,
> +            "detect_zeroes": "off",
>              "bps": 0,
>              "bps_rd": 0,
> -            "cache": {
> -                "no-flush": false,
> -                "direct": false,
> -                "writeback": true
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
> +            "image": {
> +                "filename": "TEST_DIR/t.IMGFMT",
> +                "format": "IMGFMT",
> +                "dirty-flag": false,
> +                "actual-size": SIZE,
> +                "virtual-size": 67108864,
> +                "cluster-size": 65536,
> +                "backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
> +                "backing-filename-format": "IMGFMT",
> +                "backing-image": {
> +                    "filename": "TEST_DIR/t.IMGFMT.base",
> +                    "format": "IMGFMT",
> +                    "dirty-flag": false,
> +                    "actual-size": SIZE,
> +                    "virtual-size": 67108864,
> +                    "cluster-size": 65536,
> +                },
>              },
> -            "file": "TEST_DIR/t.IMGFMT"
> +            "cache": {
> +                "writeback": true,
> +                "direct": false,
> +                "no-flush": false
> +            },
> +            "write_threshold": 0
>          },
>          {
> -            "iops_rd": 0,
> -            "detect_zeroes": "off",
> -            "image": {
> -                "virtual-size": 197120,
> -                "filename": "TEST_DIR/t.IMGFMT",
> -                "format": "file",
> -                "actual-size": SIZE,
> -                "dirty-flag": false
> -            },
> -            "iops_wr": 0,
> -            "ro": false,
> +            "file": "TEST_DIR/t.IMGFMT",
>              "node-name": "NODE_NAME",
> -            "backing_file_depth": 0,
> +            "ro": false,
>              "drv": "file",
> -            "iops": 0,
> -            "bps_wr": 0,
> -            "write_threshold": 0,
> +            "backing_file_depth": 0,
>              "encrypted": false,
> +            "detect_zeroes": "off",
>              "bps": 0,
>              "bps_rd": 0,
> -            "cache": {
> -                "no-flush": false,
> -                "direct": false,
> -                "writeback": true
> +            "bps_wr": 0,
> +            "iops": 0,
> +            "iops_rd": 0,
> +            "iops_wr": 0,
> +            "image": {
> +                "filename": "TEST_DIR/t.IMGFMT",
> +                "format": "file",
> +                "dirty-flag": false,
> +                "actual-size": SIZE,
> +                "virtual-size": 197120
>              },
> -            "file": "TEST_DIR/t.IMGFMT"
> +            "cache": {
> +                "writeback": true,
> +                "direct": false,
> +                "no-flush": false
> +            },
> +            "write_threshold": 0
>          }
>      ]
>  }
> @@ -801,11 +801,11 @@ wrote 65536/65536 bytes at offset 1048576
>      }
>  }
>  {
> +    "event": "SHUTDOWN",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "SHUTDOWN",
>      "data": {
>          "guest": false,
>          "reason": "host-qmp-quit"
> diff --git a/tests/qemu-iotests/195.out b/tests/qemu-iotests/195.out
> index ec84df5012..485d7a1115 100644
> --- a/tests/qemu-iotests/195.out
> +++ b/tests/qemu-iotests/195.out
> @@ -22,11 +22,11 @@ Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,backing.node-name=mid
>      }
>  }
>  {
> +    "event": "SHUTDOWN",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "SHUTDOWN",
>      "data": {
>          "guest": false,
>          "reason": "host-qmp-quit"
> @@ -60,11 +60,11 @@ Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,node-name=top
>      }
>  }
>  {
> +    "event": "SHUTDOWN",
>      "timestamp": {
>          "seconds":  TIMESTAMP,
>          "microseconds":  TIMESTAMP
>      },
> -    "event": "SHUTDOWN",
>      "data": {
>          "guest": false,
>          "reason": "host-qmp-quit"
> diff --git a/tests/qemu-iotests/229.out b/tests/qemu-iotests/229.out
> index 7d2bfbfbe6..3f4391df6e 100644
> --- a/tests/qemu-iotests/229.out
> +++ b/tests/qemu-iotests/229.out
> @@ -16,19 +16,19 @@ wrote 2097152/2097152 bytes at offset 0
>                                 'mode':   'existing',
>                                 'on-source-error': 'stop',
>                                 'on-target-error': 'stop' }}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "testdisk"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "testdisk", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "testdisk", "status": "running"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "testdisk", "operation": "write", "action": "stop"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "testdisk"}}
> +{"event": "BLOCK_JOB_ERROR", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"device": "testdisk", "operation": "write", "action": "stop"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "testdisk", "status": "paused"}}
>  
>  === Force cancel job paused in error state  ===
>  
>  {'execute': 'block-job-cancel',
>                   'arguments': { 'device': 'testdisk',
>                                  'force': true}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "testdisk", "status": "running"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "testdisk"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "testdisk", "len": 2097152, "offset": OFFSET, "speed": 0, "type": "mirror"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "testdisk", "status": "aborting"}}
> +{"event": "BLOCK_JOB_CANCELLED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "testdisk", "len": 2097152, "offset": OFFSET, "speed": 0}}
>  *** done
> diff --git a/tests/qemu-iotests/244.out b/tests/qemu-iotests/244.out
> index 5e03add054..57cffee1ea 100644
> --- a/tests/qemu-iotests/244.out
> +++ b/tests/qemu-iotests/244.out
> @@ -156,14 +156,14 @@ wrote 1048576/1048576 bytes at offset 0
>                 "data-file": "data",
>                 "data-file-raw": true
>             } } }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "create"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "create"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "running"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "create"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "create"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "create"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "waiting"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "pending"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "concluded"}}
>  { "execute": "job-dismiss", "arguments": { "id": "create" } }
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "create"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "null"}}
>  {"return": {}}
>  
>  Comparing pattern:
> diff --git a/tests/qemu-iotests/249.out b/tests/qemu-iotests/249.out
> index d2bf9be85e..a1a1a1b851 100644
> --- a/tests/qemu-iotests/249.out
> +++ b/tests/qemu-iotests/249.out
> @@ -16,8 +16,8 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
>  { 'execute': 'block-commit',
>         'arguments': {'job-id': 'job0', 'device': 'none1', 'top-node': 'int',
>                       'filter-node-name': '1234'}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>  {"error": {"class": "GenericError", "desc": "Invalid node-name: '1234'"}}
>  
>  === Send a write command to a drive opened in read-only mode (2)
> @@ -30,14 +30,14 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
>  
>  { 'execute': 'block-commit',
>         'arguments': {'job-id': 'job0', 'device': 'none1', 'top-node': 'int'}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 1048576, "offset": 1048576, "speed": 0, "type": "commit"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "waiting"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "pending"}}
> +{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "job0", "len": 1048576, "offset": 1048576, "speed": 0}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>  
>  === Send a write command to a drive opened in read-only mode (3)
>  
> diff --git a/tests/qemu-iotests/tests/qsd-jobs.out b/tests/qemu-iotests/tests/qsd-jobs.out
> index c1bc9b8356..336a5c3946 100644
> --- a/tests/qemu-iotests/tests/qsd-jobs.out
> +++ b/tests/qemu-iotests/tests/qsd-jobs.out
> @@ -8,15 +8,15 @@ QMP_VERSION
>  {"return": {}}
>  {"return": {}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
> +{"event": "BLOCK_JOB_CANCELLED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "job0", "len": 0, "offset": 0, "speed": 0}}
>  
>  === Streaming can't get permission on base node ===
>  
>  QMP_VERSION
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
> +{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
>  {"error": {"class": "GenericError", "desc": "Permission conflict on node 'fmt_base': permissions 'write' are both required by an unnamed block device (uses node 'fmt_base' as 'root' child) and unshared by stream job 'job0' (uses node 'fmt_base' as 'intermediate node' child)."}}
>  {"return": {}}
> -{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export1"}}
> +{"event": "BLOCK_EXPORT_DELETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "export1"}}
>  *** done
Markus Armbruster July 8, 2022, 10:19 a.m. UTC | #9
Alex Bennée <alex.bennee@linaro.org> writes:

> Markus Armbruster <armbru@redhat.com> writes:
>
>> QDict is implemented as a simple hash table of fixed size.  Observe:
>>
>> * Slow for large n.  Not sure this matters.
>>
>> * A QDict with n entries takes 4120 + n * 32 bytes on my box.  Wastes
>>   space for small n, which is a common case.
>>
>> * Order of traversal depends on the hash function and on insertion
>>   order, because it iterates first over buckets, then collision
>>   chains.
>>
>> * Special code ensures qdict_size() takes constant time.
>>
>> Replace the hash table by a linked list.  Observe:
>>
>> * Even slower for large n.  Might be bad enough to matter.
>>
>> * A QDict with n entries takes 32 + n * 24 bytes.
>>
>> * Traversal is in insertion order.
>>
>> * qdict_size() is linear in the number of entries.
>>
>> This is an experiment.  Do not commit to master as is.
>
> Did you consider just using a straight array? What is the usual size of
> a QDict - how many entries do you expect to scale to?

I like the way you think :)

Let me hazard an educated guess.

QDict's intended purpose is "JSON AST for QMP".

Output and syntactically correct input satisfy the QAPI schema.  JSON
objects correspond to a complex type in the schema (struct or union).
The number of members in the schema limits the number of members in the
JSON object ("limits" because members can be optional).

BlockDeviceInfo has 32 members.  As far as I can tell, no type has more.

Exception 1: the 'any' type, currently used for QOM properties

Exception 2: the "'gen': false" schema backdoor, currenrly used for
             device_add arguments, so basically QOM properties again

I can't be bothered to go fishing for the QOM object with the most
properties.  Could exceed 32, but exceeding it by much would surprise
me.

For incorrect input, all bets are off.  We may hand-wave this away, but
only as long as input is trusted.

QDict is used for other purposes in places.  Can't say how many keys to
expect there.  Can say I wish it wasn't.

>> The change of traversal order affects expected test output.  I updated
>> only the tests covered by "make check" so far.  I expect some more to
>> hide under tests/qemu-iotests/.
>>
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
Daniel P. Berrangé July 8, 2022, 11:01 a.m. UTC | #10
On Wed, Jul 06, 2022 at 01:35:22PM +0200, Markus Armbruster wrote:
> Markus Armbruster <armbru@redhat.com> writes:
> 
> > QDict is implemented as a simple hash table of fixed size.  Observe:
> >
> > * Slow for large n.  Not sure this matters.
> >
> > * A QDict with n entries takes 4120 + n * 32 bytes on my box.  Wastes
> >   space for small n, which is a common case.
> >
> > * Order of traversal depends on the hash function and on insertion
> >   order, because it iterates first over buckets, then collision
> >   chains.
> >
> > * Special code ensures qdict_size() takes constant time.
> >
> > Replace the hash table by a linked list.  Observe:
> >
> > * Even slower for large n.  Might be bad enough to matter.
> >
> > * A QDict with n entries takes 32 + n * 24 bytes.
> >
> > * Traversal is in insertion order.
> >
> > * qdict_size() is linear in the number of entries.
> >
> > This is an experiment.  Do not commit to master as is.
> 
> Forgot to mention: see also
> 
>         Subject: Re: [PULL 14/15] qdev: Base object creation on QDict rather than QemuOpts
>         Message-ID: <87wnctzdl9.fsf@pond.sub.org>
>         https://lists.nongnu.org/archive/html/qemu-devel/2022-07/msg00358.html

What alternative options do we have for addressing this scenario.

I can think of

  - Auto-create array elements, if seeing an element set before length.

    This is based on the theory that 'len-PROP' field is largely
    redundant. It is only needed if you want to create a sparse
    array, with empty elements /after/ the last one explicitly
    set, or if you want to get error reporting for an app setting
    element 3 after saying it wanted a 2 element list. IMHO the
    error reporting benefit is dubious, because the error scenario
    only exists because we made the app set this redundant 'len-PROP'
    attribute. Does anything actually need the 'sparse array'
    facility ?

  - Special case array properties

    Modify object_set_properties_from_qdict, so that it has a special
    case first iterating over any properties with 'len-' prefix in
    their name, then iterating over everything else.

    Assuming this 'len-' property is the only case where we genuinely
    have ordering dependancies between properties, this is quite a
    simple fix, and avoid imposes ordering requirements on either
    clients or QEMU in general.


  - Insertion order preserving QDict

    What you've done here, pushing the ordering problem off to be
    the caller's responsibility to get right. The caller could
    easily have the same problem though. For example, for CLI args
    these days, libvirt will populate a data structure based on
    QAPI, and then serialize that to CLI args. I don't know offhand
    if our code is insertion order preserving, or will hit this
    exact same problem. Luckily we don't support the 'rocker'
    object so havent hit this precise issue.


  - Any other options ?


With regards,
Daniel
Peter Maydell July 11, 2022, 10:32 a.m. UTC | #11
On Fri, 8 Jul 2022 at 12:01, Daniel P. Berrangé <berrange@redhat.com> wrote:
> What alternative options do we have for addressing this scenario.
>
> I can think of
>
>   - Auto-create array elements, if seeing an element set before length.
>
>     This is based on the theory that 'len-PROP' field is largely
>     redundant. It is only needed if you want to create a sparse
>     array, with empty elements /after/ the last one explicitly
>     set, or if you want to get error reporting for an app setting
>     element 3 after saying it wanted a 2 element list. IMHO the
>     error reporting benefit is dubious, because the error scenario
>     only exists because we made the app set this redundant 'len-PROP'
>     attribute. Does anything actually need the 'sparse array'
>     facility ?

I'm pretty sure that nothing needs sparse array elements like
that. The major reason for the len-PROP field is an implementation
one: because there is currently no way for a QOM object to
say "call this method if somebody tries to set a non-existent
property", the way array properties work is that the 'set'
method for the len-PROP property is the place where we then
add the PROP[0], PROP[1], ... properties.

If we either had a "call this for any property set/get attempt
where there is no specific method set" or else had array
properties supported by the core QOM code, we could avoid
having to set len-PROP first.

thanks
-- PMM
Daniel P. Berrangé July 11, 2022, 11:09 a.m. UTC | #12
On Mon, Jul 11, 2022 at 11:32:35AM +0100, Peter Maydell wrote:
> On Fri, 8 Jul 2022 at 12:01, Daniel P. Berrangé <berrange@redhat.com> wrote:
> > What alternative options do we have for addressing this scenario.
> >
> > I can think of
> >
> >   - Auto-create array elements, if seeing an element set before length.
> >
> >     This is based on the theory that 'len-PROP' field is largely
> >     redundant. It is only needed if you want to create a sparse
> >     array, with empty elements /after/ the last one explicitly
> >     set, or if you want to get error reporting for an app setting
> >     element 3 after saying it wanted a 2 element list. IMHO the
> >     error reporting benefit is dubious, because the error scenario
> >     only exists because we made the app set this redundant 'len-PROP'
> >     attribute. Does anything actually need the 'sparse array'
> >     facility ?
> 
> I'm pretty sure that nothing needs sparse array elements like
> that. The major reason for the len-PROP field is an implementation
> one: because there is currently no way for a QOM object to
> say "call this method if somebody tries to set a non-existent
> property", the way array properties work is that the 'set'
> method for the len-PROP property is the place where we then
> add the PROP[0], PROP[1], ... properties.

Ahhh, I see what you mean. I totally missed this subtle detail.

IIUC, there's essentially no such thing as array properties
in QOM. 'prop[0]', 'prop[1]', 'prop[2]', etc are all simply
scalar properties from QOM's, that just happen to follow a
common naming scheme, but QOM doesn't care about that.

> If we either had a "call this for any property set/get attempt
> where there is no specific method set" or else had array
> properties supported by the core QOM code, we could avoid
> having to set len-PROP first.

Techically arrays are already supported at the core QOM level, because
you can use any QAPI type as a property.  The authz/list.c object
has a 'rules' property that is an array of QAuthzListRule objects:

  { 'struct': 'AuthZListProperties',
    'data': { '*policy': 'QAuthZListPolicy',
              '*rules': ['QAuthZListRule'] } }

At the time I wrote that, we couldn't express it on the CLI though,
without using JSON syntax for -object. I don't think we've ever
made it possible to use the opts_visitor with non-scalar properties
though.

With regards,
Daniel
Peter Maydell July 11, 2022, 11:15 a.m. UTC | #13
On Mon, 11 Jul 2022 at 12:09, Daniel P. Berrangé <berrange@redhat.com> wrote:
>
> On Mon, Jul 11, 2022 at 11:32:35AM +0100, Peter Maydell wrote:
> > I'm pretty sure that nothing needs sparse array elements like
> > that. The major reason for the len-PROP field is an implementation
> > one: because there is currently no way for a QOM object to
> > say "call this method if somebody tries to set a non-existent
> > property", the way array properties work is that the 'set'
> > method for the len-PROP property is the place where we then
> > add the PROP[0], PROP[1], ... properties.
>
> Ahhh, I see what you mean. I totally missed this subtle detail.
>
> IIUC, there's essentially no such thing as array properties
> in QOM. 'prop[0]', 'prop[1]', 'prop[2]', etc are all simply
> scalar properties from QOM's, that just happen to follow a
> common naming scheme, but QOM doesn't care about that.

Yeah. The exception is the bit Markus pointed out where somebody
has later added special case support for setting "prop[*]" to
mean "whatever the next index is".

> > If we either had a "call this for any property set/get attempt
> > where there is no specific method set" or else had array
> > properties supported by the core QOM code, we could avoid
> > having to set len-PROP first.
>
> Techically arrays are already supported at the core QOM level, because
> you can use any QAPI type as a property.  The authz/list.c object
> has a 'rules' property that is an array of QAuthzListRule objects:
>
>   { 'struct': 'AuthZListProperties',
>     'data': { '*policy': 'QAuthZListPolicy',
>               '*rules': ['QAuthZListRule'] } }
>
> At the time I wrote that, we couldn't express it on the CLI though,
> without using JSON syntax for -object. I don't think we've ever
> made it possible to use the opts_visitor with non-scalar properties
> though.

Mmm, if we had started the array-property implementation starting
from a QAPI API (or even with the idea of setting properties from
command line arguments) and working from there we'd probably have ended
up with something different. The primary use case though has
never involved QAPI or the command line, it's just C code for setting
property values on devices created within QEMU.

-- PMM
Markus Armbruster July 18, 2022, 10:45 a.m. UTC | #14
Peter Maydell <peter.maydell@linaro.org> writes:

> On Mon, 11 Jul 2022 at 12:09, Daniel P. Berrangé <berrange@redhat.com> wrote:
>>
>> On Mon, Jul 11, 2022 at 11:32:35AM +0100, Peter Maydell wrote:
>> > I'm pretty sure that nothing needs sparse array elements like
>> > that. The major reason for the len-PROP field is an implementation
>> > one: because there is currently no way for a QOM object to
>> > say "call this method if somebody tries to set a non-existent
>> > property", the way array properties work is that the 'set'
>> > method for the len-PROP property is the place where we then
>> > add the PROP[0], PROP[1], ... properties.
>>
>> Ahhh, I see what you mean. I totally missed this subtle detail.
>>
>> IIUC, there's essentially no such thing as array properties
>> in QOM. 'prop[0]', 'prop[1]', 'prop[2]', etc are all simply
>> scalar properties from QOM's, that just happen to follow a
>> common naming scheme, but QOM doesn't care about that.
>
> Yeah. The exception is the bit Markus pointed out where somebody
> has later added special case support for setting "prop[*]" to
> mean "whatever the next index is".
>
>> > If we either had a "call this for any property set/get attempt
>> > where there is no specific method set" or else had array
>> > properties supported by the core QOM code, we could avoid
>> > having to set len-PROP first.
>>
>> Techically arrays are already supported at the core QOM level, because
>> you can use any QAPI type as a property.  The authz/list.c object
>> has a 'rules' property that is an array of QAuthzListRule objects:
>>
>>   { 'struct': 'AuthZListProperties',
>>     'data': { '*policy': 'QAuthZListPolicy',
>>               '*rules': ['QAuthZListRule'] } }
>>
>> At the time I wrote that, we couldn't express it on the CLI though,
>> without using JSON syntax for -object. I don't think we've ever
>> made it possible to use the opts_visitor with non-scalar properties
>> though.

The opts visitor is flat by design.  Avoid it in new code, use
qobject_input_visitor_new_keyval() instead.  Typical use is via a
wrapper such as qobject_input_visitor_new_str().

> Mmm, if we had started the array-property implementation starting
> from a QAPI API (or even with the idea of setting properties from
> command line arguments) and working from there we'd probably have ended
> up with something different. The primary use case though has
> never involved QAPI or the command line, it's just C code for setting
> property values on devices created within QEMU.

Trouble with QOM is that things meant for internal use bleed to the
external interface so easily.  We've been quite cavalier about that.
Should we change our attitude?
diff mbox series

Patch

diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
index 82e90fc072..cf5c602286 100644
--- a/include/qapi/qmp/qdict.h
+++ b/include/qapi/qmp/qdict.h
@@ -16,8 +16,7 @@ 
 #include "qapi/qmp/qobject.h"
 #include "qemu/queue.h"
 
-#define QDICT_BUCKET_MAX 512
-
+#if 0
 typedef struct QDictEntry {
     char *key;
     QObject *value;
@@ -29,6 +28,18 @@  struct QDict {
     size_t size;
     QLIST_HEAD(,QDictEntry) table[QDICT_BUCKET_MAX];
 };
+#else
+typedef struct QDictEntry {
+    char *key;
+    QObject *value;
+    QSIMPLEQ_ENTRY(QDictEntry) next;
+} QDictEntry;
+
+struct QDict {
+    struct QObjectBase_ base;
+    QSIMPLEQ_HEAD(, QDictEntry) entries;
+};
+#endif
 
 void qdict_unref(QDict *q);
 
diff --git a/qobject/qdict.c b/qobject/qdict.c
index 8faff230d3..444608cbc4 100644
--- a/qobject/qdict.c
+++ b/qobject/qdict.c
@@ -29,27 +29,11 @@  QDict *qdict_new(void)
 
     qdict = g_malloc0(sizeof(*qdict));
     qobject_init(QOBJECT(qdict), QTYPE_QDICT);
+    QSIMPLEQ_INIT(&qdict->entries);
 
     return qdict;
 }
 
-/**
- * tdb_hash(): based on the hash algorithm from gdbm, via tdb
- * (from module-init-tools)
- */
-static unsigned int tdb_hash(const char *name)
-{
-    unsigned value;    /* Used to compute the hash value.  */
-    unsigned   i;      /* Used to cycle through random values. */
-
-    /* Set the initial value from the key size. */
-    for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++) {
-        value = (value + (((const unsigned char *)name)[i] << (i * 5 % 24)));
-    }
-
-    return (1103515243 * value + 12345);
-}
-
 /**
  * alloc_entry(): allocate a new QDictEntry
  */
@@ -88,15 +72,14 @@  const char *qdict_entry_key(const QDictEntry *entry)
 /**
  * qdict_find(): List lookup function
  */
-static QDictEntry *qdict_find(const QDict *qdict,
-                              const char *key, unsigned int bucket)
+static QDictEntry *qdict_find(const QDict *qdict, const char *key)
 {
     QDictEntry *entry;
 
-    QLIST_FOREACH(entry, &qdict->table[bucket], next)
-        if (!strcmp(entry->key, key)) {
+    QSIMPLEQ_FOREACH(entry, &qdict->entries, next) {
+        if (!strcmp(key, entry->key))
             return entry;
-        }
+    }
 
     return NULL;
 }
@@ -114,11 +97,8 @@  static QDictEntry *qdict_find(const QDict *qdict,
  */
 void qdict_put_obj(QDict *qdict, const char *key, QObject *value)
 {
-    unsigned int bucket;
-    QDictEntry *entry;
+    QDictEntry *entry = qdict_find(qdict, key);
 
-    bucket = tdb_hash(key) % QDICT_BUCKET_MAX;
-    entry = qdict_find(qdict, key, bucket);
     if (entry) {
         /* replace key's value */
         qobject_unref(entry->value);
@@ -126,8 +106,7 @@  void qdict_put_obj(QDict *qdict, const char *key, QObject *value)
     } else {
         /* allocate a new entry */
         entry = alloc_entry(key, value);
-        QLIST_INSERT_HEAD(&qdict->table[bucket], entry, next);
-        qdict->size++;
+        QSIMPLEQ_INSERT_TAIL(&qdict->entries, entry, next);
     }
 }
 
@@ -161,8 +140,8 @@  QObject *qdict_get(const QDict *qdict, const char *key)
 {
     QDictEntry *entry;
 
-    entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX);
-    return (entry == NULL ? NULL : entry->value);
+    entry = qdict_find(qdict, key);
+    return entry ? entry->value : NULL;
 }
 
 /**
@@ -172,8 +151,7 @@  QObject *qdict_get(const QDict *qdict, const char *key)
  */
 int qdict_haskey(const QDict *qdict, const char *key)
 {
-    unsigned int bucket = tdb_hash(key) % QDICT_BUCKET_MAX;
-    return (qdict_find(qdict, key, bucket) == NULL ? 0 : 1);
+    return qdict_find(qdict, key) != NULL;
 }
 
 /**
@@ -181,7 +159,14 @@  int qdict_haskey(const QDict *qdict, const char *key)
  */
 size_t qdict_size(const QDict *qdict)
 {
-    return qdict->size;
+    QDictEntry *entry;
+    size_t sz = 0;
+
+    QSIMPLEQ_FOREACH(entry, &qdict->entries, next) {
+        sz++;
+    }
+
+    return sz;
 }
 
 /**
@@ -301,25 +286,13 @@  const char *qdict_get_try_str(const QDict *qdict, const char *key)
     return qstr ? qstring_get_str(qstr) : NULL;
 }
 
-static QDictEntry *qdict_next_entry(const QDict *qdict, int first_bucket)
-{
-    int i;
-
-    for (i = first_bucket; i < QDICT_BUCKET_MAX; i++) {
-        if (!QLIST_EMPTY(&qdict->table[i])) {
-            return QLIST_FIRST(&qdict->table[i]);
-        }
-    }
-
-    return NULL;
-}
-
 /**
  * qdict_first(): Return first qdict entry for iteration.
  */
 const QDictEntry *qdict_first(const QDict *qdict)
 {
-    return qdict_next_entry(qdict, 0);
+    return QSIMPLEQ_FIRST(&qdict->entries);
+
 }
 
 /**
@@ -327,15 +300,7 @@  const QDictEntry *qdict_first(const QDict *qdict)
  */
 const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry)
 {
-    QDictEntry *ret;
-
-    ret = QLIST_NEXT(entry, next);
-    if (!ret) {
-        unsigned int bucket = tdb_hash(entry->key) % QDICT_BUCKET_MAX;
-        ret = qdict_next_entry(qdict, bucket + 1);
-    }
-
-    return ret;
+    return QSIMPLEQ_NEXT(entry, next);
 }
 
 /**
@@ -346,14 +311,11 @@  QDict *qdict_clone_shallow(const QDict *src)
 {
     QDict *dest;
     QDictEntry *entry;
-    int i;
 
     dest = qdict_new();
 
-    for (i = 0; i < QDICT_BUCKET_MAX; i++) {
-        QLIST_FOREACH(entry, &src->table[i], next) {
-            qdict_put_obj(dest, entry->key, qobject_ref(entry->value));
-        }
+    QSIMPLEQ_FOREACH(entry, &src->entries, next) {
+        qdict_put_obj(dest, entry->key, qobject_ref(entry->value));
     }
 
     return dest;
@@ -380,13 +342,11 @@  static void qentry_destroy(QDictEntry *e)
  */
 void qdict_del(QDict *qdict, const char *key)
 {
-    QDictEntry *entry;
+    QDictEntry *entry = qdict_find(qdict, key);
 
-    entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX);
     if (entry) {
-        QLIST_REMOVE(entry, next);
+        QSIMPLEQ_REMOVE(&qdict->entries, entry, QDictEntry, next);
         qentry_destroy(entry);
-        qdict->size--;
     }
 }
 
@@ -424,20 +384,16 @@  bool qdict_is_equal(const QObject *x, const QObject *y)
  */
 void qdict_destroy_obj(QObject *obj)
 {
-    int i;
     QDict *qdict;
 
     assert(obj != NULL);
     qdict = qobject_to(QDict, obj);
 
-    for (i = 0; i < QDICT_BUCKET_MAX; i++) {
-        QDictEntry *entry = QLIST_FIRST(&qdict->table[i]);
-        while (entry) {
-            QDictEntry *tmp = QLIST_NEXT(entry, next);
-            QLIST_REMOVE(entry, next);
-            qentry_destroy(entry);
-            entry = tmp;
-        }
+    while (!QSIMPLEQ_EMPTY(&qdict->entries)) {
+        QDictEntry *entry = QSIMPLEQ_FIRST(&qdict->entries);
+
+        QSIMPLEQ_REMOVE_HEAD(&qdict->entries, next);
+        qentry_destroy(entry);
     }
 
     g_free(qdict);
diff --git a/tests/unit/check-qdict.c b/tests/unit/check-qdict.c
index b5efa859b0..d7d3df5efb 100644
--- a/tests/unit/check-qdict.c
+++ b/tests/unit/check-qdict.c
@@ -47,7 +47,7 @@  static void qdict_put_obj_test(void)
     qdict_put_int(qdict, "", num);
 
     g_assert(qdict_size(qdict) == 1);
-    ent = QLIST_FIRST(&qdict->table[12345 % QDICT_BUCKET_MAX]);
+    ent = QSIMPLEQ_FIRST(&qdict->entries);
     qn = qobject_to(QNum, ent->value);
     g_assert_cmpint(qnum_get_int(qn), ==, num);
 
diff --git a/tests/unit/check-qobject.c b/tests/unit/check-qobject.c
index 022b7c74fe..0416762f80 100644
--- a/tests/unit/check-qobject.c
+++ b/tests/unit/check-qobject.c
@@ -192,10 +192,10 @@  static void qobject_is_equal_dict_test(void)
     qdict_put_int(dict_0, "baz", 3);
     qdict_put_null(dict_0, "null");
 
-    qdict_put_int(dict_1, "f.o", 1);
     qdict_put_int(dict_1, "bar", 2);
     qdict_put_int(dict_1, "baz", 3);
     qdict_put_null(dict_1, "null");
+    qdict_put_int(dict_1, "f.o", 1);
 
     qdict_put_int(dict_different_key, "F.o", 1);
     qdict_put_int(dict_different_key, "bar", 2);
diff --git a/tests/qemu-iotests/043.out b/tests/qemu-iotests/043.out
index 63ecb21816..d8fcff24e9 100644
--- a/tests/qemu-iotests/043.out
+++ b/tests/qemu-iotests/043.out
@@ -40,29 +40,29 @@  cluster_size: 65536
 == finite chain of length 3 (json) ==
 [
     {
-        "virtual-size": 134217728,
         "filename": "TEST_DIR/t.IMGFMT",
-        "cluster-size": 65536,
         "format": "IMGFMT",
-        "full-backing-filename": "TEST_DIR/t.IMGFMT.2.base",
+        "dirty-flag": false,
+        "virtual-size": 134217728,
+        "cluster-size": 65536,
         "backing-filename": "TEST_DIR/t.IMGFMT.2.base",
-        "dirty-flag": false
+        "full-backing-filename": "TEST_DIR/t.IMGFMT.2.base",
     },
     {
-        "virtual-size": 134217728,
         "filename": "TEST_DIR/t.IMGFMT.2.base",
-        "cluster-size": 65536,
         "format": "IMGFMT",
-        "full-backing-filename": "TEST_DIR/t.IMGFMT.1.base",
+        "dirty-flag": false,
+        "virtual-size": 134217728,
+        "cluster-size": 65536,
         "backing-filename": "TEST_DIR/t.IMGFMT.1.base",
-        "dirty-flag": false
+        "full-backing-filename": "TEST_DIR/t.IMGFMT.1.base",
     },
     {
-        "virtual-size": 134217728,
         "filename": "TEST_DIR/t.IMGFMT.1.base",
-        "cluster-size": 65536,
         "format": "IMGFMT",
-        "dirty-flag": false
+        "dirty-flag": false,
+        "virtual-size": 134217728,
+        "cluster-size": 65536,
     }
 ]
 *** done
diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out
index 329977d9b9..f654a6579c 100644
--- a/tests/qemu-iotests/060.out
+++ b/tests/qemu-iotests/060.out
@@ -17,11 +17,11 @@  virtual size: 64 MiB (67108864 bytes)
 cluster_size: 65536
 Format specific information:
     compat: 1.1
-    compression type: COMPRESSION_TYPE
-    lazy refcounts: false
-    refcount bits: 16
-    corrupt: true
     extended l2: false
+    lazy refcounts: false
+    corrupt: true
+    refcount bits: 16
+    compression type: COMPRESSION_TYPE
 qemu-io: can't open device TEST_DIR/t.IMGFMT: IMGFMT: Image is corrupt; cannot be opened read/write
 no file open, try 'help open'
 read 512/512 bytes at offset 0
@@ -418,11 +418,11 @@  Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with refcount table); further corruption events will be suppressed
 QMP_VERSION
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_IMAGE_CORRUPTED", "data": {"device": "none0", "msg": "Preventing invalid write on metadata (overlaps with refcount table)", "offset": 65536, "node-name": "drive", "fatal": true, "size": 65536}}
+{"event": "BLOCK_IMAGE_CORRUPTED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"device": "none0", "node-name": "drive", "msg": "Preventing invalid write on metadata (overlaps with refcount table)", "offset": 65536, "size": 65536, "fatal": true}}
 write failed: Input/output error
 {"return": ""}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
 
 === Testing incoming inactive corrupted image ===
 
@@ -430,10 +430,10 @@  Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 QMP_VERSION
 {"return": {}}
 qcow2: Image is corrupt: L2 table offset 0x2a2a2a00 unaligned (L1 index: 0); further non-fatal corruption events will be suppressed
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_IMAGE_CORRUPTED", "data": {"device": "", "msg": "L2 table offset 0x2a2a2a00 unaligned (L1 index: 0)", "node-name": "drive", "fatal": false}}
+{"event": "BLOCK_IMAGE_CORRUPTED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"device": "", "node-name": "drive", "msg": "L2 table offset 0x2a2a2a00 unaligned (L1 index: 0)", "fatal": false}}
 {"return": ""}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
 
     corrupt: false
 *** done
diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
index 139fc68177..6a05d67378 100644
--- a/tests/qemu-iotests/061.out
+++ b/tests/qemu-iotests/061.out
@@ -497,7 +497,7 @@  wrote 65536/65536 bytes at offset 2147483648
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 65536/65536 bytes at offset 3221225472
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-    (0.00/100%)
    (12.50/100%)
    (25.00/100%)
    (37.50/100%)
    (50.00/100%)
    (62.50/100%)
    (75.00/100%)
    (87.50/100%)
    (100.00/100%)
    (100.00/100%)
+    (0.00/100%)
    (12.50/100%)
    (25.00/100%)
    (37.50/100%)
    (50.00/100%)
    (62.50/100%)
    (75.00/100%)
    (87.50/100%)
    (100.00/100%)
    (100.00/100%)
 No errors were found on the image.
 
 === Testing progress report with snapshot ===
@@ -512,7 +512,7 @@  wrote 65536/65536 bytes at offset 2147483648
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 65536/65536 bytes at offset 3221225472
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-    (0.00/100%)
    (6.25/100%)
    (12.50/100%)
    (18.75/100%)
    (25.00/100%)
    (31.25/100%)
    (37.50/100%)
    (43.75/100%)
    (50.00/100%)
    (56.25/100%)
    (62.50/100%)
    (68.75/100%)
    (75.00/100%)
    (81.25/100%)
    (87.50/100%)
    (93.75/100%)
    (100.00/100%)
    (100.00/100%)
+    (0.00/100%)
    (6.25/100%)
    (12.50/100%)
    (18.75/100%)
    (25.00/100%)
    (31.25/100%)
    (37.50/100%)
    (43.75/100%)
    (50.00/100%)
    (56.25/100%)
    (62.50/100%)
    (68.75/100%)
    (75.00/100%)
    (81.25/100%)
    (87.50/100%)
    (93.75/100%)
    (100.00/100%)
    (100.00/100%)
 No errors were found on the image.
 
 === Testing version downgrade with external data file ===
@@ -525,13 +525,13 @@  virtual size: 64 MiB (67108864 bytes)
 cluster_size: 65536
 Format specific information:
     compat: 1.1
-    compression type: COMPRESSION_TYPE
-    lazy refcounts: false
-    refcount bits: 16
     data file: TEST_DIR/t.IMGFMT.data
     data file raw: false
-    corrupt: false
     extended l2: false
+    lazy refcounts: false
+    corrupt: false
+    refcount bits: 16
+    compression type: COMPRESSION_TYPE
 No errors were found on the image.
 
 === Testing version downgrade with extended L2 entries ===
@@ -552,13 +552,13 @@  virtual size: 64 MiB (67108864 bytes)
 cluster_size: 65536
 Format specific information:
     compat: 1.1
-    compression type: COMPRESSION_TYPE
-    lazy refcounts: false
-    refcount bits: 16
     data file: foo
     data file raw: false
-    corrupt: false
     extended l2: false
+    lazy refcounts: false
+    corrupt: false
+    refcount bits: 16
+    compression type: COMPRESSION_TYPE
 
 qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'data-file' is required for this image
 image: TEST_DIR/t.IMGFMT
@@ -567,12 +567,12 @@  virtual size: 64 MiB (67108864 bytes)
 cluster_size: 65536
 Format specific information:
     compat: 1.1
-    compression type: COMPRESSION_TYPE
-    lazy refcounts: false
-    refcount bits: 16
     data file raw: false
-    corrupt: false
     extended l2: false
+    lazy refcounts: false
+    corrupt: false
+    refcount bits: 16
+    compression type: COMPRESSION_TYPE
 
 === Clearing and setting data-file-raw ===
 
@@ -583,13 +583,13 @@  virtual size: 64 MiB (67108864 bytes)
 cluster_size: 65536
 Format specific information:
     compat: 1.1
-    compression type: COMPRESSION_TYPE
-    lazy refcounts: false
-    refcount bits: 16
     data file: TEST_DIR/t.IMGFMT.data
     data file raw: true
-    corrupt: false
     extended l2: false
+    lazy refcounts: false
+    corrupt: false
+    refcount bits: 16
+    compression type: COMPRESSION_TYPE
 No errors were found on the image.
 image: TEST_DIR/t.IMGFMT
 file format: IMGFMT
@@ -597,13 +597,13 @@  virtual size: 64 MiB (67108864 bytes)
 cluster_size: 65536
 Format specific information:
     compat: 1.1
-    compression type: COMPRESSION_TYPE
-    lazy refcounts: false
-    refcount bits: 16
     data file: TEST_DIR/t.IMGFMT.data
     data file raw: false
-    corrupt: false
     extended l2: false
+    lazy refcounts: false
+    corrupt: false
+    refcount bits: 16
+    compression type: COMPRESSION_TYPE
 No errors were found on the image.
 qemu-img: data-file-raw cannot be set on existing images
 image: TEST_DIR/t.IMGFMT
@@ -612,12 +612,12 @@  virtual size: 64 MiB (67108864 bytes)
 cluster_size: 65536
 Format specific information:
     compat: 1.1
-    compression type: COMPRESSION_TYPE
-    lazy refcounts: false
-    refcount bits: 16
     data file: TEST_DIR/t.IMGFMT.data
     data file raw: false
-    corrupt: false
     extended l2: false
+    lazy refcounts: false
+    corrupt: false
+    refcount bits: 16
+    compression type: COMPRESSION_TYPE
 No errors were found on the image.
 *** done
diff --git a/tests/qemu-iotests/071.out b/tests/qemu-iotests/071.out
index bca0c02f5c..ff00da1ad1 100644
--- a/tests/qemu-iotests/071.out
+++ b/tests/qemu-iotests/071.out
@@ -46,7 +46,7 @@  QMP_VERSION
 read failed: Input/output error
 {"return": ""}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
 
 
 === Testing blkverify on existing block device ===
@@ -85,7 +85,7 @@  wrote 512/512 bytes at offset 0
 read failed: Input/output error
 {"return": ""}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
 QEMU_PROG: Failed to flush the L2 table cache: Input/output error
 QEMU_PROG: Failed to flush the refcount block cache: Input/output error
 
diff --git a/tests/qemu-iotests/099.out b/tests/qemu-iotests/099.out
index 8cce627529..5726466bc6 100644
--- a/tests/qemu-iotests/099.out
+++ b/tests/qemu-iotests/099.out
@@ -12,11 +12,11 @@  blkverify:TEST_DIR/t.IMGFMT.compare:TEST_DIR/t.IMGFMT
 
 === Testing JSON filename for blkdebug ===
 
-json:{"driver": "IMGFMT", "file": {"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "l1_update"}}
+json:{"driver": "IMGFMT", "file": {"driver": "blkdebug", "inject-error.0.event": "l1_update", "image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}}}
 
 === Testing indirectly enforced JSON filename ===
 
-json:{"driver": "raw", "file": {"test": {"driver": "IMGFMT", "file": {"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "l1_update"}}, "driver": "blkverify", "raw": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.compare"}}}
+json:{"driver": "raw", "file": {"driver": "blkverify", "test": {"driver": "IMGFMT", "file": {"driver": "blkdebug", "inject-error.0.event": "l1_update", "image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}}}, "raw": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.compare"}}}
 
 === Testing plain filename for blkdebug ===
 
diff --git a/tests/qemu-iotests/108.out b/tests/qemu-iotests/108.out
index b5401d788d..faaabbcdf3 100644
--- a/tests/qemu-iotests/108.out
+++ b/tests/qemu-iotests/108.out
@@ -163,18 +163,18 @@  OK: Reftable is where we expect it
                "size": 67108864,
                "cluster-size": 512
            } } }
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "create"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "create"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "created"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "running"}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "create"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "create"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "create"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "waiting"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "pending"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "concluded"}}
 { "execute": "job-dismiss", "arguments": { "id": "create" } }
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "create"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "null"}}
 {"return": {}}
 { "execute": "quit" }
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
 
 wrote 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
diff --git a/tests/qemu-iotests/117.out b/tests/qemu-iotests/117.out
index 735ffd25c6..015c971197 100644
--- a/tests/qemu-iotests/117.out
+++ b/tests/qemu-iotests/117.out
@@ -19,7 +19,7 @@  wrote 65536/65536 bytes at offset 0
 {"return": ""}
 { 'execute': 'quit' }
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
 No errors were found on the image.
 read 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
diff --git a/tests/qemu-iotests/120.out b/tests/qemu-iotests/120.out
index 0744c1f136..d677c72599 100644
--- a/tests/qemu-iotests/120.out
+++ b/tests/qemu-iotests/120.out
@@ -6,7 +6,7 @@  wrote 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 {"return": ""}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
 read 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 read 65536/65536 bytes at offset 0
diff --git a/tests/qemu-iotests/127.out b/tests/qemu-iotests/127.out
index 1685c4850a..863832d162 100644
--- a/tests/qemu-iotests/127.out
+++ b/tests/qemu-iotests/127.out
@@ -14,20 +14,20 @@  wrote 42/42 bytes at offset 0
            'mode':   'existing',
            'sync':   'top'
        } }
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "mirror"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "mirror"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "created"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "running"}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "mirror"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "mirror", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "ready"}}
+{"event": "BLOCK_JOB_READY", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "mirror", "len": 65536, "offset": 65536, "speed": 0}}
 { 'execute': 'block-job-complete',
        'arguments': { 'device': 'mirror' } }
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "mirror"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "mirror"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "mirror", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "waiting"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "pending"}}
+{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "mirror", "len": 65536, "offset": 65536, "speed": 0}}
 { 'execute': 'quit' }
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "mirror"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "mirror"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "concluded"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "mirror", "status": "null"}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
 *** done
diff --git a/tests/qemu-iotests/140.out b/tests/qemu-iotests/140.out
index 312f76d5da..586b64b24e 100644
--- a/tests/qemu-iotests/140.out
+++ b/tests/qemu-iotests/140.out
@@ -15,10 +15,10 @@  read 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 { 'execute': 'eject',
        'arguments': { 'device': 'drv' }}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "drv"}}
+{"event": "BLOCK_EXPORT_DELETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "drv"}}
 qemu-io: can't open device nbd+unix:///drv?socket=SOCK_DIR/nbd: Requested export not available
 server reported: export 'drv' not present
 { 'execute': 'quit' }
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
 *** done
diff --git a/tests/qemu-iotests/141.out b/tests/qemu-iotests/141.out
index 63203d9944..4d8c7b598c 100644
--- a/tests/qemu-iotests/141.out
+++ b/tests/qemu-iotests/141.out
@@ -23,20 +23,20 @@  Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/m.
 'format': 'IMGFMT',
 'sync': 'none'}}
 Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT backing_fmt=IMGFMT
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "paused"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
 {'execute': 'blockdev-del',
           'arguments': {'node-name': 'drv0'}}
 {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: node is used as backing hd of 'NODE_NAME'"}}
 {'execute': 'block-job-cancel',
           'arguments': {'device': 'job0'}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 0, "speed": 0, "type": "backup"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "aborting"}}
+{"event": "BLOCK_JOB_CANCELLED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "backup", "device": "job0", "len": 1048576, "offset": 0, "speed": 0}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
 {'execute': 'blockdev-del',
           'arguments': {'node-name': 'drv0'}}
 {"return": {}}
@@ -59,21 +59,21 @@  Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
 'format': 'IMGFMT',
 'sync': 'none'}}
 Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT backing_fmt=IMGFMT
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "ready"}}
+{"event": "BLOCK_JOB_READY", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "job0", "len": 0, "offset": 0, "speed": 0}}
 {'execute': 'blockdev-del',
           'arguments': {'node-name': 'drv0'}}
 {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: mirror"}}
 {'execute': 'block-job-cancel',
           'arguments': {'device': 'job0'}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "waiting"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "pending"}}
+{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "job0", "len": 0, "offset": 0, "speed": 0}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
 {'execute': 'blockdev-del',
           'arguments': {'node-name': 'drv0'}}
 {"return": {}}
@@ -91,21 +91,21 @@  Formatting 'TEST_DIR/o.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
 {"return": {}}
 {'execute': 'block-commit',
 'arguments': {'job-id': 'job0', 'device': 'drv0'}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "ready"}}
+{"event": "BLOCK_JOB_READY", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "job0", "len": 0, "offset": 0, "speed": 0}}
 {'execute': 'blockdev-del',
           'arguments': {'node-name': 'drv0'}}
 {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: commit"}}
 {'execute': 'block-job-cancel',
           'arguments': {'device': 'job0'}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "waiting"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "pending"}}
+{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "job0", "len": 0, "offset": 0, "speed": 0}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
 {'execute': 'blockdev-del',
           'arguments': {'node-name': 'drv0'}}
 {"return": {}}
@@ -128,18 +128,18 @@  wrote 1048576/1048576 bytes at offset 0
 'device': 'drv0',
 'top':    'TEST_DIR/m.IMGFMT',
 'speed':  1}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
 {'execute': 'blockdev-del',
           'arguments': {'node-name': 'drv0'}}
 {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: commit"}}
 {'execute': 'block-job-cancel',
           'arguments': {'device': 'job0'}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, "type": "commit"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "aborting"}}
+{"event": "BLOCK_JOB_CANCELLED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "job0", "len": 1048576, "offset": 524288, "speed": 1}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
 {'execute': 'blockdev-del',
           'arguments': {'node-name': 'drv0'}}
 {"return": {}}
@@ -161,18 +161,18 @@  wrote 1048576/1048576 bytes at offset 0
 'arguments': {'job-id': 'job0',
 'device': 'drv0',
 'speed': 1}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
 {'execute': 'blockdev-del',
           'arguments': {'node-name': 'drv0'}}
 {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block device is in use by block job: stream"}}
 {'execute': 'block-job-cancel',
           'arguments': {'device': 'job0'}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, "type": "stream"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "aborting"}}
+{"event": "BLOCK_JOB_CANCELLED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "stream", "device": "job0", "len": 1048576, "offset": 524288, "speed": 1}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
 {'execute': 'blockdev-del',
           'arguments': {'node-name': 'drv0'}}
 {"return": {}}
diff --git a/tests/qemu-iotests/143.out b/tests/qemu-iotests/143.out
index 9ec5888e0e..ec58b08e43 100644
--- a/tests/qemu-iotests/143.out
+++ b/tests/qemu-iotests/143.out
@@ -11,5 +11,5 @@  qemu-io: can't open device nbd+unix:///aa--aa1?socket=SOCK_DIR/nbd: Requested ex
 server reported: export 'aa--aa...' not present
 { 'execute': 'quit' }
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
 *** done
diff --git a/tests/qemu-iotests/156.out b/tests/qemu-iotests/156.out
index 4a22f0c41a..bb01818fc7 100644
--- a/tests/qemu-iotests/156.out
+++ b/tests/qemu-iotests/156.out
@@ -26,11 +26,11 @@  Formatting 'TEST_DIR/t.IMGFMT.target.overlay', fmt=IMGFMT size=1048576 backing_f
                       'target': 'TEST_DIR/t.IMGFMT.target.overlay',
                       'mode': 'existing',
                       'sync': 'top' } }
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "source"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "source"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "created"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "running"}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "source"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "source", "len": 131072, "offset": 131072, "speed": 0, "type": "mirror"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "ready"}}
+{"event": "BLOCK_JOB_READY", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "source", "len": 131072, "offset": 131072, "speed": 0}}
 { 'execute': 'human-monitor-command',
        'arguments': { 'command-line':
                       'qemu-io source "write -P 4 192k 64k"' } }
@@ -40,11 +40,11 @@  wrote 65536/65536 bytes at offset 196608
 { 'execute': 'block-job-complete',
        'arguments': { 'device': 'source' } }
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "source"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "source"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "source", "len": 196608, "offset": 196608, "speed": 0, "type": "mirror"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "source"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "source"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "waiting"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "pending"}}
+{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "source", "len": 196608, "offset": 196608, "speed": 0}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "concluded"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "source", "status": "null"}}
 
 { 'execute': 'human-monitor-command',
        'arguments': { 'command-line':
@@ -73,7 +73,7 @@  read 65536/65536 bytes at offset 196608
 
 { 'execute': 'quit' }
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
 
 read 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
diff --git a/tests/qemu-iotests/161.out b/tests/qemu-iotests/161.out
index 6cc285afcf..c62657639a 100644
--- a/tests/qemu-iotests/161.out
+++ b/tests/qemu-iotests/161.out
@@ -18,17 +18,17 @@  Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
 {"return": {}}
 { 'execute': 'block-stream',        'arguments': { 'device': 'none0',
                       'base': 'TEST_DIR/t.IMGFMT.base' } }
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "none0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "none0"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "created"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "running"}}
 {"return": {}}
 { 'execute': 'human-monitor-command',
        'arguments': { 'command-line':
                       'qemu-io none0 "reopen -o backing.detect-zeroes=on"' } }
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "none0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "none0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "none0", "len": 1048576, "offset": 1048576, "speed": 0, "type": "stream"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "none0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "none0"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "waiting"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "pending"}}
+{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "stream", "device": "none0", "len": 1048576, "offset": 1048576, "speed": 0}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "concluded"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "null"}}
 {"return": ""}
 
 *** Commit and then change an option on the backing file
@@ -40,16 +40,16 @@  Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
 {"return": {}}
 { 'execute': 'block-commit',        'arguments': { 'device': 'none0',
                       'top': 'TEST_DIR/t.IMGFMT.int' } }
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "none0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "none0"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "created"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "running"}}
 {"return": {}}
 { 'execute': 'human-monitor-command',
        'arguments': { 'command-line':
                       'qemu-io none0 "reopen -o backing.detect-zeroes=on"' } }
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "none0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "none0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "none0", "len": 1048576, "offset": 1048576, "speed": 0, "type": "commit"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "none0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "none0"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "waiting"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "pending"}}
+{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "none0", "len": 1048576, "offset": 1048576, "speed": 0}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "concluded"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "none0", "status": "null"}}
 {"return": ""}
 *** done
diff --git a/tests/qemu-iotests/176.out b/tests/qemu-iotests/176.out
index 9d09b60452..b46b743850 100644
--- a/tests/qemu-iotests/176.out
+++ b/tests/qemu-iotests/176.out
@@ -170,7 +170,7 @@  QMP_VERSION
 {"return": {}}
 {"return": {}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
 wrote 196608/196608 bytes at offset 2147287040
 192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 131072/131072 bytes at offset 2147352576
@@ -207,7 +207,7 @@  QMP_VERSION
 {"return": {}}
 {"return": {"sha256": HASH}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
 
 === Test pass bitmap.1 ===
 
@@ -219,7 +219,7 @@  QMP_VERSION
 {"return": {}}
 {"return": {}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
 wrote 196608/196608 bytes at offset 2147287040
 192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 131072/131072 bytes at offset 2147352576
@@ -257,7 +257,7 @@  QMP_VERSION
 {"return": {}}
 {"return": {"sha256": HASH}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
 
 === Test pass bitmap.2 ===
 
@@ -269,7 +269,7 @@  QMP_VERSION
 {"return": {}}
 {"return": {}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
 wrote 196608/196608 bytes at offset 2147287040
 192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 131072/131072 bytes at offset 2147352576
@@ -307,7 +307,7 @@  QMP_VERSION
 {"return": {}}
 {"return": {"sha256": HASH}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
 
 === Test pass bitmap.3 ===
 
@@ -319,7 +319,7 @@  QMP_VERSION
 {"return": {}}
 {"return": {}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
 wrote 196608/196608 bytes at offset 2147287040
 192 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 wrote 131072/131072 bytes at offset 2147352576
@@ -354,5 +354,5 @@  QMP_VERSION
 {"return": {}}
 {"return": {"sha256": HASH}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
+{"event": "SHUTDOWN", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"guest": false, "reason": "host-qmp-quit"}}
 *** done
diff --git a/tests/qemu-iotests/184.out b/tests/qemu-iotests/184.out
index 77e5489d65..93e33ba20a 100644
--- a/tests/qemu-iotests/184.out
+++ b/tests/qemu-iotests/184.out
@@ -24,64 +24,64 @@  Testing:
 {
     "return": [
         {
-            "iops_rd": 0,
+            "file": "json:{\"driver\": \"throttle\", \"throttle-group\": \"group0\", \"file\": {\"driver\": \"null-co\"}}",
+            "node-name": "throttle0",
+            "ro": false,
+            "drv": "throttle",
+            "backing_file_depth": 1,
+            "encrypted": false,
             "detect_zeroes": "off",
+            "bps": 0,
+            "bps_rd": 0,
+            "bps_wr": 0,
+            "iops": 0,
+            "iops_rd": 0,
+            "iops_wr": 0,
             "image": {
+                "filename": "json:{\"driver\": \"throttle\", \"throttle-group\": \"group0\", \"file\": {\"driver\": \"null-co\"}}",
+                "format": "throttle",
+                "actual-size": 0,
+                "virtual-size": 1073741824,
                 "backing-image": {
-                    "virtual-size": 1073741824,
                     "filename": "null-co://",
                     "format": "null-co",
-                    "actual-size": 0
-                },
-                "virtual-size": 1073741824,
-                "filename": "json:{\"throttle-group\": \"group0\", \"driver\": \"throttle\", \"file\": {\"driver\": \"null-co\"}}",
-                "format": "throttle",
-                "actual-size": 0
+                    "actual-size": 0,
+                    "virtual-size": 1073741824
+                }
             },
-            "iops_wr": 0,
-            "ro": false,
-            "node-name": "throttle0",
-            "backing_file_depth": 1,
-            "drv": "throttle",
-            "iops": 0,
-            "bps_wr": 0,
-            "write_threshold": 0,
-            "encrypted": false,
-            "bps": 0,
-            "bps_rd": 0,
             "cache": {
-                "no-flush": false,
+                "writeback": true,
                 "direct": false,
-                "writeback": true
+                "no-flush": false
             },
-            "file": "json:{\"throttle-group\": \"group0\", \"driver\": \"throttle\", \"file\": {\"driver\": \"null-co\"}}"
+            "write_threshold": 0
         },
         {
-            "iops_rd": 0,
-            "detect_zeroes": "off",
-            "image": {
-                "virtual-size": 1073741824,
-                "filename": "null-co://",
-                "format": "null-co",
-                "actual-size": 0
-            },
-            "iops_wr": 0,
-            "ro": false,
+            "file": "null-co://",
             "node-name": "disk0",
-            "backing_file_depth": 0,
+            "ro": false,
             "drv": "null-co",
-            "iops": 0,
-            "bps_wr": 0,
-            "write_threshold": 0,
+            "backing_file_depth": 0,
             "encrypted": false,
+            "detect_zeroes": "off",
             "bps": 0,
             "bps_rd": 0,
-            "cache": {
-                "no-flush": false,
-                "direct": false,
-                "writeback": true
+            "bps_wr": 0,
+            "iops": 0,
+            "iops_rd": 0,
+            "iops_wr": 0,
+            "image": {
+                "filename": "null-co://",
+                "format": "null-co",
+                "actual-size": 0,
+                "virtual-size": 1073741824
             },
-            "file": "null-co://"
+            "cache": {
+                "writeback": true,
+                "direct": false,
+                "no-flush": false
+            },
+            "write_threshold": 0
         }
     ]
 }
@@ -94,11 +94,11 @@  Testing:
     }
 }
 {
+    "event": "SHUTDOWN",
     "timestamp": {
         "seconds":  TIMESTAMP,
         "microseconds":  TIMESTAMP
     },
-    "event": "SHUTDOWN",
     "data": {
         "guest": false,
         "reason": "host-qmp-quit"
@@ -121,52 +121,25 @@  Testing:
 }
 {
     "return": {
-        "bps-read-max-length": 1,
-        "iops-read-max-length": 1,
-        "bps-read-max": 0,
-        "bps-total": 0,
-        "iops-total-max-length": 1,
         "iops-total": 1000,
-        "iops-write-max": 0,
-        "bps-write": 0,
-        "bps-total-max": 0,
-        "bps-write-max": 0,
-        "iops-size": 0,
-        "iops-read": 0,
-        "iops-write-max-length": 1,
-        "iops-write": 0,
-        "bps-total-max-length": 1,
-        "iops-read-max": 0,
-        "bps-read": 0,
-        "bps-write-max-length": 1,
-        "iops-total-max": 0
-    }
-}
-{
-    "return": {
-    }
-}
-{
-    "return": {
-        "bps-read-max-length": 1,
-        "iops-read-max-length": 1,
-        "bps-read-max": 0,
-        "bps-total": 0,
+        "iops-total-max": 0,
         "iops-total-max-length": 1,
-        "iops-total": 0,
-        "iops-write-max": 0,
-        "bps-write": 0,
-        "bps-total-max": 0,
-        "bps-write-max": 0,
-        "iops-size": 0,
         "iops-read": 0,
-        "iops-write-max-length": 1,
-        "iops-write": 0,
-        "bps-total-max-length": 1,
         "iops-read-max": 0,
+        "iops-read-max-length": 1,
+        "iops-write": 0,
+        "iops-write-max": 0,
+        "iops-write-max-length": 1,
+        "bps-total": 0,
+        "bps-total-max": 0,
+        "bps-total-max-length": 1,
         "bps-read": 0,
+        "bps-read-max": 0,
+        "bps-read-max-length": 1,
+        "bps-write": 0,
+        "bps-write-max": 0,
         "bps-write-max-length": 1,
-        "iops-total-max": 0
+        "iops-size": 0
     }
 }
 {
@@ -174,11 +147,38 @@  Testing:
     }
 }
 {
+    "return": {
+        "iops-total": 0,
+        "iops-total-max": 0,
+        "iops-total-max-length": 1,
+        "iops-read": 0,
+        "iops-read-max": 0,
+        "iops-read-max-length": 1,
+        "iops-write": 0,
+        "iops-write-max": 0,
+        "iops-write-max-length": 1,
+        "bps-total": 0,
+        "bps-total-max": 0,
+        "bps-total-max-length": 1,
+        "bps-read": 0,
+        "bps-read-max": 0,
+        "bps-read-max-length": 1,
+        "bps-write": 0,
+        "bps-write-max": 0,
+        "bps-write-max-length": 1,
+        "iops-size": 0
+    }
+}
+{
+    "return": {
+    }
+}
+{
+    "event": "SHUTDOWN",
     "timestamp": {
         "seconds":  TIMESTAMP,
         "microseconds":  TIMESTAMP
     },
-    "event": "SHUTDOWN",
     "data": {
         "guest": false,
         "reason": "host-qmp-quit"
@@ -216,11 +216,11 @@  Testing:
     }
 }
 {
+    "event": "SHUTDOWN",
     "timestamp": {
         "seconds":  TIMESTAMP,
         "microseconds":  TIMESTAMP
     },
-    "event": "SHUTDOWN",
     "data": {
         "guest": false,
         "reason": "host-qmp-quit"
@@ -252,11 +252,11 @@  Testing:
     }
 }
 {
+    "event": "SHUTDOWN",
     "timestamp": {
         "seconds":  TIMESTAMP,
         "microseconds":  TIMESTAMP
     },
-    "event": "SHUTDOWN",
     "data": {
         "guest": false,
         "reason": "host-qmp-quit"
diff --git a/tests/qemu-iotests/186.out b/tests/qemu-iotests/186.out
index 01530040e5..12ea630222 100644
--- a/tests/qemu-iotests/186.out
+++ b/tests/qemu-iotests/186.out
@@ -57,7 +57,7 @@  qdev_id: [not inserted]
 Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device ide-hd,drive=null
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
+null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
     Attached to:      /machine/peripheral-anon/device[N]
     Cache mode:       writeback
 (qemu) quit
@@ -65,7 +65,7 @@  null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
 Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device ide-hd,drive=null,id=qdev_id
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
+null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
     Attached to:      qdev_id
     Cache mode:       writeback
 (qemu) quit
@@ -73,7 +73,7 @@  null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
 Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device scsi-hd,drive=null
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
+null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
     Attached to:      /machine/peripheral-anon/device[N]
     Cache mode:       writeback
 (qemu) quit
@@ -81,7 +81,7 @@  null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
 Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device scsi-hd,drive=null,id=qdev_id
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
+null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
     Attached to:      qdev_id
     Cache mode:       writeback
 (qemu) quit
@@ -89,7 +89,7 @@  null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
 Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device virtio-blk-pci,drive=null
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
+null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
     Attached to:      /machine/peripheral-anon/device[N]/virtio-backend
     Cache mode:       writeback
 (qemu) quit
@@ -97,7 +97,7 @@  null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
 Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device virtio-blk-pci,drive=null,id=qdev_id
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
+null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
     Attached to:      /machine/peripheral/qdev_id/virtio-backend
     Cache mode:       writeback
 (qemu) quit
@@ -105,7 +105,7 @@  null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
 Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device floppy,drive=null
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
+null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
     Attached to:      /machine/peripheral-anon/device[N]
     Removable device: not locked, tray closed
     Cache mode:       writeback
@@ -114,7 +114,7 @@  null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
 Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device floppy,drive=null,id=qdev_id
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
+null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
     Attached to:      qdev_id
     Removable device: not locked, tray closed
     Cache mode:       writeback
@@ -123,7 +123,7 @@  null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
 Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device ide-cd,drive=null
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
+null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
     Attached to:      /machine/peripheral-anon/device[N]
     Removable device: not locked, tray closed
     Cache mode:       writeback
@@ -132,7 +132,7 @@  null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
 Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device ide-cd,drive=null,id=qdev_id
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
+null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
     Attached to:      qdev_id
     Removable device: not locked, tray closed
     Cache mode:       writeback
@@ -141,7 +141,7 @@  null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
 Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device scsi-cd,drive=null
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
+null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
     Attached to:      /machine/peripheral-anon/device[N]
     Removable device: not locked, tray closed
     Cache mode:       writeback
@@ -150,7 +150,7 @@  null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
 Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device scsi-cd,drive=null,id=qdev_id
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
+null: json:{"driver": "null-co", "read-zeroes": true} (null-co)
     Attached to:      qdev_id
     Removable device: not locked, tray closed
     Cache mode:       writeback
@@ -162,11 +162,11 @@  null: json:{"read-zeroes": true, "driver": "null-co"} (null-co)
 Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-hd,drive=null,id=qdev_id
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Removable device: not locked, tray closed
     Cache mode:       writeback
 
-null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Attached to:      qdev_id
     Cache mode:       writeback
 (qemu) quit
@@ -174,11 +174,11 @@  null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
 Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-hd,drive=null,id=qdev_id
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Removable device: not locked, tray closed
     Cache mode:       writeback
 
-null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Attached to:      qdev_id
     Cache mode:       writeback
 (qemu) quit
@@ -186,11 +186,11 @@  null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
 Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device virtio-blk-pci,drive=null,id=qdev_id
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Removable device: not locked, tray closed
     Cache mode:       writeback
 
-null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Attached to:      /machine/peripheral/qdev_id/virtio-backend
     Cache mode:       writeback
 (qemu) quit
@@ -198,11 +198,11 @@  null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
 Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device floppy,drive=null,id=qdev_id
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Removable device: not locked, tray closed
     Cache mode:       writeback
 
-null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Attached to:      qdev_id
     Removable device: not locked, tray closed
     Cache mode:       writeback
@@ -211,11 +211,11 @@  null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
 Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-cd,drive=null,id=qdev_id
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Removable device: not locked, tray closed
     Cache mode:       writeback
 
-null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Attached to:      qdev_id
     Removable device: not locked, tray closed
     Cache mode:       writeback
@@ -224,11 +224,11 @@  null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
 Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-cd,drive=null,id=qdev_id
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Removable device: not locked, tray closed
     Cache mode:       writeback
 
-null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+null: json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Attached to:      qdev_id
     Removable device: not locked, tray closed
     Cache mode:       writeback
@@ -240,7 +240,7 @@  null: json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
 Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-hd,drive=none0
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Attached to:      /machine/peripheral-anon/device[N]
     Cache mode:       writeback
 (qemu) quit
@@ -248,7 +248,7 @@  none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
 Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-hd,drive=none0,id=qdev_id
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Attached to:      qdev_id
     Cache mode:       writeback
 (qemu) quit
@@ -256,7 +256,7 @@  none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
 Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-hd,drive=none0
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Attached to:      /machine/peripheral-anon/device[N]
     Cache mode:       writeback
 (qemu) quit
@@ -264,7 +264,7 @@  none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
 Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-hd,drive=none0,id=qdev_id
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Attached to:      qdev_id
     Cache mode:       writeback
 (qemu) quit
@@ -272,7 +272,7 @@  none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
 Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device virtio-blk-pci,drive=none0
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Attached to:      /machine/peripheral-anon/device[N]/virtio-backend
     Cache mode:       writeback
 (qemu) quit
@@ -280,7 +280,7 @@  none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
 Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device virtio-blk-pci,drive=none0,id=qdev_id
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Attached to:      /machine/peripheral/qdev_id/virtio-backend
     Cache mode:       writeback
 (qemu) quit
@@ -288,7 +288,7 @@  none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
 Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device floppy,drive=none0
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Attached to:      /machine/peripheral-anon/device[N]
     Removable device: not locked, tray closed
     Cache mode:       writeback
@@ -297,7 +297,7 @@  none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
 Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device floppy,drive=none0,id=qdev_id
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Attached to:      qdev_id
     Removable device: not locked, tray closed
     Cache mode:       writeback
@@ -306,7 +306,7 @@  none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
 Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-cd,drive=none0
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Attached to:      /machine/peripheral-anon/device[N]
     Removable device: not locked, tray closed
     Cache mode:       writeback
@@ -315,7 +315,7 @@  none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
 Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device ide-cd,drive=none0,id=qdev_id
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Attached to:      qdev_id
     Removable device: not locked, tray closed
     Cache mode:       writeback
@@ -324,7 +324,7 @@  none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
 Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-cd,drive=none0
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Attached to:      /machine/peripheral-anon/device[N]
     Removable device: not locked, tray closed
     Cache mode:       writeback
@@ -333,7 +333,7 @@  none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
 Testing: -drive if=none,driver=null-co,read-zeroes=on,node-name=null -device scsi-cd,drive=none0,id=qdev_id
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-none0 (null): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+none0 (null): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Attached to:      qdev_id
     Removable device: not locked, tray closed
     Cache mode:       writeback
@@ -411,7 +411,7 @@  floppy0: [not inserted]
 Testing: -drive if=floppy,driver=null-co,read-zeroes=on
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-floppy0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+floppy0 (NODE_NAME): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Attached to:      /machine/unattached/device[N]
     Removable device: not locked, tray closed
     Cache mode:       writeback
@@ -420,7 +420,7 @@  floppy0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
 Testing: -drive if=ide,driver=null-co,read-zeroes=on
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-ide0-hd0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+ide0-hd0 (NODE_NAME): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Attached to:      /machine/unattached/device[N]
     Cache mode:       writeback
 (qemu) quit
@@ -436,7 +436,7 @@  ide0-cd0: [not inserted]
 Testing: -drive if=ide,driver=null-co,read-zeroes=on,media=cdrom
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-ide0-cd0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co, read-only)
+ide0-cd0 (NODE_NAME): json:{"driver": "null-co", "read-zeroes": "on"} (null-co, read-only)
     Attached to:      /machine/unattached/device[N]
     Removable device: not locked, tray closed
     Cache mode:       writeback
@@ -445,7 +445,7 @@  ide0-cd0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co,
 Testing: -drive if=virtio,driver=null-co,read-zeroes=on
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-virtio0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
+virtio0 (NODE_NAME): json:{"driver": "null-co", "read-zeroes": "on"} (null-co)
     Attached to:      /machine/peripheral-anon/device[N]/virtio-backend
     Cache mode:       writeback
 (qemu) quit
@@ -453,7 +453,7 @@  virtio0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co"} (null-co)
 Testing: -drive if=pflash,driver=null-co,read-zeroes=on,size=1M
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) info block
-pflash0 (NODE_NAME): json:{"read-zeroes": "on", "driver": "null-co", "size": "1M"} (null-co)
+pflash0 (NODE_NAME): json:{"driver": "null-co", "size": "1M", "read-zeroes": "on"} (null-co)
     Attached to:      /machine/system.flash0
     Cache mode:       writeback
 (qemu) quit
diff --git a/tests/qemu-iotests/190.out b/tests/qemu-iotests/190.out
index ed9d8214eb..2acea9982c 100644
--- a/tests/qemu-iotests/190.out
+++ b/tests/qemu-iotests/190.out
@@ -29,8 +29,8 @@  bitmaps size: 537198592
 
 expected bitmap 545259520
 {
-    "bitmaps": 545259520,
     "required": 18874368,
-    "fully-allocated": 2199042129920
+    "fully-allocated": 2199042129920,
+    "bitmaps": 545259520
 }
 *** done
diff --git a/tests/qemu-iotests/191.out b/tests/qemu-iotests/191.out
index ea88777374..a7dfb22080 100644
--- a/tests/qemu-iotests/191.out
+++ b/tests/qemu-iotests/191.out
@@ -22,25 +22,25 @@  wrote 65536/65536 bytes at offset 1048576
                       'base':'TEST_DIR/t.IMGFMT.base',
                       'top': 'TEST_DIR/t.IMGFMT.mid' } }
 {
+    "event": "JOB_STATUS_CHANGE",
     "timestamp": {
         "seconds":  TIMESTAMP,
         "microseconds":  TIMESTAMP
     },
-    "event": "JOB_STATUS_CHANGE",
     "data": {
-        "status": "created",
-        "id": "commit0"
+        "id": "commit0",
+        "status": "created"
     }
 }
 {
+    "event": "JOB_STATUS_CHANGE",
     "timestamp": {
         "seconds":  TIMESTAMP,
         "microseconds":  TIMESTAMP
     },
-    "event": "JOB_STATUS_CHANGE",
     "data": {
-        "status": "running",
-        "id": "commit0"
+        "id": "commit0",
+        "status": "running"
     }
 }
 {
@@ -48,61 +48,61 @@  wrote 65536/65536 bytes at offset 1048576
     }
 }
 {
+    "event": "JOB_STATUS_CHANGE",
     "timestamp": {
         "seconds":  TIMESTAMP,
         "microseconds":  TIMESTAMP
     },
-    "event": "JOB_STATUS_CHANGE",
     "data": {
-        "status": "waiting",
-        "id": "commit0"
+        "id": "commit0",
+        "status": "waiting"
     }
 }
 {
+    "event": "JOB_STATUS_CHANGE",
     "timestamp": {
         "seconds":  TIMESTAMP,
         "microseconds":  TIMESTAMP
     },
-    "event": "JOB_STATUS_CHANGE",
     "data": {
-        "status": "pending",
-        "id": "commit0"
+        "id": "commit0",
+        "status": "pending"
     }
 }
 {
-    "timestamp": {
-        "seconds":  TIMESTAMP,
-        "microseconds":  TIMESTAMP
-    },
     "event": "BLOCK_JOB_COMPLETED",
+    "timestamp": {
+        "seconds":  TIMESTAMP,
+        "microseconds":  TIMESTAMP
+    },
     "data": {
+        "type": "commit",
         "device": "commit0",
         "len": 67108864,
         "offset": 67108864,
-        "speed": 0,
-        "type": "commit"
+        "speed": 0
     }
 }
 {
+    "event": "JOB_STATUS_CHANGE",
     "timestamp": {
         "seconds":  TIMESTAMP,
         "microseconds":  TIMESTAMP
     },
-    "event": "JOB_STATUS_CHANGE",
     "data": {
-        "status": "concluded",
-        "id": "commit0"
+        "id": "commit0",
+        "status": "concluded"
     }
 }
 {
+    "event": "JOB_STATUS_CHANGE",
     "timestamp": {
         "seconds":  TIMESTAMP,
         "microseconds":  TIMESTAMP
     },
-    "event": "JOB_STATUS_CHANGE",
     "data": {
-        "status": "null",
-        "id": "commit0"
+        "id": "commit0",
+        "status": "null"
     }
 }
 
@@ -112,268 +112,268 @@  wrote 65536/65536 bytes at offset 1048576
 {
     "return": [
         {
-            "iops_rd": 0,
-            "detect_zeroes": "off",
-            "image": {
-                "backing-image": {
-                    "virtual-size": 67108864,
-                    "filename": "TEST_DIR/t.IMGFMT.base",
-                    "cluster-size": 65536,
-                    "format": "IMGFMT",
-                    "actual-size": SIZE,
-                    "dirty-flag": false
-                },
-                "backing-filename-format": "IMGFMT",
-                "virtual-size": 67108864,
-                "filename": "TEST_DIR/t.IMGFMT.ovl2",
-                "cluster-size": 65536,
-                "format": "IMGFMT",
-                "actual-size": SIZE,
-                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
-                "backing-filename": "TEST_DIR/t.IMGFMT.base",
-                "dirty-flag": false
-            },
-            "iops_wr": 0,
-            "ro": false,
+            "file": "TEST_DIR/t.IMGFMT.ovl2",
             "node-name": "top2",
-            "backing_file_depth": 1,
+            "ro": false,
             "drv": "IMGFMT",
-            "iops": 0,
-            "bps_wr": 0,
-            "write_threshold": 0,
             "backing_file": "TEST_DIR/t.IMGFMT.base",
+            "backing_file_depth": 1,
             "encrypted": false,
+            "detect_zeroes": "off",
             "bps": 0,
             "bps_rd": 0,
-            "cache": {
-                "no-flush": false,
-                "direct": false,
-                "writeback": true
+            "bps_wr": 0,
+            "iops": 0,
+            "iops_rd": 0,
+            "iops_wr": 0,
+            "image": {
+                "filename": "TEST_DIR/t.IMGFMT.ovl2",
+                "format": "IMGFMT",
+                "dirty-flag": false,
+                "actual-size": SIZE,
+                "virtual-size": 67108864,
+                "cluster-size": 65536,
+                "backing-filename": "TEST_DIR/t.IMGFMT.base",
+                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
+                "backing-filename-format": "IMGFMT",
+                "backing-image": {
+                    "filename": "TEST_DIR/t.IMGFMT.base",
+                    "format": "IMGFMT",
+                    "dirty-flag": false,
+                    "actual-size": SIZE,
+                    "virtual-size": 67108864,
+                    "cluster-size": 65536,
+                },
             },
-            "file": "TEST_DIR/t.IMGFMT.ovl2"
+            "cache": {
+                "writeback": true,
+                "direct": false,
+                "no-flush": false
+            },
+            "write_threshold": 0
         },
         {
-            "iops_rd": 0,
+            "file": "TEST_DIR/t.IMGFMT.ovl2",
+            "node-name": "NODE_NAME",
+            "ro": false,
+            "drv": "file",
+            "backing_file_depth": 0,
+            "encrypted": false,
             "detect_zeroes": "off",
+            "bps": 0,
+            "bps_rd": 0,
+            "bps_wr": 0,
+            "iops": 0,
+            "iops_rd": 0,
+            "iops_wr": 0,
             "image": {
-                "virtual-size": 197120,
                 "filename": "TEST_DIR/t.IMGFMT.ovl2",
                 "format": "file",
+                "dirty-flag": false,
                 "actual-size": SIZE,
-                "dirty-flag": false
+                "virtual-size": 197120
             },
-            "iops_wr": 0,
-            "ro": false,
-            "node-name": "NODE_NAME",
-            "backing_file_depth": 0,
-            "drv": "file",
-            "iops": 0,
-            "bps_wr": 0,
-            "write_threshold": 0,
-            "encrypted": false,
-            "bps": 0,
-            "bps_rd": 0,
             "cache": {
-                "no-flush": false,
+                "writeback": true,
                 "direct": false,
-                "writeback": true
+                "no-flush": false
             },
-            "file": "TEST_DIR/t.IMGFMT.ovl2"
+            "write_threshold": 0
         },
         {
-            "iops_rd": 0,
-            "detect_zeroes": "off",
-            "image": {
-                "backing-image": {
-                    "virtual-size": 67108864,
-                    "filename": "TEST_DIR/t.IMGFMT.base",
-                    "cluster-size": 65536,
-                    "format": "IMGFMT",
-                    "actual-size": SIZE,
-                    "dirty-flag": false
-                },
-                "backing-filename-format": "IMGFMT",
-                "virtual-size": 67108864,
-                "filename": "TEST_DIR/t.IMGFMT",
-                "cluster-size": 65536,
-                "format": "IMGFMT",
-                "actual-size": SIZE,
-                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
-                "backing-filename": "TEST_DIR/t.IMGFMT.base",
-                "dirty-flag": false
-            },
-            "iops_wr": 0,
-            "ro": false,
+            "file": "TEST_DIR/t.IMGFMT",
             "node-name": "top",
-            "backing_file_depth": 1,
+            "ro": false,
             "drv": "IMGFMT",
-            "iops": 0,
-            "bps_wr": 0,
-            "write_threshold": 0,
             "backing_file": "TEST_DIR/t.IMGFMT.base",
+            "backing_file_depth": 1,
             "encrypted": false,
+            "detect_zeroes": "off",
             "bps": 0,
             "bps_rd": 0,
-            "cache": {
-                "no-flush": false,
-                "direct": false,
-                "writeback": true
+            "bps_wr": 0,
+            "iops": 0,
+            "iops_rd": 0,
+            "iops_wr": 0,
+            "image": {
+                "filename": "TEST_DIR/t.IMGFMT",
+                "format": "IMGFMT",
+                "dirty-flag": false,
+                "actual-size": SIZE,
+                "virtual-size": 67108864,
+                "cluster-size": 65536,
+                "backing-filename": "TEST_DIR/t.IMGFMT.base",
+                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
+                "backing-filename-format": "IMGFMT",
+                "backing-image": {
+                    "filename": "TEST_DIR/t.IMGFMT.base",
+                    "format": "IMGFMT",
+                    "dirty-flag": false,
+                    "actual-size": SIZE,
+                    "virtual-size": 67108864,
+                    "cluster-size": 65536,
+                },
             },
-            "file": "TEST_DIR/t.IMGFMT"
+            "cache": {
+                "writeback": true,
+                "direct": false,
+                "no-flush": false
+            },
+            "write_threshold": 0
         },
         {
-            "iops_rd": 0,
+            "file": "TEST_DIR/t.IMGFMT",
+            "node-name": "NODE_NAME",
+            "ro": false,
+            "drv": "file",
+            "backing_file_depth": 0,
+            "encrypted": false,
             "detect_zeroes": "off",
+            "bps": 0,
+            "bps_rd": 0,
+            "bps_wr": 0,
+            "iops": 0,
+            "iops_rd": 0,
+            "iops_wr": 0,
             "image": {
-                "virtual-size": 197120,
                 "filename": "TEST_DIR/t.IMGFMT",
                 "format": "file",
+                "dirty-flag": false,
                 "actual-size": SIZE,
-                "dirty-flag": false
+                "virtual-size": 197120
             },
-            "iops_wr": 0,
-            "ro": false,
-            "node-name": "NODE_NAME",
-            "backing_file_depth": 0,
-            "drv": "file",
-            "iops": 0,
-            "bps_wr": 0,
-            "write_threshold": 0,
-            "encrypted": false,
-            "bps": 0,
-            "bps_rd": 0,
             "cache": {
-                "no-flush": false,
+                "writeback": true,
                 "direct": false,
-                "writeback": true
+                "no-flush": false
             },
-            "file": "TEST_DIR/t.IMGFMT"
+            "write_threshold": 0
         },
         {
-            "iops_rd": 0,
-            "detect_zeroes": "off",
-            "image": {
-                "backing-image": {
-                    "virtual-size": 67108864,
-                    "filename": "TEST_DIR/t.IMGFMT.base",
-                    "cluster-size": 65536,
-                    "format": "IMGFMT",
-                    "actual-size": SIZE,
-                    "dirty-flag": false
-                },
-                "backing-filename-format": "IMGFMT",
-                "virtual-size": 67108864,
-                "filename": "TEST_DIR/t.IMGFMT.mid",
-                "cluster-size": 65536,
-                "format": "IMGFMT",
-                "actual-size": SIZE,
-                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
-                "backing-filename": "TEST_DIR/t.IMGFMT.base",
-                "dirty-flag": false
-            },
-            "iops_wr": 0,
-            "ro": false,
+            "file": "TEST_DIR/t.IMGFMT.mid",
             "node-name": "mid",
-            "backing_file_depth": 1,
+            "ro": false,
             "drv": "IMGFMT",
-            "iops": 0,
-            "bps_wr": 0,
-            "write_threshold": 0,
             "backing_file": "TEST_DIR/t.IMGFMT.base",
+            "backing_file_depth": 1,
             "encrypted": false,
+            "detect_zeroes": "off",
             "bps": 0,
             "bps_rd": 0,
-            "cache": {
-                "no-flush": false,
-                "direct": false,
-                "writeback": true
+            "bps_wr": 0,
+            "iops": 0,
+            "iops_rd": 0,
+            "iops_wr": 0,
+            "image": {
+                "filename": "TEST_DIR/t.IMGFMT.mid",
+                "format": "IMGFMT",
+                "dirty-flag": false,
+                "actual-size": SIZE,
+                "virtual-size": 67108864,
+                "cluster-size": 65536,
+                "backing-filename": "TEST_DIR/t.IMGFMT.base",
+                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
+                "backing-filename-format": "IMGFMT",
+                "backing-image": {
+                    "filename": "TEST_DIR/t.IMGFMT.base",
+                    "format": "IMGFMT",
+                    "dirty-flag": false,
+                    "actual-size": SIZE,
+                    "virtual-size": 67108864,
+                    "cluster-size": 65536,
+                },
             },
-            "file": "TEST_DIR/t.IMGFMT.mid"
+            "cache": {
+                "writeback": true,
+                "direct": false,
+                "no-flush": false
+            },
+            "write_threshold": 0
         },
         {
-            "iops_rd": 0,
+            "file": "TEST_DIR/t.IMGFMT.mid",
+            "node-name": "NODE_NAME",
+            "ro": false,
+            "drv": "file",
+            "backing_file_depth": 0,
+            "encrypted": false,
             "detect_zeroes": "off",
+            "bps": 0,
+            "bps_rd": 0,
+            "bps_wr": 0,
+            "iops": 0,
+            "iops_rd": 0,
+            "iops_wr": 0,
             "image": {
-                "virtual-size": 393216,
                 "filename": "TEST_DIR/t.IMGFMT.mid",
                 "format": "file",
+                "dirty-flag": false,
                 "actual-size": SIZE,
-                "dirty-flag": false
+                "virtual-size": 393216
             },
-            "iops_wr": 0,
-            "ro": false,
-            "node-name": "NODE_NAME",
-            "backing_file_depth": 0,
-            "drv": "file",
-            "iops": 0,
-            "bps_wr": 0,
-            "write_threshold": 0,
-            "encrypted": false,
-            "bps": 0,
-            "bps_rd": 0,
             "cache": {
-                "no-flush": false,
+                "writeback": true,
                 "direct": false,
-                "writeback": true
+                "no-flush": false
             },
-            "file": "TEST_DIR/t.IMGFMT.mid"
+            "write_threshold": 0
         },
         {
-            "iops_rd": 0,
-            "detect_zeroes": "off",
-            "image": {
-                "virtual-size": 67108864,
-                "filename": "TEST_DIR/t.IMGFMT.base",
-                "cluster-size": 65536,
-                "format": "IMGFMT",
-                "actual-size": SIZE,
-                "dirty-flag": false
-            },
-            "iops_wr": 0,
-            "ro": false,
+            "file": "TEST_DIR/t.IMGFMT.base",
             "node-name": "base",
-            "backing_file_depth": 0,
+            "ro": false,
             "drv": "IMGFMT",
-            "iops": 0,
-            "bps_wr": 0,
-            "write_threshold": 0,
+            "backing_file_depth": 0,
             "encrypted": false,
+            "detect_zeroes": "off",
             "bps": 0,
             "bps_rd": 0,
-            "cache": {
-                "no-flush": false,
-                "direct": false,
-                "writeback": true
+            "bps_wr": 0,
+            "iops": 0,
+            "iops_rd": 0,
+            "iops_wr": 0,
+            "image": {
+                "filename": "TEST_DIR/t.IMGFMT.base",
+                "format": "IMGFMT",
+                "dirty-flag": false,
+                "actual-size": SIZE,
+                "virtual-size": 67108864,
+                "cluster-size": 65536,
             },
-            "file": "TEST_DIR/t.IMGFMT.base"
+            "cache": {
+                "writeback": true,
+                "direct": false,
+                "no-flush": false
+            },
+            "write_threshold": 0
         },
         {
-            "iops_rd": 0,
+            "file": "TEST_DIR/t.IMGFMT.base",
+            "node-name": "NODE_NAME",
+            "ro": false,
+            "drv": "file",
+            "backing_file_depth": 0,
+            "encrypted": false,
             "detect_zeroes": "off",
+            "bps": 0,
+            "bps_rd": 0,
+            "bps_wr": 0,
+            "iops": 0,
+            "iops_rd": 0,
+            "iops_wr": 0,
             "image": {
-                "virtual-size": 393216,
                 "filename": "TEST_DIR/t.IMGFMT.base",
                 "format": "file",
+                "dirty-flag": false,
                 "actual-size": SIZE,
-                "dirty-flag": false
+                "virtual-size": 393216
             },
-            "iops_wr": 0,
-            "ro": false,
-            "node-name": "NODE_NAME",
-            "backing_file_depth": 0,
-            "drv": "file",
-            "iops": 0,
-            "bps_wr": 0,
-            "write_threshold": 0,
-            "encrypted": false,
-            "bps": 0,
-            "bps_rd": 0,
             "cache": {
-                "no-flush": false,
+                "writeback": true,
                 "direct": false,
-                "writeback": true
+                "no-flush": false
             },
-            "file": "TEST_DIR/t.IMGFMT.base"
+            "write_threshold": 0
         }
     ]
 }
@@ -383,11 +383,11 @@  wrote 65536/65536 bytes at offset 1048576
     }
 }
 {
+    "event": "SHUTDOWN",
     "timestamp": {
         "seconds":  TIMESTAMP,
         "microseconds":  TIMESTAMP
     },
-    "event": "SHUTDOWN",
     "data": {
         "guest": false,
         "reason": "host-qmp-quit"
@@ -429,25 +429,25 @@  wrote 65536/65536 bytes at offset 1048576
                       'base':'TEST_DIR/t.IMGFMT.base',
                       'top': 'TEST_DIR/t.IMGFMT.mid' } }
 {
+    "event": "JOB_STATUS_CHANGE",
     "timestamp": {
         "seconds":  TIMESTAMP,
         "microseconds":  TIMESTAMP
     },
-    "event": "JOB_STATUS_CHANGE",
     "data": {
-        "status": "created",
-        "id": "commit0"
+        "id": "commit0",
+        "status": "created"
     }
 }
 {
+    "event": "JOB_STATUS_CHANGE",
     "timestamp": {
         "seconds":  TIMESTAMP,
         "microseconds":  TIMESTAMP
     },
-    "event": "JOB_STATUS_CHANGE",
     "data": {
-        "status": "running",
-        "id": "commit0"
+        "id": "commit0",
+        "status": "running"
     }
 }
 {
@@ -455,61 +455,61 @@  wrote 65536/65536 bytes at offset 1048576
     }
 }
 {
+    "event": "JOB_STATUS_CHANGE",
     "timestamp": {
         "seconds":  TIMESTAMP,
         "microseconds":  TIMESTAMP
     },
-    "event": "JOB_STATUS_CHANGE",
     "data": {
-        "status": "waiting",
-        "id": "commit0"
+        "id": "commit0",
+        "status": "waiting"
     }
 }
 {
+    "event": "JOB_STATUS_CHANGE",
     "timestamp": {
         "seconds":  TIMESTAMP,
         "microseconds":  TIMESTAMP
     },
-    "event": "JOB_STATUS_CHANGE",
     "data": {
-        "status": "pending",
-        "id": "commit0"
+        "id": "commit0",
+        "status": "pending"
     }
 }
 {
-    "timestamp": {
-        "seconds":  TIMESTAMP,
-        "microseconds":  TIMESTAMP
-    },
     "event": "BLOCK_JOB_COMPLETED",
+    "timestamp": {
+        "seconds":  TIMESTAMP,
+        "microseconds":  TIMESTAMP
+    },
     "data": {
+        "type": "commit",
         "device": "commit0",
         "len": 67108864,
         "offset": 67108864,
-        "speed": 0,
-        "type": "commit"
+        "speed": 0
     }
 }
 {
+    "event": "JOB_STATUS_CHANGE",
     "timestamp": {
         "seconds":  TIMESTAMP,
         "microseconds":  TIMESTAMP
     },
-    "event": "JOB_STATUS_CHANGE",
     "data": {
-        "status": "concluded",
-        "id": "commit0"
+        "id": "commit0",
+        "status": "concluded"
     }
 }
 {
+    "event": "JOB_STATUS_CHANGE",
     "timestamp": {
         "seconds":  TIMESTAMP,
         "microseconds":  TIMESTAMP
     },
-    "event": "JOB_STATUS_CHANGE",
     "data": {
-        "status": "null",
-        "id": "commit0"
+        "id": "commit0",
+        "status": "null"
     }
 }
 
@@ -519,279 +519,279 @@  wrote 65536/65536 bytes at offset 1048576
 {
     "return": [
         {
-            "iops_rd": 0,
-            "detect_zeroes": "off",
-            "image": {
-                "backing-image": {
-                    "virtual-size": 67108864,
-                    "filename": "TEST_DIR/t.IMGFMT.base",
-                    "cluster-size": 65536,
-                    "format": "IMGFMT",
-                    "actual-size": SIZE,
-                    "dirty-flag": false
-                },
-                "backing-filename-format": "IMGFMT",
-                "virtual-size": 67108864,
-                "filename": "TEST_DIR/t.IMGFMT.ovl2",
-                "cluster-size": 65536,
-                "format": "IMGFMT",
-                "actual-size": SIZE,
-                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
-                "backing-filename": "TEST_DIR/t.IMGFMT.base",
-                "dirty-flag": false
-            },
-            "iops_wr": 0,
-            "ro": true,
+            "file": "TEST_DIR/t.IMGFMT.ovl2",
             "node-name": "NODE_NAME",
-            "backing_file_depth": 1,
+            "ro": true,
             "drv": "IMGFMT",
-            "iops": 0,
-            "bps_wr": 0,
-            "write_threshold": 0,
             "backing_file": "TEST_DIR/t.IMGFMT.base",
+            "backing_file_depth": 1,
             "encrypted": false,
+            "detect_zeroes": "off",
             "bps": 0,
             "bps_rd": 0,
-            "cache": {
-                "no-flush": false,
-                "direct": false,
-                "writeback": true
+            "bps_wr": 0,
+            "iops": 0,
+            "iops_rd": 0,
+            "iops_wr": 0,
+            "image": {
+                "filename": "TEST_DIR/t.IMGFMT.ovl2",
+                "format": "IMGFMT",
+                "dirty-flag": false,
+                "actual-size": SIZE,
+                "virtual-size": 67108864,
+                "cluster-size": 65536,
+                "backing-filename": "TEST_DIR/t.IMGFMT.base",
+                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
+                "backing-filename-format": "IMGFMT",
+                "backing-image": {
+                    "filename": "TEST_DIR/t.IMGFMT.base",
+                    "format": "IMGFMT",
+                    "dirty-flag": false,
+                    "actual-size": SIZE,
+                    "virtual-size": 67108864,
+                    "cluster-size": 65536,
+                },
             },
-            "file": "TEST_DIR/t.IMGFMT.ovl2"
+            "cache": {
+                "writeback": true,
+                "direct": false,
+                "no-flush": false
+            },
+            "write_threshold": 0
         },
         {
-            "iops_rd": 0,
+            "file": "TEST_DIR/t.IMGFMT.ovl2",
+            "node-name": "NODE_NAME",
+            "ro": true,
+            "drv": "file",
+            "backing_file_depth": 0,
+            "encrypted": false,
             "detect_zeroes": "off",
+            "bps": 0,
+            "bps_rd": 0,
+            "bps_wr": 0,
+            "iops": 0,
+            "iops_rd": 0,
+            "iops_wr": 0,
             "image": {
-                "virtual-size": 197120,
                 "filename": "TEST_DIR/t.IMGFMT.ovl2",
                 "format": "file",
+                "dirty-flag": false,
                 "actual-size": SIZE,
-                "dirty-flag": false
+                "virtual-size": 197120
             },
-            "iops_wr": 0,
-            "ro": true,
-            "node-name": "NODE_NAME",
-            "backing_file_depth": 0,
-            "drv": "file",
-            "iops": 0,
-            "bps_wr": 0,
-            "write_threshold": 0,
-            "encrypted": false,
-            "bps": 0,
-            "bps_rd": 0,
             "cache": {
-                "no-flush": false,
+                "writeback": true,
                 "direct": false,
-                "writeback": true
+                "no-flush": false
             },
-            "file": "TEST_DIR/t.IMGFMT.ovl2"
+            "write_threshold": 0
         },
         {
-            "iops_rd": 0,
-            "detect_zeroes": "off",
-            "image": {
-                "backing-image": {
-                    "backing-image": {
-                        "virtual-size": 67108864,
-                        "filename": "TEST_DIR/t.IMGFMT.base",
-                        "cluster-size": 65536,
-                        "format": "IMGFMT",
-                        "actual-size": SIZE,
-                        "dirty-flag": false
-                    },
-                    "backing-filename-format": "IMGFMT",
-                    "virtual-size": 67108864,
-                    "filename": "TEST_DIR/t.IMGFMT.ovl2",
-                    "cluster-size": 65536,
-                    "format": "IMGFMT",
-                    "actual-size": SIZE,
-                    "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
-                    "backing-filename": "TEST_DIR/t.IMGFMT.base",
-                    "dirty-flag": false
-                },
-                "backing-filename-format": "IMGFMT",
-                "virtual-size": 67108864,
-                "filename": "TEST_DIR/t.IMGFMT.ovl3",
-                "cluster-size": 65536,
-                "format": "IMGFMT",
-                "actual-size": SIZE,
-                "full-backing-filename": "TEST_DIR/t.IMGFMT.ovl2",
-                "backing-filename": "TEST_DIR/t.IMGFMT.ovl2",
-                "dirty-flag": false
-            },
-            "iops_wr": 0,
-            "ro": false,
+            "file": "TEST_DIR/t.IMGFMT.ovl3",
             "node-name": "top2",
-            "backing_file_depth": 2,
+            "ro": false,
             "drv": "IMGFMT",
-            "iops": 0,
-            "bps_wr": 0,
-            "write_threshold": 0,
             "backing_file": "TEST_DIR/t.IMGFMT.ovl2",
+            "backing_file_depth": 2,
             "encrypted": false,
+            "detect_zeroes": "off",
             "bps": 0,
             "bps_rd": 0,
-            "cache": {
-                "no-flush": false,
-                "direct": false,
-                "writeback": true
+            "bps_wr": 0,
+            "iops": 0,
+            "iops_rd": 0,
+            "iops_wr": 0,
+            "image": {
+                "filename": "TEST_DIR/t.IMGFMT.ovl3",
+                "format": "IMGFMT",
+                "dirty-flag": false,
+                "actual-size": SIZE,
+                "virtual-size": 67108864,
+                "cluster-size": 65536,
+                "backing-filename": "TEST_DIR/t.IMGFMT.ovl2",
+                "full-backing-filename": "TEST_DIR/t.IMGFMT.ovl2",
+                "backing-filename-format": "IMGFMT",
+                "backing-image": {
+                    "filename": "TEST_DIR/t.IMGFMT.ovl2",
+                    "format": "IMGFMT",
+                    "dirty-flag": false,
+                    "actual-size": SIZE,
+                    "virtual-size": 67108864,
+                    "cluster-size": 65536,
+                    "backing-filename": "TEST_DIR/t.IMGFMT.base",
+                    "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
+                    "backing-filename-format": "IMGFMT",
+                    "backing-image": {
+                        "filename": "TEST_DIR/t.IMGFMT.base",
+                        "format": "IMGFMT",
+                        "dirty-flag": false,
+                        "actual-size": SIZE,
+                        "virtual-size": 67108864,
+                        "cluster-size": 65536,
+                    },
+                },
             },
-            "file": "TEST_DIR/t.IMGFMT.ovl3"
+            "cache": {
+                "writeback": true,
+                "direct": false,
+                "no-flush": false
+            },
+            "write_threshold": 0
         },
         {
-            "iops_rd": 0,
+            "file": "TEST_DIR/t.IMGFMT.ovl3",
+            "node-name": "NODE_NAME",
+            "ro": false,
+            "drv": "file",
+            "backing_file_depth": 0,
+            "encrypted": false,
             "detect_zeroes": "off",
+            "bps": 0,
+            "bps_rd": 0,
+            "bps_wr": 0,
+            "iops": 0,
+            "iops_rd": 0,
+            "iops_wr": 0,
             "image": {
-                "virtual-size": 197120,
                 "filename": "TEST_DIR/t.IMGFMT.ovl3",
                 "format": "file",
+                "dirty-flag": false,
                 "actual-size": SIZE,
-                "dirty-flag": false
+                "virtual-size": 197120
             },
-            "iops_wr": 0,
-            "ro": false,
-            "node-name": "NODE_NAME",
-            "backing_file_depth": 0,
-            "drv": "file",
-            "iops": 0,
-            "bps_wr": 0,
-            "write_threshold": 0,
-            "encrypted": false,
-            "bps": 0,
-            "bps_rd": 0,
             "cache": {
-                "no-flush": false,
+                "writeback": true,
                 "direct": false,
-                "writeback": true
+                "no-flush": false
             },
-            "file": "TEST_DIR/t.IMGFMT.ovl3"
+            "write_threshold": 0
         },
         {
-            "iops_rd": 0,
-            "detect_zeroes": "off",
-            "image": {
-                "virtual-size": 67108864,
-                "filename": "TEST_DIR/t.IMGFMT.base",
-                "cluster-size": 65536,
-                "format": "IMGFMT",
-                "actual-size": SIZE,
-                "dirty-flag": false
-            },
-            "iops_wr": 0,
+            "file": "TEST_DIR/t.IMGFMT.base",
+            "node-name": "NODE_NAME",
             "ro": true,
-            "node-name": "NODE_NAME",
-            "backing_file_depth": 0,
             "drv": "IMGFMT",
-            "iops": 0,
-            "bps_wr": 0,
-            "write_threshold": 0,
+            "backing_file_depth": 0,
             "encrypted": false,
+            "detect_zeroes": "off",
             "bps": 0,
             "bps_rd": 0,
-            "cache": {
-                "no-flush": false,
-                "direct": false,
-                "writeback": true
+            "bps_wr": 0,
+            "iops": 0,
+            "iops_rd": 0,
+            "iops_wr": 0,
+            "image": {
+                "filename": "TEST_DIR/t.IMGFMT.base",
+                "format": "IMGFMT",
+                "dirty-flag": false,
+                "actual-size": SIZE,
+                "virtual-size": 67108864,
+                "cluster-size": 65536,
             },
-            "file": "TEST_DIR/t.IMGFMT.base"
+            "cache": {
+                "writeback": true,
+                "direct": false,
+                "no-flush": false
+            },
+            "write_threshold": 0
         },
         {
-            "iops_rd": 0,
+            "file": "TEST_DIR/t.IMGFMT.base",
+            "node-name": "NODE_NAME",
+            "ro": true,
+            "drv": "file",
+            "backing_file_depth": 0,
+            "encrypted": false,
             "detect_zeroes": "off",
+            "bps": 0,
+            "bps_rd": 0,
+            "bps_wr": 0,
+            "iops": 0,
+            "iops_rd": 0,
+            "iops_wr": 0,
             "image": {
-                "virtual-size": 393216,
                 "filename": "TEST_DIR/t.IMGFMT.base",
                 "format": "file",
+                "dirty-flag": false,
                 "actual-size": SIZE,
-                "dirty-flag": false
+                "virtual-size": 393216
             },
-            "iops_wr": 0,
-            "ro": true,
-            "node-name": "NODE_NAME",
-            "backing_file_depth": 0,
-            "drv": "file",
-            "iops": 0,
-            "bps_wr": 0,
-            "write_threshold": 0,
-            "encrypted": false,
-            "bps": 0,
-            "bps_rd": 0,
             "cache": {
-                "no-flush": false,
+                "writeback": true,
                 "direct": false,
-                "writeback": true
+                "no-flush": false
             },
-            "file": "TEST_DIR/t.IMGFMT.base"
+            "write_threshold": 0
         },
         {
-            "iops_rd": 0,
-            "detect_zeroes": "off",
-            "image": {
-                "backing-image": {
-                    "virtual-size": 67108864,
-                    "filename": "TEST_DIR/t.IMGFMT.base",
-                    "cluster-size": 65536,
-                    "format": "IMGFMT",
-                    "actual-size": SIZE,
-                    "dirty-flag": false
-                },
-                "backing-filename-format": "IMGFMT",
-                "virtual-size": 67108864,
-                "filename": "TEST_DIR/t.IMGFMT",
-                "cluster-size": 65536,
-                "format": "IMGFMT",
-                "actual-size": SIZE,
-                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
-                "backing-filename": "TEST_DIR/t.IMGFMT.base",
-                "dirty-flag": false
-            },
-            "iops_wr": 0,
-            "ro": false,
+            "file": "TEST_DIR/t.IMGFMT",
             "node-name": "top",
-            "backing_file_depth": 1,
+            "ro": false,
             "drv": "IMGFMT",
-            "iops": 0,
-            "bps_wr": 0,
-            "write_threshold": 0,
             "backing_file": "TEST_DIR/t.IMGFMT.base",
+            "backing_file_depth": 1,
             "encrypted": false,
+            "detect_zeroes": "off",
             "bps": 0,
             "bps_rd": 0,
-            "cache": {
-                "no-flush": false,
-                "direct": false,
-                "writeback": true
+            "bps_wr": 0,
+            "iops": 0,
+            "iops_rd": 0,
+            "iops_wr": 0,
+            "image": {
+                "filename": "TEST_DIR/t.IMGFMT",
+                "format": "IMGFMT",
+                "dirty-flag": false,
+                "actual-size": SIZE,
+                "virtual-size": 67108864,
+                "cluster-size": 65536,
+                "backing-filename": "TEST_DIR/t.IMGFMT.base",
+                "full-backing-filename": "TEST_DIR/t.IMGFMT.base",
+                "backing-filename-format": "IMGFMT",
+                "backing-image": {
+                    "filename": "TEST_DIR/t.IMGFMT.base",
+                    "format": "IMGFMT",
+                    "dirty-flag": false,
+                    "actual-size": SIZE,
+                    "virtual-size": 67108864,
+                    "cluster-size": 65536,
+                },
             },
-            "file": "TEST_DIR/t.IMGFMT"
+            "cache": {
+                "writeback": true,
+                "direct": false,
+                "no-flush": false
+            },
+            "write_threshold": 0
         },
         {
-            "iops_rd": 0,
-            "detect_zeroes": "off",
-            "image": {
-                "virtual-size": 197120,
-                "filename": "TEST_DIR/t.IMGFMT",
-                "format": "file",
-                "actual-size": SIZE,
-                "dirty-flag": false
-            },
-            "iops_wr": 0,
-            "ro": false,
+            "file": "TEST_DIR/t.IMGFMT",
             "node-name": "NODE_NAME",
-            "backing_file_depth": 0,
+            "ro": false,
             "drv": "file",
-            "iops": 0,
-            "bps_wr": 0,
-            "write_threshold": 0,
+            "backing_file_depth": 0,
             "encrypted": false,
+            "detect_zeroes": "off",
             "bps": 0,
             "bps_rd": 0,
-            "cache": {
-                "no-flush": false,
-                "direct": false,
-                "writeback": true
+            "bps_wr": 0,
+            "iops": 0,
+            "iops_rd": 0,
+            "iops_wr": 0,
+            "image": {
+                "filename": "TEST_DIR/t.IMGFMT",
+                "format": "file",
+                "dirty-flag": false,
+                "actual-size": SIZE,
+                "virtual-size": 197120
             },
-            "file": "TEST_DIR/t.IMGFMT"
+            "cache": {
+                "writeback": true,
+                "direct": false,
+                "no-flush": false
+            },
+            "write_threshold": 0
         }
     ]
 }
@@ -801,11 +801,11 @@  wrote 65536/65536 bytes at offset 1048576
     }
 }
 {
+    "event": "SHUTDOWN",
     "timestamp": {
         "seconds":  TIMESTAMP,
         "microseconds":  TIMESTAMP
     },
-    "event": "SHUTDOWN",
     "data": {
         "guest": false,
         "reason": "host-qmp-quit"
diff --git a/tests/qemu-iotests/195.out b/tests/qemu-iotests/195.out
index ec84df5012..485d7a1115 100644
--- a/tests/qemu-iotests/195.out
+++ b/tests/qemu-iotests/195.out
@@ -22,11 +22,11 @@  Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,backing.node-name=mid
     }
 }
 {
+    "event": "SHUTDOWN",
     "timestamp": {
         "seconds":  TIMESTAMP,
         "microseconds":  TIMESTAMP
     },
-    "event": "SHUTDOWN",
     "data": {
         "guest": false,
         "reason": "host-qmp-quit"
@@ -60,11 +60,11 @@  Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,node-name=top
     }
 }
 {
+    "event": "SHUTDOWN",
     "timestamp": {
         "seconds":  TIMESTAMP,
         "microseconds":  TIMESTAMP
     },
-    "event": "SHUTDOWN",
     "data": {
         "guest": false,
         "reason": "host-qmp-quit"
diff --git a/tests/qemu-iotests/229.out b/tests/qemu-iotests/229.out
index 7d2bfbfbe6..3f4391df6e 100644
--- a/tests/qemu-iotests/229.out
+++ b/tests/qemu-iotests/229.out
@@ -16,19 +16,19 @@  wrote 2097152/2097152 bytes at offset 0
                                'mode':   'existing',
                                'on-source-error': 'stop',
                                'on-target-error': 'stop' }}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "testdisk"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "testdisk", "status": "created"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "testdisk", "status": "running"}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "testdisk", "operation": "write", "action": "stop"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "testdisk"}}
+{"event": "BLOCK_JOB_ERROR", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"device": "testdisk", "operation": "write", "action": "stop"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "testdisk", "status": "paused"}}
 
 === Force cancel job paused in error state  ===
 
 {'execute': 'block-job-cancel',
                  'arguments': { 'device': 'testdisk',
                                 'force': true}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "testdisk", "status": "running"}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "testdisk"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "testdisk", "len": 2097152, "offset": OFFSET, "speed": 0, "type": "mirror"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "testdisk", "status": "aborting"}}
+{"event": "BLOCK_JOB_CANCELLED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "mirror", "device": "testdisk", "len": 2097152, "offset": OFFSET, "speed": 0}}
 *** done
diff --git a/tests/qemu-iotests/244.out b/tests/qemu-iotests/244.out
index 5e03add054..57cffee1ea 100644
--- a/tests/qemu-iotests/244.out
+++ b/tests/qemu-iotests/244.out
@@ -156,14 +156,14 @@  wrote 1048576/1048576 bytes at offset 0
                "data-file": "data",
                "data-file-raw": true
            } } }
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "create"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "create"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "created"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "running"}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "create"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "create"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "create"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "waiting"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "pending"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "concluded"}}
 { "execute": "job-dismiss", "arguments": { "id": "create" } }
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "create"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "create", "status": "null"}}
 {"return": {}}
 
 Comparing pattern:
diff --git a/tests/qemu-iotests/249.out b/tests/qemu-iotests/249.out
index d2bf9be85e..a1a1a1b851 100644
--- a/tests/qemu-iotests/249.out
+++ b/tests/qemu-iotests/249.out
@@ -16,8 +16,8 @@  Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
 { 'execute': 'block-commit',
        'arguments': {'job-id': 'job0', 'device': 'none1', 'top-node': 'int',
                      'filter-node-name': '1234'}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
 {"error": {"class": "GenericError", "desc": "Invalid node-name: '1234'"}}
 
 === Send a write command to a drive opened in read-only mode (2)
@@ -30,14 +30,14 @@  Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
 
 { 'execute': 'block-commit',
        'arguments': {'job-id': 'job0', 'device': 'none1', 'top-node': 'int'}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "running"}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 1048576, "offset": 1048576, "speed": 0, "type": "commit"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "waiting"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "pending"}}
+{"event": "BLOCK_JOB_COMPLETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "job0", "len": 1048576, "offset": 1048576, "speed": 0}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "concluded"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
 
 === Send a write command to a drive opened in read-only mode (3)
 
diff --git a/tests/qemu-iotests/tests/qsd-jobs.out b/tests/qemu-iotests/tests/qsd-jobs.out
index c1bc9b8356..336a5c3946 100644
--- a/tests/qemu-iotests/tests/qsd-jobs.out
+++ b/tests/qemu-iotests/tests/qsd-jobs.out
@@ -8,15 +8,15 @@  QMP_VERSION
 {"return": {}}
 {"return": {}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
+{"event": "BLOCK_JOB_CANCELLED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"type": "commit", "device": "job0", "len": 0, "offset": 0, "speed": 0}}
 
 === Streaming can't get permission on base node ===
 
 QMP_VERSION
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "created"}}
+{"event": "JOB_STATUS_CHANGE", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "job0", "status": "null"}}
 {"error": {"class": "GenericError", "desc": "Permission conflict on node 'fmt_base': permissions 'write' are both required by an unnamed block device (uses node 'fmt_base' as 'root' child) and unshared by stream job 'job0' (uses node 'fmt_base' as 'intermediate node' child)."}}
 {"return": {}}
-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export1"}}
+{"event": "BLOCK_EXPORT_DELETED", "timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "data": {"id": "export1"}}
 *** done