Data files are simple raw images. Thus, we don't need to parse too much. The main objectives are: - allow only RAW format - forbid storage slices - include this parsing/formatting into backing chain parse/format as well as into top storage source parse/format because data file can belong to backing image Signed-off-by: Nikolai Barybin <nikolai.barybin@xxxxxxxxxxxxx> --- src/conf/domain_conf.c | 100 +++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 13 ++++++ 2 files changed, 113 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 295707ec1f..9348c12725 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -7670,6 +7670,62 @@ virDomainStorageSourceParse(xmlNodePtr node, } +int +virDomainDiskDataFileStoreParse(xmlXPathContextPtr ctxt, + virStorageSource *src, + unsigned int flags, + virDomainXMLOption *xmlopt) +{ + VIR_XPATH_NODE_AUTORESTORE(ctxt) + xmlNodePtr source; + g_autofree char *type = NULL; + g_autofree char *format = NULL; + g_autoptr(virStorageSource) dataFileStore = NULL; + + if (!(ctxt->node = virXPathNode("./dataFileStore", ctxt))) + return 0; + + if (!(type = virXMLPropStringRequired(ctxt->node, "type"))) + return -1; + + if (!(format = virXPathString("string(./format/@type)", ctxt))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing data file store format")); + return -1; + } + + if (!(source = virXPathNode("./source", ctxt))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing disk data file store source")); + return -1; + } + + if (virStorageFileFormatTypeFromString(format) != VIR_STORAGE_FILE_RAW) { + virReportError(VIR_ERR_XML_ERROR, + _("unexpected disk data file format '%1$s', only raw format is supported"), + format); + return -1; + } + + if (!(dataFileStore = virDomainStorageSourceParseBase(type, format, NULL))) + return -1; + + if (virDomainStorageSourceParse(source, ctxt, dataFileStore, flags, xmlopt) < 0) + return -1; + + if (dataFileStore->sliceStorage) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("slices are not supported for fata file store source")); + return -1; + } + + dataFileStore->readonly = src->readonly; + src->dataFileStore = g_steal_pointer(&dataFileStore); + + return 0; +} + + int virDomainDiskBackingStoreParse(xmlXPathContextPtr ctxt, virStorageSource *src, @@ -7720,6 +7776,7 @@ virDomainDiskBackingStoreParse(xmlXPathContextPtr ctxt, backingStore->readonly = true; if (virDomainStorageSourceParse(source, ctxt, backingStore, flags, xmlopt) < 0 || + virDomainDiskDataFileStoreParse(ctxt, backingStore, flags, xmlopt) < 0 || virDomainDiskBackingStoreParse(ctxt, backingStore, flags, xmlopt) < 0) return -1; @@ -8112,6 +8169,9 @@ virDomainDiskDefParseSourceXML(virDomainXMLOption *xmlopt, return NULL; } + if (virDomainDiskDataFileStoreParse(ctxt, src, flags, xmlopt) < 0) + return NULL; + if (virDomainDiskBackingStoreParse(ctxt, src, flags, xmlopt) < 0) return NULL; @@ -22885,6 +22945,38 @@ virDomainDiskSourceFormat(virBuffer *buf, return 0; } +int +virDomainDiskDataFileStoreFormat(virBuffer *buf, + virStorageSource *src, + virDomainXMLOption *xmlopt, + unsigned int flags) +{ + g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER; + g_auto(virBuffer) formatAttrBuf = VIR_BUFFER_INITIALIZER; + g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf); + virStorageSource *dataFileStore = src->dataFileStore; + bool inactive = flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE; + + if (!dataFileStore) + return 0; + + /* don't write detected data file member to inactive xml */ + if (inactive && dataFileStore->detected) + return 0; + + virBufferAsprintf(&attrBuf, " type='%s'", + virStorageTypeToString(dataFileStore->type)); + + virBufferAsprintf(&formatAttrBuf, " type='%s'", "raw"); + virXMLFormatElement(&childBuf, "format", &formatAttrBuf, NULL); + + if (virDomainDiskSourceFormat(&childBuf, dataFileStore, "source", 0, false, + flags, false, false, xmlopt) < 0) + return -1; + + virXMLFormatElement(buf, "dataFileStore", &attrBuf, &childBuf); + return 0; +} int virDomainDiskBackingStoreFormat(virBuffer *buf, @@ -22943,6 +23035,10 @@ virDomainDiskBackingStoreFormat(virBuffer *buf, flags, false, false, xmlopt) < 0) return -1; + if (backingStore->dataFileStore && + virDomainDiskDataFileStoreFormat(&childBuf, backingStore, xmlopt, flags) < 0) + return -1; + if (virDomainDiskBackingStoreFormat(&childBuf, backingStore, xmlopt, flags) < 0) return -1; @@ -23261,6 +23357,10 @@ virDomainDiskDefFormat(virBuffer *buf, if (virDomainDiskBackingStoreFormat(&childBuf, def->src, xmlopt, flags) < 0) return -1; + if (def->src->dataFileStore && + virDomainDiskDataFileStoreFormat(&childBuf, def->src, xmlopt, flags) < 0) + return -1; + virBufferEscapeString(&childBuf, "<backenddomain name='%s'/>\n", def->domain_name); virDomainDiskGeometryDefFormat(&childBuf, def); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index a187ab4083..4d1939aa1b 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3909,6 +3909,12 @@ int virDomainDiskSourceFormat(virBuffer *buf, bool skipEnc, virDomainXMLOption *xmlopt); +int +virDomainDiskDataFileStoreFormat(virBuffer *buf, + virStorageSource *src, + virDomainXMLOption *xmlopt, + unsigned int flags); + int virDomainDiskBackingStoreFormat(virBuffer *buf, virStorageSource *src, @@ -4426,6 +4432,13 @@ int virDomainStorageSourceParse(xmlNodePtr node, virDomainXMLOption *xmlopt) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); +int +virDomainDiskDataFileStoreParse(xmlXPathContextPtr ctxt, + virStorageSource *src, + unsigned int flags, + virDomainXMLOption *xmlopt) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) G_GNUC_WARN_UNUSED_RESULT; + int virDomainDiskBackingStoreParse(xmlXPathContextPtr ctxt, virStorageSource *src, -- 2.43.5