The current storage pools for NFS and iSCSI only require one host to
connect to. Future storage pools like RBD and Sheepdog will require
multiple hosts.

This patch allows multiple source hosts and rewrites the current
storage drivers.

Signed-off-by: Wido den Hollander <w...@widodh.nl>
---
 src/conf/storage_conf.c             |   59 ++++++++++++++++++++++++----------
 src/conf/storage_conf.h             |    5 ++-
 src/esx/esx_storage_driver.c        |    6 +++-
 src/storage/storage_backend_fs.c    |   12 +++---
 src/storage/storage_backend_iscsi.c |   12 +++---
 src/test/test_driver.c              |    4 +-
 6 files changed, 63 insertions(+), 35 deletions(-)

diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index 2330fa1..aa23ff3 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -276,7 +276,11 @@ virStoragePoolSourceClear(virStoragePoolSourcePtr source)
     if (!source)
         return;
 
-    VIR_FREE(source->host.name);
+    for (i = 0 ; i < source->nhost ; i++) {
+        VIR_FREE(source->hosts[i].name);
+    }
+    VIR_FREE(source->hosts);
+
     for (i = 0 ; i < source->ndevice ; i++) {
         VIR_FREE(source->devices[i].freeExtents);
         VIR_FREE(source->devices[i].path);
@@ -404,6 +408,7 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt,
     char *authType = NULL;
     int nsource, i;
     virStoragePoolOptionsPtr options;
+    char *name = NULL;
     char *port = NULL;
 
     relnode = ctxt->node;
@@ -431,17 +436,34 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt,
         VIR_FREE(format);
     }
 
-    source->host.name = virXPathString("string(./host/@name)", ctxt);
-    port = virXPathString("string(./host/@port)", ctxt);
-    if (port) {
-        if (virStrToLong_i(port, NULL, 10, &source->host.port) < 0) {
-            virStorageReportError(VIR_ERR_XML_ERROR,
-                                  _("Invalid port number: %s"),
-                                  port);
+    source->nhost = virXPathNodeSet("./host", ctxt, &nodeset);
+
+    if (source->nhost) {
+        if (VIR_ALLOC_N(source->hosts, source->nhost) < 0) {
+            virReportOOMError();
             goto cleanup;
         }
-    }
 
+        for (i = 0 ; i < source->nhost ; i++) {
+            name = virXMLPropString(nodeset[i], "name");
+            if (name == NULL) {
+                virStorageReportError(VIR_ERR_XML_ERROR,
+                        "%s", _("missing storage pool host name"));
+                goto cleanup;
+            }
+            source->hosts[i].name = name;
+
+            port = virXMLPropString(nodeset[i], "port");
+            if (port) {
+                if (virStrToLong_i(port, NULL, 10, &source->hosts[i].port) < 
0) {
+                    virStorageReportError(VIR_ERR_XML_ERROR,
+                                          _("Invalid port number: %s"),
+                                          port);
+                    goto cleanup;
+                }
+            }
+        }
+    }
 
     source->initiator.iqn = virXPathString("string(./initiator/iqn/@name)", 
ctxt);
 
@@ -674,7 +696,7 @@ virStoragePoolDefParseXML(xmlXPathContextPtr ctxt) {
     }
 
     if (options->flags & VIR_STORAGE_POOL_SOURCE_HOST) {
-        if (!ret->source.host.name) {
+        if (!ret->source.nhost) {
             virStorageReportError(VIR_ERR_XML_ERROR,
                                   "%s",
                                   _("missing storage pool source host name"));
@@ -800,12 +822,13 @@ virStoragePoolSourceFormat(virBufferPtr buf,
     int i, j;
 
     virBufferAddLit(buf,"  <source>\n");
-    if ((options->flags & VIR_STORAGE_POOL_SOURCE_HOST) &&
-        src->host.name) {
-        virBufferAsprintf(buf, "    <host name='%s'", src->host.name);
-        if (src->host.port)
-            virBufferAsprintf(buf, " port='%d'", src->host.port);
-        virBufferAddLit(buf, "/>\n");
+    if ((options->flags & VIR_STORAGE_POOL_SOURCE_HOST) && src->nhost) {
+        for (i = 0; i < src->nhost; i++) {
+            virBufferAsprintf(buf, " <host name='%s'", src->hosts[i].name);
+            if (src->hosts[i].port)
+                virBufferAsprintf(buf, " port='%d'", src->hosts[i].port);
+            virBufferAddLit(buf, "/>\n");
+        }
     }
 
     if ((options->flags & VIR_STORAGE_POOL_SOURCE_DEVICE) &&
@@ -1677,7 +1700,7 @@ int 
virStoragePoolSourceFindDuplicate(virStoragePoolObjListPtr pools,
             break;
         case VIR_STORAGE_POOL_NETFS:
             if ((STREQ(pool->def->source.dir, def->source.dir)) \
-                && (STREQ(pool->def->source.host.name, def->source.host.name)))
+                && (STREQ(pool->def->source.hosts[0].name, 
def->source.hosts[0].name)))
                 matchpool = pool;
             break;
         case VIR_STORAGE_POOL_SCSI:
@@ -1688,7 +1711,7 @@ int 
virStoragePoolSourceFindDuplicate(virStoragePoolObjListPtr pools,
         {
             matchpool = virStoragePoolSourceFindDuplicateDevices(pool, def);
             if (matchpool) {
-                if (STREQ(matchpool->def->source.host.name, 
def->source.host.name)) {
+                if (STREQ(matchpool->def->source.hosts[0].name, 
def->source.hosts[0].name)) {
                     if ((matchpool->def->source.initiator.iqn) && 
(def->source.initiator.iqn)) {
                         if (STREQ(matchpool->def->source.initiator.iqn, 
def->source.initiator.iqn))
                             break;
diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h
index 1ef9295..9222c4a 100644
--- a/src/conf/storage_conf.h
+++ b/src/conf/storage_conf.h
@@ -212,8 +212,9 @@ struct _virStoragePoolSourceDevice {
 typedef struct _virStoragePoolSource virStoragePoolSource;
 typedef virStoragePoolSource *virStoragePoolSourcePtr;
 struct _virStoragePoolSource {
-    /* An optional host */
-    virStoragePoolSourceHost host;
+    /* An optional (maybe multiple) host(s) */
+    size_t nhost;
+    virStoragePoolSourceHostPtr hosts;
 
     /* And either one or more devices ... */
     int ndevice;
diff --git a/src/esx/esx_storage_driver.c b/src/esx/esx_storage_driver.c
index adf1edb..9b64891 100644
--- a/src/esx/esx_storage_driver.c
+++ b/src/esx/esx_storage_driver.c
@@ -544,8 +544,12 @@ esxStoragePoolGetXMLDesc(virStoragePoolPtr pool, unsigned 
int flags)
     if (esxVI_LocalDatastoreInfo_DynamicCast(info) != NULL) {
         def.type = VIR_STORAGE_POOL_DIR;
     } else if ((nasInfo = esxVI_NasDatastoreInfo_DynamicCast(info)) != NULL) {
+        if (VIR_ALLOC_N(def.source.hosts, 1) < 0) {
+            virReportOOMError();
+            goto cleanup;
+        }
         def.type = VIR_STORAGE_POOL_NETFS;
-        def.source.host.name = nasInfo->nas->remoteHost;
+        def.source.hosts[0].name = nasInfo->nas->remoteHost;
         def.source.dir = nasInfo->nas->remotePath;
 
         if (STRCASEEQ(nasInfo->nas->type, "NFS")) {
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index 1af12e6..79eefd3 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -206,7 +206,7 @@ 
virStorageBackendFileSystemNetFindPoolSourcesFunc(virStoragePoolObjPtr pool ATTR
     if (!(src = virStoragePoolSourceListNewSource(&state->list)))
         goto cleanup;
 
-    if (!(src->host.name = strdup(state->host)) ||
+    if (!(src->hosts[0].name = strdup(state->host)) ||
         !(src->dir = strdup(path))) {
         virReportOOMError();
         goto cleanup;
@@ -260,8 +260,8 @@ virStorageBackendFileSystemNetFindPoolSources(virConnectPtr 
conn ATTRIBUTE_UNUSE
     if (!source)
         goto cleanup;
 
-    state.host = source->host.name;
-    prog[3] = source->host.name;
+    state.host = source->hosts[0].name;
+    prog[3] = source->hosts[0].name;
 
     if (virStorageBackendRunProgRegex(NULL, prog, 1, regexes, vars,
                             virStorageBackendFileSystemNetFindPoolSourcesFunc,
@@ -387,7 +387,7 @@ virStorageBackendFileSystemMount(virStoragePoolObjPtr pool) 
{
     int ret;
 
     if (pool->def->type == VIR_STORAGE_POOL_NETFS) {
-        if (pool->def->source.host.name == NULL) {
+        if (pool->def->source.hosts[0].name == NULL) {
             virStorageReportError(VIR_ERR_INTERNAL_ERROR,
                                   "%s", _("missing source host"));
             return -1;
@@ -415,7 +415,7 @@ virStorageBackendFileSystemMount(virStoragePoolObjPtr pool) 
{
 
     if (pool->def->type == VIR_STORAGE_POOL_NETFS) {
         if (virAsprintf(&src, "%s:%s",
-                        pool->def->source.host.name,
+                        pool->def->source.hosts[0].name,
                         pool->def->source.dir) == -1) {
             virReportOOMError();
             return -1;
@@ -452,7 +452,7 @@ virStorageBackendFileSystemUnmount(virStoragePoolObjPtr 
pool) {
     int ret;
 
     if (pool->def->type == VIR_STORAGE_POOL_NETFS) {
-        if (pool->def->source.host.name == NULL) {
+        if (pool->def->source.hosts[0].name == NULL) {
             virStorageReportError(VIR_ERR_INTERNAL_ERROR,
                                   "%s", _("missing source host"));
             return -1;
diff --git a/src/storage/storage_backend_iscsi.c 
b/src/storage/storage_backend_iscsi.c
index f04473d..3acc5fe 100644
--- a/src/storage/storage_backend_iscsi.c
+++ b/src/storage/storage_backend_iscsi.c
@@ -96,13 +96,13 @@ virStorageBackendISCSIPortal(virStoragePoolSourcePtr source)
     char ipaddr[NI_MAXHOST];
     char *portal;
 
-    if (virStorageBackendISCSITargetIP(source->host.name,
+    if (virStorageBackendISCSITargetIP(source->hosts[0].name,
                                        ipaddr, sizeof(ipaddr)) < 0)
         return NULL;
 
     if (virAsprintf(&portal, "%s:%d,1", ipaddr,
-                    source->host.port ?
-                    source->host.port : 3260) < 0) {
+                    source->hosts[0].port ?
+                    source->hosts[0].port : 3260) < 0) {
         virReportOOMError();
         return NULL;
     }
@@ -581,7 +581,7 @@ virStorageBackendISCSIFindPoolSources(virConnectPtr conn 
ATTRIBUTE_UNUSED,
             virReportOOMError();
             goto cleanup;
         }
-        list.sources[i].host = source->host;
+        list.sources[i].host = source->hosts[0];
         list.sources[i].initiator = source->initiator;
         list.sources[i].ndevice = 1;
         list.sources[i].devices[0].path = targets[i];
@@ -617,7 +617,7 @@ virStorageBackendISCSICheckPool(virConnectPtr conn 
ATTRIBUTE_UNUSED,
 
     *isActive = false;
 
-    if (pool->def->source.host.name == NULL) {
+    if (pool->def->source.hosts[0].name == NULL) {
         virStorageReportError(VIR_ERR_INTERNAL_ERROR,
                               "%s", _("missing source host"));
         return -1;
@@ -649,7 +649,7 @@ virStorageBackendISCSIStartPool(virConnectPtr conn 
ATTRIBUTE_UNUSED,
     int ret = -1;
     const char *loginargv[] = { "--login", NULL };
 
-    if (pool->def->source.host.name == NULL) {
+    if (pool->def->source.hosts[0].name == NULL) {
         virStorageReportError(VIR_ERR_INTERNAL_ERROR,
                               "%s", _("missing source host"));
         return -1;
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 39ac503..73a7cb1 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -4053,14 +4053,14 @@ testStorageFindPoolSources(virConnectPtr conn 
ATTRIBUTE_UNUSED,
         break;
 
     case VIR_STORAGE_POOL_NETFS:
-        if (!source || !source->host.name) {
+        if (!source || !source->hosts[0].name) {
             testError(VIR_ERR_INVALID_ARG,
                       "%s", "hostname must be specified for netfs sources");
             goto cleanup;
         }
 
         if (virAsprintf(&ret, defaultPoolSourcesNetFSXML,
-                        source->host.name) < 0)
+                        source->hosts[0].name) < 0)
             virReportOOMError();
         break;
 
-- 
1.7.0.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to