[libvirt] [PATCH v5 1/3] util: change the virStorageNetHostDef type

Prasanna Kumar Kalever prasanna.kalever at redhat.com
Thu Dec 15 08:07:03 UTC 2016


Currently, the Host object looks like

struct _virStorageNetHostDef {
        char *name;
        char *port;
        int transport; /* virStorageNetHostTransport */
        char *socket;  /* path to unix socket */
}

We don't actually need a 'name' and 'port' if the transport type is unix
domain sockets, and if the transport is inet tcp/rdma we don't actually
care for socket path.

With a simple union discrimination we can make this much better

struct _virStorageNetHostUnixSockAddr {
    char *path;
};

struct _virStorageNetHostInetSockAddr {
    char *addr;
    char *port;
};

struct _virStorageNetHostDef {
        virStorageNetHostTransport type;
        union { /* union tag is @type */
            virStorageNetHostUnixSockAddr uds;
            virStorageNetHostInetSockAddr inet;
        } u;
};

This patch performs the required changes in transforming _virStorageNetHostDef
to fit union discrimination.

Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever at redhat.com>
---
 src/conf/domain_conf.c                           | 60 +++++++++------
 src/libxl/libxl_conf.c                           | 10 +--
 src/qemu/qemu_command.c                          | 97 ++++++++++++++----------
 src/qemu/qemu_parse_command.c                    | 50 ++++++------
 src/storage/storage_backend_gluster.c            | 21 ++---
 src/storage/storage_driver.c                     |  7 +-
 src/util/virstoragefile.c                        | 93 +++++++++++++----------
 src/util/virstoragefile.h                        | 20 ++++-
 src/xenconfig/xen_xl.c                           | 10 +--
 tests/domainsnapshotxml2xmlin/disk_snapshot.xml  |  2 +-
 tests/domainsnapshotxml2xmlout/disk_snapshot.xml |  2 +-
 tests/virstoragetest.c                           |  2 +-
 12 files changed, 214 insertions(+), 160 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 0e879e1..d3684ee 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -5967,6 +5967,7 @@ virDomainStorageHostParse(xmlNodePtr node,
     int ret = -1;
     xmlNodePtr child;
     char *transport = NULL;
+    char *socket = NULL;
     virStorageNetHostDef host;
 
     memset(&host, 0, sizeof(host));
@@ -5976,12 +5977,13 @@ virDomainStorageHostParse(xmlNodePtr node,
         if (child->type == XML_ELEMENT_NODE &&
             xmlStrEqual(child->name, BAD_CAST "host")) {
 
-            host.transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
+            host.type = VIR_STORAGE_NET_HOST_TRANS_TCP;
 
             /* transport can be tcp (default), unix or rdma.  */
             if ((transport = virXMLPropString(child, "transport"))) {
-                host.transport = virStorageNetHostTransportTypeFromString(transport);
-                if (host.transport < 0) {
+                host.type = virStorageNetHostTransportTypeFromString(transport);
+                if (host.type < 0 ||
+                    host.type >= VIR_STORAGE_NET_HOST_TRANS_LAST) {
                     virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                    _("unknown protocol transport type '%s'"),
                                    transport);
@@ -5989,17 +5991,17 @@ virDomainStorageHostParse(xmlNodePtr node,
                 }
             }
 
-            host.socket = virXMLPropString(child, "socket");
+            socket = virXMLPropString(child, "socket");
 
-            if (host.transport == VIR_STORAGE_NET_HOST_TRANS_UNIX &&
-                host.socket == NULL) {
+            if (host.type == VIR_STORAGE_NET_HOST_TRANS_UNIX &&
+                socket == NULL) {
                 virReportError(VIR_ERR_XML_ERROR, "%s",
                                _("missing socket for unix transport"));
                 goto cleanup;
             }
 
-            if (host.transport != VIR_STORAGE_NET_HOST_TRANS_UNIX &&
-                host.socket != NULL) {
+            if (host.type != VIR_STORAGE_NET_HOST_TRANS_UNIX &&
+                socket != NULL) {
                 virReportError(VIR_ERR_XML_ERROR,
                                _("transport '%s' does not support "
                                  "socket attribute"),
@@ -6007,16 +6009,17 @@ virDomainStorageHostParse(xmlNodePtr node,
                 goto cleanup;
             }
 
+            host.u.uds.path = socket;
             VIR_FREE(transport);
 
-            if (host.transport != VIR_STORAGE_NET_HOST_TRANS_UNIX) {
-                if (!(host.name = virXMLPropString(child, "name"))) {
+            if (host.type != VIR_STORAGE_NET_HOST_TRANS_UNIX) {
+                if (!(host.u.inet.addr = virXMLPropString(child, "name"))) {
                     virReportError(VIR_ERR_XML_ERROR, "%s",
                                    _("missing name for host"));
                     goto cleanup;
                 }
 
-                host.port = virXMLPropString(child, "port");
+                host.u.inet.port = virXMLPropString(child, "port");
             }
 
             if (VIR_APPEND_ELEMENT(*hosts, *nhosts, host) < 0)
@@ -14065,8 +14068,8 @@ virDomainHostdevMatchSubsysSCSIiSCSI(virDomainHostdevDefPtr first,
     virDomainHostdevSubsysSCSIiSCSIPtr second_iscsisrc =
         &second->source.subsys.u.scsi.u.iscsi;
 
-    if (STREQ(first_iscsisrc->hosts[0].name, second_iscsisrc->hosts[0].name) &&
-        STREQ(first_iscsisrc->hosts[0].port, second_iscsisrc->hosts[0].port) &&
+    if (STREQ(first_iscsisrc->hosts[0].u.inet.addr, second_iscsisrc->hosts[0].u.inet.addr) &&
+        STREQ(first_iscsisrc->hosts[0].u.inet.port, second_iscsisrc->hosts[0].u.inet.port) &&
         STREQ(first_iscsisrc->path, second_iscsisrc->path))
         return 1;
     return 0;
@@ -20322,17 +20325,26 @@ virDomainDiskSourceFormatInternal(virBufferPtr buf,
 
                 for (n = 0; n < src->nhosts; n++) {
                     virBufferAddLit(buf, "<host");
-                    virBufferEscapeString(buf, " name='%s'",
-                                          src->hosts[n].name);
-                    virBufferEscapeString(buf, " port='%s'",
-                                          src->hosts[n].port);
 
-                    if (src->hosts[n].transport)
+                    if (src->hosts[n].type)
                         virBufferAsprintf(buf, " transport='%s'",
-                                          virStorageNetHostTransportTypeToString(src->hosts[n].transport));
-
-                    virBufferEscapeString(buf, " socket='%s'",
-                                          src->hosts[n].socket);
+                                          virStorageNetHostTransportTypeToString(src->hosts[n].type));
+
+                    switch (src->hosts[n].type) {
+                    case VIR_STORAGE_NET_HOST_TRANS_TCP:
+                    case VIR_STORAGE_NET_HOST_TRANS_RDMA:
+                        virBufferEscapeString(buf, " name='%s'",
+                                          src->hosts[n].u.inet.addr);
+                        virBufferEscapeString(buf, " port='%s'",
+                                          src->hosts[n].u.inet.port);
+                        break;
+                    case VIR_STORAGE_NET_HOST_TRANS_UNIX:
+                        virBufferEscapeString(buf, " socket='%s'",
+                                              src->hosts[n].u.uds.path);
+                        break;
+                    case VIR_STORAGE_NET_HOST_TRANS_LAST:
+                        break;
+                    }
 
                     virBufferAddLit(buf, "/>\n");
                 }
@@ -21103,8 +21115,8 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
         if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
             virBufferAddLit(buf, "<host");
-            virBufferEscapeString(buf, " name='%s'", iscsisrc->hosts[0].name);
-            virBufferEscapeString(buf, " port='%s'", iscsisrc->hosts[0].port);
+            virBufferEscapeString(buf, " name='%s'", iscsisrc->hosts[0].u.inet.addr);
+            virBufferEscapeString(buf, " port='%s'", iscsisrc->hosts[0].u.inet.port);
             virBufferAddLit(buf, "/>\n");
         } else {
             virBufferAsprintf(buf, "<adapter name='%s'/>\n",
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index dcf8e7e..3d80ea8 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -637,14 +637,14 @@ libxlMakeNetworkDiskSrcStr(virStorageSourcePtr src,
                     virBufferAddLit(&buf, "\\;");
 
                 /* assume host containing : is ipv6 */
-                if (strchr(src->hosts[i].name, ':'))
+                if (strchr(src->hosts[i].u.inet.addr, ':'))
                     virBufferEscape(&buf, '\\', ":", "[%s]",
-                                    src->hosts[i].name);
+                                    src->hosts[i].u.inet.addr);
                 else
-                    virBufferAsprintf(&buf, "%s", src->hosts[i].name);
+                    virBufferAsprintf(&buf, "%s", src->hosts[i].u.inet.addr);
 
-                if (src->hosts[i].port)
-                    virBufferAsprintf(&buf, "\\:%s", src->hosts[i].port);
+                if (src->hosts[i].u.inet.port)
+                    virBufferAsprintf(&buf, "\\:%s", src->hosts[i].u.inet.port);
             }
         }
 
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 6c457dd..39c1fdc 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -822,19 +822,18 @@ qemuBuildGlusterDriveJSONHosts(virStorageSourcePtr src)
 
     for (i = 0; i < src->nhosts; i++) {
         host = src->hosts + i;
-        transport = virStorageNetHostTransportTypeToString(host->transport);
-        portstr = host->port;
+        transport = virStorageNetHostTransportTypeToString(host->type);
 
         if (virJSONValueObjectCreate(&server, "s:type", transport, NULL) < 0)
             goto cleanup;
 
-        if (!portstr)
-            portstr = QEMU_DEFAULT_GLUSTER_PORT;
-
-        switch ((virStorageNetHostTransport) host->transport) {
+        switch ((virStorageNetHostTransport) host->type) {
         case VIR_STORAGE_NET_HOST_TRANS_TCP:
+            portstr = host->u.inet.port;
+            if (!portstr)
+                portstr = QEMU_DEFAULT_GLUSTER_PORT;
             if (virJSONValueObjectAdd(server,
-                                      "s:host", host->name,
+                                      "s:host", host->u.inet.addr,
                                       "s:port", portstr,
                                       NULL) < 0)
                 goto cleanup;
@@ -842,7 +841,7 @@ qemuBuildGlusterDriveJSONHosts(virStorageSourcePtr src)
 
         case VIR_STORAGE_NET_HOST_TRANS_UNIX:
             if (virJSONValueObjectAdd(server,
-                                      "s:socket", host->socket,
+                                      "s:socket", host->u.uds.path,
                                       NULL) < 0)
                 goto cleanup;
             break;
@@ -916,20 +915,41 @@ qemuBuildNetworkDriveURI(virStorageSourcePtr src,
     if (VIR_ALLOC(uri) < 0)
         goto cleanup;
 
-    if (src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP) {
+    switch (src->hosts->type) {
+    case VIR_STORAGE_NET_HOST_TRANS_TCP:
         if (VIR_STRDUP(uri->scheme,
                        virStorageNetProtocolTypeToString(src->protocol)) < 0)
             goto cleanup;
-    } else {
-        if (virAsprintf(&uri->scheme, "%s+%s",
-                        virStorageNetProtocolTypeToString(src->protocol),
-                        virStorageNetHostTransportTypeToString(src->hosts->transport)) < 0)
+
+    case VIR_STORAGE_NET_HOST_TRANS_RDMA:
+        if (VIR_STRDUP(uri->server, src->hosts->u.inet.addr) < 0)
+            goto cleanup;
+
+        if ((uri->port = qemuNetworkDriveGetPort(src->protocol,
+                                                 src->hosts->u.inet.port)) < 0)
             goto cleanup;
-    }
 
-    if ((uri->port = qemuNetworkDriveGetPort(src->protocol,
-                                             src->hosts->port)) < 0)
+    case VIR_STORAGE_NET_HOST_TRANS_UNIX:
+        if (src->hosts->type != VIR_STORAGE_NET_HOST_TRANS_TCP) {
+            if (virAsprintf(&uri->scheme, "%s+%s",
+                            virStorageNetProtocolTypeToString(src->protocol),
+                            virStorageNetHostTransportTypeToString(src->hosts->type)) < 0)
+                goto cleanup;
+        }
+
+        if (src->hosts->type == VIR_STORAGE_NET_HOST_TRANS_UNIX &&
+            virAsprintf(&uri->query, "socket=%s", src->hosts->u.uds.path) < 0)
+            goto cleanup;
+        break;
+
+    case VIR_STORAGE_NET_HOST_TRANS_LAST:
+    default:
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("protocol '%s' doesn't support transport %s"),
+                       virStorageNetProtocolTypeToString(src->protocol),
+                       virStorageNetHostTransportTypeToString(src->hosts->type));
         goto cleanup;
+    }
 
     if (src->path) {
         if (src->volume) {
@@ -944,16 +964,9 @@ qemuBuildNetworkDriveURI(virStorageSourcePtr src,
         }
     }
 
-    if (src->hosts->socket &&
-        virAsprintf(&uri->query, "socket=%s", src->hosts->socket) < 0)
-        goto cleanup;
-
     if (qemuBuildGeneralSecinfoURI(uri, secinfo) < 0)
         goto cleanup;
 
-    if (VIR_STRDUP(uri->server, src->hosts->name) < 0)
-        goto cleanup;
-
     ret = virURIFormat(uri);
 
  cleanup:
@@ -979,38 +992,38 @@ qemuBuildNetworkDriveStr(virStorageSourcePtr src,
                 goto cleanup;
             }
 
-            if (!((src->hosts->name && strchr(src->hosts->name, ':')) ||
-                  (src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP &&
-                   !src->hosts->name) ||
-                  (src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_UNIX &&
-                   src->hosts->socket &&
-                   src->hosts->socket[0] != '/'))) {
+            if (!((src->hosts->u.inet.addr && strchr(src->hosts->u.inet.addr, ':')) ||
+                  (src->hosts->type == VIR_STORAGE_NET_HOST_TRANS_TCP &&
+                   !src->hosts->u.inet.addr) ||
+                  (src->hosts->type == VIR_STORAGE_NET_HOST_TRANS_UNIX &&
+                   src->hosts->u.uds.path &&
+                   src->hosts->u.uds.path[0] != '/'))) {
 
                 virBufferAddLit(&buf, "nbd:");
 
-                switch (src->hosts->transport) {
+                switch (src->hosts->type) {
                 case VIR_STORAGE_NET_HOST_TRANS_TCP:
-                    virBufferStrcat(&buf, src->hosts->name, NULL);
+                    virBufferStrcat(&buf, src->hosts->u.inet.addr, NULL);
                     virBufferAsprintf(&buf, ":%s",
-                                      src->hosts->port ? src->hosts->port :
+                                      src->hosts->u.inet.port ? src->hosts->u.inet.port :
                                       QEMU_DEFAULT_NBD_PORT);
                     break;
 
                 case VIR_STORAGE_NET_HOST_TRANS_UNIX:
-                    if (!src->hosts->socket) {
+                    if (!src->hosts->u.uds.path) {
                         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                        _("socket attribute required for "
                                          "unix transport"));
                         goto cleanup;
                     }
 
-                    virBufferAsprintf(&buf, "unix:%s", src->hosts->socket);
+                    virBufferAsprintf(&buf, "unix:%s", src->hosts->u.uds.path);
                     break;
 
                 default:
                     virReportError(VIR_ERR_INTERNAL_ERROR,
                                    _("nbd does not support transport '%s'"),
-                                   virStorageNetHostTransportTypeToString(src->hosts->transport));
+                                   virStorageNetHostTransportTypeToString(src->hosts->type));
                     goto cleanup;
                 }
 
@@ -1049,8 +1062,8 @@ qemuBuildNetworkDriveStr(virStorageSourcePtr src,
                     goto cleanup;
             } else if (src->nhosts == 1) {
                 if (virAsprintf(&ret, "sheepdog:%s:%s:%s",
-                                src->hosts->name,
-                                src->hosts->port ? src->hosts->port : "7000",
+                                src->hosts->u.inet.addr,
+                                src->hosts->u.inet.port ? src->hosts->u.inet.port : "7000",
                                 src->path) < 0)
                     goto cleanup;
             } else {
@@ -1084,14 +1097,14 @@ qemuBuildNetworkDriveStr(virStorageSourcePtr src,
                         virBufferAddLit(&buf, "\\;");
 
                     /* assume host containing : is ipv6 */
-                    if (strchr(src->hosts[i].name, ':'))
+                    if (strchr(src->hosts[i].u.inet.addr, ':'))
                         virBufferEscape(&buf, '\\', ":", "[%s]",
-                                        src->hosts[i].name);
+                                        src->hosts[i].u.inet.addr);
                     else
-                        virBufferAsprintf(&buf, "%s", src->hosts[i].name);
+                        virBufferAsprintf(&buf, "%s", src->hosts[i].u.inet.addr);
 
-                    if (src->hosts[i].port)
-                        virBufferAsprintf(&buf, "\\:%s", src->hosts[i].port);
+                    if (src->hosts[i].u.inet.port)
+                        virBufferAsprintf(&buf, "\\:%s", src->hosts[i].u.inet.port);
                 }
             }
 
diff --git a/src/qemu/qemu_parse_command.c b/src/qemu/qemu_parse_command.c
index 405e655..d6f7010 100644
--- a/src/qemu/qemu_parse_command.c
+++ b/src/qemu/qemu_parse_command.c
@@ -77,10 +77,10 @@ qemuParseDriveURIString(virDomainDiskDefPtr def, virURIPtr uri,
     }
 
     if (!transp) {
-        def->src->hosts->transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
+        def->src->hosts->type = VIR_STORAGE_NET_HOST_TRANS_TCP;
     } else {
-        def->src->hosts->transport = virStorageNetHostTransportTypeFromString(transp);
-        if (def->src->hosts->transport < 0) {
+        def->src->hosts->type = virStorageNetHostTransportTypeFromString(transp);
+        if (def->src->hosts->type < 0) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("Invalid %s transport type '%s'"), scheme, transp);
             goto error;
@@ -88,19 +88,20 @@ qemuParseDriveURIString(virDomainDiskDefPtr def, virURIPtr uri,
     }
     def->src->nhosts = 0; /* set to 1 once everything succeeds */
 
-    if (def->src->hosts->transport != VIR_STORAGE_NET_HOST_TRANS_UNIX) {
-        if (VIR_STRDUP(def->src->hosts->name, uri->server) < 0)
+    switch (def->src->hosts->type) {
+    case VIR_STORAGE_NET_HOST_TRANS_TCP:
+    case VIR_STORAGE_NET_HOST_TRANS_RDMA:
+        if (VIR_STRDUP(def->src->hosts->u.inet.addr, uri->server) < 0)
             goto error;
 
-        if (virAsprintf(&def->src->hosts->port, "%d", uri->port) < 0)
+        if (virAsprintf(&def->src->hosts->u.inet.port, "%d", uri->port) < 0)
             goto error;
-    } else {
-        def->src->hosts->name = NULL;
-        def->src->hosts->port = 0;
+        break;
+    case VIR_STORAGE_NET_HOST_TRANS_UNIX:
         if (uri->query) {
             if (STRPREFIX(uri->query, "socket=")) {
                 sock = strchr(uri->query, '=') + 1;
-                if (VIR_STRDUP(def->src->hosts->socket, sock) < 0)
+                if (VIR_STRDUP(def->src->hosts->u.uds.path, sock) < 0)
                     goto error;
             } else {
                 virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -108,6 +109,9 @@ qemuParseDriveURIString(virDomainDiskDefPtr def, virURIPtr uri,
                 goto error;
             }
         }
+        break;
+    case VIR_STORAGE_NET_HOST_TRANS_LAST:
+        break;
     }
     if (uri->path) {
         volimg = uri->path + 1; /* skip the prefix slash */
@@ -221,8 +225,8 @@ qemuParseNBDString(virDomainDiskDefPtr disk)
         if (src)
             *src++ = '\0';
 
-        h->transport = VIR_STORAGE_NET_HOST_TRANS_UNIX;
-        if (VIR_STRDUP(h->socket, host + strlen("unix:")) < 0)
+        h->type = VIR_STORAGE_NET_HOST_TRANS_UNIX;
+        if (VIR_STRDUP(h->u.uds.path, host + strlen("unix:")) < 0)
             goto error;
     } else {
         port = strchr(host, ':');
@@ -233,14 +237,14 @@ qemuParseNBDString(virDomainDiskDefPtr disk)
         }
 
         *port++ = '\0';
-        if (VIR_STRDUP(h->name, host) < 0)
+        if (VIR_STRDUP(h->u.inet.addr, host) < 0)
             goto error;
 
         src = strchr(port, ':');
         if (src)
             *src++ = '\0';
 
-        if (VIR_STRDUP(h->port, port) < 0)
+        if (VIR_STRDUP(h->u.inet.port, port) < 0)
             goto error;
     }
 
@@ -729,11 +733,10 @@ qemuParseCommandLineDisk(virDomainXMLOptionPtr xmlopt,
                         if (VIR_ALLOC(def->src->hosts) < 0)
                             goto error;
                         def->src->nhosts = 1;
-                        def->src->hosts->name = def->src->path;
-                        if (VIR_STRDUP(def->src->hosts->port, port) < 0)
+                        def->src->hosts->u.inet.addr = def->src->path;
+                        if (VIR_STRDUP(def->src->hosts->u.inet.port, port) < 0)
                             goto error;
-                        def->src->hosts->transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
-                        def->src->hosts->socket = NULL;
+                        def->src->hosts->type = VIR_STORAGE_NET_HOST_TRANS_TCP;
                         if (VIR_STRDUP(def->src->path, vdi) < 0)
                             goto error;
                     }
@@ -2006,8 +2009,8 @@ qemuParseCommandLine(virCapsPtr caps,
                         if (VIR_ALLOC(disk->src->hosts) < 0)
                             goto error;
                         disk->src->nhosts = 1;
-                        disk->src->hosts->name = disk->src->path;
-                        if (VIR_STRDUP(disk->src->hosts->port, port) < 0)
+                        disk->src->hosts->u.inet.addr = disk->src->path;
+                        if (VIR_STRDUP(disk->src->hosts->u.inet.port, port) < 0)
                             goto error;
                         if (VIR_STRDUP(disk->src->path, vdi) < 0)
                             goto error;
@@ -2548,14 +2551,13 @@ qemuParseCommandLine(virCapsPtr caps,
                     goto error;
                 }
             }
-            first_rbd_disk->src->hosts[first_rbd_disk->src->nhosts].port = port;
-            if (VIR_STRDUP(first_rbd_disk->src->hosts[first_rbd_disk->src->nhosts].name,
+            first_rbd_disk->src->hosts[first_rbd_disk->src->nhosts].u.inet.port = port;
+            if (VIR_STRDUP(first_rbd_disk->src->hosts[first_rbd_disk->src->nhosts].u.inet.addr,
                            token) < 0) {
                 VIR_FREE(hosts);
                 goto error;
             }
-            first_rbd_disk->src->hosts[first_rbd_disk->src->nhosts].transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
-            first_rbd_disk->src->hosts[first_rbd_disk->src->nhosts].socket = NULL;
+            first_rbd_disk->src->hosts[first_rbd_disk->src->nhosts].type = VIR_STORAGE_NET_HOST_TRANS_TCP;
 
             first_rbd_disk->src->nhosts++;
             token = strtok_r(NULL, ",", &saveptr);
diff --git a/src/storage/storage_backend_gluster.c b/src/storage/storage_backend_gluster.c
index 8e86704..0d5b7f6 100644
--- a/src/storage/storage_backend_gluster.c
+++ b/src/storage/storage_backend_gluster.c
@@ -553,7 +553,8 @@ virStorageFileBackendGlusterDeinit(virStorageSourcePtr src)
     virStorageFileBackendGlusterPrivPtr priv = src->drv->priv;
 
     VIR_DEBUG("deinitializing gluster storage file %p (gluster://%s:%s/%s%s)",
-              src, src->hosts->name, src->hosts->port ? src->hosts->port : "0",
+              src, src->hosts->u.inet.addr,
+              src->hosts->u.inet.port ? src->hosts->u.inet.port : "0",
               src->volume, src->path);
 
     if (priv->vol)
@@ -568,27 +569,27 @@ static int
 virStorageFileBackendGlusterInitServer(virStorageFileBackendGlusterPrivPtr priv,
                                        virStorageNetHostDefPtr host)
 {
-    const char *transport = virStorageNetHostTransportTypeToString(host->transport);
+    const char *transport = virStorageNetHostTransportTypeToString(host->type);
     const char *hoststr = NULL;
     int port = 0;
 
-    switch ((virStorageNetHostTransport) host->transport) {
+    switch ((virStorageNetHostTransport) host->type) {
     case VIR_STORAGE_NET_HOST_TRANS_RDMA:
     case VIR_STORAGE_NET_HOST_TRANS_TCP:
-        hoststr = host->name;
+        hoststr = host->u.inet.addr;
 
-        if (host->port &&
-            virStrToLong_i(host->port, NULL, 10, &port) < 0) {
+        if (host->u.inet.port &&
+            virStrToLong_i(host->u.inet.port, NULL, 10, &port) < 0) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("failed to parse port number '%s'"),
-                           host->port);
+                           host->u.inet.port);
             return -1;
         }
 
         break;
 
     case VIR_STORAGE_NET_HOST_TRANS_UNIX:
-        hoststr = host->socket;
+        hoststr = host->u.uds.path;
         break;
 
     case VIR_STORAGE_NET_HOST_TRANS_LAST:
@@ -797,8 +798,8 @@ virStorageFileBackendGlusterGetUniqueIdentifier(virStorageSourcePtr src)
         return NULL;
 
     ignore_value(virAsprintf(&priv->canonpath, "gluster://%s:%s/%s/%s",
-                             src->hosts->name,
-                             src->hosts->port,
+                             src->hosts->u.inet.addr,
+                             src->hosts->u.inet.port,
                              src->volume,
                              filePath));
 
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index a79acc6..7c7fddd 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -3355,10 +3355,10 @@ virStorageAddISCSIPoolSourceHost(virDomainDiskDefPtr def,
     if (VIR_ALLOC_N(def->src->hosts, def->src->nhosts) < 0)
         goto cleanup;
 
-    if (VIR_STRDUP(def->src->hosts[0].name, pooldef->source.hosts[0].name) < 0)
+    if (VIR_STRDUP(def->src->hosts[0].u.inet.addr, pooldef->source.hosts[0].name) < 0)
         goto cleanup;
 
-    if (virAsprintf(&def->src->hosts[0].port, "%d",
+    if (virAsprintf(&def->src->hosts[0].u.inet.port, "%d",
                     pooldef->source.hosts[0].port ?
                     pooldef->source.hosts[0].port :
                     3260) < 0)
@@ -3384,8 +3384,7 @@ virStorageAddISCSIPoolSourceHost(virDomainDiskDefPtr def,
     /* Storage pool have not supported these 2 attributes yet,
      * use the defaults.
      */
-    def->src->hosts[0].transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
-    def->src->hosts[0].socket = NULL;
+    def->src->hosts[0].type = VIR_STORAGE_NET_HOST_TRANS_TCP;
 
     def->src->protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI;
 
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 1011bd0..8ec8081 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -1603,9 +1603,18 @@ virStorageNetHostDefClear(virStorageNetHostDefPtr def)
     if (!def)
         return;
 
-    VIR_FREE(def->name);
-    VIR_FREE(def->port);
-    VIR_FREE(def->socket);
+    switch (def->type) {
+    case VIR_STORAGE_NET_HOST_TRANS_UNIX:
+        VIR_FREE(def->u.uds.path);
+        break;
+    case VIR_STORAGE_NET_HOST_TRANS_TCP:
+    case VIR_STORAGE_NET_HOST_TRANS_RDMA:
+        VIR_FREE(def->u.inet.addr);
+        VIR_FREE(def->u.inet.port);
+        break;
+    case VIR_STORAGE_NET_HOST_TRANS_LAST:
+        break;
+    }
 }
 
 
@@ -1650,16 +1659,23 @@ virStorageNetHostDefCopy(size_t nhosts,
         virStorageNetHostDefPtr src = &hosts[i];
         virStorageNetHostDefPtr dst = &ret[i];
 
-        dst->transport = src->transport;
-
-        if (VIR_STRDUP(dst->name, src->name) < 0)
-            goto error;
+        dst->type = src->type;
 
-        if (VIR_STRDUP(dst->port, src->port) < 0)
-            goto error;
-
-        if (VIR_STRDUP(dst->socket, src->socket) < 0)
-            goto error;
+        switch (src->type) {
+        case VIR_STORAGE_NET_HOST_TRANS_UNIX:
+            if (VIR_STRDUP(dst->u.uds.path, src->u.uds.path) < 0)
+               goto error;
+            break;
+        case VIR_STORAGE_NET_HOST_TRANS_TCP:
+        case VIR_STORAGE_NET_HOST_TRANS_RDMA:
+            if (VIR_STRDUP(dst->u.inet.addr, src->u.inet.addr)< 0)
+                goto error;
+            if (VIR_STRDUP(dst->u.inet.port, src->u.inet.port)< 0)
+                goto error;
+            break;
+        case VIR_STORAGE_NET_HOST_TRANS_LAST:
+            break;
+        }
     }
 
     return ret;
@@ -2292,7 +2308,7 @@ virStorageSourceParseBackingURI(virStorageSourcePtr src,
     }
 
     if (scheme[1] &&
-        (src->hosts->transport = virStorageNetHostTransportTypeFromString(scheme[1])) < 0) {
+        (src->hosts->type = virStorageNetHostTransportTypeFromString(scheme[1])) < 0) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("invalid protocol transport type '%s'"),
                        scheme[1]);
@@ -2301,7 +2317,7 @@ virStorageSourceParseBackingURI(virStorageSourcePtr src,
 
     /* handle socket stored as a query */
     if (uri->query) {
-        if (VIR_STRDUP(src->hosts->socket, STRSKIP(uri->query, "socket=")) < 0)
+        if (VIR_STRDUP(src->hosts->u.uds.path, STRSKIP(uri->query, "socket=")) < 0)
             goto cleanup;
     }
 
@@ -2339,11 +2355,11 @@ virStorageSourceParseBackingURI(virStorageSourcePtr src,
     }
 
     if (uri->port > 0) {
-        if (virAsprintf(&src->hosts->port, "%d", uri->port) < 0)
+        if (virAsprintf(&src->hosts->u.inet.port, "%d", uri->port) < 0)
             goto cleanup;
     }
 
-    if (VIR_STRDUP(src->hosts->name, uri->server) < 0)
+    if (VIR_STRDUP(src->hosts->u.inet.addr, uri->server) < 0)
         goto cleanup;
 
     ret = 0;
@@ -2378,26 +2394,25 @@ virStorageSourceRBDAddHost(virStorageSourcePtr src,
     if (port) {
         *port = '\0';
         port += skip;
-        if (VIR_STRDUP(src->hosts[src->nhosts - 1].port, port) < 0)
+        if (VIR_STRDUP(src->hosts[src->nhosts - 1].u.inet.port, port) < 0)
             goto error;
     }
 
     parts = virStringSplit(hostport, "\\:", 0);
     if (!parts)
         goto error;
-    src->hosts[src->nhosts-1].name = virStringListJoin((const char **)parts, ":");
+    src->hosts[src->nhosts-1].u.inet.addr = virStringListJoin((const char **)parts, ":");
     virStringListFree(parts);
-    if (!src->hosts[src->nhosts-1].name)
+    if (!src->hosts[src->nhosts-1].u.inet.addr)
         goto error;
 
-    src->hosts[src->nhosts-1].transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
-    src->hosts[src->nhosts-1].socket = NULL;
+    src->hosts[src->nhosts-1].type = VIR_STORAGE_NET_HOST_TRANS_TCP;
 
     return 0;
 
  error:
-    VIR_FREE(src->hosts[src->nhosts-1].port);
-    VIR_FREE(src->hosts[src->nhosts-1].name);
+    VIR_FREE(src->hosts[src->nhosts-1].u.inet.port);
+    VIR_FREE(src->hosts[src->nhosts-1].u.inet.addr);
     return -1;
 }
 
@@ -2524,7 +2539,7 @@ virStorageSourceParseNBDColonString(const char *nbdstr,
         goto cleanup;
 
     src->nhosts = 1;
-    src->hosts->transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
+    src->hosts->type = VIR_STORAGE_NET_HOST_TRANS_TCP;
 
     /* format: [] denotes optional sections, uppercase are variable strings
      * nbd:unix:/PATH/TO/SOCKET[:exportname=EXPORTNAME]
@@ -2543,7 +2558,7 @@ virStorageSourceParseNBDColonString(const char *nbdstr,
             goto cleanup;
         }
 
-        if (VIR_STRDUP(src->hosts->socket, backing[2]) < 0)
+        if (VIR_STRDUP(src->hosts->u.uds.path, backing[2]) < 0)
             goto cleanup;
 
    } else {
@@ -2554,7 +2569,7 @@ virStorageSourceParseNBDColonString(const char *nbdstr,
             goto cleanup;
         }
 
-        if (VIR_STRDUP(src->hosts->name, backing[1]) < 0)
+        if (VIR_STRDUP(src->hosts->u.inet.addr, backing[1]) < 0)
             goto cleanup;
 
         if (!backing[2]) {
@@ -2564,7 +2579,7 @@ virStorageSourceParseNBDColonString(const char *nbdstr,
             goto cleanup;
         }
 
-        if (VIR_STRDUP(src->hosts->port, backing[2]) < 0)
+        if (VIR_STRDUP(src->hosts->u.inet.port, backing[2]) < 0)
             goto cleanup;
     }
 
@@ -2724,7 +2739,7 @@ virStorageSourceParseBackingJSONGlusterHost(virStorageNetHostDefPtr host,
         return -1;
     }
 
-    host->transport = transport;
+    host->type = transport;
 
     switch ((virStorageNetHostTransport) transport) {
     case VIR_STORAGE_NET_HOST_TRANS_TCP:
@@ -2735,8 +2750,8 @@ virStorageSourceParseBackingJSONGlusterHost(virStorageNetHostDefPtr host,
             return -1;
         }
 
-        if (VIR_STRDUP(host->name, hostname) < 0 ||
-            VIR_STRDUP(host->port, port) < 0)
+        if (VIR_STRDUP(host->u.inet.addr, hostname) < 0 ||
+            VIR_STRDUP(host->u.inet.port, port) < 0)
             return -1;
         break;
 
@@ -2749,7 +2764,7 @@ virStorageSourceParseBackingJSONGlusterHost(virStorageNetHostDefPtr host,
         }
 
 
-        if (VIR_STRDUP(host->socket, socket) < 0)
+        if (VIR_STRDUP(host->u.uds.path, socket) < 0)
             return -1;
         break;
 
@@ -2866,15 +2881,15 @@ virStorageSourceParseBackingJSONNbd(virStorageSourcePtr src,
     src->nhosts = 1;
 
     if (path) {
-        src->hosts[0].transport = VIR_STORAGE_NET_HOST_TRANS_UNIX;
-        if (VIR_STRDUP(src->hosts[0].socket, path) < 0)
+        src->hosts[0].type = VIR_STORAGE_NET_HOST_TRANS_UNIX;
+        if (VIR_STRDUP(src->hosts[0].u.uds.path, path) < 0)
             return -1;
     } else {
-        src->hosts[0].transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
-        if (VIR_STRDUP(src->hosts[0].name, host) < 0)
+        src->hosts[0].type = VIR_STORAGE_NET_HOST_TRANS_TCP;
+        if (VIR_STRDUP(src->hosts[0].u.inet.addr, host) < 0)
             return -1;
 
-        if (VIR_STRDUP(src->hosts[0].port, port) < 0)
+        if (VIR_STRDUP(src->hosts[0].u.inet.port, port) < 0)
             return -1;
     }
 
@@ -2932,11 +2947,11 @@ virStorageSourceParseBackingJSONSSH(virStorageSourcePtr src,
         return -1;
     src->nhosts = 1;
 
-    src->hosts[0].transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
-    if (VIR_STRDUP(src->hosts[0].name, host) < 0)
+    src->hosts[0].type = VIR_STORAGE_NET_HOST_TRANS_TCP;
+    if (VIR_STRDUP(src->hosts[0].u.inet.addr, host) < 0)
         return -1;
 
-    if (VIR_STRDUP(src->hosts[0].port, port) < 0)
+    if (VIR_STRDUP(src->hosts[0].u.inet.port, port) < 0)
         return -1;
 
     return 0;
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index 3d09468..99b4a31 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -149,13 +149,25 @@ typedef enum {
 
 VIR_ENUM_DECL(virStorageNetHostTransport)
 
+typedef struct _virStorageNetHostUnixSockAddr virStorageNetHostUnixSockAddr;
+struct _virStorageNetHostUnixSockAddr {
+    char *path;
+};
+
+typedef struct _virStorageNetHostInetSockAddr virStorageNetHostInetSockAddr;
+struct _virStorageNetHostInetSockAddr {
+    char *addr;
+    char *port;
+};
+
 typedef struct _virStorageNetHostDef virStorageNetHostDef;
 typedef virStorageNetHostDef *virStorageNetHostDefPtr;
 struct _virStorageNetHostDef {
-    char *name;
-    char *port;
-    int transport; /* virStorageNetHostTransport */
-    char *socket;  /* path to unix socket */
+    virStorageNetHostTransport type;
+    union { /* union tag is @type */
+        virStorageNetHostUnixSockAddr uds;
+        virStorageNetHostInetSockAddr inet;
+    } u;
 };
 
 /* Information for a storage volume from a virStoragePool */
diff --git a/src/xenconfig/xen_xl.c b/src/xenconfig/xen_xl.c
index bcdd355..0fadf2b 100644
--- a/src/xenconfig/xen_xl.c
+++ b/src/xenconfig/xen_xl.c
@@ -951,14 +951,14 @@ xenFormatXLDiskSrcNet(virStorageSourcePtr src)
                     virBufferAddLit(&buf, "\\\\;");
 
                 /* assume host containing : is ipv6 */
-                if (strchr(src->hosts[i].name, ':'))
+                if (strchr(src->hosts[i].u.inet.addr, ':'))
                     virBufferEscape(&buf, '\\', ":", "[%s]",
-                                    src->hosts[i].name);
+                                    src->hosts[i].u.inet.addr);
                 else
-                    virBufferAsprintf(&buf, "%s", src->hosts[i].name);
+                    virBufferAsprintf(&buf, "%s", src->hosts[i].u.inet.addr);
 
-                if (src->hosts[i].port)
-                    virBufferAsprintf(&buf, "\\\\:%s", src->hosts[i].port);
+                if (src->hosts[i].u.inet.port)
+                    virBufferAsprintf(&buf, "\\\\:%s", src->hosts[i].u.inet.port);
             }
         }
 
diff --git a/tests/domainsnapshotxml2xmlin/disk_snapshot.xml b/tests/domainsnapshotxml2xmlin/disk_snapshot.xml
index aa1522a..5149ac2 100644
--- a/tests/domainsnapshotxml2xmlin/disk_snapshot.xml
+++ b/tests/domainsnapshotxml2xmlin/disk_snapshot.xml
@@ -26,7 +26,7 @@
     <disk name='hdh' snapshot='external' type='network'>
       <source protocol='rbd' name='name'>
         <host name='host' port='1234'/>
-        <host name='host2' port='1234' transport='rdma'/>
+        <host transport='rdma' name='host2' port='1234'/>
         <host name='host3' port='1234'/>
       </source>
     </disk>
diff --git a/tests/domainsnapshotxml2xmlout/disk_snapshot.xml b/tests/domainsnapshotxml2xmlout/disk_snapshot.xml
index c2e77d7..3d4eb52 100644
--- a/tests/domainsnapshotxml2xmlout/disk_snapshot.xml
+++ b/tests/domainsnapshotxml2xmlout/disk_snapshot.xml
@@ -25,7 +25,7 @@
     <disk name='hdh' snapshot='external' type='network'>
       <source protocol='rbd' name='name'>
         <host name='host' port='1234'/>
-        <host name='host2' port='1234' transport='rdma'/>
+        <host transport='rdma' name='host2' port='1234'/>
         <host name='host3' port='1234'/>
       </source>
     </disk>
diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
index f766df1..5c685dd 100644
--- a/tests/virstoragetest.c
+++ b/tests/virstoragetest.c
@@ -387,7 +387,7 @@ testStorageChain(const void *args)
                         elt->type,
                         elt->format,
                         virStorageNetProtocolTypeToString(elt->protocol),
-                        NULLSTR(elt->nhosts ? elt->hosts[0].name : NULL),
+                        NULLSTR(elt->nhosts ? elt->hosts[0].u.inet.addr : NULL),
                         NULLSTR(elt->auth ? elt->auth->username : NULL)) < 0) {
             VIR_FREE(expect);
             VIR_FREE(actual);
-- 
2.7.4




More information about the libvir-list mailing list