|
|
c401cc |
From 38d996886dd96d39f2c812150ad2edcf53c00e0b Mon Sep 17 00:00:00 2001
|
|
|
c401cc |
Message-Id: <38d996886dd96d39f2c812150ad2edcf53c00e0b@dist-git>
|
|
|
c401cc |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
c401cc |
Date: Wed, 26 Feb 2014 14:54:11 +0100
|
|
|
c401cc |
Subject: [PATCH] conf: Split out code to parse the source of a disk definition
|
|
|
c401cc |
|
|
|
c401cc |
https://bugzilla.redhat.com/show_bug.cgi?id=1032370
|
|
|
c401cc |
|
|
|
c401cc |
To avoid code duplication between snapshot configuration code that
|
|
|
c401cc |
parses the disk source too we need to split out this code that will be
|
|
|
c401cc |
reused later on.
|
|
|
c401cc |
|
|
|
c401cc |
This patch tries to be code movement, some aspects of this function will
|
|
|
c401cc |
be refactored later.
|
|
|
c401cc |
|
|
|
c401cc |
(cherry picked from commit 16bc7864087707c84e71a03b3a28a8912e44ae67)
|
|
|
c401cc |
|
|
|
c401cc |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
c401cc |
---
|
|
|
c401cc |
src/conf/domain_conf.c | 266 +++++++++++++++++++++++++++----------------------
|
|
|
c401cc |
1 file changed, 149 insertions(+), 117 deletions(-)
|
|
|
c401cc |
|
|
|
c401cc |
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
|
|
|
c401cc |
index 96185ca..60e8849 100644
|
|
|
c401cc |
--- a/src/conf/domain_conf.c
|
|
|
c401cc |
+++ b/src/conf/domain_conf.c
|
|
|
c401cc |
@@ -4831,6 +4831,142 @@ cleanup:
|
|
|
c401cc |
return ret;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
+
|
|
|
c401cc |
+static int
|
|
|
c401cc |
+virDomainDiskSourceDefParse(xmlNodePtr node,
|
|
|
c401cc |
+ int type,
|
|
|
c401cc |
+ char **source,
|
|
|
c401cc |
+ int *proto,
|
|
|
c401cc |
+ size_t *ndefhosts,
|
|
|
c401cc |
+ virDomainDiskHostDefPtr *defhosts,
|
|
|
c401cc |
+ virDomainDiskSourcePoolDefPtr *srcpool)
|
|
|
c401cc |
+{
|
|
|
c401cc |
+ char *protocol = NULL;
|
|
|
c401cc |
+ char *transport = NULL;
|
|
|
c401cc |
+ virDomainDiskHostDefPtr hosts = NULL;
|
|
|
c401cc |
+ int nhosts = 0;
|
|
|
c401cc |
+ xmlNodePtr child;
|
|
|
c401cc |
+ int ret = -1;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ switch (type) {
|
|
|
c401cc |
+ case VIR_DOMAIN_DISK_TYPE_FILE:
|
|
|
c401cc |
+ *source = virXMLPropString(node, "file");
|
|
|
c401cc |
+ break;
|
|
|
c401cc |
+ case VIR_DOMAIN_DISK_TYPE_BLOCK:
|
|
|
c401cc |
+ *source = virXMLPropString(node, "dev");
|
|
|
c401cc |
+ break;
|
|
|
c401cc |
+ case VIR_DOMAIN_DISK_TYPE_DIR:
|
|
|
c401cc |
+ *source = virXMLPropString(node, "dir");
|
|
|
c401cc |
+ break;
|
|
|
c401cc |
+ case VIR_DOMAIN_DISK_TYPE_NETWORK:
|
|
|
c401cc |
+ protocol = virXMLPropString(node, "protocol");
|
|
|
c401cc |
+ if (protocol == NULL) {
|
|
|
c401cc |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c401cc |
+ "%s", _("missing protocol type"));
|
|
|
c401cc |
+ goto error;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ *proto = virDomainDiskProtocolTypeFromString(protocol);
|
|
|
c401cc |
+ if (*proto < 0) {
|
|
|
c401cc |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c401cc |
+ _("unknown protocol type '%s'"),
|
|
|
c401cc |
+ protocol);
|
|
|
c401cc |
+ goto error;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (!(*source = virXMLPropString(node, "name")) &&
|
|
|
c401cc |
+ *proto != VIR_DOMAIN_DISK_PROTOCOL_NBD) {
|
|
|
c401cc |
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
c401cc |
+ _("missing name for disk source"));
|
|
|
c401cc |
+ goto error;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ child = node->children;
|
|
|
c401cc |
+ while (child != NULL) {
|
|
|
c401cc |
+ if (child->type == XML_ELEMENT_NODE &&
|
|
|
c401cc |
+ xmlStrEqual(child->name, BAD_CAST "host")) {
|
|
|
c401cc |
+ if (VIR_REALLOC_N(hosts, nhosts + 1) < 0)
|
|
|
c401cc |
+ goto error;
|
|
|
c401cc |
+ hosts[nhosts].name = NULL;
|
|
|
c401cc |
+ hosts[nhosts].port = NULL;
|
|
|
c401cc |
+ hosts[nhosts].transport = VIR_DOMAIN_DISK_PROTO_TRANS_TCP;
|
|
|
c401cc |
+ hosts[nhosts].socket = NULL;
|
|
|
c401cc |
+ nhosts++;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ /* transport can be tcp (default), unix or rdma. */
|
|
|
c401cc |
+ transport = virXMLPropString(child, "transport");
|
|
|
c401cc |
+ if (transport != NULL) {
|
|
|
c401cc |
+ hosts[nhosts - 1].transport = virDomainDiskProtocolTransportTypeFromString(transport);
|
|
|
c401cc |
+ if (hosts[nhosts - 1].transport < 0) {
|
|
|
c401cc |
+ virReportError(VIR_ERR_XML_ERROR,
|
|
|
c401cc |
+ _("unknown protocol transport type '%s'"),
|
|
|
c401cc |
+ transport);
|
|
|
c401cc |
+ goto error;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ hosts[nhosts - 1].socket = virXMLPropString(child, "socket");
|
|
|
c401cc |
+ if (hosts[nhosts - 1].transport == VIR_DOMAIN_DISK_PROTO_TRANS_UNIX &&
|
|
|
c401cc |
+ hosts[nhosts - 1].socket == NULL) {
|
|
|
c401cc |
+ virReportError(VIR_ERR_XML_ERROR,
|
|
|
c401cc |
+ "%s", _("missing socket for unix transport"));
|
|
|
c401cc |
+ goto error;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ if (hosts[nhosts - 1].transport != VIR_DOMAIN_DISK_PROTO_TRANS_UNIX &&
|
|
|
c401cc |
+ hosts[nhosts - 1].socket != NULL) {
|
|
|
c401cc |
+ virReportError(VIR_ERR_XML_ERROR,
|
|
|
c401cc |
+ _("transport %s does not support socket attribute"),
|
|
|
c401cc |
+ transport);
|
|
|
c401cc |
+ goto error;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ VIR_FREE(transport);
|
|
|
c401cc |
+ if (hosts[nhosts - 1].transport != VIR_DOMAIN_DISK_PROTO_TRANS_UNIX) {
|
|
|
c401cc |
+ hosts[nhosts - 1].name = virXMLPropString(child, "name");
|
|
|
c401cc |
+ if (!hosts[nhosts - 1].name) {
|
|
|
c401cc |
+ virReportError(VIR_ERR_XML_ERROR,
|
|
|
c401cc |
+ "%s", _("missing name for host"));
|
|
|
c401cc |
+ goto error;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ hosts[nhosts - 1].port = virXMLPropString(child, "port");
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ child = child->next;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+ break;
|
|
|
c401cc |
+ case VIR_DOMAIN_DISK_TYPE_VOLUME:
|
|
|
c401cc |
+ if (virDomainDiskSourcePoolDefParse(node, srcpool) < 0)
|
|
|
c401cc |
+ goto error;
|
|
|
c401cc |
+ break;
|
|
|
c401cc |
+ default:
|
|
|
c401cc |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c401cc |
+ _("unexpected disk type %s"),
|
|
|
c401cc |
+ virDomainDiskTypeToString(type));
|
|
|
c401cc |
+ goto error;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+
|
|
|
c401cc |
+ /* People sometimes pass a bogus '' source path
|
|
|
c401cc |
+ when they mean to omit the source element
|
|
|
c401cc |
+ completely (e.g. CDROM without media). This is
|
|
|
c401cc |
+ just a little compatibility check to help
|
|
|
c401cc |
+ those broken apps */
|
|
|
c401cc |
+ if (*source && STREQ(*source, ""))
|
|
|
c401cc |
+ VIR_FREE(*source);
|
|
|
c401cc |
+
|
|
|
c401cc |
+ *ndefhosts = nhosts;
|
|
|
c401cc |
+ *defhosts = hosts;
|
|
|
c401cc |
+ nhosts = 0;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ ret = 0;
|
|
|
c401cc |
+
|
|
|
c401cc |
+error:
|
|
|
c401cc |
+ VIR_FREE(protocol);
|
|
|
c401cc |
+ VIR_FREE(transport);
|
|
|
c401cc |
+ while (nhosts > 0) {
|
|
|
c401cc |
+ virDomainDiskHostDefFree(&hosts[nhosts - 1]);
|
|
|
c401cc |
+ nhosts--;
|
|
|
c401cc |
+ }
|
|
|
c401cc |
+
|
|
|
c401cc |
+ return ret;
|
|
|
c401cc |
+}
|
|
|
c401cc |
+
|
|
|
c401cc |
+
|
|
|
c401cc |
#define VENDOR_LEN 8
|
|
|
c401cc |
#define PRODUCT_LEN 16
|
|
|
c401cc |
|
|
|
c401cc |
@@ -4859,11 +4995,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
|
|
|
c401cc |
char *driverType = NULL;
|
|
|
c401cc |
char *source = NULL;
|
|
|
c401cc |
char *target = NULL;
|
|
|
c401cc |
- char *protocol = NULL;
|
|
|
c401cc |
- char *protocol_transport = NULL;
|
|
|
c401cc |
char *trans = NULL;
|
|
|
c401cc |
- virDomainDiskHostDefPtr hosts = NULL;
|
|
|
c401cc |
- int nhosts = 0;
|
|
|
c401cc |
char *bus = NULL;
|
|
|
c401cc |
char *cachetag = NULL;
|
|
|
c401cc |
char *error_policy = NULL;
|
|
|
c401cc |
@@ -4925,116 +5057,27 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
|
|
|
c401cc |
cur = node->children;
|
|
|
c401cc |
while (cur != NULL) {
|
|
|
c401cc |
if (cur->type == XML_ELEMENT_NODE) {
|
|
|
c401cc |
- if (!source && !hosts && !def->srcpool &&
|
|
|
c401cc |
+ if (!source && !def->hosts && !def->srcpool &&
|
|
|
c401cc |
xmlStrEqual(cur->name, BAD_CAST "source")) {
|
|
|
c401cc |
sourceNode = cur;
|
|
|
c401cc |
|
|
|
c401cc |
- switch (def->type) {
|
|
|
c401cc |
- case VIR_DOMAIN_DISK_TYPE_FILE:
|
|
|
c401cc |
- source = virXMLPropString(cur, "file");
|
|
|
c401cc |
- break;
|
|
|
c401cc |
- case VIR_DOMAIN_DISK_TYPE_BLOCK:
|
|
|
c401cc |
- source = virXMLPropString(cur, "dev");
|
|
|
c401cc |
- break;
|
|
|
c401cc |
- case VIR_DOMAIN_DISK_TYPE_DIR:
|
|
|
c401cc |
- source = virXMLPropString(cur, "dir");
|
|
|
c401cc |
- break;
|
|
|
c401cc |
- case VIR_DOMAIN_DISK_TYPE_NETWORK:
|
|
|
c401cc |
- protocol = virXMLPropString(cur, "protocol");
|
|
|
c401cc |
- if (protocol == NULL) {
|
|
|
c401cc |
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c401cc |
- "%s", _("missing protocol type"));
|
|
|
c401cc |
- goto error;
|
|
|
c401cc |
- }
|
|
|
c401cc |
- def->protocol = virDomainDiskProtocolTypeFromString(protocol);
|
|
|
c401cc |
- if (def->protocol < 0) {
|
|
|
c401cc |
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c401cc |
- _("unknown protocol type '%s'"),
|
|
|
c401cc |
- protocol);
|
|
|
c401cc |
- goto error;
|
|
|
c401cc |
- }
|
|
|
c401cc |
- if (def->protocol == VIR_DOMAIN_DISK_PROTOCOL_ISCSI) {
|
|
|
c401cc |
+ if (virDomainDiskSourceDefParse(cur, def->type,
|
|
|
c401cc |
+ &source,
|
|
|
c401cc |
+ &def->protocol,
|
|
|
c401cc |
+ &def->nhosts,
|
|
|
c401cc |
+ &def->hosts,
|
|
|
c401cc |
+ &def->srcpool) < 0)
|
|
|
c401cc |
+ goto error;
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (def->type == VIR_DOMAIN_DISK_TYPE_NETWORK) {
|
|
|
c401cc |
+ if (def->protocol == VIR_DOMAIN_DISK_PROTOCOL_ISCSI)
|
|
|
c401cc |
expected_secret_usage = VIR_SECRET_USAGE_TYPE_ISCSI;
|
|
|
c401cc |
- } else if (def->protocol == VIR_DOMAIN_DISK_PROTOCOL_RBD) {
|
|
|
c401cc |
+ else if (def->protocol == VIR_DOMAIN_DISK_PROTOCOL_RBD)
|
|
|
c401cc |
expected_secret_usage = VIR_SECRET_USAGE_TYPE_CEPH;
|
|
|
c401cc |
- }
|
|
|
c401cc |
- if (!(source = virXMLPropString(cur, "name")) &&
|
|
|
c401cc |
- def->protocol != VIR_DOMAIN_DISK_PROTOCOL_NBD) {
|
|
|
c401cc |
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
c401cc |
- _("missing name for disk source"));
|
|
|
c401cc |
- goto error;
|
|
|
c401cc |
- }
|
|
|
c401cc |
- child = cur->children;
|
|
|
c401cc |
- while (child != NULL) {
|
|
|
c401cc |
- if (child->type == XML_ELEMENT_NODE &&
|
|
|
c401cc |
- xmlStrEqual(child->name, BAD_CAST "host")) {
|
|
|
c401cc |
- if (VIR_REALLOC_N(hosts, nhosts + 1) < 0)
|
|
|
c401cc |
- goto error;
|
|
|
c401cc |
- hosts[nhosts].name = NULL;
|
|
|
c401cc |
- hosts[nhosts].port = NULL;
|
|
|
c401cc |
- hosts[nhosts].transport = VIR_DOMAIN_DISK_PROTO_TRANS_TCP;
|
|
|
c401cc |
- hosts[nhosts].socket = NULL;
|
|
|
c401cc |
- nhosts++;
|
|
|
c401cc |
-
|
|
|
c401cc |
- /* transport can be tcp (default), unix or rdma. */
|
|
|
c401cc |
- protocol_transport = virXMLPropString(child, "transport");
|
|
|
c401cc |
- if (protocol_transport != NULL) {
|
|
|
c401cc |
- hosts[nhosts - 1].transport = virDomainDiskProtocolTransportTypeFromString(protocol_transport);
|
|
|
c401cc |
- if (hosts[nhosts - 1].transport < 0) {
|
|
|
c401cc |
- virReportError(VIR_ERR_XML_ERROR,
|
|
|
c401cc |
- _("unknown protocol transport type '%s'"),
|
|
|
c401cc |
- protocol_transport);
|
|
|
c401cc |
- goto error;
|
|
|
c401cc |
- }
|
|
|
c401cc |
- }
|
|
|
c401cc |
- hosts[nhosts - 1].socket = virXMLPropString(child, "socket");
|
|
|
c401cc |
- if (hosts[nhosts - 1].transport == VIR_DOMAIN_DISK_PROTO_TRANS_UNIX &&
|
|
|
c401cc |
- hosts[nhosts - 1].socket == NULL) {
|
|
|
c401cc |
- virReportError(VIR_ERR_XML_ERROR,
|
|
|
c401cc |
- "%s", _("missing socket for unix transport"));
|
|
|
c401cc |
- goto error;
|
|
|
c401cc |
- }
|
|
|
c401cc |
- if (hosts[nhosts - 1].transport != VIR_DOMAIN_DISK_PROTO_TRANS_UNIX &&
|
|
|
c401cc |
- hosts[nhosts - 1].socket != NULL) {
|
|
|
c401cc |
- virReportError(VIR_ERR_XML_ERROR,
|
|
|
c401cc |
- _("transport %s does not support socket attribute"),
|
|
|
c401cc |
- protocol_transport);
|
|
|
c401cc |
- goto error;
|
|
|
c401cc |
- }
|
|
|
c401cc |
- VIR_FREE(protocol_transport);
|
|
|
c401cc |
- if (hosts[nhosts - 1].transport != VIR_DOMAIN_DISK_PROTO_TRANS_UNIX) {
|
|
|
c401cc |
- hosts[nhosts - 1].name = virXMLPropString(child, "name");
|
|
|
c401cc |
- if (!hosts[nhosts - 1].name) {
|
|
|
c401cc |
- virReportError(VIR_ERR_XML_ERROR,
|
|
|
c401cc |
- "%s", _("missing name for host"));
|
|
|
c401cc |
- goto error;
|
|
|
c401cc |
- }
|
|
|
c401cc |
- hosts[nhosts - 1].port = virXMLPropString(child, "port");
|
|
|
c401cc |
- }
|
|
|
c401cc |
- }
|
|
|
c401cc |
- child = child->next;
|
|
|
c401cc |
- }
|
|
|
c401cc |
- break;
|
|
|
c401cc |
- case VIR_DOMAIN_DISK_TYPE_VOLUME:
|
|
|
c401cc |
- if (virDomainDiskSourcePoolDefParse(cur, &def->srcpool) < 0)
|
|
|
c401cc |
- goto error;
|
|
|
c401cc |
- break;
|
|
|
c401cc |
- default:
|
|
|
c401cc |
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
c401cc |
- _("unexpected disk type %s"),
|
|
|
c401cc |
- virDomainDiskTypeToString(def->type));
|
|
|
c401cc |
- goto error;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
startupPolicy = virXMLPropString(cur, "startupPolicy");
|
|
|
c401cc |
|
|
|
c401cc |
- /* People sometimes pass a bogus '' source path
|
|
|
c401cc |
- when they mean to omit the source element
|
|
|
c401cc |
- completely (e.g. CDROM without media). This is
|
|
|
c401cc |
- just a little compatibility check to help
|
|
|
c401cc |
- those broken apps */
|
|
|
c401cc |
- if (source && STREQ(source, ""))
|
|
|
c401cc |
- VIR_FREE(source);
|
|
|
c401cc |
} else if (!target &&
|
|
|
c401cc |
xmlStrEqual(cur->name, BAD_CAST "target")) {
|
|
|
c401cc |
target = virXMLPropString(cur, "dev");
|
|
|
c401cc |
@@ -5329,7 +5372,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
|
|
|
c401cc |
/* Only CDROM and Floppy devices are allowed missing source path
|
|
|
c401cc |
* to indicate no media present. LUN is for raw access CD-ROMs
|
|
|
c401cc |
* that are not attached to a physical device presently */
|
|
|
c401cc |
- if (source == NULL && hosts == NULL && !def->srcpool &&
|
|
|
c401cc |
+ if (source == NULL && def->hosts == NULL && !def->srcpool &&
|
|
|
c401cc |
def->device != VIR_DOMAIN_DISK_DEVICE_CDROM &&
|
|
|
c401cc |
def->device != VIR_DOMAIN_DISK_DEVICE_LUN &&
|
|
|
c401cc |
def->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
|
|
|
c401cc |
@@ -5626,10 +5669,6 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
|
|
|
c401cc |
source = NULL;
|
|
|
c401cc |
def->dst = target;
|
|
|
c401cc |
target = NULL;
|
|
|
c401cc |
- def->hosts = hosts;
|
|
|
c401cc |
- hosts = NULL;
|
|
|
c401cc |
- def->nhosts = nhosts;
|
|
|
c401cc |
- nhosts = 0;
|
|
|
c401cc |
def->auth.username = authUsername;
|
|
|
c401cc |
authUsername = NULL;
|
|
|
c401cc |
def->driverName = driverName;
|
|
|
c401cc |
@@ -5682,13 +5721,6 @@ cleanup:
|
|
|
c401cc |
VIR_FREE(source);
|
|
|
c401cc |
VIR_FREE(tray);
|
|
|
c401cc |
VIR_FREE(trans);
|
|
|
c401cc |
- while (nhosts > 0) {
|
|
|
c401cc |
- virDomainDiskHostDefFree(&hosts[nhosts - 1]);
|
|
|
c401cc |
- nhosts--;
|
|
|
c401cc |
- }
|
|
|
c401cc |
- VIR_FREE(hosts);
|
|
|
c401cc |
- VIR_FREE(protocol);
|
|
|
c401cc |
- VIR_FREE(protocol_transport);
|
|
|
c401cc |
VIR_FREE(device);
|
|
|
c401cc |
VIR_FREE(authUsername);
|
|
|
c401cc |
VIR_FREE(usageType);
|
|
|
c401cc |
--
|
|
|
c401cc |
1.9.0
|
|
|
c401cc |
|