[libvirt] libvirt [PATCHv2 2/2] Add iSCSI backend storage driver for ESX.

Ata E Husain Bohra ata.husain at hotmail.com
Sat Nov 10 07:18:08 UTC 2012


The patch adds the backend driver to support iSCSI format storage pools
and volumes for ESX host. The mapping of ESX iSCSI specifics to Libvirt
is as follows:

1. ESX static iSCSI target <------> Libvirt Storage Pools
2. ESX iSCSI LUNs          <------> Libvirt Storage Volumes.

The above understanding is based on http://libvirt.org/storage.html.

The operation supported on iSCSI pools includes:

1. List storage pools & volumes.
2. Get xml descriptor operaion on pools & volumes.
3. Lookup operation on pools & volumes by name, uuid and path (if applicable).

iSCSI pools does not support operations such as: Create / remove pools
and volumes.
---
 src/Makefile.am                     |    1 +
 src/esx/esx_storage_backend_iscsi.c |  807 +++++++++++++++++++++++++++++++++++
 src/esx/esx_storage_backend_iscsi.h |   29 ++
 src/esx/esx_storage_driver.c        |    8 +-
 src/esx/esx_vi.c                    |  332 ++++++++++++++
 src/esx/esx_vi.h                    |   18 +
 src/esx/esx_vi_generator.input      |  302 +++++++++++++
 src/esx/esx_vi_generator.py         |   19 +
 8 files changed, 1515 insertions(+), 1 deletion(-)
 create mode 100644 src/esx/esx_storage_backend_iscsi.c
 create mode 100644 src/esx/esx_storage_backend_iscsi.h

diff --git a/src/Makefile.am b/src/Makefile.am
index 4026a15..1668b84 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -494,6 +494,7 @@ ESX_DRIVER_SOURCES =							\
 		esx/esx_network_driver.c esx/esx_network_driver.h	\
 		esx/esx_storage_driver.c esx/esx_storage_driver.h	\
 		esx/esx_storage_backend_vmfs.c esx/esx_storage_backend_vmfs.h	\
+		esx/esx_storage_backend_iscsi.c esx/esx_storage_backend_iscsi.h	\
 		esx/esx_device_monitor.c esx/esx_device_monitor.h	\
 		esx/esx_secret_driver.c esx/esx_secret_driver.h		\
 		esx/esx_nwfilter_driver.c esx/esx_nwfilter_driver.h	\
diff --git a/src/esx/esx_storage_backend_iscsi.c b/src/esx/esx_storage_backend_iscsi.c
new file mode 100644
index 0000000..fa4bf45
--- /dev/null
+++ b/src/esx/esx_storage_backend_iscsi.c
@@ -0,0 +1,807 @@
+/*
+ * esx_storage_backend_iscsi.c: ESX storage backend for iSCSI handling
+ *
+ * Copyright (C) 2012 Ata E Husain Bohra <ata.husain at hotmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+#include <config.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "internal.h"
+#include "md5.h"
+#include "util.h"
+#include "memory.h"
+#include "logging.h"
+#include "uuid.h"
+
+#include "storage_conf.h"
+#include "storage_file.h"
+#include "esx_storage_backend_iscsi.h"
+#include "esx_private.h"
+#include "esx_vi.h"
+#include "esx_vi_methods.h"
+#include "esx_util.h"
+
+#define VIR_FROM_THIS VIR_FROM_STORAGE
+
+/*
+ * The UUID of a storage pool is the MD5 sum of it's mount path. Therefore,
+ * verify that UUID and MD5 sum match in size, because we rely on that.
+ */
+verify(MD5_DIGEST_SIZE == VIR_UUID_BUFLEN);
+
+
+
+static int
+esxStorageBackendISCSINumberOfStoragePools(virConnectPtr conn)
+{
+    int count = 0;
+    esxPrivate *priv = conn->storagePrivateData;
+    esxVI_HostInternetScsiHba *hostInternetScsiHba = NULL;
+    const esxVI_HostInternetScsiHbaStaticTarget *target = NULL;
+    bool success = false;
+
+    if (esxVI_LookupHostInternetScsiHba(
+          priv->primary, &hostInternetScsiHba) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+          _("Unable to obtain iSCSI adapter"));
+        goto cleanup;
+    }
+
+    /* FIXME: code looks for software iSCSI adapter only */
+    if (hostInternetScsiHba == NULL) {
+        /* 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 != NULL;
+         target = target->_next) {
+        ++count;
+    }
+
+    success = true;
+
+cleanup:
+
+    esxVI_HostInternetScsiHba_Free(&hostInternetScsiHba);
+
+    return success ? count : -1;
+
+}
+
+
+
+static int
+esxStorageBackendISCSIListStoragePools(virConnectPtr conn,
+                                       char **const names,
+                                       const int maxnames)
+{
+    int count = 0;
+    esxPrivate *priv = conn->storagePrivateData;
+    esxVI_HostInternetScsiHba *hostInternetScsiHba = NULL;
+    const esxVI_HostInternetScsiHbaStaticTarget *target = NULL;
+    bool success = false;
+    int i = 0;
+
+    if (maxnames ==0) {
+        return 0;
+    }
+
+    if (esxVI_LookupHostInternetScsiHba(
+          priv->primary, &hostInternetScsiHba) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+          _("Unable to obtain iSCSI adapter"));
+        goto cleanup;
+    }
+
+    /* FIXME: code looks for software iSCSI adapter only */
+    if (hostInternetScsiHba == NULL) {
+        /* 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 != NULL && count < maxnames;
+         target = target->_next, ++count) {
+        names[count] = strdup(target->iScsiName);
+
+        if (names[count] == NULL) {
+            virReportOOMError();
+            goto cleanup;
+        }
+    }
+
+    success = true;
+
+cleanup:
+    if (! success) {
+        for (i = 0; i < count; ++i) {
+            VIR_FREE(names[i]);
+        }
+        count = -1;
+    }
+
+    esxVI_HostInternetScsiHba_Free(&hostInternetScsiHba);
+
+    return success ? count : -1;
+}
+
+
+
+static virStoragePoolPtr
+esxStorageBackendISCSIPoolLookupByName(virConnectPtr conn,
+                                       const char *name)
+{
+    esxPrivate *priv = conn->storagePrivateData;
+    esxVI_HostInternetScsiHbaStaticTarget *target = NULL;
+    /* MD5_DIGEST_SIZE = VIR_UUID_BUFLEN = 16 */
+    unsigned char md5[MD5_DIGEST_SIZE];
+    virStoragePoolPtr pool = NULL;
+
+    /* lookup routine are used by the base driver to determine
+     * appropriate backend driver, lookup targetName as optional
+     * parameter
+     */
+    if (esxVI_LookupHostInternetScsiHbaStaticTargetByName(
+          priv->primary, name, &target, esxVI_Occurrence_OptionalItem) < 0 ||
+        target == NULL) {
+        goto cleanup;
+    }
+
+    /**
+     * HostInternetScsiHbaStaticTarget does not provide a uuid field,
+     * but iScsiName (or widely known as IQN) is unique across the multiple
+     * hosts, using it to compute key
+     */
+
+    md5_buffer(target->iScsiName, strlen(target->iScsiName), md5);
+
+    pool = virGetStoragePool(conn, name, md5, &esxStorageBackendISCSIDrv, NULL);
+
+ cleanup:
+
+    esxVI_HostInternetScsiHbaStaticTarget_Free(&target);
+
+    return pool;
+
+}
+
+
+
+static virStoragePoolPtr
+esxStorageBackendISCSIPoolLookupByUUID(virConnectPtr conn,
+                                       const unsigned char *uuid)
+{
+    virStoragePoolPtr pool = NULL;
+    esxPrivate *priv = conn->storagePrivateData;
+    esxVI_HostInternetScsiHba *hostInternetScsiHba = NULL;
+    const esxVI_HostInternetScsiHbaStaticTarget *target = NULL;
+    /* MD5_DIGEST_SIZE = VIR_UUID_BUFLEN = 16 */
+    unsigned char md5[MD5_DIGEST_SIZE];
+
+    if (esxVI_LookupHostInternetScsiHba(
+          priv->primary, &hostInternetScsiHba) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+          _("Unable to obtain iSCSI adapter"));
+        goto cleanup;
+    }
+
+    /* FIXME: code just looks for software iSCSI adapter */
+    if (hostInternetScsiHba == NULL) {
+        /* iSCSI adapter may not be enabled for this host */
+        return NULL;
+    }
+
+    for (target = hostInternetScsiHba->configuredStaticTarget;
+         target != NULL;
+         target = target->_next) {
+        md5_buffer(target->iScsiName, strlen(target->iScsiName), md5);
+
+        if (memcmp(uuid, md5, VIR_UUID_STRING_BUFLEN) == 0) {
+            break;
+        }
+    }
+
+    if (target == NULL) {
+        /* pool not found, error handling done by the base driver */
+        goto cleanup;
+    }
+
+    pool = virGetStoragePool(conn,
+                             target->iScsiName,
+                             md5,
+                             &esxStorageBackendISCSIDrv,
+                             NULL);
+
+ cleanup:
+    esxVI_HostInternetScsiHba_Free(&hostInternetScsiHba);
+
+    return pool;
+
+}
+
+
+
+static int
+esxStorageBackendISCSIPoolRefresh(virStoragePoolPtr pool,
+                                  unsigned int flags)
+{
+    int result = -1;
+    esxPrivate *priv = pool->conn->storagePrivateData;
+    esxVI_ManagedObjectReference *hostStorageSystem = NULL;
+    esxVI_HostInternetScsiHba *hostInternetScsiHba = NULL;
+    esxVI_ObjectContent *hostSystem = NULL;
+    esxVI_String *propertyNameList = NULL;
+
+    virCheckFlags(0, -1);
+
+    if (esxVI_String_AppendValueToList(&propertyNameList,
+          "configManager.storageSystem\0") < 0 ||
+        esxVI_LookupHostSystemProperties(priv->primary,
+            propertyNameList, &hostSystem) < 0 ||
+        esxVI_GetManagedObjectReference(hostSystem,
+            "configManager.storageSystem", &hostStorageSystem,
+            esxVI_Occurrence_RequiredItem) < 0 ||
+        esxVI_LookupHostInternetScsiHba(
+            priv->primary, &hostInternetScsiHba) < 0) {
+        goto cleanup;
+    }
+
+     /**
+      * ESX does not allow rescan on a particular target,
+      * rescan all the static targets
+     */
+    if (esxVI_RescanHba(priv->primary, hostStorageSystem,
+                        hostInternetScsiHba->device) < 0) {
+        goto cleanup;
+    }
+
+    result = 0;
+
+ cleanup:
+    esxVI_String_Free(&propertyNameList);
+    esxVI_ManagedObjectReference_Free(&hostStorageSystem);
+    esxVI_ObjectContent_Free(&hostSystem);
+    esxVI_HostInternetScsiHba_Free(&hostInternetScsiHba);
+
+    return result;
+
+}
+
+
+
+static int
+esxStorageBackendISCSIPoolGetInfo(virStoragePoolPtr pool ATTRIBUTE_UNUSED,
+                                  virStoragePoolInfoPtr info)
+{
+    /* these fields are not valid for iSCSI pool */
+    info->allocation = info->capacity = info->available = 0;
+    info->state = VIR_STORAGE_POOL_RUNNING;
+
+    return 0;
+}
+
+
+
+static char *
+esxStorageBackendISCSIPoolGetXMLDesc(virStoragePoolPtr pool, unsigned int flags)
+{
+    char *xml = NULL;
+    esxPrivate *priv = pool->conn->storagePrivateData;
+    esxVI_HostInternetScsiHba *hostInternetScsiHba = NULL;
+    const esxVI_HostInternetScsiHbaStaticTarget *target = NULL;
+    virStoragePoolDef def;
+
+    virCheckFlags(0, NULL);
+
+    memset(&def, 0, sizeof(def));
+
+    if (esxVI_LookupHostInternetScsiHba(priv->primary, &hostInternetScsiHba)) {
+        goto cleanup;
+    }
+
+    for (target = hostInternetScsiHba->configuredStaticTarget;
+         target != NULL;
+         target = target->_next) {
+        if (STREQ(target->iScsiName, pool->name)) {
+            break;
+        }
+    }
+
+    if (target == NULL) {
+        /* pool not found */
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+          _("Could not find storage pool with name '%s'"), pool->name);
+        goto cleanup;
+    }
+
+    def.name = pool->name;
+    memcpy(def.uuid, pool->uuid, VIR_UUID_BUFLEN);
+
+    def.type = VIR_STORAGE_POOL_ISCSI;
+
+    def.source.initiator.iqn = target->iScsiName;
+
+    def.source.nhost = 1;
+    if (VIR_ALLOC_N(def.source.hosts, def.source.nhost) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    def.source.hosts[0].name = target->address;
+    if (target->port) {
+        def.source.hosts[0].port = target->port->value;
+    }
+
+    /* TODO: add CHAP authentication params */
+
+    xml = virStoragePoolDefFormat(&def);
+
+  cleanup:
+
+    VIR_FREE(def.source.hosts);
+    esxVI_HostInternetScsiHba_Free(&hostInternetScsiHba);
+
+    return xml;
+
+}
+
+
+
+static int
+esxStorageBackendISCSIPoolNumberOfStorageVolumes(virStoragePoolPtr pool)
+{
+    int  count = 0;
+    esxPrivate *priv = pool->conn->storagePrivateData;
+    esxVI_HostScsiTopologyLun *hostScsiTopologyLunList = NULL;
+    const esxVI_HostScsiTopologyLun *hostScsiTopologyLun = NULL;
+    bool success = false;
+
+    if (esxVI_LookupHostScsiTopologyLunListByTargetName(
+          priv->primary, pool->name, &hostScsiTopologyLunList) < 0) {
+        goto cleanup;
+    }
+
+    for (hostScsiTopologyLun = hostScsiTopologyLunList ;
+         hostScsiTopologyLun != NULL;
+         hostScsiTopologyLun = hostScsiTopologyLun->_next) {
+        ++count;
+    }
+
+    success = true;
+
+  cleanup:
+
+    esxVI_HostScsiTopologyLun_Free(&hostScsiTopologyLunList);
+
+    return success ? count : -1;
+
+}
+
+
+static int
+esxStorageBackendISCSIPoolListStorageVolumes(virStoragePoolPtr pool,
+                                             char **const names,
+                                             int maxnames)
+{
+    int  count = 0;
+    esxPrivate *priv = pool->conn->storagePrivateData;
+    esxVI_HostScsiTopologyLun *hostScsiTopologyLunList = NULL;
+    const esxVI_HostScsiTopologyLun *hostScsiTopologyLun = NULL;
+    esxVI_ScsiLun *scsiLunList = NULL;
+    const esxVI_ScsiLun *scsiLun = NULL;
+    bool success = false;
+    int i = 0;
+
+    if (esxVI_LookupHostScsiTopologyLunListByTargetName(
+          priv->primary, pool->name, &hostScsiTopologyLunList) < 0) {
+        goto cleanup;
+    }
+
+    if (hostScsiTopologyLunList == NULL) {
+        /* iSCSI adapter may not be enabled on ESX host */
+        return 0;
+    }
+
+    if (esxVI_LookupScsiLunList(priv->primary, &scsiLunList) < 0) {
+        goto cleanup;
+    }
+
+    /* O^2 but still faster than hash given N is not that large */
+    for (scsiLun = scsiLunList; scsiLun != NULL && count < maxnames;
+         scsiLun = scsiLun->_next) {
+        for (hostScsiTopologyLun = hostScsiTopologyLunList;
+             hostScsiTopologyLun != NULL && count < maxnames;
+             hostScsiTopologyLun = hostScsiTopologyLun->_next) {
+            if (STREQ(hostScsiTopologyLun->scsiLun, scsiLun->key)) {
+                names[count] = strdup(scsiLun->deviceName);
+
+                if (names[count] == NULL) {
+                    virReportOOMError();
+                    goto cleanup;
+                }
+                ++count;
+            }
+        }
+    }
+
+    success = true;
+
+  cleanup:
+    if (! success) {
+        for (i = 0; i < count; ++i) {
+            VIR_FREE(names[i]);
+        }
+        count = -1;
+    }
+
+    esxVI_HostScsiTopologyLun_Free(&hostScsiTopologyLunList);
+    esxVI_ScsiLun_Free(&scsiLunList);
+
+    return count;
+}
+
+
+static virStorageVolPtr
+esxStorageBackendISCSIVolumeLookupByName(virStoragePoolPtr pool,
+                                         const char *name)
+{
+    virStorageVolPtr volume = NULL;
+    esxPrivate *priv = pool->conn->storagePrivateData;
+    esxVI_ScsiLun *scsiLunList = NULL;
+    const esxVI_ScsiLun *scsiLun = NULL;
+    /* MD5_DIGEST_SIZE = VIR_UUID_BUFLEN = 16 */
+    unsigned char md5[MD5_DIGEST_SIZE];
+    char uuid_string[VIR_UUID_STRING_BUFLEN] = "";
+
+    if (esxVI_LookupScsiLunList(priv->primary, &scsiLunList) < 0) {
+        goto cleanup;
+    }
+
+    for (scsiLun = scsiLunList; scsiLun != NULL;
+         scsiLun = scsiLun->_next) {
+        if (STREQ(scsiLun->deviceName, name)) {
+            /**
+             * ScsiLun provides an UUID field that is unique accross
+             * multiple servers. But this field length is ~55 characters
+             * compute MD5 hash to transform it to an acceptable
+             * libvirt format
+             */
+            md5_buffer(scsiLun->uuid, strlen(scsiLun->uuid), md5);
+
+            virUUIDFormat(md5, uuid_string);
+
+            /**
+             * ScsiLun provides displayName and canonicalName but both are
+             * optional and its observed that they can be NULL, using
+             * deviceName to create volume.
+             */
+            volume = virGetStorageVol(pool->conn, pool->name, name, uuid_string,
+                                      &esxStorageBackendISCSIDrv, NULL);
+            break;
+        }
+    }
+
+  cleanup:
+
+    esxVI_ScsiLun_Free(&scsiLunList);
+
+    return volume;
+
+}
+
+
+static virStorageVolPtr
+esxStorageBackendISCSIVolumeLookupByPath(virConnectPtr conn, const char *path)
+{
+    virStorageVolPtr volume = NULL;
+    esxPrivate *priv = conn->storagePrivateData;
+    char *poolName = NULL;
+    esxVI_ScsiLun *scsiLunList = NULL;
+    esxVI_ScsiLun *scsiLun = NULL;
+    const esxVI_HostScsiDisk *hostScsiDisk = NULL;
+    /* MD5_DIGEST_SIZE = VIR_UUID_BUFLEN = 16 */
+    unsigned char md5[MD5_DIGEST_SIZE];
+    char uuid_string[VIR_UUID_STRING_BUFLEN] = "";
+
+    if (esxVI_LookupScsiLunList(priv->primary, &scsiLunList) < 0) {
+        goto cleanup;
+    }
+
+    for (scsiLun = scsiLunList ; scsiLun != NULL;
+         scsiLun = scsiLun->_next) {
+         hostScsiDisk = esxVI_HostScsiDisk_DynamicCast(scsiLun);
+
+        if (hostScsiDisk != NULL &&
+            STREQ(hostScsiDisk->devicePath, path)) {
+            /* Found matching device */
+            if (esxVI_LookupStoragePoolNameByScsiLunKey(
+                  priv->primary, hostScsiDisk->key, &poolName) < 0) {
+                goto cleanup;
+            }
+
+            md5_buffer(scsiLun->uuid, strlen(scsiLun->uuid), md5);
+
+            virUUIDFormat(md5, uuid_string);
+
+            volume = virGetStorageVol(conn, poolName, path, uuid_string,
+                                      &esxStorageBackendISCSIDrv, NULL);
+            break;
+        }
+    }
+
+  cleanup:
+
+    esxVI_ScsiLun_Free(&scsiLunList);
+    VIR_FREE(poolName);
+
+    return volume;
+
+}
+
+
+static virStorageVolPtr
+esxStorageBackendISCSIVolumeLookupByKey(virConnectPtr conn, const char *key)
+{
+    virStorageVolPtr volume = NULL;
+    esxPrivate *priv = conn->storagePrivateData;
+    char *poolName = NULL;
+    esxVI_ScsiLun *scsiLunList = NULL;
+    const esxVI_ScsiLun *scsiLun = NULL;
+    /* MD5_DIGEST_SIZE = VIR_UUID_BUFLEN = 16 */
+    unsigned char md5[MD5_DIGEST_SIZE];
+    char uuid_string[VIR_UUID_STRING_BUFLEN] = "";
+
+
+    /* key may be LUN device path */
+    if (STRPREFIX(key, "/")) {
+        return esxStorageBackendISCSIVolumeLookupByPath(conn, key);
+    }
+
+    if (esxVI_LookupScsiLunList(priv->primary, &scsiLunList) < 0) {
+        goto cleanup;
+    }
+
+    for (scsiLun = scsiLunList; scsiLun != NULL;
+         scsiLun = scsiLun->_next) {
+
+        memset(uuid_string, '\0', sizeof(uuid_string));
+        memset(md5, '\0', sizeof(md5));
+
+        md5_buffer(scsiLun->uuid, strlen(scsiLun->uuid), md5);
+
+        virUUIDFormat(md5, uuid_string);
+
+        if (STREQ(key, uuid_string)) {
+            /* Found matching UUID */
+            if (esxVI_LookupStoragePoolNameByScsiLunKey(
+                  priv->primary, scsiLun->key, &poolName) < 0) {
+                goto cleanup;
+            }
+
+            volume = virGetStorageVol(conn,
+                                      poolName,
+                                      scsiLun->deviceName,
+                                      uuid_string,
+                                      &esxStorageBackendISCSIDrv,
+                                      NULL);
+            break;
+        }
+    }
+
+  cleanup:
+
+    esxVI_ScsiLun_Free(&scsiLunList);
+    VIR_FREE(poolName);
+
+    return volume;
+
+}
+
+
+
+static virStorageVolPtr
+esxStorageBackendISCSIVolumeCreateXML(virStoragePoolPtr pool ATTRIBUTE_UNUSED,
+                                      const char *xmldesc ATTRIBUTE_UNUSED,
+                                      unsigned int flags)
+{
+    virCheckFlags(0, NULL);
+
+    /* not supported operation for iSCSI pools */
+    return NULL;
+}
+
+
+
+static virStorageVolPtr
+esxStorageBackendISCSIVolumeCreateXMLFrom(
+  virStoragePoolPtr pool ATTRIBUTE_UNUSED,
+  const char *xmldesc ATTRIBUTE_UNUSED,
+  virStorageVolPtr sourceVolume ATTRIBUTE_UNUSED,
+  unsigned int flags)
+{
+    virCheckFlags(0, NULL);
+
+    /* not supported operation for iSCSI pools */
+    return NULL;
+}
+
+
+
+static char*
+esxStorageBackendISCSIVolumeGetXMLDesc(virStorageVolPtr volume,
+                                       unsigned int flags)
+{
+    char *xml = NULL;
+    esxPrivate *priv = volume->conn->storagePrivateData;
+    virStoragePoolDef pool;
+    esxVI_ScsiLun *scsiLunList = NULL;
+    const esxVI_ScsiLun *scsiLun = NULL;
+    const esxVI_HostScsiDisk *hostScsiDisk = NULL;
+    virStorageVolDef def;
+    /* MD5_DIGEST_SIZE = VIR_UUID_BUFLEN = 16 */
+    unsigned char md5[MD5_DIGEST_SIZE];
+    char uuid_string[VIR_UUID_STRING_BUFLEN] = "";
+
+    virCheckFlags(0, NULL);
+
+    memset(&pool, 0, sizeof(pool));
+    memset(&def, 0, sizeof(def));
+
+    if (esxVI_LookupScsiLunList(priv->primary, &scsiLunList) < 0) {
+        goto cleanup;
+    }
+
+    for (scsiLun = scsiLunList; scsiLun != NULL;
+         scsiLun = scsiLun->_next) {
+         hostScsiDisk =
+             esxVI_HostScsiDisk_DynamicCast((esxVI_ScsiLun *)scsiLun);
+
+        if (hostScsiDisk != NULL &&
+            STREQ(hostScsiDisk->deviceName, volume->name)) {
+            break;
+        }
+    }
+
+    if (hostScsiDisk == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+          _("Could find volume with name: %s"), volume->name);
+        goto cleanup;
+    }
+
+    pool.type = VIR_STORAGE_POOL_ISCSI;
+
+    def.name = volume->name;
+
+    md5_buffer(scsiLun->uuid, strlen(hostScsiDisk->uuid), md5);
+
+    virUUIDFormat(md5, uuid_string);
+
+    if (esxVI_String_DeepCopyValue(&def.key, uuid_string) < 0) {
+        goto cleanup;
+    }
+
+    /* iSCSI LUN exposes a block device */
+    def.type = VIR_STORAGE_VOL_BLOCK;
+
+    def.target.path = hostScsiDisk->devicePath;
+
+    def.capacity = hostScsiDisk->capacity->block->value *
+                   hostScsiDisk->capacity->blockSize->value;
+
+    def.allocation = def.capacity;
+
+    /* iSCSI LUN(s) hosting a datastore will be auto-mounted by
+     * ESX host
+     */
+    def.target.format = VIR_STORAGE_FILE_RAW;
+
+    xml = virStorageVolDefFormat(&pool, &def);
+
+  cleanup:
+
+    esxVI_ScsiLun_Free(&scsiLunList);
+    VIR_FREE(def.key);
+
+    return xml;
+
+}
+
+static int
+esxStorageBackendISCSIVolumeDelete(virStorageVolPtr volume ATTRIBUTE_UNUSED,
+                                   unsigned int flags)
+{
+    virCheckFlags(0, -1);
+
+    /* unsupported operation for iSCSI volume */
+    return 1;
+
+}
+
+
+
+static int
+esxStorageBackendISCSIVolumeWipe(virStorageVolPtr volume ATTRIBUTE_UNUSED,
+                                   unsigned int flags)
+{
+    virCheckFlags(0, -1);
+
+    /* unsupported operation for iSCSI volume */
+    return 1;
+
+}
+
+
+
+static char*
+esxStorageBackendISCSIVolumeGetPath(virStorageVolPtr volume)
+{
+    char *path;
+
+    if (virAsprintf(&path, "%s", volume->name) < 0) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    return path;
+
+}
+
+
+
+virStorageDriver esxStorageBackendISCSIDrv = {
+    .name = "ESX ISCSI backend",
+    .open = NULL, /* 1.0.0 */
+    .close = NULL, /* 1.0.0 */
+    .numOfPools = esxStorageBackendISCSINumberOfStoragePools, /* 1.0.0 */
+    .listPools = esxStorageBackendISCSIListStoragePools, /* 1.0.0 */
+    .poolLookupByName = esxStorageBackendISCSIPoolLookupByName, /* 1.0.0 */
+    .poolLookupByUUID = esxStorageBackendISCSIPoolLookupByUUID, /* 1.0.0 */
+    .poolRefresh = esxStorageBackendISCSIPoolRefresh, /* 1.0.0 */
+    .poolGetInfo = esxStorageBackendISCSIPoolGetInfo, /* 1.0.0 */
+    .poolGetXMLDesc = esxStorageBackendISCSIPoolGetXMLDesc, /* 1.0.0 */
+    .poolNumOfVolumes = esxStorageBackendISCSIPoolNumberOfStorageVolumes, /* 1.0.0 */
+    .poolListVolumes = esxStorageBackendISCSIPoolListStorageVolumes, /* 1.0.0 */
+    .volLookupByName = esxStorageBackendISCSIVolumeLookupByName, /* 1.0.0 */
+    .volLookupByKey = esxStorageBackendISCSIVolumeLookupByKey, /* 1.0.0 */
+    .volLookupByPath = esxStorageBackendISCSIVolumeLookupByPath, /* 1.0.0 */
+    .volCreateXML = esxStorageBackendISCSIVolumeCreateXML, /* 1.0.0 */
+    .volCreateXMLFrom = esxStorageBackendISCSIVolumeCreateXMLFrom, /* 1.0.0 */
+    .volGetXMLDesc = esxStorageBackendISCSIVolumeGetXMLDesc, /* 1.0.0 */
+    .volDelete = esxStorageBackendISCSIVolumeDelete, /* 1.0.0 */
+    .volWipe = esxStorageBackendISCSIVolumeWipe, /* 1.0.0 */
+    .volGetPath = esxStorageBackendISCSIVolumeGetPath, /* 1.0.0 */
+};
diff --git a/src/esx/esx_storage_backend_iscsi.h b/src/esx/esx_storage_backend_iscsi.h
new file mode 100644
index 0000000..f78da46
--- /dev/null
+++ b/src/esx/esx_storage_backend_iscsi.h
@@ -0,0 +1,29 @@
+/*
+ * esx_storage_backend_iscsi.h: ESX storage backend for iSCSI handling
+ *
+ * Copyright (C) 2012 Ata E Husain Bohra <ata.husain at hotmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __ESX_STORAGE_BACKEND_ISCSI_H__
+# define __ESX_STORAGE_BACKEND_ISCSI_H__
+
+# include "driver.h"
+
+extern virStorageDriver esxStorageBackendISCSIDrv;
+
+#endif /* __ESX_STORAGE_BACKEND_ISCSI_H__ */
diff --git a/src/esx/esx_storage_driver.c b/src/esx/esx_storage_driver.c
index 5530ea7..6952c69 100644
--- a/src/esx/esx_storage_driver.c
+++ b/src/esx/esx_storage_driver.c
@@ -31,6 +31,7 @@
 #include "esx_private.h"
 #include "esx_storage_driver.h"
 #include "esx_storage_backend_vmfs.h"
+#include "esx_storage_backend_iscsi.h"
 
 #define VIR_FROM_THIS VIR_FROM_ESX
 
@@ -42,11 +43,13 @@
 */
 enum {
     VMFS = 0,
+    ISCSI,
     LAST_DRIVER
 };
 
 static virStorageDriverPtr backendDrv[] = {
-    &esxStorageBackendVMFSDrv
+    &esxStorageBackendVMFSDrv,
+    &esxStorageBackendISCSIDrv
 };
 
 static virDrvOpenStatus
@@ -465,9 +468,12 @@ esxStorageVolumeLookupByPath(virConnectPtr conn, const char *path)
      * VMFS Datastore path follows cannonical format i.e.:
      * [<datastore_name>] <file_path>
      *          WHEREAS
+     * iSCSI LUNs device path follows normal linux path convention
      */
     if (STRPREFIX(path, "[")) {
         volume = backendDrv[VMFS]->volLookupByPath(conn, path);
+    } else if (STRPREFIX(path, "/")) {
+        volume = backendDrv[ISCSI]->volLookupByPath(conn, path);
     } else {
         virReportError(VIR_ERR_INTERNAL_ERROR,
           _("Unexpected volume path format: %s"), path);
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 9fb2c11..12100d7 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -4875,5 +4875,337 @@ esxVI_LookupManagedObjectHelper(esxVI_Context *ctx,
 }
 
 
+int
+esxVI_LookupHostInternetScsiHbaStaticTargetByName(
+  esxVI_Context *ctx,
+  const char *name,
+  esxVI_HostInternetScsiHbaStaticTarget **ret,
+  esxVI_Occurrence occurrence)
+{
+    int result = -1;
+    esxVI_HostInternetScsiHba *hostInternetScsiHba = NULL;
+    const esxVI_HostInternetScsiHbaStaticTarget *target = NULL;
+
+    if (esxVI_LookupHostInternetScsiHba(ctx, &hostInternetScsiHba) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+          _("Unable to obtain hostInternetScsiHba"));
+        goto cleanup;
+    }
+
+    if (hostInternetScsiHba == NULL) {
+        /* iSCSI adapter may not be enabled for this host */
+        return 0;
+    }
+
+    for (target = hostInternetScsiHba->configuredStaticTarget;
+         target != NULL;
+         target = target->_next) {
+        if (STREQ(target->iScsiName, name)) {
+            break;
+        }
+    }
+
+    if (target == NULL) {
+        if (occurrence == esxVI_Occurrence_RequiredItem) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+              _("Could not find storage pool with name: %s"), name);
+        }
+        goto cleanup;
+    }
+
+    if (esxVI_HostInternetScsiHbaStaticTarget_DeepCopy(
+          ret, (esxVI_HostInternetScsiHbaStaticTarget *)target) < 0) {
+        goto cleanup;
+    }
+
+    result = 0;
+
+  cleanup:
+
+    esxVI_HostInternetScsiHba_Free(&hostInternetScsiHba);
+
+    return result;
+}
+
+
+int
+esxVI_LookupHostInternetScsiHba(
+  esxVI_Context *ctx,
+  esxVI_HostInternetScsiHba **hostInternetScsiHba)
+{
+    int result = -1;
+    esxVI_DynamicProperty *dynamicProperty = NULL;
+    esxVI_ObjectContent *hostSystem = NULL;
+    esxVI_String *propertyNameList = NULL;
+    esxVI_HostHostBusAdapter *hostHostBusAdapterList = NULL;
+    esxVI_HostHostBusAdapter *hostHostBusAdapter = NULL;
+
+    if (esxVI_String_AppendValueToList(&propertyNameList,
+          "config.storageDevice.hostBusAdapter\0") < 0 ||
+        esxVI_LookupHostSystemProperties(ctx, propertyNameList,
+            &hostSystem) < 0) {
+        goto cleanup;
+    }
+
+    for (dynamicProperty = hostSystem->propSet;
+         dynamicProperty != NULL;
+         dynamicProperty = dynamicProperty->_next) {
+        if (STREQ(dynamicProperty->name,
+              "config.storageDevice.hostBusAdapter")) {
+            if (esxVI_HostHostBusAdapter_CastListFromAnyType(
+                  dynamicProperty->val, &hostHostBusAdapterList) < 0 ||
+                hostHostBusAdapterList == NULL) {
+                goto cleanup;
+            }
+        } else {
+            VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
+        }
+    }
+
+    /* See vSphere API documentation about HostInternetScsiHba for details */
+    for (hostHostBusAdapter = hostHostBusAdapterList;
+         hostHostBusAdapter != NULL;
+         hostHostBusAdapter = hostHostBusAdapter->_next) {
+        esxVI_HostInternetScsiHba *candidate=
+            esxVI_HostInternetScsiHba_DynamicCast(hostHostBusAdapter);
+
+        if (candidate) {
+            if (esxVI_HostInternetScsiHba_DeepCopy(hostInternetScsiHba,
+                  candidate) < 0) {
+                goto cleanup;
+            }
+            break;
+        }
+    }
+
+    result = 0;
+
+cleanup:
+    esxVI_String_Free(&propertyNameList);
+    esxVI_ObjectContent_Free(&hostSystem);
+    esxVI_HostHostBusAdapter_Free(&hostHostBusAdapterList);
+
+    return result;
+}
+
+
+int
+esxVI_LookupScsiLunList(esxVI_Context *ctx,
+                        esxVI_ScsiLun **ret)
+{
+    int result = -1;
+    esxVI_DynamicProperty *dynamicProperty = NULL;
+    esxVI_ObjectContent *hostSystem = NULL;
+    esxVI_String *propertyNameList = NULL;
+    esxVI_ScsiLun *scsiLunList = NULL;
+
+    if (esxVI_String_AppendValueToList(&propertyNameList,
+        "config.storageDevice.scsiLun\0") < 0 ||
+        esxVI_LookupHostSystemProperties(
+            ctx, propertyNameList, &hostSystem) < 0) {
+        goto cleanup;
+    }
+
+    for (dynamicProperty = hostSystem->propSet;
+         dynamicProperty != NULL;
+         dynamicProperty = dynamicProperty->_next) {
+        if (STREQ(dynamicProperty->name,
+                     "config.storageDevice.scsiLun")) {
+            if (esxVI_ScsiLun_CastListFromAnyType(dynamicProperty->val,
+                                                  &scsiLunList) < 0) {
+                goto cleanup;
+            }
+        } else {
+            VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
+        }
+    }
+
+    if (scsiLunList == NULL ||
+        esxVI_ScsiLun_DeepCopyList(ret, scsiLunList) < 0) {
+        goto cleanup;
+    }
+
+    result = 0;
+
+cleanup:
+
+    esxVI_ScsiLun_Free(&scsiLunList);
+
+    return result;
+
+}
+
+
+int
+esxVI_LookupHostScsiTopologyLunListByTargetName(
+  esxVI_Context *ctx, const char *name, esxVI_HostScsiTopologyLun **ret)
+{
+    int result = -1;
+    esxVI_DynamicProperty *dynamicProperty = NULL;
+    esxVI_ObjectContent *hostSystem = NULL;
+    esxVI_String *propertyNameList = NULL;
+    esxVI_HostScsiTopologyInterface *hostScsiInterfaceList = NULL;
+    const esxVI_HostScsiTopologyInterface *hostScsiInterface = NULL;
+    const esxVI_HostScsiTopologyTarget *hostScsiTopologyTarget = NULL;
+    bool found = false;
+
+    if (esxVI_String_AppendValueToList(&propertyNameList,
+        "config.storageDevice.scsiTopology.adapter\0") < 0 ||
+        esxVI_LookupHostSystemProperties(
+            ctx, propertyNameList, &hostSystem) < 0) {
+        goto cleanup;
+    }
+
+    for (dynamicProperty = hostSystem->propSet;
+         dynamicProperty != NULL;
+         dynamicProperty = dynamicProperty->_next) {
+        if (STREQ(dynamicProperty->name,
+              "config.storageDevice.scsiTopology.adapter")) {
+            esxVI_HostScsiTopologyInterface_Free(&hostScsiInterfaceList);
+
+            if ((esxVI_HostScsiTopologyInterface_CastListFromAnyType
+                  (dynamicProperty->val, &hostScsiInterfaceList) < 0)) {
+                goto cleanup;
+            }
+        } else {
+            VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
+        }
+    }
+
+    if (hostScsiInterfaceList == NULL) {
+        /* iSCSI adapter may not be enabled */
+        return 0;
+    }
+
+    /* See vSphere API documentation about HostScsiTopologyInterface */
+    for (hostScsiInterface = hostScsiInterfaceList;
+         hostScsiInterface != NULL && !found;
+         hostScsiInterface = hostScsiInterface->_next) {
+        for (hostScsiTopologyTarget = hostScsiInterface->target;
+             hostScsiTopologyTarget != NULL;
+             hostScsiTopologyTarget = hostScsiTopologyTarget->_next) {
+            const esxVI_HostInternetScsiTargetTransport *candidate =
+                esxVI_HostInternetScsiTargetTransport_DynamicCast(
+                  hostScsiTopologyTarget->transport);
+
+            if (candidate && STREQ(candidate->iScsiName, name)) {
+                found = true;
+                break;
+            }
+        }
+    }
+
+    if (!found || hostScsiTopologyTarget == NULL) {
+        goto cleanup;
+    }
+
+    if (esxVI_HostScsiTopologyLun_DeepCopyList(
+          ret, hostScsiTopologyTarget->lun) < 0) {
+        goto cleanup;
+    }
+
+    if (*ret == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+          _("Target not found"));
+        goto cleanup;
+    }
+
+    result = 0;
+
+  cleanup:
+
+    esxVI_String_Free(&propertyNameList);
+    esxVI_ObjectContent_Free(&hostSystem);
+    esxVI_HostScsiTopologyInterface_Free(&hostScsiInterfaceList);
+
+    return result;
+}
+
+
+int
+esxVI_LookupStoragePoolNameByScsiLunKey(esxVI_Context *ctx,
+                                        const char *key,
+                                        char **poolName)
+{
+    int result = -1;
+    esxVI_DynamicProperty *dynamicProperty = NULL;
+    esxVI_ObjectContent *hostSystem = NULL;
+    esxVI_String *propertyNameList = NULL;
+    esxVI_HostScsiTopologyInterface *hostScsiInterfaceList = NULL;
+    const esxVI_HostScsiTopologyInterface *hostScsiInterface = NULL;
+    const esxVI_HostScsiTopologyTarget *hostScsiTopologyTarget = NULL;
+    bool found = false;
+
+    if (esxVI_String_AppendValueToList(&propertyNameList,
+        "config.storageDevice.scsiTopology.adapter\0") < 0 ||
+        esxVI_LookupHostSystemProperties(
+            ctx, propertyNameList, &hostSystem) < 0) {
+        goto cleanup;
+    }
+
+    for (dynamicProperty = hostSystem->propSet;
+         dynamicProperty != NULL;
+         dynamicProperty = dynamicProperty->_next) {
+        if (STREQ(dynamicProperty->name,
+              "config.storageDevice.scsiTopology.adapter")) {
+            esxVI_HostScsiTopologyInterface_Free(&hostScsiInterfaceList);
+
+            if ((esxVI_HostScsiTopologyInterface_CastListFromAnyType
+                  (dynamicProperty->val, &hostScsiInterfaceList) < 0)) {
+                goto cleanup;
+            }
+        } else {
+            VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
+        }
+    }
+
+    if (hostScsiInterfaceList == NULL) {
+        /* iSCSI adapter may not be enabled */
+        return 0;
+    }
+
+    /* See vSphere API documentation about HostScsiTopologyInterface */
+    for (hostScsiInterface = hostScsiInterfaceList;
+         hostScsiInterface != NULL && !found;
+         hostScsiInterface = hostScsiInterface->_next) {
+        for (hostScsiTopologyTarget = hostScsiInterface->target;
+             hostScsiTopologyTarget != NULL;
+             hostScsiTopologyTarget = hostScsiTopologyTarget->_next) {
+            const esxVI_HostInternetScsiTargetTransport *candidate =
+                esxVI_HostInternetScsiTargetTransport_DynamicCast(
+                  hostScsiTopologyTarget->transport);
+
+            if (candidate) {
+                /* iterate hostScsiTopologyLun list to find matching key */
+                const esxVI_HostScsiTopologyLun *hostScsiTopologyLun =
+                                                hostScsiTopologyTarget->lun;
+                for (; hostScsiTopologyLun != NULL;
+                     hostScsiTopologyLun = hostScsiTopologyLun->_next) {
+                    if (STREQ(hostScsiTopologyLun->scsiLun, key)) {
+                        *poolName = strdup(candidate->iScsiName);
+
+                        if (*poolName == NULL) {
+                            virReportOOMError();
+                            goto cleanup;
+                        }
+                    }
+                }
+                /* hostScsiTopologyLun iteration done, terminate loop */
+                break;
+            }
+        }
+    }
+
+    result = 0;
+
+  cleanup:
+    esxVI_ObjectContent_Free(&hostSystem);
+    esxVI_String_Free(&propertyNameList);
+    esxVI_HostScsiTopologyInterface_Free(&hostScsiInterfaceList);
+
+    return result;
+}
+
+
 
 #include "esx_vi.generated.c"
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
index d7895a0..8e56044 100644
--- a/src/esx/esx_vi.h
+++ b/src/esx/esx_vi.h
@@ -528,6 +528,24 @@ int esxVI_ParseHostCpuIdInfo(esxVI_ParsedHostCpuIdInfo *parsedHostCpuIdInfo,
 
 int esxVI_ProductVersionToDefaultVirtualHWVersion(esxVI_ProductVersion productVersion);
 
+int esxVI_LookupHostInternetScsiHbaStaticTargetByName(esxVI_Context *ctx,
+  const char *name, esxVI_HostInternetScsiHbaStaticTarget **ret,
+  esxVI_Occurrence occurrence);
+
+int esxVI_LookupHostInternetScsiHba(
+  esxVI_Context *ctx,
+  esxVI_HostInternetScsiHba **hostInternetScsiHba);
+
+int esxVI_LookupScsiLunList(esxVI_Context *ctx, esxVI_ScsiLun **ret);
+
+int esxVI_LookupHostScsiTopologyLunListByTargetName(
+  esxVI_Context *ctx, const char *name, esxVI_HostScsiTopologyLun **ret);
+
+int
+esxVI_LookupStoragePoolNameByScsiLunKey(esxVI_Context *ctx,
+                                        const char *key,
+                                        char **poolName);
+
 # include "esx_vi.generated.h"
 
 #endif /* __ESX_VI_H__ */
diff --git a/src/esx/esx_vi_generator.input b/src/esx/esx_vi_generator.input
index c4a3e56..21f5b10 100644
--- a/src/esx/esx_vi_generator.input
+++ b/src/esx/esx_vi_generator.input
@@ -58,6 +58,14 @@ enum AutoStartWaitHeartbeatSetting
 end
 
 
+enum FibreChannelPortType
+    fabric
+    loop
+    pointToPoint
+    unknown
+end
+
+
 enum ManagedEntityStatus
     gray
     green
@@ -128,6 +136,12 @@ enum VirtualMachinePowerState
 end
 
 
+enum vStorageSupport
+    vStorageUnknown
+end
+
+
+
 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
 # Objects
 #
@@ -262,6 +276,13 @@ object HostAutoStartManagerConfig
     AutoStartPowerInfo                       powerInfo                      ol
 end
 
+object HostBlockAdapterTargetTransport extends HostTargetTransport
+end
+
+
+object HostBlockHba extends HostHostBusAdapter
+end
+
 
 object HostConfigManager
     ManagedObjectReference                   cpuScheduler                   o
@@ -309,6 +330,31 @@ object HostDatastoreBrowserSearchSpec
     Boolean                                  sortFoldersFirst               o
 end
 
+object HostDevice
+    String                                   deviceName                     r
+    String                                   deviceType                     r
+end
+
+
+object HostDiskDimensionsLba
+    Int                                      blockSize                      r
+    Long                                     block                          r
+end
+
+
+object HostFibreChannelHba extends HostHostBusAdapter
+    Long                                     nodeWorldWideName              r
+    FibreChannelPortType                     portType                       r
+    Long                                     portWorldWideName              r
+    Long                                     speed                          r
+end
+
+
+object HostFibreChannelTargetTransport extends HostTargetTransport
+    Long                                     nodeWorldWideName              r
+    Long                                     portWorldWideName              r
+end
+
 
 object HostFileSystemVolume
     String                                   type                           r
@@ -323,6 +369,164 @@ object HostIpConfig
     String                                   subnetMask                     o
 end
 
+object HostHostBusAdapter
+    Int                                      bus                            r
+    String                                   device                         r
+    String                                   driver                         o
+    String                                   key                            o
+    String                                   model                          r
+    String                                   pci                            o
+    String                                   status                         r
+end
+
+
+object HostInternetScsiTargetTransport extends HostTargetTransport
+    String                                   iScsiName                      r
+    String                                   iScsiAlias                     r
+    String                                   address                        ol
+
+end
+
+
+object HostInternetScsiHba extends HostHostBusAdapter
+    HostInternetScsiHbaAuthenticationCapabilities   authenticationCapabilities  r
+    HostInternetScsiHbaAuthenticationProperties     authenticationProperties    r
+    HostInternetScsiHbaDiscoveryCapabilities        discoveryCapabilities       r
+    HostInternetScsiHbaDiscoveryProperties          discoveryProperties         r
+    HostInternetScsiHbaIPCapabilities               ipCapabilities              r
+    HostInternetScsiHbaIPProperties                 ipProperties                r
+    String                                          iScsiName                   r
+    Boolean                                         isSoftwareBased             r
+    HostInternetScsiHbaParamValue                   advancedOptions             ol
+    HostInternetScsiHbaSendTarget                   configuredSendTarget        ol
+    HostInternetScsiHbaStaticTarget                 configuredStaticTarget      ol
+    Int                                             currentSpeedMb              o
+    HostInternetScsiHbaDigestCapabilities           digestCapabilities          o
+    HostInternetScsiHbaDigestProperties             digestProperties            o
+    String                                          iScsiAlias                  o
+    Int                                             maxSpeedMb                  o
+    OptionDef                                       supportedAdvancedOptions    ol
+end
+
+
+
+object HostInternetScsiHbaAuthenticationCapabilities
+    Boolean                                  chapAuthSettable               r
+    Boolean                                  krb5AuthSettable               r
+    Boolean                                  spkmAuthSettable               r
+    Boolean                                  srpAuthSettable                r
+    Boolean                                  mutualChapSettable             o
+    Boolean                                  targetChapSettable             o
+    Boolean                                  targetMutualChapSettable       o
+end
+
+
+object HostInternetScsiHbaAuthenticationProperties
+    Boolean                                  chapAuthEnabled                r
+    String                                   chapAuthenticationType         o
+    Boolean                                  chapInherited                  o
+    String                                   chapName                       o
+    String                                   chapSecret                     o
+    String                                   mutualChapAuthenticationType   o
+    Boolean                                  mutualChapInherited            o
+    String                                   mutualChapName                 o
+    String                                   mutualChapSecret               o
+end
+
+
+object HostInternetScsiHbaDigestCapabilities
+    Boolean                                  dataDigestSettable             o
+    Boolean                                  headerDigestSettable           o
+    Boolean                                  targetDataDigestSettable       o
+    Boolean                                  targetHeaderDigestSettable     o
+end
+
+
+object HostInternetScsiHbaDigestProperties
+    Boolean                                  dataDigestInherited            o
+    String                                   dataDigestType                 o
+    Boolean                                  headerDigestInherited          o
+    String                                   headerDigestType               o
+end
+
+
+object HostInternetScsiHbaDiscoveryCapabilities
+    Boolean                                  iSnsDiscoverySettable          r
+    Boolean                                  sendTargetsDiscoverySettable   r
+    Boolean                                  slpDiscoverySettable           r
+    Boolean                                  staticTargetDiscoverySettable  r
+end
+
+
+object HostInternetScsiHbaDiscoveryProperties
+    Boolean                                  iSnsDiscoveryEnabled           r
+    Boolean                                  sendTargetsDiscoveryEnabled    r
+    Boolean                                  slpDiscoveryEnabled            r
+    Boolean                                  staticTargetDiscoveryEnabled   r
+    String                                   iSnsDiscoveryMethod            o
+    String                                   iSnsHost                       o
+    String                                   slpDiscoveryMethod             o
+    String                                   slpHost                        o
+end
+
+object HostInternetScsiHbaIPCapabilities
+    Boolean                                         addressSettable             r
+    Boolean                                         alternateDnsServerAddressSettable   r
+    Boolean                                         defaultGatewaySettable              r
+    Boolean                                         ipConfigurationMethodSettable       r
+    Boolean                                         primaryDnsServerAddressSettable     r
+    Boolean                                         subnetMaskSettable                  r
+    Boolean                                         arpRedirectSettable                 o
+    Boolean                                         hostNameAsTargetAddress             o
+    Boolean                                         ipv6Supported                       o
+    Boolean                                         mtuSettable                         o
+    Boolean                                         nameAliasSettable                   o
+end
+
+
+object HostInternetScsiHbaIPProperties
+    Boolean                                         dhcpConfigurationEnabled    r
+    String                                          address                     o
+    String                                          alternateDnsServerAddress   o
+    Boolean                                         arpRedirectEnabled          o
+    String                                          defaultGateway              o
+    String                                          ipv6Address                 o
+    String                                          ipv6DefaultGateway          o
+    Boolean                                         jumboFramesEnabled          o
+    String                                          mac                         o
+    Int                                             mtu                         o
+    String                                          primaryDnsServerAddress     o
+    String                                          subnetMask                  o
+end
+
+
+object HostInternetScsiHbaParamValue extends OptionValue
+    Boolean                                  isInherited                    o
+end
+
+
+object HostInternetScsiHbaSendTarget
+    String                                   address                        r
+    HostInternetScsiHbaParamValue            advancedOptions                ol
+    HostInternetScsiHbaAuthenticationProperties  authenticationProperties   o
+    HostInternetScsiHbaDigestProperties      digestProperties               o
+    String                                   parent                         o
+    Int                                      port                           o
+    OptionDef                                supportedAdvancedOptions       ol
+end
+
+
+object HostInternetScsiHbaStaticTarget
+    String                                   address                        r
+    String                                   iScsiName                      r
+    HostInternetScsiHbaParamValue            advancedOptions                ol
+    HostInternetScsiHbaAuthenticationProperties  authenticationProperties   o
+    HostInternetScsiHbaDigestProperties      digestProperties               o
+    String                                   parent                         o
+    Int                                      port                           o
+    OptionDef                                supportedAdvancedOptions       ol
+end
+
 
 object HostMountInfo
     String                                   path                           o
@@ -418,12 +622,55 @@ object HostPortGroupSpec
     HostNetworkPolicy                        policy                         r
 end
 
+object HostParallelScsiHba extends HostHostBusAdapter
+end
+
+
+object HostParallelScsiTargetTransport extends HostTargetTransport
+end
+
+
+object HostScsiDisk extends ScsiLun
+    HostDiskDimensionsLba                    capacity                       r
+    String                                   devicePath                     r
+end
+
 
 object HostScsiDiskPartition
     String                                   diskName                       r
     Int                                      partition                      r
 end
 
+object HostScsiTopology
+    HostScsiTopologyInterface                adapater                       ol
+end
+
+
+object HostScsiTopologyInterface
+    String                                   adapter                        r
+    String                                   key                            r
+    HostScsiTopologyTarget                   target                         ol
+end
+
+
+object HostScsiTopologyLun
+    String                                   key                            r
+    Int                                      lun                            r
+    String                                   scsiLun                        r
+end
+
+
+object HostScsiTopologyTarget
+    String                                   key                            r
+    Int                                      target                         r
+    HostScsiTopologyLun                      lun                            ol
+    HostTargetTransport                      transport                      o
+end
+
+
+object HostTargetTransport
+end
+
 
 object HostVirtualSwitch
     String                                   name                           r
@@ -526,12 +773,22 @@ object ObjectUpdate
     MissingProperty                          missingSet                     i
 end
 
+object OptionDef extends ElementDescription
+    OptionType                               optionType                     r
+end
+
 
 object OptionType
     Boolean                                  valueIsReadonly                o
 end
 
 
+object OptionValue
+    String                                   key                            r
+    AnyType                                  value                          r
+end
+
+
 object PerfCounterInfo
     Int                                      key                            r
     ElementDescription                       nameInfo                       r
@@ -664,6 +921,45 @@ object SelectionSpec
 end
 
 
+object ScsiLun extends HostDevice
+    String                                   lunType                        r
+    String                                   operationalState               rl
+    String                                   uuid                           r
+    ScsiLunDurableName                       alternateName                  ol
+    String                                   canonicalName                  o
+    ScsiLunCapabilities                      capabilities                   o
+    ScsiLunDescriptor                        descriptor                     ol
+    String                                   displayName                    o
+    ScsiLunDurableName                       durableName                    o
+    String                                   key                            o
+    String                                   model                          o
+    Int                                      queueDepth                     o
+    String                                   revision                       o
+    Int                                      scsiLevel                      o
+    String                                   serialNumber                   o
+    Byte                                     standardInquiry                ol
+    String                                   vendor                         o
+end
+
+
+object ScsiLunCapabilities
+    Boolean                                  updateDisplayNameSupported     r
+end
+
+
+object ScsiLunDescriptor
+    String                                   id                             r
+    String                                   quality                        r
+end
+
+
+object ScsiLunDurableName
+    String                                   namespace                      r
+    Byte                                     namespaceId                    r
+    Byte                                     data                           ol
+end
+
+
 object ServiceContent
     ManagedObjectReference                   rootFolder                     r
     ManagedObjectReference                   propertyCollector              r
@@ -1138,6 +1434,12 @@ method RemoveVirtualSwitch
 end
 
 
+method RescanHba
+   ManagedObjectReference                    _this                          r
+   String                                    hbaDevice                      r
+end
+
+
 method RetrieveProperties            returns ObjectContent                  ol
     ManagedObjectReference                   _this:propertyCollector        r
     PropertyFilterSpec                       specSet                        rl
diff --git a/src/esx/esx_vi_generator.py b/src/esx/esx_vi_generator.py
index 2883ac0..af4e7e8 100755
--- a/src/esx/esx_vi_generator.py
+++ b/src/esx/esx_vi_generator.py
@@ -1532,6 +1532,21 @@ additional_object_features = { "AutoStartDefaults"          : Object.FEATURE__AN
                                                               Object.FEATURE__ANY_TYPE,
                                "HostDatastoreBrowserSearchResults" : Object.FEATURE__LIST |
                                                               Object.FEATURE__ANY_TYPE,
+                               "HostHostBusAdapter"         : Object.FEATURE__LIST |
+                                                              Object.FEATURE__ANY_TYPE,
+                               "HostInternetScsiHba"        : Object.FEATURE__DYNAMIC_CAST |
+                                                              Object.FEATURE__DEEP_COPY,
+                               "HostInternetScsiTargetTransport"  : Object.FEATURE__DYNAMIC_CAST,
+                               "HostScsiDisk"               : Object.FEATURE__LIST |
+                                                              Object.FEATURE__ANY_TYPE |
+                                                              Object.FEATURE__DYNAMIC_CAST,
+                               "HostScsiTopologyInterface"  : Object.FEATURE__LIST |
+                                                              Object.FEATURE__ANY_TYPE,
+                               "HostScsiTopologyLun"        : Object.FEATURE__ANY_TYPE |
+                                                              Object.FEATURE__LIST |
+                                                              Object.FEATURE__DEEP_COPY,
+                               "HostScsiTopologyTarget"     : Object.FEATURE__ANY_TYPE |
+                                                              Object.FEATURE__LIST,
                                "HostPortGroup"              : Object.FEATURE__LIST |
                                                               Object.FEATURE__ANY_TYPE,
                                "HostVirtualSwitch"          : Object.FEATURE__DEEP_COPY |
@@ -1543,6 +1558,10 @@ additional_object_features = { "AutoStartDefaults"          : Object.FEATURE__AN
                                                               Object.FEATURE__LIST |
                                                               Object.FEATURE__ANY_TYPE,
                                "ResourcePoolResourceUsage"  : Object.FEATURE__ANY_TYPE,
+                               "ScsiLun"                    : Object.FEATURE__LIST |
+                                                              Object.FEATURE__ANY_TYPE |
+                                                              Object.FEATURE__DEEP_COPY,
+                               "ScsiLunDurableName"         : Object.FEATURE__LIST,
                                "ServiceContent"             : Object.FEATURE__DESERIALIZE,
                                "SharesInfo"                 : Object.FEATURE__ANY_TYPE,
                                "TaskInfo"                   : Object.FEATURE__LIST |
-- 
1.7.9.5




More information about the libvir-list mailing list