mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
conf: Rework virStorageVolDefParseXML
Rather than having an error path, let's rework the code to allocate and fill into an @def variable and then steal that into @ret when we are successful leaving just a cleanup: path. Signed-off-by: John Ferlan <jferlan@redhat.com> Reviewed-by: Erik Skultety <eskultet@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
e687538d3a
commit
d04fbe7dab
@ -1168,7 +1168,8 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool,
|
|||||||
xmlXPathContextPtr ctxt,
|
xmlXPathContextPtr ctxt,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
virStorageVolDefPtr ret;
|
virStorageVolDefPtr def;
|
||||||
|
virStorageVolDefPtr ret = NULL;
|
||||||
virStorageVolOptionsPtr options;
|
virStorageVolOptionsPtr options;
|
||||||
char *type = NULL;
|
char *type = NULL;
|
||||||
char *allocation = NULL;
|
char *allocation = NULL;
|
||||||
@ -1187,132 +1188,132 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool,
|
|||||||
if (options == NULL)
|
if (options == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (VIR_ALLOC(ret) < 0)
|
if (VIR_ALLOC(def) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ret->target.type = VIR_STORAGE_TYPE_FILE;
|
def->target.type = VIR_STORAGE_TYPE_FILE;
|
||||||
|
|
||||||
ret->name = virXPathString("string(./name)", ctxt);
|
def->name = virXPathString("string(./name)", ctxt);
|
||||||
if (ret->name == NULL) {
|
if (def->name == NULL) {
|
||||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
_("missing volume name element"));
|
_("missing volume name element"));
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Normally generated by pool refresh, but useful for unit tests */
|
/* Normally generated by pool refresh, but useful for unit tests */
|
||||||
ret->key = virXPathString("string(./key)", ctxt);
|
def->key = virXPathString("string(./key)", ctxt);
|
||||||
|
|
||||||
/* Technically overridden by pool refresh, but useful for unit tests */
|
/* Technically overridden by pool refresh, but useful for unit tests */
|
||||||
type = virXPathString("string(./@type)", ctxt);
|
type = virXPathString("string(./@type)", ctxt);
|
||||||
if (type) {
|
if (type) {
|
||||||
if ((ret->type = virStorageVolTypeFromString(type)) < 0) {
|
if ((def->type = virStorageVolTypeFromString(type)) < 0) {
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
_("unknown volume type '%s'"), type);
|
_("unknown volume type '%s'"), type);
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((backingStore = virXPathString("string(./backingStore/path)", ctxt))) {
|
if ((backingStore = virXPathString("string(./backingStore/path)", ctxt))) {
|
||||||
if (VIR_ALLOC(ret->target.backingStore) < 0)
|
if (VIR_ALLOC(def->target.backingStore) < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
|
|
||||||
ret->target.backingStore->type = VIR_STORAGE_TYPE_FILE;
|
def->target.backingStore->type = VIR_STORAGE_TYPE_FILE;
|
||||||
|
|
||||||
ret->target.backingStore->path = backingStore;
|
def->target.backingStore->path = backingStore;
|
||||||
backingStore = NULL;
|
backingStore = NULL;
|
||||||
|
|
||||||
if (options->formatFromString) {
|
if (options->formatFromString) {
|
||||||
char *format = virXPathString("string(./backingStore/format/@type)", ctxt);
|
char *format = virXPathString("string(./backingStore/format/@type)", ctxt);
|
||||||
if (format == NULL)
|
if (format == NULL)
|
||||||
ret->target.backingStore->format = options->defaultFormat;
|
def->target.backingStore->format = options->defaultFormat;
|
||||||
else
|
else
|
||||||
ret->target.backingStore->format = (options->formatFromString)(format);
|
def->target.backingStore->format = (options->formatFromString)(format);
|
||||||
|
|
||||||
if (ret->target.backingStore->format < 0) {
|
if (def->target.backingStore->format < 0) {
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
_("unknown volume format type %s"), format);
|
_("unknown volume format type %s"), format);
|
||||||
VIR_FREE(format);
|
VIR_FREE(format);
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
VIR_FREE(format);
|
VIR_FREE(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VIR_ALLOC(ret->target.backingStore->perms) < 0)
|
if (VIR_ALLOC(def->target.backingStore->perms) < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
if (virStorageDefParsePerms(ctxt, ret->target.backingStore->perms,
|
if (virStorageDefParsePerms(ctxt, def->target.backingStore->perms,
|
||||||
"./backingStore/permissions") < 0)
|
"./backingStore/permissions") < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
capacity = virXPathString("string(./capacity)", ctxt);
|
capacity = virXPathString("string(./capacity)", ctxt);
|
||||||
unit = virXPathString("string(./capacity/@unit)", ctxt);
|
unit = virXPathString("string(./capacity/@unit)", ctxt);
|
||||||
if (capacity) {
|
if (capacity) {
|
||||||
if (virStorageSize(unit, capacity, &ret->target.capacity) < 0)
|
if (virStorageSize(unit, capacity, &def->target.capacity) < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
} else if (!(flags & VIR_VOL_XML_PARSE_NO_CAPACITY) &&
|
} else if (!(flags & VIR_VOL_XML_PARSE_NO_CAPACITY) &&
|
||||||
!((flags & VIR_VOL_XML_PARSE_OPT_CAPACITY) &&
|
!((flags & VIR_VOL_XML_PARSE_OPT_CAPACITY) &&
|
||||||
virStorageSourceHasBacking(&ret->target))) {
|
virStorageSourceHasBacking(&def->target))) {
|
||||||
virReportError(VIR_ERR_XML_ERROR, "%s", _("missing capacity element"));
|
virReportError(VIR_ERR_XML_ERROR, "%s", _("missing capacity element"));
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
VIR_FREE(unit);
|
VIR_FREE(unit);
|
||||||
|
|
||||||
allocation = virXPathString("string(./allocation)", ctxt);
|
allocation = virXPathString("string(./allocation)", ctxt);
|
||||||
if (allocation) {
|
if (allocation) {
|
||||||
unit = virXPathString("string(./allocation/@unit)", ctxt);
|
unit = virXPathString("string(./allocation/@unit)", ctxt);
|
||||||
if (virStorageSize(unit, allocation, &ret->target.allocation) < 0)
|
if (virStorageSize(unit, allocation, &def->target.allocation) < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
ret->target.has_allocation = true;
|
def->target.has_allocation = true;
|
||||||
} else {
|
} else {
|
||||||
ret->target.allocation = ret->target.capacity;
|
def->target.allocation = def->target.capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret->target.path = virXPathString("string(./target/path)", ctxt);
|
def->target.path = virXPathString("string(./target/path)", ctxt);
|
||||||
if (options->formatFromString) {
|
if (options->formatFromString) {
|
||||||
char *format = virXPathString("string(./target/format/@type)", ctxt);
|
char *format = virXPathString("string(./target/format/@type)", ctxt);
|
||||||
if (format == NULL)
|
if (format == NULL)
|
||||||
ret->target.format = options->defaultFormat;
|
def->target.format = options->defaultFormat;
|
||||||
else
|
else
|
||||||
ret->target.format = (options->formatFromString)(format);
|
def->target.format = (options->formatFromString)(format);
|
||||||
|
|
||||||
if (ret->target.format < 0) {
|
if (def->target.format < 0) {
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
_("unknown volume format type %s"), format);
|
_("unknown volume format type %s"), format);
|
||||||
VIR_FREE(format);
|
VIR_FREE(format);
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
VIR_FREE(format);
|
VIR_FREE(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VIR_ALLOC(ret->target.perms) < 0)
|
if (VIR_ALLOC(def->target.perms) < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
if (virStorageDefParsePerms(ctxt, ret->target.perms,
|
if (virStorageDefParsePerms(ctxt, def->target.perms,
|
||||||
"./target/permissions") < 0)
|
"./target/permissions") < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
|
|
||||||
node = virXPathNode("./target/encryption", ctxt);
|
node = virXPathNode("./target/encryption", ctxt);
|
||||||
if (node != NULL) {
|
if (node != NULL) {
|
||||||
ret->target.encryption = virStorageEncryptionParseNode(node, ctxt);
|
def->target.encryption = virStorageEncryptionParseNode(node, ctxt);
|
||||||
if (ret->target.encryption == NULL)
|
if (def->target.encryption == NULL)
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret->target.compat = virXPathString("string(./target/compat)", ctxt);
|
def->target.compat = virXPathString("string(./target/compat)", ctxt);
|
||||||
if (virStorageFileCheckCompat(ret->target.compat) < 0)
|
if (virStorageFileCheckCompat(def->target.compat) < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
|
|
||||||
if (virXPathNode("./target/nocow", ctxt))
|
if (virXPathNode("./target/nocow", ctxt))
|
||||||
ret->target.nocow = true;
|
def->target.nocow = true;
|
||||||
|
|
||||||
if (virXPathNode("./target/features", ctxt)) {
|
if (virXPathNode("./target/features", ctxt)) {
|
||||||
if ((n = virXPathNodeSet("./target/features/*", ctxt, &nodes)) < 0)
|
if ((n = virXPathNodeSet("./target/features/*", ctxt, &nodes)) < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
|
|
||||||
if (!ret->target.compat && VIR_STRDUP(ret->target.compat, "1.1") < 0)
|
if (!def->target.compat && VIR_STRDUP(def->target.compat, "1.1") < 0)
|
||||||
goto error;
|
goto cleanup;
|
||||||
|
|
||||||
if (!(ret->target.features = virBitmapNew(VIR_STORAGE_FILE_FEATURE_LAST)))
|
if (!(def->target.features = virBitmapNew(VIR_STORAGE_FILE_FEATURE_LAST)))
|
||||||
goto error;
|
goto cleanup;
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
int f = virStorageFileFeatureTypeFromString((const char*)nodes[i]->name);
|
int f = virStorageFileFeatureTypeFromString((const char*)nodes[i]->name);
|
||||||
@ -1320,14 +1321,17 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool,
|
|||||||
if (f < 0) {
|
if (f < 0) {
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("unsupported feature %s"),
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("unsupported feature %s"),
|
||||||
(const char*)nodes[i]->name);
|
(const char*)nodes[i]->name);
|
||||||
goto error;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
ignore_value(virBitmapSetBit(ret->target.features, f));
|
ignore_value(virBitmapSetBit(def->target.features, f));
|
||||||
}
|
}
|
||||||
VIR_FREE(nodes);
|
VIR_FREE(nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VIR_STEAL_PTR(ret, def);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
virStorageVolDefFree(def);
|
||||||
VIR_FREE(nodes);
|
VIR_FREE(nodes);
|
||||||
VIR_FREE(allocation);
|
VIR_FREE(allocation);
|
||||||
VIR_FREE(capacity);
|
VIR_FREE(capacity);
|
||||||
@ -1335,11 +1339,6 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool,
|
|||||||
VIR_FREE(type);
|
VIR_FREE(type);
|
||||||
VIR_FREE(backingStore);
|
VIR_FREE(backingStore);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
error:
|
|
||||||
virStorageVolDefFree(ret);
|
|
||||||
ret = NULL;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user