The code is rather magic so a test case will help making sure that
everything works well. The first case is a simple backing chain.
---
.../qemumonitorjson-nodename-1.json | 268 +++++++++++++++++++++
.../qemumonitorjson-nodename-1.result | 15 ++
tests/qemumonitorjsontest.c | 116 +++++++++
3 files changed, 399 insertions(+)
create mode 100644 tests/qemumonitorjsondata/qemumonitorjson-nodename-1.json
create mode 100644 tests/qemumonitorjsondata/qemumonitorjson-nodename-1.result
diff --git a/tests/qemumonitorjsondata/qemumonitorjson-nodename-1.json
b/tests/qemumonitorjsondata/qemumonitorjson-nodename-1.json
new file mode 100644
index 000000000..fe2f32176
--- /dev/null
+++ b/tests/qemumonitorjsondata/qemumonitorjson-nodename-1.json
@@ -0,0 +1,268 @@
+[
+ {
+ "iops_rd": 0,
+ "detect_zeroes": "off",
+ "image": {
+ "virtual-size": 9663676416,
+ "filename": "/var/lib/libvirt/images/rhel7.3.qcow2",
+ "cluster-size": 65536,
+ "format": "qcow2",
+ "actual-size": 9665384448,
+ "format-specific": {
+ "type": "qcow2",
+ "data": {
+ "compat": "1.1",
+ "lazy-refcounts": true,
+ "refcount-bits": 16,
+ "corrupt": false
+ }
+ },
+ "dirty-flag": false
+ },
+ "iops_wr": 0,
+ "ro": true,
+ "node-name": "#block567",
+ "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": "/var/lib/libvirt/images/rhel7.3.qcow2",
+ "encryption_key_missing": false
+ },
+ {
+ "iops_rd": 0,
+ "detect_zeroes": "off",
+ "image": {
+ "virtual-size": 9665380352,
+ "filename": "/var/lib/libvirt/images/rhel7.3.qcow2",
+ "format": "file",
+ "actual-size": 9665384448,
+ "dirty-flag": false
+ },
+ "iops_wr": 0,
+ "ro": true,
+ "node-name": "#block424",
+ "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": "/var/lib/libvirt/images/rhel7.3.qcow2",
+ "encryption_key_missing": false
+ },
+ {
+ "iops_rd": 0,
+ "detect_zeroes": "off",
+ "image": {
+ "backing-image": {
+ "virtual-size": 9663676416,
+ "filename": "/var/lib/libvirt/images/rhel7.3.qcow2",
+ "cluster-size": 65536,
+ "format": "qcow2",
+ "actual-size": 9665384448,
+ "format-specific": {
+ "type": "qcow2",
+ "data": {
+ "compat": "1.1",
+ "lazy-refcounts": true,
+ "refcount-bits": 16,
+ "corrupt": false
+ }
+ },
+ "dirty-flag": false
+ },
+ "backing-filename-format": "qcow2",
+ "virtual-size": 9663676416,
+ "filename": "/var/lib/libvirt/images/rhel7.3.1483536402",
+ "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":
"/var/lib/libvirt/images/rhel7.3.qcow2",
+ "backing-filename": "/var/lib/libvirt/images/rhel7.3.qcow2",
+ "dirty-flag": false
+ },
+ "iops_wr": 0,
+ "ro": true,
+ "node-name": "#block331",
+ "backing_file_depth": 1,
+ "drv": "qcow2",
+ "iops": 0,
+ "bps_wr": 0,
+ "write_threshold": 0,
+ "backing_file": "/var/lib/libvirt/images/rhel7.3.qcow2",
+ "encrypted": false,
+ "bps": 0,
+ "bps_rd": 0,
+ "cache": {
+ "no-flush": false,
+ "direct": false,
+ "writeback": true
+ },
+ "file": "/var/lib/libvirt/images/rhel7.3.1483536402",
+ "encryption_key_missing": false
+ },
+ {
+ "iops_rd": 0,
+ "detect_zeroes": "off",
+ "image": {
+ "virtual-size": 197120,
+ "filename": "/var/lib/libvirt/images/rhel7.3.1483536402",
+ "format": "file",
+ "actual-size": 200704,
+ "dirty-flag": false
+ },
+ "iops_wr": 0,
+ "ro": true,
+ "node-name": "#block281",
+ "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": "/var/lib/libvirt/images/rhel7.3.1483536402",
+ "encryption_key_missing": false
+ },
+ {
+ "iops_rd": 0,
+ "detect_zeroes": "off",
+ "image": {
+ "backing-image": {
+ "backing-image": {
+ "virtual-size": 9663676416,
+ "filename": "/var/lib/libvirt/images/rhel7.3.qcow2",
+ "cluster-size": 65536,
+ "format": "qcow2",
+ "actual-size": 9665384448,
+ "format-specific": {
+ "type": "qcow2",
+ "data": {
+ "compat": "1.1",
+ "lazy-refcounts": true,
+ "refcount-bits": 16,
+ "corrupt": false
+ }
+ },
+ "dirty-flag": false
+ },
+ "backing-filename-format": "qcow2",
+ "virtual-size": 9663676416,
+ "filename": "/var/lib/libvirt/images/rhel7.3.1483536402",
+ "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":
"/var/lib/libvirt/images/rhel7.3.qcow2",
+ "backing-filename":
"/var/lib/libvirt/images/rhel7.3.qcow2",
+ "dirty-flag": false
+ },
+ "backing-filename-format": "qcow2",
+ "virtual-size": 9663676416,
+ "filename": "/var/lib/libvirt/images/rhel7.3.1483545313",
+ "cluster-size": 65536,
+ "format": "qcow2",
+ "actual-size": 32968704,
+ "format-specific": {
+ "type": "qcow2",
+ "data": {
+ "compat": "1.1",
+ "lazy-refcounts": false,
+ "refcount-bits": 16,
+ "corrupt": false
+ }
+ },
+ "full-backing-filename":
"/var/lib/libvirt/images/rhel7.3.1483536402",
+ "backing-filename":
"/var/lib/libvirt/images/rhel7.3.1483536402",
+ "dirty-flag": false
+ },
+ "iops_wr": 0,
+ "ro": false,
+ "node-name": "#block118",
+ "backing_file_depth": 2,
+ "drv": "qcow2",
+ "iops": 0,
+ "bps_wr": 0,
+ "write_threshold": 0,
+ "backing_file": "/var/lib/libvirt/images/rhel7.3.1483536402",
+ "encrypted": false,
+ "bps": 0,
+ "bps_rd": 0,
+ "cache": {
+ "no-flush": false,
+ "direct": false,
+ "writeback": true
+ },
+ "file": "/var/lib/libvirt/images/rhel7.3.1483545313",
+ "encryption_key_missing": false
+ },
+ {
+ "iops_rd": 0,
+ "detect_zeroes": "off",
+ "image": {
+ "virtual-size": 33030144,
+ "filename": "/var/lib/libvirt/images/rhel7.3.1483545313",
+ "format": "file",
+ "actual-size": 32968704,
+ "dirty-flag": false
+ },
+ "iops_wr": 0,
+ "ro": false,
+ "node-name": "#block078",
+ "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": "/var/lib/libvirt/images/rhel7.3.1483545313",
+ "encryption_key_missing": false
+ }
+]
diff --git a/tests/qemumonitorjsondata/qemumonitorjson-nodename-1.result
b/tests/qemumonitorjsondata/qemumonitorjson-nodename-1.result
new file mode 100644
index 000000000..e43f3d366
--- /dev/null
+++ b/tests/qemumonitorjsondata/qemumonitorjson-nodename-1.result
@@ -0,0 +1,15 @@
+filename : '/var/lib/libvirt/images/rhel7.3.1483545313'
+format node : '#block118'
+storage node: '#block078'
+backingfile : '/var/lib/libvirt/images/rhel7.3.1483536402'
+backing ptr : '#block331'
+ filename : '/var/lib/libvirt/images/rhel7.3.1483536402'
+ format node : '#block331'
+ storage node: '#block281'
+ backingfile : '/var/lib/libvirt/images/rhel7.3.qcow2'
+ backing ptr : '#block567'
+ filename : '/var/lib/libvirt/images/rhel7.3.qcow2'
+ format node : '#block567'
+ storage node: '#block424'
+ backingfile : '<null>'
+ backing ptr : '<null>'
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index 402c87d45..fcc1540a8 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -23,6 +23,7 @@
#include "testutilsqemu.h"
#include "qemumonitortestutils.h"
#include "qemu/qemu_domain.h"
+#include "qemu/qemu_block.h"
#include "qemu/qemu_monitor_json.h"
#include "virthread.h"
#include "virerror.h"
@@ -2659,6 +2660,109 @@ testQemuMonitorCPUInfo(const void *opaque)
}
+struct testBlockNodeNameDetectData {
+ const char *name;
+ const char *nodenames;
+};
+
+
+static void
+testBlockNodeNameDetectFormat(virBufferPtr buf,
+ const char *basenode,
+ virHashTablePtr nodedata)
+{
+ qemuBlockNodeNameBackingChainDataPtr entry = NULL;
+ const char *node = basenode;
+
+ virBufferSetIndent(buf, 0);
+
+ while (node) {
+ if (!(entry = virHashLookup(nodedata, node)))
+ break;
+
+ virBufferAsprintf(buf, "filename : '%s'\n",
entry->qemufilename);
+ virBufferAsprintf(buf, "format node : '%s'\n",
+ NULLSTR(entry->nodeformat));
+ virBufferAsprintf(buf, "storage node: '%s'\n",
+ NULLSTR(entry->nodestorage));
+ virBufferAsprintf(buf, "backingfile : '%s'\n",
+ NULLSTR(entry->backingstore));
+ virBufferAsprintf(buf, "backing ptr : '%s'\n",
+ NULLSTR(entry->nodebacking));
+
+ virBufferAdjustIndent(buf, 2);
+
+ node = entry->nodebacking;
+ }
+
+ virBufferSetIndent(buf, 0);
+ virBufferAddLit(buf, "\n");
+}
+
+
+static int
+testBlockNodeNameDetect(const void *opaque)
+{
+ const struct testBlockNodeNameDetectData *data = opaque;
+ char *jsonFile = NULL;
+ char *jsonStr = NULL;
+ char *resultFile = NULL;
+ char *actual = NULL;
+ char **nodenames = NULL;
+ char **next;
+ virJSONValuePtr json = NULL;
+ virHashTablePtr nodedata = NULL;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ int ret = -1;
+
+ if (virAsprintf(&jsonFile,
+ "%s/qemumonitorjsondata/qemumonitorjson-nodename-%s.json",
+ abs_srcdir, data->name) < 0 ||
+ virAsprintf(&resultFile,
+
"%s/qemumonitorjsondata/qemumonitorjson-nodename-%s.result",
+ abs_srcdir, data->name) < 0)
+ goto cleanup;
+
+ if (!(nodenames = virStringSplit(data->nodenames, ",", 0)))
+ goto cleanup;
+
+ if (virTestLoadFile(jsonFile, &jsonStr) < 0)
+ goto cleanup;
+
+ if (!(json = virJSONValueFromString(jsonStr)))
+ goto cleanup;
+
+ if (!(nodedata = qemuBlockNodeNameGetBackingChain(json)))
+ goto cleanup;
+
+ for (next = nodenames; *next; next++)
+ testBlockNodeNameDetectFormat(&buf, *next, nodedata);
+
+ virBufferTrim(&buf, "\n", -1);
+
+ if (virBufferCheckError(&buf) < 0)
+ goto cleanup;
+
+ actual = virBufferContentAndReset(&buf);
+
+ if (virTestCompareToFile(actual, resultFile) < 0)
+ goto cleanup;
+
+ ret = 0;
+
+ cleanup:
+ VIR_FREE(jsonFile);
+ VIR_FREE(resultFile);
+ VIR_FREE(jsonStr);
+ VIR_FREE(actual);
+ virHashFree(nodedata);
+ virStringListFree(nodenames);
+ virJSONValueFree(json);
+
+ return ret;
+}
+
+
static int
mymain(void)
{
@@ -2793,6 +2897,18 @@ mymain(void)
DO_TEST_CPU_INFO("ppc64-hotplug-4", 24);
DO_TEST_CPU_INFO("ppc64-no-threads", 16);
+#define DO_TEST_BLOCK_NODE_DETECT(testname, testnodes) \
+ do { \
+ struct testBlockNodeNameDetectData testdata = {testname, testnodes}; \
+ if (virTestRun("node-name-detect(" testname ")",
\
+ testBlockNodeNameDetect, &testdata) < 0) \
+ ret = -1; \
+ } while (0)
+
+ DO_TEST_BLOCK_NODE_DETECT("1", "#block118");
+
+#undef DO_TEST_BLOCK_NODE_DETECT
+
qemuTestDriverFree(&driver);
return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
--
2.12.0