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'(*)