mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 05:35:25 +00:00
conf: implement XML parsing/formating for <dataStore> element of a storage <source>
Introduce parsing and formatting of <dataStore> element. The <dataStore represents a different storage volume meant for storing the actual blocks of guest-visible data. The original disk source is then just a metadata storage for any advanced features. This currently works only for 'qcow2' images. Signed-off-by: Nikolai Barybin <nikolai.barybin@virtuozzo.com> Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
parent
28d88e9fc3
commit
b3171cf8da
@ -7561,6 +7561,53 @@ virDomainStorageSourceParseSlices(virStorageSource *src,
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virDomainDiskDataStoreParse(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_autofree char *idx = NULL;
|
||||
g_autoptr(virStorageSource) dataFileStore = NULL;
|
||||
|
||||
if (!(ctxt->node = virXPathNode("./dataStore", 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 (!(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE))
|
||||
idx = virXMLPropString(source, "index");
|
||||
|
||||
if (!(dataFileStore = virDomainStorageSourceParseBase(type, format, idx)))
|
||||
return -1;
|
||||
|
||||
if (virDomainStorageSourceParse(source, ctxt, dataFileStore, flags, xmlopt) < 0)
|
||||
return -1;
|
||||
|
||||
dataFileStore->readonly = src->readonly;
|
||||
src->dataFileStore = g_steal_pointer(&dataFileStore);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virDomainStorageSourceParse:
|
||||
* @node: XML node pointing to the source element to parse
|
||||
@ -7651,6 +7698,9 @@ virDomainStorageSourceParse(xmlNodePtr node,
|
||||
ctxt, flags) < 0)
|
||||
return -1;
|
||||
|
||||
if (virDomainDiskDataStoreParse(ctxt, src, flags, xmlopt) < 0)
|
||||
return -1;
|
||||
|
||||
/* People sometimes pass a bogus '' source path when they mean to omit the
|
||||
* source element completely (e.g. CDROM without media). This is just a
|
||||
* little compatibility check to help those broken apps */
|
||||
@ -7720,6 +7770,7 @@ virDomainDiskBackingStoreParse(xmlXPathContextPtr ctxt,
|
||||
backingStore->readonly = true;
|
||||
|
||||
if (virDomainStorageSourceParse(source, ctxt, backingStore, flags, xmlopt) < 0 ||
|
||||
virDomainDiskDataStoreParse(ctxt, backingStore, flags, xmlopt) < 0 ||
|
||||
virDomainDiskBackingStoreParse(ctxt, backingStore, flags, xmlopt) < 0)
|
||||
return -1;
|
||||
|
||||
@ -22762,6 +22813,39 @@ virDomainDiskSourceFormatSlices(virBuffer *buf,
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virDomainDiskDataStoreFormat(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);
|
||||
bool inactive = flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE;
|
||||
|
||||
if (!src->dataFileStore)
|
||||
return 0;
|
||||
|
||||
/* don't write detected data file member to inactive xml */
|
||||
if (inactive && src->dataFileStore->detected)
|
||||
return 0;
|
||||
|
||||
virBufferAsprintf(&attrBuf, " type='%s'",
|
||||
virStorageTypeToString(src->dataFileStore->type));
|
||||
|
||||
virBufferAsprintf(&formatAttrBuf, " type='%s'", "raw");
|
||||
virXMLFormatElement(&childBuf, "format", &formatAttrBuf, NULL);
|
||||
|
||||
if (virDomainDiskSourceFormat(&childBuf, src->dataFileStore, "source", 0,
|
||||
true, flags, false, false, xmlopt) < 0)
|
||||
return -1;
|
||||
|
||||
virXMLFormatElement(buf, "dataStore", &attrBuf, &childBuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virDomainDiskSourceFormat:
|
||||
* @buf: output buffer
|
||||
@ -22877,6 +22961,9 @@ virDomainDiskSourceFormat(virBuffer *buf,
|
||||
if (attrIndex && src->id != 0)
|
||||
virBufferAsprintf(&attrBuf, " index='%u'", src->id);
|
||||
|
||||
if (virDomainDiskDataStoreFormat(&childBuf, src, xmlopt, flags) < 0)
|
||||
return -1;
|
||||
|
||||
if (virDomainDiskSourceFormatPrivateData(&childBuf, src, flags, xmlopt) < 0)
|
||||
return -1;
|
||||
|
||||
|
@ -542,6 +542,32 @@ virDomainDiskDefValidateSourceChainOne(const virStorageSource *src)
|
||||
}
|
||||
}
|
||||
|
||||
if (src->dataFileStore) {
|
||||
if (src->format != VIR_STORAGE_FILE_QCOW2) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("<dataStore> feature available only with qcow2 images"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (src->dataFileStore->format != VIR_STORAGE_FILE_RAW) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("only 'raw' images supported as <dataStore>"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (src->dataFileStore->dataFileStore || src->backingStore) {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("The <source> of <dataStore> can't have another nested <dataStore> or <backingStore> element"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (src->dataFileStore->sliceStorage) {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("slices are not supported for <dataStore>"));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* internal snapshots and config files are currently supported only with rbd: */
|
||||
if (virStorageSourceGetActualType(src) != VIR_STORAGE_TYPE_NETWORK &&
|
||||
src->protocol != VIR_STORAGE_NET_PROTOCOL_RBD) {
|
||||
|
Loading…
Reference in New Issue
Block a user