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

Prasanna Kumar Kalever prasanna.kalever at redhat.com
Mon Dec 5 13:25:17 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                | 46 ++++++++++---------
 src/qemu/qemu_command.c               | 65 +++++++++++++--------------
 src/qemu/qemu_parse_command.c         | 44 +++++++++---------
 src/storage/storage_backend_gluster.c | 21 ++++-----
 src/storage/storage_driver.c          |  7 ++-
 src/util/virstoragefile.c             | 85 ++++++++++++++++++-----------------
 src/util/virstoragefile.h             | 20 +++++++--
 tests/virstoragetest.c                |  2 +-
 8 files changed, 154 insertions(+), 136 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b001efc..bdb60a7 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -5849,6 +5849,7 @@ virDomainStorageHostParse(xmlNodePtr node,
     int ret = -1;
     xmlNodePtr child;
     char *transport = NULL;
+    char *socket = NULL;
     virStorageNetHostDef host;
 
     memset(&host, 0, sizeof(host));
@@ -5858,12 +5859,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);
@@ -5871,17 +5873,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"),
@@ -5889,16 +5891,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)
@@ -13946,8 +13949,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;
@@ -20204,16 +20207,17 @@ virDomainDiskSourceFormatInternal(virBufferPtr buf,
                 for (n = 0; n < src->nhosts; n++) {
                     virBufferAddLit(buf, "<host");
                     virBufferEscapeString(buf, " name='%s'",
-                                          src->hosts[n].name);
+                                          src->hosts[n].u.inet.addr);
                     virBufferEscapeString(buf, " port='%s'",
-                                          src->hosts[n].port);
+                                          src->hosts[n].u.inet.port);
 
-                    if (src->hosts[n].transport)
+                    if (src->hosts[n].type)
                         virBufferAsprintf(buf, " transport='%s'",
-                                          virStorageNetHostTransportTypeToString(src->hosts[n].transport));
+                                          virStorageNetHostTransportTypeToString(src->hosts[n].type));
 
-                    virBufferEscapeString(buf, " socket='%s'",
-                                          src->hosts[n].socket);
+                    if (src->hosts[n].type == VIR_STORAGE_NET_HOST_TRANS_UNIX)
+                        virBufferEscapeString(buf, " socket='%s'",
+                                              src->hosts[n].u.uds.path);
 
                     virBufferAddLit(buf, "/>\n");
                 }
@@ -20984,8 +20988,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/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 6c457dd..5058560 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,19 +915,19 @@ qemuBuildNetworkDriveURI(virStorageSourcePtr src,
     if (VIR_ALLOC(uri) < 0)
         goto cleanup;
 
-    if (src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP) {
+    if (src->hosts->type == 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)
+                        virStorageNetHostTransportTypeToString(src->hosts->type)) < 0)
             goto cleanup;
     }
 
     if ((uri->port = qemuNetworkDriveGetPort(src->protocol,
-                                             src->hosts->port)) < 0)
+                                             src->hosts->u.inet.port)) < 0)
         goto cleanup;
 
     if (src->path) {
@@ -944,14 +943,14 @@ qemuBuildNetworkDriveURI(virStorageSourcePtr src,
         }
     }
 
-    if (src->hosts->socket &&
-        virAsprintf(&uri->query, "socket=%s", src->hosts->socket) < 0)
+    if ((src->hosts->type == VIR_STORAGE_NET_HOST_TRANS_UNIX) &&
+        (virAsprintf(&uri->query, "socket=%s", src->hosts->u.uds.path) < 0))
         goto cleanup;
 
     if (qemuBuildGeneralSecinfoURI(uri, secinfo) < 0)
         goto cleanup;
 
-    if (VIR_STRDUP(uri->server, src->hosts->name) < 0)
+    if (VIR_STRDUP(uri->server, src->hosts->u.inet.addr) < 0)
         goto cleanup;
 
     ret = virURIFormat(uri);
@@ -979,38 +978,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 +1048,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 +1083,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..41a8172 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,19 @@ 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)
+    if (def->src->hosts->type != VIR_STORAGE_NET_HOST_TRANS_UNIX) {
+        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;
+        def->src->hosts->u.inet.addr = NULL;
+        def->src->hosts->u.inet.port = 0;
         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,
@@ -221,8 +221,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 +233,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 +729,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 +2005,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 +2547,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 df65807..52099a2 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..900a801 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -1603,9 +1603,12 @@ virStorageNetHostDefClear(virStorageNetHostDefPtr def)
     if (!def)
         return;
 
-    VIR_FREE(def->name);
-    VIR_FREE(def->port);
-    VIR_FREE(def->socket);
+    if (def->type == VIR_STORAGE_NET_HOST_TRANS_UNIX) {
+        VIR_FREE(def->u.uds.path);
+    } else {
+        VIR_FREE(def->u.inet.addr);
+        VIR_FREE(def->u.inet.port);
+    }
 }
 
 
@@ -1643,6 +1646,9 @@ virStorageNetHostDefCopy(size_t nhosts,
     virStorageNetHostDefPtr ret = NULL;
     size_t i;
 
+    if (!hosts)
+        return NULL;
+
     if (VIR_ALLOC_N(ret, nhosts) < 0)
         goto error;
 
@@ -1650,16 +1656,17 @@ 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;
+        if (src->type == VIR_STORAGE_NET_HOST_TRANS_UNIX) {
+            if (VIR_STRDUP(dst->u.uds.path, src->u.uds.path) < 0)
+               goto error;
+        } else {
+            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;
+        }
     }
 
     return ret;
@@ -1669,7 +1676,6 @@ virStorageNetHostDefCopy(size_t nhosts,
     return NULL;
 }
 
-
 void
 virStorageAuthDefFree(virStorageAuthDefPtr authdef)
 {
@@ -2292,7 +2298,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 +2307,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 +2345,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 +2384,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 +2529,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 +2548,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 +2559,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 +2569,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 +2729,7 @@ virStorageSourceParseBackingJSONGlusterHost(virStorageNetHostDefPtr host,
         return -1;
     }
 
-    host->transport = transport;
+    host->type = transport;
 
     switch ((virStorageNetHostTransport) transport) {
     case VIR_STORAGE_NET_HOST_TRANS_TCP:
@@ -2735,8 +2740,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 +2754,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 +2871,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 +2937,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/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