qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-block] [PATCH RFC] block: add block-insert-node QMP command


From: Manos Pitsidianakis
Subject: [Qemu-block] [PATCH RFC] block: add block-insert-node QMP command
Date: Tue, 15 Aug 2017 10:45:13 +0300

block-insert-node and its pair command block-remove-node provide runtime
insertion and removal of filter nodes.

block-insert-node takes a (parent, child) and (node, child) pair of
edges and unrefs the (parent, child) BdrvChild relationship and creates
a new (parent, node) child with the same BdrvChildRole.

This is a different approach than x-blockdev-change which uses the driver
methods bdrv_add_child() and bdrv_del_child(),

Signed-off-by: Manos Pitsidianakis <address@hidden>
---
 block.c                    |  192 ++++++++
 blockdev.c                 |   44 ++
 include/block/block.h      |    6 +
 qapi/block-core.json       |   60 +++
 tests/qemu-iotests/193     |  241 ++++++++++
 tests/qemu-iotests/193.out | 1116 ++++++++++++++++++++++++++++++++++++++++++++
 tests/qemu-iotests/group   |    1 +
 7 files changed, 1660 insertions(+)
 create mode 100755 tests/qemu-iotests/193
 create mode 100644 tests/qemu-iotests/193.out

diff --git a/block.c b/block.c
index 81bd51b670..f874aabbfb 100644
--- a/block.c
+++ b/block.c
@@ -930,6 +930,9 @@ static void bdrv_backing_attach(BdrvChild *c)
                     parent->backing_blocker);
     bdrv_op_unblock(backing_hd, BLOCK_OP_TYPE_STREAM,
                     parent->backing_blocker);
+    /* Unblock filter node insertion */
+    bdrv_op_unblock(backing_hd, BLOCK_OP_TYPE_EDGE_MODIFICATION,
+                    parent->backing_blocker);
     /*
      * We do backup in 3 ways:
      * 1. drive backup
@@ -5036,3 +5039,192 @@ BlockDriverState 
*bdrv_get_first_explicit(BlockDriverState *bs)
     }
     return bs;
 }
+
+
+static inline BdrvChild *bdrv_find_child(BlockDriverState *parent_bs,
+                                  const char *child_name)
+{
+    BdrvChild *child;
+    assert(child_name);
+
+    QLIST_FOREACH(child, &parent_bs->children, next) {
+        if (child->bs && !g_strcmp0(child->bs->node_name, child_name)) {
+            return child;
+        }
+    }
+
+    return NULL;
+}
+
+static int check_node_edge(const char *parent, const char *child, Error **errp)
+{
+    BlockDriverState *parent_bs, *child_bs;
+    parent_bs = bdrv_find_node(parent);
+    if (!parent_bs) {
+        error_setg(errp, "'%s' not a node name", parent);
+        return 1;
+    }
+    child_bs = bdrv_find_node(child);
+    if (!child_bs) {
+        error_setg(errp, "'%s' not a node name", child);
+        return 1;
+    }
+    if (!bdrv_find_child(parent_bs, child)) {
+        error_setg(errp, "'%s' not a child of '%s'", child, parent);
+        return 1;
+    }
+    if (bdrv_op_is_blocked(parent_bs, BLOCK_OP_TYPE_EDGE_MODIFICATION, errp) ||
+        bdrv_op_is_blocked(child_bs, BLOCK_OP_TYPE_EDGE_MODIFICATION, errp)) {
+        return 1;
+    }
+    return 0;
+}
+
+void bdrv_insert_node(const char *parent, const char *child,
+                      const char *node, Error **errp)
+{
+    BlockBackend *blk;
+    BlockDriverState *parent_bs, *node_bs, *child_bs;
+    BdrvChild *c;
+    const BdrvChildRole *role;
+
+    if (check_node_edge(node, child, errp)) {
+        return;
+    }
+    node_bs = bdrv_find_node(node);
+    child_bs = bdrv_find_node(child);
+    blk = blk_by_name(parent);
+    if (blk) {
+        /* insert 'node' as root bs of 'parent' device */
+        if (!blk_bs(blk)) {
+            error_setg(errp, "Device '%s' has no medium", parent);
+            return;
+        }
+        if (blk_bs(blk) != child_bs) {
+            error_setg(errp, "'%s' not a child of device '%s'", child, parent);
+            return;
+        }
+        bdrv_drained_begin(child_bs);
+        blk_remove_bs(blk);
+        blk_insert_bs(blk, node_bs, errp);
+        if (!blk_bs(blk)) {
+            blk_insert_bs(blk, child_bs, &error_abort);
+        }
+        bdrv_drained_end(child_bs);
+        return;
+    }
+
+    /* insert 'node' as child bs of 'parent' node */
+    if (check_node_edge(parent, child, errp)) {
+        return;
+    }
+    parent_bs = bdrv_find_node(parent);
+    c = bdrv_find_child(parent_bs, child);
+    role = c->role;
+    assert(role == &child_file || role == &child_backing);
+
+    bdrv_ref(node_bs);
+
+    bdrv_drained_begin(parent_bs);
+    bdrv_unref_child(parent_bs, c);
+    if (role == &child_file) {
+        parent_bs->file = bdrv_attach_child(parent_bs, node_bs, "file",
+                                            &child_file, errp);
+        if (!parent_bs->file) {
+            parent_bs->file = bdrv_attach_child(parent_bs, child_bs, "file",
+                                                &child_file, &error_abort);
+            goto out;
+        }
+    } else if (role == &child_backing) {
+        parent_bs->backing = bdrv_attach_child(parent_bs, node_bs, "backing",
+                                               &child_backing, errp);
+        if (!parent_bs->backing) {
+            parent_bs->backing = bdrv_attach_child(parent_bs, child_bs,
+                                                   "backing", &child_backing,
+                                                   &error_abort);
+            goto out;
+        }
+    }
+    bdrv_refresh_filename(parent_bs);
+    bdrv_refresh_limits(parent_bs, NULL);
+
+out:
+    bdrv_drained_end(parent_bs);
+}
+
+void bdrv_remove_node(const char *parent, const char *child,
+                      const char *node, Error **errp)
+{
+    BlockBackend *blk;
+    BlockDriverState *node_bs, *parent_bs, *child_bs;
+    BdrvChild *c;
+    const BdrvChildRole *role;
+
+    if (check_node_edge(node, child, errp)) {
+        return;
+    }
+    node_bs = bdrv_find_node(node);
+    child_bs = bdrv_find_node(child);
+    blk = blk_by_name(parent);
+    if (blk) {
+        /* remove 'node' as root bs of 'parent' device */
+        if (!blk_bs(blk)) {
+            error_setg(errp, "Device '%s' has no medium", parent);
+            return;
+        }
+        if (blk_bs(blk) != node_bs) {
+            error_setg(errp, "'%s' not a child of device '%s'", node, parent);
+            return;
+        }
+        bdrv_drained_begin(node_bs);
+        blk_remove_bs(blk);
+        blk_insert_bs(blk, child_bs, errp);
+        if (!blk_bs(blk)) {
+            blk_insert_bs(blk, node_bs, &error_abort);
+        }
+        bdrv_drained_end(node_bs);
+        return;
+    }
+
+    if (check_node_edge(parent, node, errp)) {
+        return;
+    }
+    parent_bs = bdrv_find_node(parent);
+    c = bdrv_find_child(node_bs, child);
+    role = c->role;
+    assert(role == &child_file || role == &child_backing);
+
+
+    bdrv_ref(child_bs);
+    bdrv_ref(node_bs);
+
+    bdrv_drained_begin(parent_bs);
+    bdrv_unref_child(parent_bs, bdrv_find_child(parent_bs, node));
+    if (role == &child_file) {
+        parent_bs->file = bdrv_attach_child(parent_bs, child_bs, "file",
+                &child_file, errp);
+        if (!parent_bs->file) {
+            parent_bs->file = bdrv_attach_child(parent_bs, node_bs, "file",
+                                                &child_file, &error_abort);
+            node_bs->file = bdrv_attach_child(node_bs, child_bs, "file",
+                                              &child_file, &error_abort);
+            goto out;
+        }
+    } else if (role == &child_backing) {
+        parent_bs->backing = bdrv_attach_child(parent_bs, child_bs, "backing",
+                                               &child_backing, errp);
+        if (!parent_bs->backing) {
+            parent_bs->backing = bdrv_attach_child(parent_bs, node_bs,
+                                                   "backing", &child_backing,
+                                                   &error_abort);
+            node_bs->backing = bdrv_attach_child(node_bs, child_bs, "backing",
+                                                 &child_backing, &error_abort);
+            goto out;
+        }
+    }
+    bdrv_refresh_filename(parent_bs);
+    bdrv_refresh_limits(parent_bs, NULL);
+    bdrv_unref(node_bs);
+out:
+    bdrv_drained_end(parent_bs);
+}
diff --git a/blockdev.c b/blockdev.c
index 8e2fc6e64c..5195ec1b61 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -4238,3 +4238,47 @@ QemuOptsList qemu_drive_opts = {
         { /* end of list */ }
     },
 };
+
+void qmp_block_insert_node(const char *parent, const char *child,
+                           const char *node, Error **errp)
+{
+    BlockDriverState *bs = bdrv_find_node(node);
+    if (!bs) {
+        error_setg(errp, "Node '%s' not found", node);
+        return;
+    }
+    if (!bs->monitor_list.tqe_prev) {
+        error_setg(errp, "Node '%s' is not owned by the monitor",
+                   bs->node_name);
+        return;
+    }
+    if (!bs->drv->is_filter) {
+        error_setg(errp, "Block format '%s' used by node '%s' does not support"
+                   "insertion", bs->drv->format_name, bs->node_name);
+        return;
+    }
+
+    bdrv_insert_node(parent, child, node, errp);
+}
+
+void qmp_block_remove_node(const char *parent, const char *child,
+                           const char *node, Error **errp)
+{
+    BlockDriverState *bs = bdrv_find_node(node);
+    if (!bs) {
+        error_setg(errp, "Node '%s' not found", node);
+        return;
+    }
+    if (!bs->monitor_list.tqe_prev) {
+        error_setg(errp, "Node %s is not owned by the monitor",
+                   bs->node_name);
+        return;
+    }
+    if (!bs->drv->is_filter) {
+        error_setg(errp, "Block format '%s' used by node '%s' does not support"
+                   "removal", bs->drv->format_name, bs->node_name);
+        return;
+    }
+
+    bdrv_remove_node(parent, child, node, errp);
+}
diff --git a/include/block/block.h b/include/block/block.h
index 744b50e734..9e1120af1b 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -191,6 +191,8 @@ typedef enum BlockOpType {
     BLOCK_OP_TYPE_RESIZE,
     BLOCK_OP_TYPE_STREAM,
     BLOCK_OP_TYPE_REPLACE,
+    BLOCK_OP_TYPE_EDGE_MODIFICATION, /* block user modification of graph edges
+                                        including this node */
     BLOCK_OP_TYPE_MAX,
 } BlockOpType;
 
@@ -627,4 +629,8 @@ void bdrv_del_child(BlockDriverState *parent, BdrvChild 
*child, Error **errp);
 bool bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
                                      uint32_t granularity, Error **errp);
 
+void bdrv_insert_node(const char *parent, const char *child,
+                      const char *node, Error **errp);
+void bdrv_remove_node(const char *parent, const char *child,
+                      const char *node, Error **errp);
 #endif
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 4d6ba1baef..16e19cb648 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -3947,3 +3947,63 @@
   'data' : { 'parent': 'str',
              '*child': 'str',
              '*node': 'str' } }
+
+##
+# @block-insert-node:
+#
+# Insert a filter node between a specific edge in the block driver state graph.
+# @parent:  the name of the parent node or device
+# @node:    the name of the node to insert under parent
+# @child:   the name of the child of both node and parent
+#
+# Example:
+# Insert and remove a throttle filter on top of a device chain, between the
+# device 'ide0-hd0' and node 'node-A'
+#
+# -> {'execute': 'object-add',
+#     "arguments": {
+#       "qom-type": "throttle-group",
+#       "id": "group0",
+#       "props" : { "limits": { "iops-total": 300 } }
+#     }
+#    }
+# <- { 'return': {} }
+# -> {'execute': 'blockdev-add',
+#       'arguments': {
+#           'driver': 'throttle',
+#           'node-name': 'throttle0',
+#           'throttle-group': 'group0',
+#           'file': 'node-A'
+#       }
+#    }
+# <- { 'return': {} }
+# -> { 'execute': 'block-insert-node',
+#       'arguments': { 'parent': 'ide0-hd0', 'child': 'node-A', 'node': 
'throttle0' }
+#    }
+# <- { 'return': {} }
+# -> { 'execute': 'block-remove-node',
+#       'arguments': { 'parent': 'ide0-hd0', 'child': 'node-A', 'node': 
'throttle0' }
+#    }
+# <- { 'return': {} }
+# -> { 'execute': 'blockdev-del',
+#       'arguments': { 'node-name': 'throttle0' }
+#    }
+# <- { 'return': {} }
+#
+##
+{ 'command': 'block-insert-node',
+  'data': { 'parent': 'str',
+             'child': 'str',
+             'node': 'str'} }
+##
+# @block-remove-node:
+#
+# Remove a filter node between two other nodes in the block driver state graph.
+# @parent:  the name of the parent node or device
+# @node:    the name of the node to remove from parent
+# @child:   the name of the child of node which will go under parent
+##
+{ 'command': 'block-remove-node',
+  'data': { 'parent': 'str',
+             'child': 'str',
+             'node': 'str'} }
diff --git a/tests/qemu-iotests/193 b/tests/qemu-iotests/193
new file mode 100755
index 0000000000..2936eba95e
--- /dev/null
+++ b/tests/qemu-iotests/193
@@ -0,0 +1,241 @@
+#!/bin/bash
+#
+# Test block-insert-node & block-remove-node commands
+#
+# Copyright (C) 2017 Manos Pitsidianakis
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner="Manos Pitsidianakis"
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+status=1       # failure is the default!
+
+_cleanup()
+{
+    _cleanup_test_img
+    rm -rf "$TEST_IMG".s
+    rm -rf "$TEST_IMG".e
+
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow2
+_supported_proto file
+_supported_os Linux
+
+function do_run_qemu()
+{
+    echo Testing: "$@" | _filter_imgfmt
+    $QEMU -nographic -qmp-pretty stdio -serial none "$@"
+    echo
+}
+
+function run_qemu()
+{
+    do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_qmp\
+                          | _filter_qemu_io | _filter_generated_node_ids
+}
+
+_make_test_img 64M
+test_throttle=$($QEMU_IMG --help|grep throttle)
+[ "$test_throttle" = "" ] && _supported_fmt throttle
+
+echo
+echo "== inserting node =="
+
+run_qemu <<EOF
+{ "execute": "qmp_capabilities" }
+
+{ "execute": "blockdev-add",
+  "arguments": {
+    "node-name": "disk",
+    "driver": "$IMGFMT",
+    "file": {
+      "driver": "file",
+      "filename": "$TEST_IMG"
+    }
+  }
+}
+{ "execute": "device_add",
+   "arguments": { "driver": "virtio-blk", "drive": "disk",
+                  "id": "virtio0" } }
+{
+    "execute": "blockdev-snapshot-sync",
+    "arguments": {
+        "node-name": "disk",
+        "snapshot-file": "$TEST_IMG.s",
+        "format": "$IMGFMT",
+        "snapshot-node-name": "node-B"
+    }
+}
+{ "execute": "blockdev-add",
+  "arguments": {
+    "node-name": "throttle0",
+    "driver": "throttle",
+    "file": "disk"  }
+}
+
+{ "execute": "block-insert-node",
+    "arguments": {
+    "parent": "node-B",
+    "child": "disk",
+    "node": "throttle0" }
+}
+{ "execute": "query-block" }
+{ "execute": "query-named-block-nodes" }
+{ "execute": "quit" }
+EOF
+
+echo
+echo "== inserting and removing node =="
+
+run_qemu <<EOF
+{ "execute": "qmp_capabilities" }
+
+{ "execute": "blockdev-add",
+  "arguments": {
+    "node-name": "disk",
+    "driver": "$IMGFMT",
+    "file": {
+      "driver": "file",
+      "filename": "$TEST_IMG"
+    }
+  }
+}
+{"execute": "blockdev-add",
+"arguments": {
+"node-name": "throttle0", "driver": "throttle", "file": "disk", 
"throttle-group": "foo", "limits" : { "iops-total": 100 } } }
+{ "execute": "device_add",
+   "arguments": { "driver": "virtio-blk", "drive": "throttle0",
+                  "id": "virtio0" } }
+{"execute": "blockdev-add",
+"arguments": {
+"node-name": "throttle1", "driver": "throttle", "file": "disk", 
"throttle-group": "bar", "limits" : { "iops-total": 200 } } }
+{"execute": "block-insert-node",
+       "arguments": {
+       "parent": "throttle0",
+       "child": "disk",
+       "node": "throttle1"}
+}
+{ "execute": "query-block" }
+{ "execute": "query-named-block-nodes" }
+{"execute": "block-remove-node",
+       "arguments": {
+       "parent": "throttle0",
+       "child": "disk",
+       "node": "throttle1"}
+}
+{"execute": "blockdev-del",
+    "arguments": { "node-name": "throttle1" }
+}
+{ "execute": "query-block" }
+{ "execute": "query-named-block-nodes" }
+{ "execute": "quit" }
+EOF
+
+echo
+echo "== inserting node below BB =="
+
+run_qemu -drive file=$TEST_IMG,format=$IMGFMT,if=none,id=disk,node-name=disk0 
<<EOF
+{ "execute": "qmp_capabilities" }
+{ "execute": "blockdev-add",
+  "arguments": {
+    "node-name": "throttle0",
+    "driver": "throttle",
+    "file": "disk0"  }
+}
+{ "execute": "block-insert-node",
+    "arguments": {
+    "parent": "disk",
+    "child": "disk0",
+    "node": "throttle0" }
+}
+{ "execute": "query-block" }
+{ "execute": "query-named-block-nodes" }
+{"execute": "block-remove-node",
+       "arguments": {
+       "parent": "disk",
+       "child": "disk0",
+       "node": "throttle0"}
+}
+{"execute": "blockdev-del",
+    "arguments": { "node-name": "throttle0" }
+}
+{ "execute": "query-block" }
+{ "execute": "query-named-block-nodes" }
+{ "execute": "quit" }
+EOF
+
+echo
+echo "== try insert with active block job =="
+
+# this should error because of the hidden mirror filter on top
+run_qemu -drive file=$TEST_IMG,format=$IMGFMT,if=none,id=disk,node-name=disk0 
<<EOF
+{ "execute": "qmp_capabilities" }
+{
+    "execute": "blockdev-snapshot-sync",
+    "arguments": {
+        "node-name": "disk0",
+        "snapshot-file": "$TEST_IMG.s",
+        "format": "$IMGFMT",
+        "snapshot-node-name": "overlay0"
+    }
+}
+{
+    "execute": "drive-mirror",
+    "arguments": {
+        "device": "overlay0",
+        "job-id": "job0",
+        "target": "$TEST_IMG.e",
+        "sync": "full"
+    }
+}
+{
+    "execute": "query-block-jobs",
+    "arguments": {}
+}
+{ "execute": "blockdev-add",
+  "arguments": {
+    "node-name": "throttle0",
+    "driver": "throttle",
+    "file": "overlay0"  }
+}
+{ "execute": "block-insert-node",
+    "arguments": {
+    "parent": "disk",
+    "child": "overlay0",
+    "node": "throttle0" }
+}
+{ "execute": "query-block" }
+{"execute": "blockdev-del",
+    "arguments": { "node-name": "throttle0" }
+}
+{ "execute": "quit" }
+EOF
+
+echo
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/193.out b/tests/qemu-iotests/193.out
new file mode 100644
index 0000000000..01a63c7ccb
--- /dev/null
+++ b/tests/qemu-iotests/193.out
@@ -0,0 +1,1116 @@
+QA output created by 192
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+
+== inserting node ==
+Testing:
+{
+    QMP_VERSION
+}
+{
+    "return": {
+    }
+}
+{
+    "return": {
+    }
+}
+{
+    "return": {
+    }
+}
+Formatting 'TEST_DIR/t.qcow2.s', fmt=qcow2 size=67108864 
backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 cluster_size=65536 
lazy_refcounts=off refcount_bits=16
+{
+    "return": {
+    }
+}
+{
+    "return": {
+    }
+}
+{
+    "return": {
+    }
+}
+{
+    "return": [
+        {
+            "device": "",
+            "locked": false,
+            "removable": false,
+            "inserted": {
+                "iops_rd": 0,
+                "detect_zeroes": "off",
+                "image": {
+                    "backing-image": {
+                        "virtual-size": 67108864,
+                        "filename": "TEST_DIR/t.qcow2",
+                        "format": "throttle",
+                        "actual-size": 200704
+                    },
+                    "backing-filename-format": "throttle",
+                    "virtual-size": 67108864,
+                    "filename": "TEST_DIR/t.qcow2.s",
+                    "cluster-size": 65536,
+                    "format": "qcow2",
+                    "actual-size": 200704,
+                    "format-specific": {
+                        "type": "qcow2",
+                        "data": {
+                            "compat": "1.1",
+                            "lazy-refcounts": false,
+                            "refcount-bits": 16,
+                            "corrupt": false
+                        }
+                    },
+                    "full-backing-filename": "TEST_DIR/t.qcow2",
+                    "backing-filename": "TEST_DIR/t.qcow2",
+                    "dirty-flag": false
+                },
+                "iops_wr": 0,
+                "ro": false,
+                "node-name": "node-B",
+                "backing_file_depth": 1,
+                "drv": "qcow2",
+                "iops": 0,
+                "bps_wr": 0,
+                "write_threshold": 0,
+                "backing_file": "TEST_DIR/t.qcow2",
+                "encrypted": false,
+                "bps": 0,
+                "bps_rd": 0,
+                "cache": {
+                    "no-flush": false,
+                    "direct": false,
+                    "writeback": true
+                },
+                "file": "TEST_DIR/t.qcow2.s",
+                "encryption_key_missing": false
+            },
+            "qdev": "/machine/peripheral/virtio0/virtio-backend",
+            "type": "unknown"
+        }
+    ]
+}
+{
+    "return": [
+        {
+            "iops_rd": 0,
+            "detect_zeroes": "off",
+            "image": {
+                "virtual-size": 67108864,
+                "filename": "TEST_DIR/t.qcow2",
+                "format": "throttle",
+                "actual-size": 200704
+            },
+            "iops_wr": 0,
+            "ro": false,
+            "node-name": "throttle0",
+            "backing_file_depth": 0,
+            "drv": "throttle",
+            "iops": 0,
+            "bps_wr": 0,
+            "write_threshold": 0,
+            "encrypted": false,
+            "bps": 0,
+            "bps_rd": 0,
+            "cache": {
+                "no-flush": false,
+                "direct": false,
+                "writeback": true
+            },
+            "file": "TEST_DIR/t.qcow2",
+            "encryption_key_missing": false
+        },
+        {
+            "iops_rd": 0,
+            "detect_zeroes": "off",
+            "image": {
+                "backing-image": {
+                    "virtual-size": 67108864,
+                    "filename": "TEST_DIR/t.qcow2",
+                    "format": "throttle",
+                    "actual-size": 200704
+                },
+                "backing-filename-format": "throttle",
+                "virtual-size": 67108864,
+                "filename": "TEST_DIR/t.qcow2.s",
+                "cluster-size": 65536,
+                "format": "qcow2",
+                "actual-size": 200704,
+                "format-specific": {
+                    "type": "qcow2",
+                    "data": {
+                        "compat": "1.1",
+                        "lazy-refcounts": false,
+                        "refcount-bits": 16,
+                        "corrupt": false
+                    }
+                },
+                "full-backing-filename": "TEST_DIR/t.qcow2",
+                "backing-filename": "TEST_DIR/t.qcow2",
+                "dirty-flag": false
+            },
+            "iops_wr": 0,
+            "ro": false,
+            "node-name": "node-B",
+            "backing_file_depth": 1,
+            "drv": "qcow2",
+            "iops": 0,
+            "bps_wr": 0,
+            "write_threshold": 0,
+            "backing_file": "TEST_DIR/t.qcow2",
+            "encrypted": false,
+            "bps": 0,
+            "bps_rd": 0,
+            "cache": {
+                "no-flush": false,
+                "direct": false,
+                "writeback": true
+            },
+            "file": "TEST_DIR/t.qcow2.s",
+            "encryption_key_missing": false
+        },
+        {
+            "iops_rd": 0,
+            "detect_zeroes": "off",
+            "image": {
+                "virtual-size": 197120,
+                "filename": "TEST_DIR/t.qcow2.s",
+                "format": "file",
+                "actual-size": 200704,
+                "dirty-flag": false
+            },
+            "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,
+                "direct": false,
+                "writeback": true
+            },
+            "file": "TEST_DIR/t.qcow2.s",
+            "encryption_key_missing": false
+        },
+        {
+            "iops_rd": 0,
+            "detect_zeroes": "off",
+            "image": {
+                "virtual-size": 67108864,
+                "filename": "TEST_DIR/t.qcow2",
+                "cluster-size": 65536,
+                "format": "qcow2",
+                "actual-size": 200704,
+                "format-specific": {
+                    "type": "qcow2",
+                    "data": {
+                        "compat": "1.1",
+                        "lazy-refcounts": false,
+                        "refcount-bits": 16,
+                        "corrupt": false
+                    }
+                },
+                "dirty-flag": false
+            },
+            "iops_wr": 0,
+            "ro": true,
+            "node-name": "disk",
+            "backing_file_depth": 0,
+            "drv": "qcow2",
+            "iops": 0,
+            "bps_wr": 0,
+            "write_threshold": 0,
+            "encrypted": false,
+            "bps": 0,
+            "bps_rd": 0,
+            "cache": {
+                "no-flush": false,
+                "direct": false,
+                "writeback": true
+            },
+            "file": "TEST_DIR/t.qcow2",
+            "encryption_key_missing": false
+        },
+        {
+            "iops_rd": 0,
+            "detect_zeroes": "off",
+            "image": {
+                "virtual-size": 197120,
+                "filename": "TEST_DIR/t.qcow2",
+                "format": "file",
+                "actual-size": 200704,
+                "dirty-flag": false
+            },
+            "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,
+                "direct": false,
+                "writeback": true
+            },
+            "file": "TEST_DIR/t.qcow2",
+            "encryption_key_missing": false
+        }
+    ]
+}
+{
+    "return": {
+    }
+}
+{
+    "timestamp": {
+        "seconds":  TIMESTAMP,
+        "microseconds":  TIMESTAMP
+    },
+    "event": "SHUTDOWN",
+    "data": {
+        "guest": false
+    }
+}
+
+
+== inserting and removing node ==
+Testing:
+{
+    QMP_VERSION
+}
+{
+    "return": {
+    }
+}
+{
+    "return": {
+    }
+}
+{
+    "return": {
+    }
+}
+{
+    "return": {
+    }
+}
+{
+    "return": {
+    }
+}
+{
+    "return": {
+    }
+}
+{
+    "return": [
+        {
+            "device": "",
+            "locked": false,
+            "removable": false,
+            "inserted": {
+                "iops_rd": 0,
+                "detect_zeroes": "off",
+                "image": {
+                    "virtual-size": 67108864,
+                    "filename": "json:{\"throttle-group\": \"foo\", 
\"driver\": \"throttle\", \"limits.iops-total\": 100, \"file\": 
{\"throttle-group\": \"bar\", \"driver\": \"throttle\", \"limits.iops-total\": 
200, \"file\": {\"driver\": \"qcow2\", \"file\": {\"driver\": \"file\", 
\"filename\": \"TEST_DIR/t.qcow2\"}}}}",
+                    "format": "throttle",
+                    "actual-size": 200704
+                },
+                "iops_wr": 0,
+                "ro": false,
+                "node-name": "throttle0",
+                "backing_file_depth": 0,
+                "drv": "throttle",
+                "iops": 0,
+                "bps_wr": 0,
+                "write_threshold": 0,
+                "encrypted": false,
+                "bps": 0,
+                "bps_rd": 0,
+                "cache": {
+                    "no-flush": false,
+                    "direct": false,
+                    "writeback": true
+                },
+                "file": "json:{\"throttle-group\": \"foo\", \"driver\": 
\"throttle\", \"limits.iops-total\": 100, \"file\": {\"throttle-group\": 
\"bar\", \"driver\": \"throttle\", \"limits.iops-total\": 200, \"file\": 
{\"driver\": \"qcow2\", \"file\": {\"driver\": \"file\", \"filename\": 
\"TEST_DIR/t.qcow2\"}}}}",
+                "encryption_key_missing": false
+            },
+            "qdev": "/machine/peripheral/virtio0/virtio-backend",
+            "type": "unknown"
+        }
+    ]
+}
+{
+    "return": [
+        {
+            "iops_rd": 0,
+            "detect_zeroes": "off",
+            "image": {
+                "virtual-size": 67108864,
+                "filename": "json:{\"throttle-group\": \"bar\", \"driver\": 
\"throttle\", \"limits.iops-total\": 200, \"file\": {\"driver\": \"qcow2\", 
\"file\": {\"driver\": \"file\", \"filename\": \"TEST_DIR/t.qcow2\"}}}",
+                "format": "throttle",
+                "actual-size": 200704
+            },
+            "iops_wr": 0,
+            "ro": false,
+            "node-name": "throttle1",
+            "backing_file_depth": 0,
+            "drv": "throttle",
+            "iops": 0,
+            "bps_wr": 0,
+            "write_threshold": 0,
+            "encrypted": false,
+            "bps": 0,
+            "bps_rd": 0,
+            "cache": {
+                "no-flush": false,
+                "direct": false,
+                "writeback": true
+            },
+            "file": "json:{\"throttle-group\": \"bar\", \"driver\": 
\"throttle\", \"limits.iops-total\": 200, \"file\": {\"driver\": \"qcow2\", 
\"file\": {\"driver\": \"file\", \"filename\": \"TEST_DIR/t.qcow2\"}}}",
+            "encryption_key_missing": false
+        },
+        {
+            "iops_rd": 0,
+            "detect_zeroes": "off",
+            "image": {
+                "virtual-size": 67108864,
+                "filename": "json:{\"throttle-group\": \"foo\", \"driver\": 
\"throttle\", \"limits.iops-total\": 100, \"file\": {\"throttle-group\": 
\"bar\", \"driver\": \"throttle\", \"limits.iops-total\": 200, \"file\": 
{\"driver\": \"qcow2\", \"file\": {\"driver\": \"file\", \"filename\": 
\"TEST_DIR/t.qcow2\"}}}}",
+                "format": "throttle",
+                "actual-size": 200704
+            },
+            "iops_wr": 0,
+            "ro": false,
+            "node-name": "throttle0",
+            "backing_file_depth": 0,
+            "drv": "throttle",
+            "iops": 0,
+            "bps_wr": 0,
+            "write_threshold": 0,
+            "encrypted": false,
+            "bps": 0,
+            "bps_rd": 0,
+            "cache": {
+                "no-flush": false,
+                "direct": false,
+                "writeback": true
+            },
+            "file": "json:{\"throttle-group\": \"foo\", \"driver\": 
\"throttle\", \"limits.iops-total\": 100, \"file\": {\"throttle-group\": 
\"bar\", \"driver\": \"throttle\", \"limits.iops-total\": 200, \"file\": 
{\"driver\": \"qcow2\", \"file\": {\"driver\": \"file\", \"filename\": 
\"TEST_DIR/t.qcow2\"}}}}",
+            "encryption_key_missing": false
+        },
+        {
+            "iops_rd": 0,
+            "detect_zeroes": "off",
+            "image": {
+                "virtual-size": 67108864,
+                "filename": "TEST_DIR/t.qcow2",
+                "cluster-size": 65536,
+                "format": "qcow2",
+                "actual-size": 200704,
+                "format-specific": {
+                    "type": "qcow2",
+                    "data": {
+                        "compat": "1.1",
+                        "lazy-refcounts": false,
+                        "refcount-bits": 16,
+                        "corrupt": false
+                    }
+                },
+                "dirty-flag": false
+            },
+            "iops_wr": 0,
+            "ro": false,
+            "node-name": "disk",
+            "backing_file_depth": 0,
+            "drv": "qcow2",
+            "iops": 0,
+            "bps_wr": 0,
+            "write_threshold": 0,
+            "encrypted": false,
+            "bps": 0,
+            "bps_rd": 0,
+            "cache": {
+                "no-flush": false,
+                "direct": false,
+                "writeback": true
+            },
+            "file": "TEST_DIR/t.qcow2",
+            "encryption_key_missing": false
+        },
+        {
+            "iops_rd": 0,
+            "detect_zeroes": "off",
+            "image": {
+                "virtual-size": 197120,
+                "filename": "TEST_DIR/t.qcow2",
+                "format": "file",
+                "actual-size": 200704,
+                "dirty-flag": false
+            },
+            "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,
+                "direct": false,
+                "writeback": true
+            },
+            "file": "TEST_DIR/t.qcow2",
+            "encryption_key_missing": false
+        }
+    ]
+}
+{
+    "return": {
+    }
+}
+{
+    "return": {
+    }
+}
+{
+    "return": [
+        {
+            "device": "",
+            "locked": false,
+            "removable": false,
+            "inserted": {
+                "iops_rd": 0,
+                "detect_zeroes": "off",
+                "image": {
+                    "virtual-size": 67108864,
+                    "filename": "json:{\"throttle-group\": \"foo\", 
\"driver\": \"throttle\", \"limits.iops-total\": 100, \"file\": {\"driver\": 
\"qcow2\", \"file\": {\"driver\": \"file\", \"filename\": 
\"TEST_DIR/t.qcow2\"}}}",
+                    "format": "throttle",
+                    "actual-size": 200704
+                },
+                "iops_wr": 0,
+                "ro": false,
+                "node-name": "throttle0",
+                "backing_file_depth": 0,
+                "drv": "throttle",
+                "iops": 0,
+                "bps_wr": 0,
+                "write_threshold": 0,
+                "encrypted": false,
+                "bps": 0,
+                "bps_rd": 0,
+                "cache": {
+                    "no-flush": false,
+                    "direct": false,
+                    "writeback": true
+                },
+                "file": "json:{\"throttle-group\": \"foo\", \"driver\": 
\"throttle\", \"limits.iops-total\": 100, \"file\": {\"driver\": \"qcow2\", 
\"file\": {\"driver\": \"file\", \"filename\": \"TEST_DIR/t.qcow2\"}}}",
+                "encryption_key_missing": false
+            },
+            "qdev": "/machine/peripheral/virtio0/virtio-backend",
+            "type": "unknown"
+        }
+    ]
+}
+{
+    "return": [
+        {
+            "iops_rd": 0,
+            "detect_zeroes": "off",
+            "image": {
+                "virtual-size": 67108864,
+                "filename": "json:{\"throttle-group\": \"foo\", \"driver\": 
\"throttle\", \"limits.iops-total\": 100, \"file\": {\"driver\": \"qcow2\", 
\"file\": {\"driver\": \"file\", \"filename\": \"TEST_DIR/t.qcow2\"}}}",
+                "format": "throttle",
+                "actual-size": 200704
+            },
+            "iops_wr": 0,
+            "ro": false,
+            "node-name": "throttle0",
+            "backing_file_depth": 0,
+            "drv": "throttle",
+            "iops": 0,
+            "bps_wr": 0,
+            "write_threshold": 0,
+            "encrypted": false,
+            "bps": 0,
+            "bps_rd": 0,
+            "cache": {
+                "no-flush": false,
+                "direct": false,
+                "writeback": true
+            },
+            "file": "json:{\"throttle-group\": \"foo\", \"driver\": 
\"throttle\", \"limits.iops-total\": 100, \"file\": {\"driver\": \"qcow2\", 
\"file\": {\"driver\": \"file\", \"filename\": \"TEST_DIR/t.qcow2\"}}}",
+            "encryption_key_missing": false
+        },
+        {
+            "iops_rd": 0,
+            "detect_zeroes": "off",
+            "image": {
+                "virtual-size": 67108864,
+                "filename": "TEST_DIR/t.qcow2",
+                "cluster-size": 65536,
+                "format": "qcow2",
+                "actual-size": 200704,
+                "format-specific": {
+                    "type": "qcow2",
+                    "data": {
+                        "compat": "1.1",
+                        "lazy-refcounts": false,
+                        "refcount-bits": 16,
+                        "corrupt": false
+                    }
+                },
+                "dirty-flag": false
+            },
+            "iops_wr": 0,
+            "ro": false,
+            "node-name": "disk",
+            "backing_file_depth": 0,
+            "drv": "qcow2",
+            "iops": 0,
+            "bps_wr": 0,
+            "write_threshold": 0,
+            "encrypted": false,
+            "bps": 0,
+            "bps_rd": 0,
+            "cache": {
+                "no-flush": false,
+                "direct": false,
+                "writeback": true
+            },
+            "file": "TEST_DIR/t.qcow2",
+            "encryption_key_missing": false
+        },
+        {
+            "iops_rd": 0,
+            "detect_zeroes": "off",
+            "image": {
+                "virtual-size": 197120,
+                "filename": "TEST_DIR/t.qcow2",
+                "format": "file",
+                "actual-size": 200704,
+                "dirty-flag": false
+            },
+            "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,
+                "direct": false,
+                "writeback": true
+            },
+            "file": "TEST_DIR/t.qcow2",
+            "encryption_key_missing": false
+        }
+    ]
+}
+{
+    "return": {
+    }
+}
+{
+    "timestamp": {
+        "seconds":  TIMESTAMP,
+        "microseconds":  TIMESTAMP
+    },
+    "event": "SHUTDOWN",
+    "data": {
+        "guest": false
+    }
+}
+
+
+== inserting node below BB ==
+Testing: -drive 
file=TEST_DIR/t.IMGFMT,format=IMGFMT,if=none,id=disk,node-name=disk0
+{
+    QMP_VERSION
+}
+{
+    "return": {
+    }
+}
+{
+    "return": {
+    }
+}
+{
+    "return": {
+    }
+}
+{
+    "return": [
+        {
+            "device": "disk",
+            "locked": false,
+            "removable": true,
+            "inserted": {
+                "iops_rd": 0,
+                "detect_zeroes": "off",
+                "image": {
+                    "virtual-size": 67108864,
+                    "filename": "TEST_DIR/t.qcow2",
+                    "format": "throttle",
+                    "actual-size": 200704
+                },
+                "iops_wr": 0,
+                "ro": false,
+                "node-name": "throttle0",
+                "backing_file_depth": 0,
+                "drv": "throttle",
+                "iops": 0,
+                "bps_wr": 0,
+                "write_threshold": 0,
+                "encrypted": false,
+                "bps": 0,
+                "bps_rd": 0,
+                "cache": {
+                    "no-flush": false,
+                    "direct": false,
+                    "writeback": true
+                },
+                "file": "TEST_DIR/t.qcow2",
+                "encryption_key_missing": false
+            },
+            "type": "unknown"
+        }
+    ]
+}
+{
+    "return": [
+        {
+            "iops_rd": 0,
+            "detect_zeroes": "off",
+            "image": {
+                "virtual-size": 67108864,
+                "filename": "TEST_DIR/t.qcow2",
+                "format": "throttle",
+                "actual-size": 200704
+            },
+            "iops_wr": 0,
+            "ro": false,
+            "node-name": "throttle0",
+            "backing_file_depth": 0,
+            "drv": "throttle",
+            "iops": 0,
+            "bps_wr": 0,
+            "write_threshold": 0,
+            "encrypted": false,
+            "bps": 0,
+            "bps_rd": 0,
+            "cache": {
+                "no-flush": false,
+                "direct": false,
+                "writeback": true
+            },
+            "file": "TEST_DIR/t.qcow2",
+            "encryption_key_missing": false
+        },
+        {
+            "iops_rd": 0,
+            "detect_zeroes": "off",
+            "image": {
+                "virtual-size": 67108864,
+                "filename": "TEST_DIR/t.qcow2",
+                "cluster-size": 65536,
+                "format": "qcow2",
+                "actual-size": 200704,
+                "format-specific": {
+                    "type": "qcow2",
+                    "data": {
+                        "compat": "1.1",
+                        "lazy-refcounts": false,
+                        "refcount-bits": 16,
+                        "corrupt": false
+                    }
+                },
+                "dirty-flag": false
+            },
+            "iops_wr": 0,
+            "ro": false,
+            "node-name": "disk0",
+            "backing_file_depth": 0,
+            "drv": "qcow2",
+            "iops": 0,
+            "bps_wr": 0,
+            "write_threshold": 0,
+            "encrypted": false,
+            "bps": 0,
+            "bps_rd": 0,
+            "cache": {
+                "no-flush": false,
+                "direct": false,
+                "writeback": true
+            },
+            "file": "TEST_DIR/t.qcow2",
+            "encryption_key_missing": false
+        },
+        {
+            "iops_rd": 0,
+            "detect_zeroes": "off",
+            "image": {
+                "virtual-size": 197120,
+                "filename": "TEST_DIR/t.qcow2",
+                "format": "file",
+                "actual-size": 200704,
+                "dirty-flag": false
+            },
+            "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,
+                "direct": false,
+                "writeback": true
+            },
+            "file": "TEST_DIR/t.qcow2",
+            "encryption_key_missing": false
+        }
+    ]
+}
+{
+    "return": {
+    }
+}
+{
+    "return": {
+    }
+}
+{
+    "return": [
+        {
+            "device": "disk",
+            "locked": false,
+            "removable": true,
+            "inserted": {
+                "iops_rd": 0,
+                "detect_zeroes": "off",
+                "image": {
+                    "virtual-size": 67108864,
+                    "filename": "TEST_DIR/t.qcow2",
+                    "cluster-size": 65536,
+                    "format": "qcow2",
+                    "actual-size": 200704,
+                    "format-specific": {
+                        "type": "qcow2",
+                        "data": {
+                            "compat": "1.1",
+                            "lazy-refcounts": false,
+                            "refcount-bits": 16,
+                            "corrupt": false
+                        }
+                    },
+                    "dirty-flag": false
+                },
+                "iops_wr": 0,
+                "ro": false,
+                "node-name": "disk0",
+                "backing_file_depth": 0,
+                "drv": "qcow2",
+                "iops": 0,
+                "bps_wr": 0,
+                "write_threshold": 0,
+                "encrypted": false,
+                "bps": 0,
+                "bps_rd": 0,
+                "cache": {
+                    "no-flush": false,
+                    "direct": false,
+                    "writeback": true
+                },
+                "file": "TEST_DIR/t.qcow2",
+                "encryption_key_missing": false
+            },
+            "type": "unknown"
+        }
+    ]
+}
+{
+    "return": [
+        {
+            "iops_rd": 0,
+            "detect_zeroes": "off",
+            "image": {
+                "virtual-size": 67108864,
+                "filename": "TEST_DIR/t.qcow2",
+                "cluster-size": 65536,
+                "format": "qcow2",
+                "actual-size": 200704,
+                "format-specific": {
+                    "type": "qcow2",
+                    "data": {
+                        "compat": "1.1",
+                        "lazy-refcounts": false,
+                        "refcount-bits": 16,
+                        "corrupt": false
+                    }
+                },
+                "dirty-flag": false
+            },
+            "iops_wr": 0,
+            "ro": false,
+            "node-name": "disk0",
+            "backing_file_depth": 0,
+            "drv": "qcow2",
+            "iops": 0,
+            "bps_wr": 0,
+            "write_threshold": 0,
+            "encrypted": false,
+            "bps": 0,
+            "bps_rd": 0,
+            "cache": {
+                "no-flush": false,
+                "direct": false,
+                "writeback": true
+            },
+            "file": "TEST_DIR/t.qcow2",
+            "encryption_key_missing": false
+        },
+        {
+            "iops_rd": 0,
+            "detect_zeroes": "off",
+            "image": {
+                "virtual-size": 197120,
+                "filename": "TEST_DIR/t.qcow2",
+                "format": "file",
+                "actual-size": 200704,
+                "dirty-flag": false
+            },
+            "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,
+                "direct": false,
+                "writeback": true
+            },
+            "file": "TEST_DIR/t.qcow2",
+            "encryption_key_missing": false
+        }
+    ]
+}
+{
+    "return": {
+    }
+}
+{
+    "timestamp": {
+        "seconds":  TIMESTAMP,
+        "microseconds":  TIMESTAMP
+    },
+    "event": "SHUTDOWN",
+    "data": {
+        "guest": false
+    }
+}
+
+
+== try insert with active block job ==
+Testing: -drive 
file=TEST_DIR/t.IMGFMT,format=IMGFMT,if=none,id=disk,node-name=disk0
+{
+    QMP_VERSION
+}
+{
+    "return": {
+    }
+}
+Formatting 'TEST_DIR/t.qcow2.s', fmt=qcow2 size=67108864 
backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 cluster_size=65536 
lazy_refcounts=off refcount_bits=16
+{
+    "return": {
+    }
+}
+Formatting 'TEST_DIR/t.qcow2.e', fmt=qcow2 size=67108864 cluster_size=65536 
lazy_refcounts=off refcount_bits=16
+{
+    "timestamp": {
+        "seconds":  TIMESTAMP,
+        "microseconds":  TIMESTAMP
+    },
+    "event": "BLOCK_JOB_READY",
+    "data": {
+        "device": "job0",
+        "len": 0,
+        "offset": 0,
+        "speed": 0,
+        "type": "mirror"
+    }
+}
+{
+    "return": {
+    }
+}
+{
+    "return": [
+        {
+            "io-status": "ok",
+            "device": "job0",
+            "busy": false,
+            "len": 0,
+            "offset": 0,
+            "paused": false,
+            "speed": 0,
+            "ready": true,
+            "type": "mirror"
+        }
+    ]
+}
+{
+    "return": {
+    }
+}
+{
+    "error": {
+        "class": "GenericError",
+        "desc": "'overlay0' not a child of device 'disk'"
+    }
+}
+{
+    "return": [
+        {
+            "device": "disk",
+            "locked": false,
+            "removable": true,
+            "inserted": {
+                "iops_rd": 0,
+                "detect_zeroes": "off",
+                "image": {
+                    "backing-image": {
+                        "virtual-size": 67108864,
+                        "filename": "TEST_DIR/t.qcow2",
+                        "cluster-size": 65536,
+                        "format": "qcow2",
+                        "actual-size": 200704,
+                        "format-specific": {
+                            "type": "qcow2",
+                            "data": {
+                                "compat": "1.1",
+                                "lazy-refcounts": false,
+                                "refcount-bits": 16,
+                                "corrupt": false
+                            }
+                        },
+                        "dirty-flag": false
+                    },
+                    "backing-filename-format": "qcow2",
+                    "virtual-size": 67108864,
+                    "filename": "TEST_DIR/t.qcow2.s",
+                    "cluster-size": 65536,
+                    "format": "qcow2",
+                    "actual-size": 200704,
+                    "format-specific": {
+                        "type": "qcow2",
+                        "data": {
+                            "compat": "1.1",
+                            "lazy-refcounts": false,
+                            "refcount-bits": 16,
+                            "corrupt": false
+                        }
+                    },
+                    "full-backing-filename": "TEST_DIR/t.qcow2",
+                    "backing-filename": "TEST_DIR/t.qcow2",
+                    "dirty-flag": false
+                },
+                "iops_wr": 0,
+                "ro": false,
+                "node-name": "overlay0",
+                "backing_file_depth": 1,
+                "drv": "qcow2",
+                "iops": 0,
+                "bps_wr": 0,
+                "write_threshold": 0,
+                "backing_file": "TEST_DIR/t.qcow2",
+                "encrypted": false,
+                "bps": 0,
+                "bps_rd": 0,
+                "cache": {
+                    "no-flush": false,
+                    "direct": false,
+                    "writeback": true
+                },
+                "file": "TEST_DIR/t.qcow2.s",
+                "encryption_key_missing": false
+            },
+            "dirty-bitmaps": [
+                {
+                    "status": "active",
+                    "granularity": 65536,
+                    "count": 0
+                }
+            ],
+            "type": "unknown"
+        }
+    ]
+}
+{
+    "return": {
+    }
+}
+{
+    "return": {
+    }
+}
+{
+    "timestamp": {
+        "seconds":  TIMESTAMP,
+        "microseconds":  TIMESTAMP
+    },
+    "event": "SHUTDOWN",
+    "data": {
+        "guest": false
+    }
+}
+{
+    "timestamp": {
+        "seconds":  TIMESTAMP,
+        "microseconds":  TIMESTAMP
+    },
+    "event": "BLOCK_JOB_COMPLETED",
+    "data": {
+        "device": "job0",
+        "len": 0,
+        "offset": 0,
+        "speed": 0,
+        "type": "mirror"
+    }
+}
+
+
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 1b4221f26d..9ad3d3d8cb 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -188,3 +188,4 @@
 189 rw auto
 190 rw auto quick
 191 rw auto quick
+193 rw auto quick
-- 
2.11.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]