提交 9aac9d5b 编写于 作者: P Peter Krempa

tests: qemublock: Add test for bitmap detection

Test the extraction of data about changed block tracking bitmaps. The
first test case adds a simple scenario of multiple bitmaps in one layer.

The test data will be also later reused for testing the code that
determines which bitmaps to merge for an incremental backup.

The sequence of bitmaps was created by the libvirt checkpoint API with
the following sequence of commands:

virsh checkpoint-create-as VM --name a
virsh checkpoint-create-as VM --name b
virsh checkpoint-create-as VM --name c
virsh checkpoint-create-as VM --name d
virsh checkpoint-create-as VM --name current
Signed-off-by: NPeter Krempa <pkrempa@redhat.com>
Reviewed-by: NEric Blake <eblake@redhat.com>
上级 7a185d2f
......@@ -27,6 +27,7 @@
# include "virlog.h"
# include "qemu/qemu_block.h"
# include "qemu/qemu_qapi.h"
# include "qemu/qemu_monitor_json.h"
# include "qemu/qemu_command.h"
......@@ -492,6 +493,71 @@ testQemuDiskXMLToPropsValidateFileSrcOnly(const void *opaque)
}
static const char *bitmapDetectPrefix = "qemublocktestdata/bitmap/";
static void
testQemuDetectBitmapsWorker(virHashTablePtr nodedata,
const char *nodename,
virBufferPtr buf)
{
qemuBlockNamedNodeDataPtr data;
size_t i;
if (!(data = virHashLookup(nodedata, nodename)))
return;
virBufferAsprintf(buf, "%s:\n", nodename);
virBufferAdjustIndent(buf, 1);
for (i = 0; i < data->nbitmaps; i++) {
qemuBlockNamedNodeDataBitmapPtr bitmap = data->bitmaps[i];
virBufferAsprintf(buf, "%8s: record:%d busy:%d persist:%d inconsist:%d gran:%llu dirty:%llu\n",
bitmap->name, bitmap->recording, bitmap->busy,
bitmap->persistent, bitmap->inconsistent,
bitmap->granularity, bitmap->dirtybytes);
}
virBufferAdjustIndent(buf, -1);
}
static int
testQemuDetectBitmaps(const void *opaque)
{
const char *name = opaque;
g_autoptr(virJSONValue) nodedatajson = NULL;
g_autoptr(virHashTable) nodedata = NULL;
g_autofree char *actual = NULL;
g_autofree char *expectpath = NULL;
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
size_t i;
expectpath = g_strdup_printf("%s/%s%s.out", abs_srcdir,
bitmapDetectPrefix, name);
if (!(nodedatajson = virTestLoadFileJSON(bitmapDetectPrefix, name,
".json", NULL)))
return -1;
if (!(nodedata = qemuMonitorJSONBlockGetNamedNodeDataJSON(nodedatajson))) {
VIR_TEST_VERBOSE("failed to load nodedata JSON");
return -1;
}
/* we detect for the first 30 nodenames for simplicity */
for (i = 0; i < 30; i++) {
g_autofree char *nodename = g_strdup_printf("libvirt-%zu-format", i);
testQemuDetectBitmapsWorker(nodedata, nodename, &buf);
}
actual = virBufferContentAndReset(&buf);
return virTestCompareToFile(actual, expectpath);
}
static int
mymain(void)
{
......@@ -702,6 +768,15 @@ mymain(void)
TEST_IMAGE_CREATE("network-ssh-qcow2", NULL);
TEST_IMAGE_CREATE("network-sheepdog-qcow2", NULL);
# define TEST_BITMAP_DETECT(testname) \
do { \
if (virTestRun("bitmap detect " testname, \
testQemuDetectBitmaps, testname) < 0) \
ret = -1; \
} while (0)
TEST_BITMAP_DETECT("basic");
cleanup:
virHashFree(diskxmljsondata.schema);
qemuTestDriverFree(&driver);
......
[
{
"iops_rd": 0,
"detect_zeroes": "off",
"image": {
"virtual-size": 10485760,
"filename": "/tmp/pull4.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": "libvirt-1-format",
"backing_file_depth": 0,
"drv": "qcow2",
"iops": 0,
"bps_wr": 0,
"write_threshold": 0,
"dirty-bitmaps": [
{
"name": "current",
"recording": true,
"persistent": true,
"busy": false,
"status": "active",
"granularity": 65536,
"count": 0
},
{
"name": "d",
"recording": false,
"persistent": true,
"busy": false,
"status": "disabled",
"granularity": 65536,
"count": 0
},
{
"name": "c",
"recording": false,
"persistent": true,
"busy": false,
"status": "disabled",
"granularity": 65536,
"count": 0
},
{
"name": "b",
"recording": false,
"persistent": true,
"busy": false,
"status": "disabled",
"granularity": 65536,
"count": 0
},
{
"name": "a",
"recording": false,
"persistent": true,
"busy": false,
"status": "disabled",
"granularity": 65536,
"count": 0
}
],
"encrypted": false,
"bps": 0,
"bps_rd": 0,
"cache": {
"no-flush": false,
"direct": false,
"writeback": true
},
"file": "/tmp/pull4.qcow2",
"encryption_key_missing": false
},
{
"iops_rd": 0,
"detect_zeroes": "off",
"image": {
"virtual-size": 197120,
"filename": "/tmp/pull4.qcow2",
"format": "file",
"actual-size": 200704,
"dirty-flag": false
},
"iops_wr": 0,
"ro": false,
"node-name": "libvirt-1-storage",
"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": "/tmp/pull4.qcow2",
"encryption_key_missing": false
}
]
libvirt-1-format:
current: record:1 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
d: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
c: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
b: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
a: record:0 busy:0 persist:1 inconsist:0 gran:65536 dirty:0
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册