conf: Refactor virDomainDiskSourceDefParse

Now that the function is separate clean out a few ugly places and fix up
error messages.
This commit is contained in:
Peter Krempa 2013-11-06 18:37:54 +01:00
parent 2b2decbdcc
commit c2986ff0d3
1 changed files with 56 additions and 63 deletions

View File

@ -4742,17 +4742,18 @@ virDomainDiskSourceDefParse(xmlNodePtr node,
int type, int type,
char **source, char **source,
int *proto, int *proto,
size_t *ndefhosts, size_t *nhosts,
virDomainDiskHostDefPtr *defhosts, virDomainDiskHostDefPtr *hosts,
virDomainDiskSourcePoolDefPtr *srcpool) virDomainDiskSourcePoolDefPtr *srcpool)
{ {
char *protocol = NULL; char *protocol = NULL;
char *transport = NULL; char *transport = NULL;
virDomainDiskHostDefPtr hosts = NULL; virDomainDiskHostDef host;
int nhosts = 0;
xmlNodePtr child; xmlNodePtr child;
int ret = -1; int ret = -1;
memset(&host, 0, sizeof(host));
switch (type) { switch (type) {
case VIR_DOMAIN_DISK_TYPE_FILE: case VIR_DOMAIN_DISK_TYPE_FILE:
*source = virXMLPropString(node, "file"); *source = virXMLPropString(node, "file");
@ -4764,110 +4765,102 @@ virDomainDiskSourceDefParse(xmlNodePtr node,
*source = virXMLPropString(node, "dir"); *source = virXMLPropString(node, "dir");
break; break;
case VIR_DOMAIN_DISK_TYPE_NETWORK: case VIR_DOMAIN_DISK_TYPE_NETWORK:
protocol = virXMLPropString(node, "protocol"); if (!(protocol = virXMLPropString(node, "protocol"))) {
if (protocol == NULL) { virReportError(VIR_ERR_XML_ERROR, "%s",
virReportError(VIR_ERR_INTERNAL_ERROR, _("missing network source protocol type"));
"%s", _("missing protocol type")); goto cleanup;
goto error;
} }
*proto = virDomainDiskProtocolTypeFromString(protocol);
if (*proto < 0) { if ((*proto = virDomainDiskProtocolTypeFromString(protocol)) < 0){
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_XML_ERROR,
_("unknown protocol type '%s'"), _("unknown protocol type '%s'"), protocol);
protocol); goto cleanup;
goto error;
} }
if (!(*source = virXMLPropString(node, "name")) && if (!(*source = virXMLPropString(node, "name")) &&
*proto != VIR_DOMAIN_DISK_PROTOCOL_NBD) { *proto != VIR_DOMAIN_DISK_PROTOCOL_NBD) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_XML_ERROR, "%s",
_("missing name for disk source")); _("missing name for disk source"));
goto error; goto cleanup;
} }
child = node->children; child = node->children;
while (child != NULL) { while (child != NULL) {
if (child->type == XML_ELEMENT_NODE && if (child->type == XML_ELEMENT_NODE &&
xmlStrEqual(child->name, BAD_CAST "host")) { xmlStrEqual(child->name, BAD_CAST "host")) {
if (VIR_REALLOC_N(hosts, nhosts + 1) < 0)
goto error; host.transport = VIR_DOMAIN_DISK_PROTO_TRANS_TCP;
hosts[nhosts].name = NULL;
hosts[nhosts].port = NULL;
hosts[nhosts].transport = VIR_DOMAIN_DISK_PROTO_TRANS_TCP;
hosts[nhosts].socket = NULL;
nhosts++;
/* transport can be tcp (default), unix or rdma. */ /* transport can be tcp (default), unix or rdma. */
transport = virXMLPropString(child, "transport"); if ((transport = virXMLPropString(child, "transport"))) {
if (transport != NULL) { host.transport = virDomainDiskProtocolTransportTypeFromString(transport);
hosts[nhosts - 1].transport = virDomainDiskProtocolTransportTypeFromString(transport); if (host.transport < 0) {
if (hosts[nhosts - 1].transport < 0) {
virReportError(VIR_ERR_XML_ERROR, virReportError(VIR_ERR_XML_ERROR,
_("unknown protocol transport type '%s'"), _("unknown protocol transport type '%s'"),
transport); transport);
goto error; goto cleanup;
} }
} }
hosts[nhosts - 1].socket = virXMLPropString(child, "socket");
if (hosts[nhosts - 1].transport == VIR_DOMAIN_DISK_PROTO_TRANS_UNIX && host.socket = virXMLPropString(child, "socket");
hosts[nhosts - 1].socket == NULL) {
virReportError(VIR_ERR_XML_ERROR, if (host.transport == VIR_DOMAIN_DISK_PROTO_TRANS_UNIX &&
"%s", _("missing socket for unix transport")); host.socket == NULL) {
goto error; virReportError(VIR_ERR_XML_ERROR, "%s",
_("missing socket for unix transport"));
goto cleanup;
} }
if (hosts[nhosts - 1].transport != VIR_DOMAIN_DISK_PROTO_TRANS_UNIX &&
hosts[nhosts - 1].socket != NULL) { if (host.transport != VIR_DOMAIN_DISK_PROTO_TRANS_UNIX &&
host.socket != NULL) {
virReportError(VIR_ERR_XML_ERROR, virReportError(VIR_ERR_XML_ERROR,
_("transport %s does not support socket attribute"), _("transport '%s' does not support "
"socket attribute"),
transport); transport);
goto error; goto cleanup;
} }
VIR_FREE(transport); VIR_FREE(transport);
if (hosts[nhosts - 1].transport != VIR_DOMAIN_DISK_PROTO_TRANS_UNIX) {
hosts[nhosts - 1].name = virXMLPropString(child, "name"); if (host.transport != VIR_DOMAIN_DISK_PROTO_TRANS_UNIX) {
if (!hosts[nhosts - 1].name) { if (!(host.name = virXMLPropString(child, "name"))) {
virReportError(VIR_ERR_XML_ERROR, virReportError(VIR_ERR_XML_ERROR, "%s",
"%s", _("missing name for host")); _("missing name for host"));
goto error; goto cleanup;
} }
hosts[nhosts - 1].port = virXMLPropString(child, "port");
host.port = virXMLPropString(child, "port");
} }
if (VIR_APPEND_ELEMENT(*hosts, *nhosts, host) < 0)
goto cleanup;
} }
child = child->next; child = child->next;
} }
break; break;
case VIR_DOMAIN_DISK_TYPE_VOLUME: case VIR_DOMAIN_DISK_TYPE_VOLUME:
if (virDomainDiskSourcePoolDefParse(node, srcpool) < 0) if (virDomainDiskSourcePoolDefParse(node, srcpool) < 0)
goto error; goto cleanup;
break; break;
default: default:
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected disk type %s"), _("unexpected disk type %s"),
virDomainDiskTypeToString(type)); virDomainDiskTypeToString(type));
goto error; goto cleanup;
} }
/* People sometimes pass a bogus '' source path /* People sometimes pass a bogus '' source path when they mean to omit the
when they mean to omit the source element * source element completely (e.g. CDROM without media). This is just a
completely (e.g. CDROM without media). This is * little compatibility check to help those broken apps */
just a little compatibility check to help
those broken apps */
if (*source && STREQ(*source, "")) if (*source && STREQ(*source, ""))
VIR_FREE(*source); VIR_FREE(*source);
*ndefhosts = nhosts;
*defhosts = hosts;
nhosts = 0;
ret = 0; ret = 0;
error: cleanup:
virDomainDiskHostDefClear(&host);
VIR_FREE(protocol); VIR_FREE(protocol);
VIR_FREE(transport); VIR_FREE(transport);
while (nhosts > 0) {
virDomainDiskHostDefClear(&hosts[nhosts - 1]);
nhosts--;
}
return ret; return ret;
} }