Implement the .connectListAllStoragePools storage API in the esx storage
driver, and in all its subdrivers.
Signed-off-by: Pino Toscano <ptoscano(a)redhat.com>
---
src/esx/esx_storage_backend_iscsi.c | 72 +++++++++++++++++++++
src/esx/esx_storage_backend_vmfs.c | 98 +++++++++++++++++++++++++++++
src/esx/esx_storage_driver.c | 68 ++++++++++++++++++++
3 files changed, 238 insertions(+)
diff --git a/src/esx/esx_storage_backend_iscsi.c b/src/esx/esx_storage_backend_iscsi.c
index 72ab0d3cb0..4f5d8e5e24 100644
--- a/src/esx/esx_storage_backend_iscsi.c
+++ b/src/esx/esx_storage_backend_iscsi.c
@@ -779,6 +779,77 @@ esxStorageVolGetPath(virStorageVolPtr volume)
+#define MATCH(FLAG) (flags & (FLAG))
+static int
+esxConnectListAllStoragePools(virConnectPtr conn,
+ virStoragePoolPtr **pools,
+ unsigned int flags)
+{
+ bool success = false;
+ size_t count = 0;
+ esxPrivate *priv = conn->privateData;
+ esxVI_HostInternetScsiHba *hostInternetScsiHba = NULL;
+ esxVI_HostInternetScsiHbaStaticTarget *target;
+ size_t i;
+
+ /* this driver provides only iSCSI pools */
+ if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_POOL_TYPE) &&
+ !(MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_ISCSI)))
+ return 0;
+
+ if (esxVI_LookupHostInternetScsiHba(priv->primary,
+ &hostInternetScsiHba) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to obtain iSCSI adapter"));
+ goto cleanup;
+ }
+
+ /* FIXME: code looks for software iSCSI adapter only */
+ if (!hostInternetScsiHba) {
+ /* iSCSI adapter may not be enabled for this host */
+ return 0;
+ }
+
+ /*
+ * ESX has two kind of targets:
+ * 1. staticIscsiTargets
+ * 2. dynamicIscsiTargets
+ * For each dynamic target if its reachable a static target is added.
+ * return iSCSI names for all static targets to avoid duplicate names.
+ */
+ for (target = hostInternetScsiHba->configuredStaticTarget;
+ target; target = target->_next) {
+ virStoragePoolPtr pool;
+
+ pool = targetToStoragePool(conn, target->iScsiName, target);
+ if (!pool)
+ goto cleanup;
+
+ if (VIR_APPEND_ELEMENT(*pools, count, pool) < 0)
+ goto cleanup;
+ }
+
+ success = true;
+
+ cleanup:
+ if (! success) {
+ if (*pools) {
+ for (i = 0; i < count; ++i)
+ VIR_FREE((*pools)[i]);
+ VIR_FREE(*pools);
+ }
+
+ count = -1;
+ }
+
+ esxVI_HostInternetScsiHba_Free(&hostInternetScsiHba);
+
+ return count;
+}
+#undef MATCH
+
+
+
virStorageDriver esxStorageBackendISCSI = {
.connectNumOfStoragePools = esxConnectNumOfStoragePools, /* 1.0.1 */
.connectListStoragePools = esxConnectListStoragePools, /* 1.0.1 */
@@ -799,4 +870,5 @@ virStorageDriver esxStorageBackendISCSI = {
.storageVolDelete = esxStorageVolDelete, /* 1.0.1 */
.storageVolWipe = esxStorageVolWipe, /* 1.0.1 */
.storageVolGetPath = esxStorageVolGetPath, /* 1.0.1 */
+ .connectListAllStoragePools = esxConnectListAllStoragePools, /* 5.10.0 */
};
diff --git a/src/esx/esx_storage_backend_vmfs.c b/src/esx/esx_storage_backend_vmfs.c
index b890825a40..05b273aed7 100644
--- a/src/esx/esx_storage_backend_vmfs.c
+++ b/src/esx/esx_storage_backend_vmfs.c
@@ -1460,6 +1460,103 @@ esxStorageVolGetPath(virStorageVolPtr volume)
+#define MATCH(FLAG) (flags & (FLAG))
+static int
+esxConnectListAllStoragePools(virConnectPtr conn,
+ virStoragePoolPtr **pools,
+ unsigned int flags)
+{
+ bool success = false;
+ esxPrivate *priv = conn->privateData;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_DynamicProperty *dynamicProperty = NULL;
+ esxVI_ObjectContent *datastoreList = NULL;
+ esxVI_ObjectContent *datastore = NULL;
+ size_t count = 0;
+ size_t i;
+ virStoragePoolPtr pool;
+ const bool checkPoolType = MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_POOL_TYPE);
+
+ if (esxVI_String_AppendValueToList(&propertyNameList,
+ "summary.name") < 0) {
+ goto cleanup;
+ }
+
+ if (checkPoolType &&
+ esxVI_String_AppendValueToList(&propertyNameList,
+ "info") < 0) {
+ goto cleanup;
+ }
+
+ if (esxVI_LookupDatastoreList(priv->primary, propertyNameList,
+ &datastoreList) < 0) {
+ goto cleanup;
+ }
+
+ for (datastore = datastoreList; datastore;
+ datastore = datastore->_next) {
+ const char *name = NULL;
+
+ for (dynamicProperty = datastore->propSet; dynamicProperty;
+ dynamicProperty = dynamicProperty->_next) {
+ if (STREQ(dynamicProperty->name, "summary.name")) {
+ if (esxVI_AnyType_ExpectType(dynamicProperty->val,
+ esxVI_Type_String) < 0) {
+ goto cleanup;
+ }
+
+ name = dynamicProperty->val->string;
+ }
+ }
+
+ if (!name)
+ goto cleanup;
+
+ if (checkPoolType) {
+ int poolType;
+
+ if (datastorePoolType(datastore, &poolType) < 0)
+ goto cleanup;
+
+ if (!((MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_DIR) &&
+ (poolType == VIR_STORAGE_POOL_DIR)) ||
+ (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FS) &&
+ (poolType == VIR_STORAGE_POOL_FS)) ||
+ (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_NETFS) &&
+ (poolType == VIR_STORAGE_POOL_NETFS))))
+ continue;
+ }
+
+ pool = datastoreToStoragePoolPtr(conn, name, datastore);
+ if (!pool)
+ goto cleanup;
+
+ if (VIR_APPEND_ELEMENT(*pools, count, pool) < 0)
+ goto cleanup;
+ }
+
+ success = true;
+
+ cleanup:
+ if (! success) {
+ if (*pools) {
+ for (i = 0; i < count; ++i)
+ VIR_FREE((*pools)[i]);
+ VIR_FREE(*pools);
+ }
+
+ count = -1;
+ }
+
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&datastoreList);
+
+ return count;
+}
+#undef MATCH
+
+
+
virStorageDriver esxStorageBackendVMFS = {
.connectNumOfStoragePools = esxConnectNumOfStoragePools, /* 0.8.2 */
.connectListStoragePools = esxConnectListStoragePools, /* 0.8.2 */
@@ -1480,4 +1577,5 @@ virStorageDriver esxStorageBackendVMFS = {
.storageVolGetInfo = esxStorageVolGetInfo, /* 0.8.4 */
.storageVolGetXMLDesc = esxStorageVolGetXMLDesc, /* 0.8.4 */
.storageVolGetPath = esxStorageVolGetPath, /* 0.8.4 */
+ .connectListAllStoragePools = esxConnectListAllStoragePools, /* 5.10.0 */
};
diff --git a/src/esx/esx_storage_driver.c b/src/esx/esx_storage_driver.c
index 8a34732b45..6d17ac28ea 100644
--- a/src/esx/esx_storage_driver.c
+++ b/src/esx/esx_storage_driver.c
@@ -517,6 +517,73 @@ esxStoragePoolIsPersistent(virStoragePoolPtr pool G_GNUC_UNUSED)
+#define MATCH(FLAG) (flags & (FLAG))
+static int
+esxConnectListAllStoragePools(virConnectPtr conn,
+ virStoragePoolPtr **pools,
+ unsigned int flags)
+{
+ bool success = false;
+ esxPrivate *priv = conn->privateData;
+ size_t count = 0;
+ size_t i, j;
+ int tmp;
+
+ virCheckFlags(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_ALL, -1);
+
+ /*
+ * ESX storage pools are always active, persistent, and
+ * autostarted, so return zero elements in case we are asked
+ * for pools different than that.
+ *
+ * Filtering by type will be done by each backend.
+ */
+ if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_ACTIVE) &&
+ !(MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE)))
+ return 0;
+ if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_PERSISTENT) &&
+ !(MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_PERSISTENT)))
+ return 0;
+ if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_AUTOSTART) &&
+ !(MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_AUTOSTART)))
+ return 0;
+
+ if (esxVI_EnsureSession(priv->primary) < 0)
+ return -1;
+
+ for (i = 0; i < LAST_BACKEND; ++i) {
+ virStoragePoolPtr *new_pools = 0;
+ tmp = backends[i]->connectListAllStoragePools(conn, &new_pools, flags);
+
+ if (tmp < 0)
+ goto cleanup;
+
+ for (j = 0; j < tmp; ++j) {
+ if (VIR_APPEND_ELEMENT(*pools, count, new_pools[j]) < 0)
+ goto cleanup;
+ }
+ VIR_FREE(new_pools);
+ }
+
+ success = true;
+
+ cleanup:
+ if (! success) {
+ if (*pools) {
+ for (i = 0; i < count; ++i)
+ VIR_FREE((*pools)[i]);
+ VIR_FREE(*pools);
+ }
+
+ count = -1;
+ }
+
+ return count;
+}
+#undef MATCH
+
+
+
virStorageDriver esxStorageDriver = {
.connectNumOfStoragePools = esxConnectNumOfStoragePools, /* 0.8.2 */
.connectListStoragePools = esxConnectListStoragePools, /* 0.8.2 */
@@ -544,4 +611,5 @@ virStorageDriver esxStorageDriver = {
.storageVolGetPath = esxStorageVolGetPath, /* 0.8.4 */
.storagePoolIsActive = esxStoragePoolIsActive, /* 0.8.2 */
.storagePoolIsPersistent = esxStoragePoolIsPersistent, /* 0.8.2 */
+ .connectListAllStoragePools = esxConnectListAllStoragePools, /* 5.10.0 */
};
--
2.21.0