From 6d8ae98fa053919282f86d86ae277c1d8ace3114 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Wed, 2 Oct 2024 14:24:31 +0200 Subject: [PATCH] qemu: monitor: Store internal snapshot names from 'query-named-block-nodes' Store the names of internal snapshots present in supported images in the data we dump from 'query-named-block-nodes' so that the upcoming changes to the internal snapshot code can access it. To test this we use the bitmap detection test cases which can be easily extended to dump this data. Signed-off-by: Peter Krempa Reviewed-by: Pavel Hrdina --- src/qemu/qemu_monitor.h | 3 + src/qemu/qemu_monitor_json.c | 20 ++ tests/qemublocktest.c | 11 + .../bitmap/snapshots-internal.json | 298 ++++++++++++++++++ .../bitmap/snapshots-internal.out | 2 + 5 files changed, 334 insertions(+) create mode 100644 tests/qemublocktestdata/bitmap/snapshots-internal.json create mode 100644 tests/qemublocktestdata/bitmap/snapshots-internal.out diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 6251f48d28..4341519cfe 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -709,6 +709,9 @@ struct _qemuBlockNamedNodeData { qemuBlockNamedNodeDataBitmap **bitmaps; size_t nbitmaps; + /* NULL terminated string list of internal snapshot names */ + char **snapshots; + /* the cluster size of the image is valid only when > 0 */ unsigned long long clusterSize; diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 27f74181f6..c594b33106 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -2569,6 +2569,7 @@ qemuMonitorJSONBlockNamedNodeDataFree(qemuBlockNamedNodeData *data) for (i = 0; i < data->nbitmaps; i++) qemuMonitorJSONBlockNamedNodeDataBitmapFree(data->bitmaps[i]); + g_strfreev(data->snapshots); g_free(data->bitmaps); g_free(data); } @@ -2631,6 +2632,7 @@ qemuMonitorJSONBlockGetNamedNodeDataWorker(size_t pos G_GNUC_UNUSED, GHashTable *nodes = opaque; virJSONValue *img; virJSONValue *bitmaps; + virJSONValue *snapshots; virJSONValue *format_specific; const char *nodename; g_autoptr(qemuBlockNamedNodeData) ent = NULL; @@ -2654,6 +2656,24 @@ qemuMonitorJSONBlockGetNamedNodeDataWorker(size_t pos G_GNUC_UNUSED, if ((bitmaps = virJSONValueObjectGetArray(val, "dirty-bitmaps"))) qemuMonitorJSONBlockGetNamedNodeDataBitmaps(bitmaps, ent); + if ((snapshots = virJSONValueObjectGetArray(img, "snapshots"))) { + size_t nsnapshots = virJSONValueArraySize(snapshots); + size_t nsnapnames = 0; + size_t i; + + ent->snapshots = g_new0(char *, nsnapshots + 1); + + for (i = 0; i < nsnapshots; i++) { + virJSONValue *snapshot = virJSONValueArrayGet(snapshots, i); + const char *name = virJSONValueObjectGetString(snapshot, "name"); + + if (!name) + continue; + + ent->snapshots[nsnapnames++] = g_strdup(name); + } + } + /* query qcow2 format specific props */ if ((format_specific = virJSONValueObjectGetObject(img, "format-specific")) && STREQ_NULLABLE(virJSONValueObjectGetString(format_specific, "type"), "qcow2")) { diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 6c4e735466..60ac929e68 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -594,6 +594,15 @@ testQemuDetectBitmapsWorker(GHashTable *nodedata, bitmap->granularity, bitmap->dirtybytes); } + if (data->snapshots) { + char **sn; + + virBufferAddLit(buf, "internal snapshots:"); + + for (sn = data->snapshots; *sn; sn++) + virBufferAsprintf(buf, " '%s'", *sn); + } + virBufferAdjustIndent(buf, -1); } @@ -1201,6 +1210,7 @@ mymain(void) TEST_IMAGE_CREATE("network-rbd-qcow2", NULL); TEST_IMAGE_CREATE("network-ssh-qcow2", NULL); + /* The following group also tests internal snapshot detection */ #define TEST_BITMAP_DETECT(testname) \ do { \ if (virTestRun("bitmap detect " testname, \ @@ -1213,6 +1223,7 @@ mymain(void) TEST_BITMAP_DETECT("basic"); TEST_BITMAP_DETECT("snapshots"); TEST_BITMAP_DETECT("synthetic"); + TEST_BITMAP_DETECT("snapshots-internal"); #define TEST_BACKUP_BITMAP_CALCULATE(testname, source, incrbackup, named) \ do { \ diff --git a/tests/qemublocktestdata/bitmap/snapshots-internal.json b/tests/qemublocktestdata/bitmap/snapshots-internal.json new file mode 100644 index 0000000000..2198f8f364 --- /dev/null +++ b/tests/qemublocktestdata/bitmap/snapshots-internal.json @@ -0,0 +1,298 @@ +[ + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "snapshots": [ + { + "vm-clock-nsec": 992826708, + "name": "1727868651", + "date-sec": 1727868651, + "date-nsec": 317899000, + "vm-clock-sec": 466, + "id": "1", + "vm-state-size": 57440493 + }, + { + "vm-clock-nsec": 159450672, + "name": "1727872064", + "date-sec": 1727872064, + "date-nsec": 991275000, + "vm-clock-sec": 2431, + "id": "2", + "vm-state-size": 57342213 + } + ], + "virtual-size": 104857600, + "filename": "/tmp/internal-snaps.qcow2", + "cluster-size": 65536, + "format": "qcow2", + "actual-size": 115228672, + "format-specific": { + "type": "qcow2", + "data": { + "compat": "1.1", + "compression-type": "zlib", + "lazy-refcounts": false, + "refcount-bits": 16, + "corrupt": false, + "extended-l2": 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, + "encrypted": false, + "bps": 0, + "bps_rd": 0, + "cache": { + "no-flush": false, + "direct": false, + "writeback": true + }, + "file": "/tmp/internal-snaps.qcow2" + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 115409408, + "filename": "/tmp/internal-snaps.qcow2", + "format": "file", + "actual-size": 115228672, + "format-specific": { + "type": "file", + "data": { + + } + }, + "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/internal-snaps.qcow2" + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 708837376, + "filename": "/var/lib/libvirt/images/systemrescuecd-amd64-6.1.2.iso", + "format": "file", + "actual-size": 708841472, + "format-specific": { + "type": "file", + "data": { + + } + }, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": true, + "node-name": "libvirt-2-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": "/var/lib/libvirt/images/systemrescuecd-amd64-6.1.2.iso" + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "snapshots": [ + { + "vm-clock-nsec": 992826708, + "name": "1727868651", + "date-sec": 1727868651, + "date-nsec": 317899000, + "vm-clock-sec": 466, + "id": "1", + "vm-state-size": 0 + }, + { + "vm-clock-nsec": 159450672, + "name": "1727872064", + "date-sec": 1727872064, + "date-nsec": 991275000, + "vm-clock-sec": 2431, + "id": "2", + "vm-state-size": 0 + } + ], + "virtual-size": 540672, + "filename": "/var/lib/libvirt/qemu/nvram/int-q35_VARS.qcow2", + "cluster-size": 4096, + "format": "qcow2", + "actual-size": 602112, + "format-specific": { + "type": "qcow2", + "data": { + "compat": "1.1", + "compression-type": "zlib", + "lazy-refcounts": false, + "refcount-bits": 16, + "corrupt": false, + "extended-l2": false + } + }, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": false, + "node-name": "libvirt-pflash1-format", + "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/qemu/nvram/int-q35_VARS.qcow2" + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 598528, + "filename": "/var/lib/libvirt/qemu/nvram/int-q35_VARS.qcow2", + "format": "file", + "actual-size": 602112, + "format-specific": { + "type": "file", + "data": { + + } + }, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": false, + "node-name": "libvirt-pflash1-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": "/var/lib/libvirt/qemu/nvram/int-q35_VARS.qcow2" + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 3653632, + "filename": "/usr/share/edk2/ovmf/OVMF_CODE_4M.secboot.qcow2", + "cluster-size": 4096, + "format": "qcow2", + "actual-size": 3678208, + "format-specific": { + "type": "qcow2", + "data": { + "compat": "1.1", + "compression-type": "zlib", + "lazy-refcounts": false, + "refcount-bits": 16, + "corrupt": false, + "extended-l2": false + } + }, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": true, + "node-name": "libvirt-pflash0-format", + "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": "/usr/share/edk2/ovmf/OVMF_CODE_4M.secboot.qcow2" + }, + { + "iops_rd": 0, + "detect_zeroes": "off", + "image": { + "virtual-size": 3678208, + "filename": "/usr/share/edk2/ovmf/OVMF_CODE_4M.secboot.qcow2", + "format": "file", + "actual-size": 3678208, + "format-specific": { + "type": "file", + "data": { + + } + }, + "dirty-flag": false + }, + "iops_wr": 0, + "ro": false, + "node-name": "libvirt-pflash0-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": "/usr/share/edk2/ovmf/OVMF_CODE_4M.secboot.qcow2" + } +] diff --git a/tests/qemublocktestdata/bitmap/snapshots-internal.out b/tests/qemublocktestdata/bitmap/snapshots-internal.out new file mode 100644 index 0000000000..f2fb0a1dcc --- /dev/null +++ b/tests/qemublocktestdata/bitmap/snapshots-internal.out @@ -0,0 +1,2 @@ +libvirt-1-format: + internal snapshots: '1727868651' '1727872064' -- 2.39.5