--- docs/schemas/domainsnapshot.rng | 7 +++ src/conf/snapshot_conf.c | 74 ++++++++++++++++++++++++ src/conf/snapshot_conf.h | 2 + tests/domainsnapshotxml2xmlin/disk_snapshot.xml | 5 ++ tests/domainsnapshotxml2xmlout/disk_snapshot.xml | 4 ++ 5 files changed, 92 insertions(+) diff --git a/docs/schemas/domainsnapshot.rng b/docs/schemas/domainsnapshot.rng index 7b46df1..63c8511 100644 --- a/docs/schemas/domainsnapshot.rng +++ b/docs/schemas/domainsnapshot.rng @@ -6,6 +6,7 @@ </start> <include href='domaincommon.rng'/> + <include href='storagefilefeatures.rng'/> <define name='domainsnapshot'> <element name='domainsnapshot'> @@ -144,6 +145,12 @@ <empty/> </element> </optional> + <optional> + <ref name='compat'/> + </optional> + <optional> + <ref name='fileFormatFeatures'/> + </optional> </interleave> </group> </choice> diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c index 324b07f..97d8848 100644 --- a/src/conf/snapshot_conf.c +++ b/src/conf/snapshot_conf.c @@ -82,6 +82,9 @@ virDomainSnapshotDiskDefClear(virDomainSnapshotDiskDefPtr disk) { VIR_FREE(disk->name); VIR_FREE(disk->file); + VIR_FREE(disk->compat); + virBitmapFree(disk->features); + disk->features = NULL; } void virDomainSnapshotDefFree(virDomainSnapshotDefPtr def) @@ -103,6 +106,38 @@ void virDomainSnapshotDefFree(virDomainSnapshotDefPtr def) } static int +virDomainSnapshotDiskFeaturesDefParse(virDomainSnapshotDiskDefPtr def, + xmlNodePtr node) +{ + xmlNodePtr cur; + int f, n = 0; + + if (!(def->features = virBitmapNew(VIR_STORAGE_FILE_FEATURE_LAST))) { + virReportOOMError(); + return -1; + } + + for (cur = node->children; cur; cur = cur->next) { + if (cur->type != XML_ELEMENT_NODE) + continue; + + f = virStorageFileFeatureTypeFromString((const char*) cur->name); + + if (f < 0) { + virReportError(VIR_ERR_XML_ERROR, _("unsupported feature %s"), + (const char*) cur->name); + return -1; + } + ignore_value(virBitmapSetBit(def->features, f)); + n++; + + } + if (n > 0 && !def->compat && VIR_STRDUP(def->compat, "1.1") < 0) + return -1; + return 0; +} + +static int virDomainSnapshotDiskDefParseXML(xmlNodePtr node, virDomainSnapshotDiskDefPtr def) { @@ -146,6 +181,17 @@ virDomainSnapshotDiskDefParseXML(xmlNodePtr node, goto cleanup; } VIR_FREE(driver); + } else if (xmlStrEqual(cur->name, BAD_CAST "compat")) { + if (VIR_STRDUP(def->compat, (const char*)cur->content) < 0) + goto cleanup; + if (def->compat && strchr(def->compat, ',')) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("forbidden characters in 'compat' attribute")); + goto cleanup; + } + } else if (xmlStrEqual(cur->name, BAD_CAST "features")) { + if (virDomainSnapshotDiskFeaturesDefParse(def, cur) < 0) + goto cleanup; } } cur = cur->next; @@ -553,6 +599,29 @@ cleanup: } static void +virDomainSnapshotDiskFeaturesDefFormat(virBufferPtr buf, + virBitmapPtr features) +{ + int i; + + if (virBitmapIsAllClear(features)) { + virBufferAddLit(buf, "<features/>\n"); + return; + } + + virBufferAddLit(buf, "<features>\n"); + for (i = 0; i < VIR_STORAGE_FILE_FEATURE_LAST; i++) { + bool b; + + ignore_value(virBitmapGetBit(features, i, &b)); + if (b) + virBufferAsprintf(buf, " <%s/>\n", + virStorageFileFeatureTypeToString(i)); + } + virBufferAddLit(buf, "</features>\n"); +} + +static void virDomainSnapshotDiskDefFormat(virBufferPtr buf, virDomainSnapshotDiskDefPtr disk) { @@ -575,6 +644,11 @@ virDomainSnapshotDiskDefFormat(virBufferPtr buf, virBufferEscapeString(buf, "<driver type='%s'/>\n", virStorageFileFormatTypeToString(disk->format)); virBufferEscapeString(buf, "<source file='%s'/>\n", disk->file); + virBufferEscapeString(buf, "<compat>%s</compat>\n", disk->compat); + + if (disk->features) + virDomainSnapshotDiskFeaturesDefFormat(buf, disk->features); + virBufferAdjustIndent(buf, -6); virBufferAddLit(buf, " </disk>\n"); } diff --git a/src/conf/snapshot_conf.h b/src/conf/snapshot_conf.h index 6d625a7..2be5319 100644 --- a/src/conf/snapshot_conf.h +++ b/src/conf/snapshot_conf.h @@ -53,6 +53,8 @@ struct _virDomainSnapshotDiskDef { int snapshot; /* enum virDomainSnapshotLocation */ char *file; /* new source file when snapshot is external */ int format; /* enum virStorageFileFormat */ + char *compat; + virBitmapPtr features; }; /* Stores the complete snapshot metadata */ diff --git a/tests/domainsnapshotxml2xmlin/disk_snapshot.xml b/tests/domainsnapshotxml2xmlin/disk_snapshot.xml index ee6b46a..79895d7 100644 --- a/tests/domainsnapshotxml2xmlin/disk_snapshot.xml +++ b/tests/domainsnapshotxml2xmlin/disk_snapshot.xml @@ -11,6 +11,11 @@ </disk> <disk name='hde' snapshot='external'> <source file='/path/to/new'/> + <driver type='qcow2'/> + <compat>1.1</compat> + <features> + <lazy_refcounts/> + </features> </disk> </disks> </domainsnapshot> diff --git a/tests/domainsnapshotxml2xmlout/disk_snapshot.xml b/tests/domainsnapshotxml2xmlout/disk_snapshot.xml index 5f42bf5..4c3f8ad 100644 --- a/tests/domainsnapshotxml2xmlout/disk_snapshot.xml +++ b/tests/domainsnapshotxml2xmlout/disk_snapshot.xml @@ -18,6 +18,10 @@ <disk name='hde' snapshot='external'> <driver type='qcow2'/> <source file='/path/to/new'/> + <compat>1.1</compat> + <features> + <lazy_refcounts/> + </features> </disk> <disk name='hdf' snapshot='external'> <driver type='qcow2'/> -- 1.8.1.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list