Refactor the parts of qemuBlockGetNamedNodeData which fetch the names of
internal snapshots present in the on-disk state of QCOW2 images to also
extract the presence of the 'vmstate' section.
This requires conversion of the snapshot list to a hash table as we
always know the name of the snapshot that we're looking for, and the
hash table allows also storing of additional data which we'll use to
store the presence of the 'vmstate'.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/qemu/qemu_monitor.h | 12 ++++++++++--
src/qemu/qemu_monitor_json.c | 18 ++++++++++++++----
src/qemu/qemu_snapshot.c | 6 ++----
tests/qemublocktest.c | 14 +++++++++++---
.../bitmap/snapshots-internal.out | 2 +-
5 files changed, 38 insertions(+), 14 deletions(-)
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index aded771315..89a59dfd27 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -701,6 +701,13 @@ struct _qemuBlockNamedNodeDataBitmap {
unsigned long long granularity;
};
+
+typedef struct _qemuBlockNamedNodeDataSnapshot qemuBlockNamedNodeDataSnapshot;
+struct _qemuBlockNamedNodeDataSnapshot {
+ bool vmstate;
+};
+
+
typedef struct _qemuBlockNamedNodeData qemuBlockNamedNodeData;
struct _qemuBlockNamedNodeData {
unsigned long long capacity;
@@ -709,8 +716,9 @@ struct _qemuBlockNamedNodeData {
qemuBlockNamedNodeDataBitmap **bitmaps;
size_t nbitmaps;
- /* NULL terminated string list of internal snapshot names */
- char **snapshots;
+ /* hash table indexed by snapshot name containing data about snapshots
+ * (qemuBlockNamedNodeDataSnapshot) */
+ GHashTable *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 b3924461a9..1b4288b744 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -2569,7 +2569,7 @@ qemuMonitorJSONBlockNamedNodeDataFree(qemuBlockNamedNodeData *data)
for (i = 0; i < data->nbitmaps; i++)
qemuMonitorJSONBlockNamedNodeDataBitmapFree(data->bitmaps[i]);
- g_strfreev(data->snapshots);
+ g_clear_pointer(&data->snapshots, g_hash_table_unref);
g_free(data->bitmaps);
g_free(data);
}
@@ -2658,19 +2658,29 @@ qemuMonitorJSONBlockGetNamedNodeDataWorker(size_t pos
G_GNUC_UNUSED,
if ((snapshots = virJSONValueObjectGetArray(img, "snapshots"))) {
size_t nsnapshots = virJSONValueArraySize(snapshots);
- size_t nsnapnames = 0;
size_t i;
- ent->snapshots = g_new0(char *, nsnapshots + 1);
+ ent->snapshots = virHashNew(g_free);
for (i = 0; i < nsnapshots; i++) {
virJSONValue *snapshot = virJSONValueArrayGet(snapshots, i);
const char *name = virJSONValueObjectGetString(snapshot, "name");
+ unsigned long long vmstate_size = 0;
+ qemuBlockNamedNodeDataSnapshot *snd;
if (!name)
continue;
- ent->snapshots[nsnapnames++] = g_strdup(name);
+ ignore_value(virJSONValueObjectGetNumberUlong(snapshot,
+ "vm-state-size",
+ &vmstate_size));
+
+ snd = g_new0(qemuBlockNamedNodeDataSnapshot, 1);
+
+ if (vmstate_size > 0)
+ snd->vmstate = true;
+
+ g_hash_table_insert(ent->snapshots, g_strdup(name), snd);
}
}
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
index 4a17935627..aab06a09c6 100644
--- a/src/qemu/qemu_snapshot.c
+++ b/src/qemu/qemu_snapshot.c
@@ -3897,8 +3897,7 @@ qemuSnapshotActiveInternalDeleteGetDevices(virDomainObj *vm,
continue;
/* there might be no snapshot for given disk with given name */
- if (!d->snapshots ||
- !g_strv_contains((const char **) d->snapshots, snapname))
+ if (!virHashHasEntry(d->snapshots, snapname))
continue;
devices[ndevs++] = g_strdup(format_nodename);
@@ -3913,8 +3912,7 @@ qemuSnapshotActiveInternalDeleteGetDevices(virDomainObj *vm,
if ((format_nodename =
qemuBlockStorageSourceGetFormatNodename(vm->def->os.loader->nvram)) &&
(d = virHashLookup(blockNamedNodeData, format_nodename)) &&
- d->snapshots &&
- g_strv_contains((const char **) d->snapshots, snapname)) {
+ virHashHasEntry(d->snapshots, snapname)) {
devices[ndevs++] = g_strdup(format_nodename);
}
}
diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
index ac4d87b527..be3e421ac0 100644
--- a/tests/qemublocktest.c
+++ b/tests/qemublocktest.c
@@ -598,12 +598,20 @@ testQemuDetectBitmapsWorker(GHashTable *nodedata,
}
if (data->snapshots) {
- char **sn;
+ g_autofree virHashKeyValuePair *snaps = virHashGetItems(data->snapshots, NULL,
true);
+ virHashKeyValuePair *n;
virBufferAddLit(buf, "internal snapshots:");
- for (sn = data->snapshots; *sn; sn++)
- virBufferAsprintf(buf, " '%s'", *sn);
+ for (n = snaps; n->key; n++) {
+ const qemuBlockNamedNodeDataSnapshot *d = n->value;
+ const char *vms = "";
+
+ if (d->vmstate)
+ vms = "(*)";
+
+ virBufferAsprintf(buf, " '%s'%s", (const char *) n->key,
vms);
+ }
}
virBufferAdjustIndent(buf, -1);
diff --git a/tests/qemublocktestdata/bitmap/snapshots-internal.out
b/tests/qemublocktestdata/bitmap/snapshots-internal.out
index f2fb0a1dcc..dbb3cfded4 100644
--- a/tests/qemublocktestdata/bitmap/snapshots-internal.out
+++ b/tests/qemublocktestdata/bitmap/snapshots-internal.out
@@ -1,2 +1,2 @@
libvirt-1-format:
- internal snapshots: '1727868651' '1727872064'
+ internal snapshots: '1727868651'(*) '1727872064'(*)
--
2.47.0