]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Add iSCSI backend storage driver for ESX
authorAta E Husain Bohra <ata.husain@hotmail.com>
Sat, 10 Nov 2012 07:18:08 +0000 (23:18 -0800)
committerMatthias Bolte <matthias.bolte@googlemail.com>
Mon, 3 Dec 2012 20:12:23 +0000 (21:12 +0100)
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.

po/POTFILES.in
src/Makefile.am
src/esx/esx_driver.c
src/esx/esx_storage_backend_iscsi.c [new file with mode: 0644]
src/esx/esx_storage_backend_iscsi.h [new file with mode: 0644]
src/esx/esx_storage_driver.c
src/esx/esx_vi.c
src/esx/esx_vi.h
src/esx/esx_vi_generator.input
src/esx/esx_vi_generator.py

index 77bc04b937ec85a20592dcddb91ff81d17561b40..586aa2b5cd32c79d2ed0e67336bd893748ec625b 100644 (file)
@@ -32,6 +32,7 @@ src/datatypes.c
 src/driver.c
 src/esx/esx_driver.c
 src/esx/esx_network_driver.c
+src/esx/esx_storage_backend_iscsi.c
 src/esx/esx_storage_backend_vmfs.c
 src/esx/esx_storage_driver.c
 src/esx/esx_util.c
index b5c20c82ed8f663b093db79b5093bf88b815dc17..01cb9954c3c5b1c4f973c97e6246502f2df3eb9d 100644 (file)
@@ -498,6 +498,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     \
index 0374a98f131bfd143598381ba88c69b907798b5d..a8582989470a5945af69530cf8f36dbd15749496 100644 (file)
@@ -4792,7 +4792,7 @@ esxDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, unsigned int flags)
     }
 
     if (esxVI_RevertToSnapshot_Task(priv->primary, snapshotTree->snapshot, NULL,
-                                    &task) < 0 ||
+                                    esxVI_Boolean_Undefined, &task) < 0 ||
         esxVI_WaitForTaskCompletion(priv->primary, task, snapshot->domain->uuid,
                                     esxVI_Occurrence_RequiredItem,
                                     priv->parsedUri->autoAnswer, &taskInfoState,
diff --git a/src/esx/esx_storage_backend_iscsi.c b/src/esx/esx_storage_backend_iscsi.c
new file mode 100644 (file)
index 0000000..b6cde96
--- /dev/null
@@ -0,0 +1,774 @@
+
+/*
+ * esx_storage_backend_iscsi.c: ESX storage backend for iSCSI handling
+ *
+ * Copyright (C) 2012 Ata E Husain Bohra <ata.husain@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/>.
+ *
+ */
+
+#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_ESX
+
+/*
+ * 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
+esxStorageBackendISCSINumberOfPools(virConnectPtr conn)
+{
+    bool success = false;
+    int count = 0;
+    esxPrivate *priv = conn->storagePrivateData;
+    esxVI_HostInternetScsiHba *hostInternetScsiHba = NULL;
+    esxVI_HostInternetScsiHbaStaticTarget *target;
+
+    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 == 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
+esxStorageBackendISCSIListPools(virConnectPtr conn, char **const names,
+                                const int maxnames)
+{
+    bool success = false;
+    int count = 0;
+    esxPrivate *priv = conn->storagePrivateData;
+    esxVI_HostInternetScsiHba *hostInternetScsiHba = NULL;
+    esxVI_HostInternetScsiHbaStaticTarget *target;
+    int i;
+
+    if (maxnames == 0) {
+        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 == 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) {
+        names[count] = strdup(target->iScsiName);
+
+        if (names[count] == NULL) {
+            virReportOOMError();
+            goto cleanup;
+        }
+
+        ++count;
+    }
+
+    success = true;
+
+  cleanup:
+    if (! success) {
+        for (i = 0; i < count; ++i) {
+            VIR_FREE(names[i]);
+        }
+    }
+
+    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) {
+        goto cleanup;
+    }
+
+    if (target == NULL) {
+        /* pool not found, error handling done by the base driver */
+        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, &esxStorageBackendISCSI, 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;
+    esxVI_HostInternetScsiHbaStaticTarget *target;
+    /* 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, "%s",
+                       _("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,
+                             &esxStorageBackendISCSI, 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_HostInternetScsiHba *hostInternetScsiHba = NULL;
+
+    virCheckFlags(0, -1);
+
+    if (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,
+                        priv->primary->hostSystem->configManager->storageSystem,
+                        hostInternetScsiHba->device) < 0) {
+        goto cleanup;
+    }
+
+    result = 0;
+
+  cleanup:
+    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;
+    esxVI_HostInternetScsiHbaStaticTarget *target;
+    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 != NULL) {
+        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
+esxStorageBackendISCSIPoolNumberOfVolumes(virStoragePoolPtr pool)
+{
+    int count = 0;
+    esxPrivate *priv = pool->conn->storagePrivateData;
+    esxVI_HostScsiTopologyLun *hostScsiTopologyLunList = NULL;
+    esxVI_HostScsiTopologyLun *hostScsiTopologyLun;
+
+    if (esxVI_LookupHostScsiTopologyLunListByTargetName
+          (priv->primary, pool->name, &hostScsiTopologyLunList) < 0) {
+        return -1;
+    }
+
+    for (hostScsiTopologyLun = hostScsiTopologyLunList;
+         hostScsiTopologyLun != NULL;
+         hostScsiTopologyLun = hostScsiTopologyLun->_next) {
+        ++count;
+    }
+
+    esxVI_HostScsiTopologyLun_Free(&hostScsiTopologyLunList);
+
+    return count;
+}
+
+
+
+static int
+esxStorageBackendISCSIPoolListVolumes(virStoragePoolPtr pool, char **const names,
+                                      int maxnames)
+{
+    bool success = false;
+    int count = 0;
+    esxPrivate *priv = pool->conn->storagePrivateData;
+    esxVI_HostScsiTopologyLun *hostScsiTopologyLunList = NULL;
+    esxVI_HostScsiTopologyLun *hostScsiTopologyLun;
+    esxVI_ScsiLun *scsiLunList = NULL;
+    esxVI_ScsiLun *scsiLun = NULL;
+    int i;
+
+    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;
+    }
+
+    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;
+    esxVI_ScsiLun *scsiLun;
+    /* 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,
+                                      &esxStorageBackendISCSI, NULL);
+            break;
+        }
+    }
+
+  cleanup:
+    esxVI_ScsiLun_Free(&scsiLunList);
+
+    return volume;
+}
+
+
+
+static virStorageVolPtr
+esxStorageBackendISCSIVolumeLookupByPath(virConnectPtr conn, const char *path)
+{
+    virStorageVolPtr volume = NULL;
+    esxPrivate *priv = conn->storagePrivateData;
+    esxVI_ScsiLun *scsiLunList = NULL;
+    esxVI_ScsiLun *scsiLun;
+    esxVI_HostScsiDisk *hostScsiDisk = NULL;
+    char *poolName = 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 */
+            VIR_FREE(poolName);
+
+            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,
+                                      &esxStorageBackendISCSI, 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;
+    esxVI_ScsiLun *scsiLun;
+    /* 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 */
+            VIR_FREE(poolName);
+
+            if (esxVI_LookupStoragePoolNameByScsiLunKey(priv->primary,
+                                                        scsiLun->key,
+                                                        &poolName) < 0) {
+                goto cleanup;
+            }
+
+            volume = virGetStorageVol(conn, poolName, scsiLun->deviceName,
+                                      uuid_string, &esxStorageBackendISCSI,
+                                      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);
+
+    virReportError(VIR_ERR_NO_SUPPORT, "%s",
+                   _("iSCSI storage pool does not support volume creation"));
+
+    return NULL;
+}
+
+
+
+static virStorageVolPtr
+esxStorageBackendISCSIVolumeCreateXMLFrom(virStoragePoolPtr pool ATTRIBUTE_UNUSED,
+                                          const char *xmldesc ATTRIBUTE_UNUSED,
+                                          virStorageVolPtr sourceVolume ATTRIBUTE_UNUSED,
+                                          unsigned int flags)
+{
+    virCheckFlags(0, NULL);
+
+    virReportError(VIR_ERR_NO_SUPPORT, "%s",
+                   _("iSCSI storage pool does not support volume creation"));
+
+    return NULL;
+}
+
+
+
+static char *
+esxStorageBackendISCSIVolumeGetXMLDesc(virStorageVolPtr volume,
+                                       unsigned int flags)
+{
+    char *xml = NULL;
+    esxPrivate *priv = volume->conn->storagePrivateData;
+    virStoragePoolDef pool;
+    esxVI_ScsiLun *scsiLunList = NULL;
+    esxVI_ScsiLun *scsiLun;
+    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(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);
+
+    virReportError(VIR_ERR_NO_SUPPORT, "%s",
+                   _("iSCSI storage pool does not support volume deletion"));
+
+    return -1;
+}
+
+
+
+static int
+esxStorageBackendISCSIVolumeWipe(virStorageVolPtr volume ATTRIBUTE_UNUSED,
+                                 unsigned int flags)
+{
+    virCheckFlags(0, -1);
+
+
+    virReportError(VIR_ERR_NO_SUPPORT, "%s",
+                   _("iSCSI storage pool does not support volume wiping"));
+
+    return -1;
+}
+
+
+
+static char *
+esxStorageBackendISCSIVolumeGetPath(virStorageVolPtr volume)
+{
+    char *path = strdup(volume->name);
+
+    if (path == NULL) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    return path;
+}
+
+
+
+virStorageDriver esxStorageBackendISCSI = {
+    .numOfPools = esxStorageBackendISCSINumberOfPools, /* 1.0.1 */
+    .listPools = esxStorageBackendISCSIListPools, /* 1.0.1 */
+    .poolLookupByName = esxStorageBackendISCSIPoolLookupByName, /* 1.0.1 */
+    .poolLookupByUUID = esxStorageBackendISCSIPoolLookupByUUID, /* 1.0.1 */
+    .poolRefresh = esxStorageBackendISCSIPoolRefresh, /* 1.0.1 */
+    .poolGetInfo = esxStorageBackendISCSIPoolGetInfo, /* 1.0.1 */
+    .poolGetXMLDesc = esxStorageBackendISCSIPoolGetXMLDesc, /* 1.0.1 */
+    .poolNumOfVolumes = esxStorageBackendISCSIPoolNumberOfVolumes, /* 1.0.1 */
+    .poolListVolumes = esxStorageBackendISCSIPoolListVolumes, /* 1.0.1 */
+    .volLookupByName = esxStorageBackendISCSIVolumeLookupByName, /* 1.0.1 */
+    .volLookupByPath = esxStorageBackendISCSIVolumeLookupByPath, /* 1.0.1 */
+    .volLookupByKey = esxStorageBackendISCSIVolumeLookupByKey, /* 1.0.1 */
+    .volCreateXML = esxStorageBackendISCSIVolumeCreateXML, /* 1.0.1 */
+    .volCreateXMLFrom = esxStorageBackendISCSIVolumeCreateXMLFrom, /* 1.0.1 */
+    .volGetXMLDesc = esxStorageBackendISCSIVolumeGetXMLDesc, /* 1.0.1 */
+    .volDelete = esxStorageBackendISCSIVolumeDelete, /* 1.0.1 */
+    .volWipe = esxStorageBackendISCSIVolumeWipe, /* 1.0.1 */
+    .volGetPath = esxStorageBackendISCSIVolumeGetPath, /* 1.0.1 */
+};
diff --git a/src/esx/esx_storage_backend_iscsi.h b/src/esx/esx_storage_backend_iscsi.h
new file mode 100644 (file)
index 0000000..00c9e29
--- /dev/null
@@ -0,0 +1,30 @@
+
+/*
+ * esx_storage_backend_iscsi.h: ESX storage backend for iSCSI handling
+ *
+ * Copyright (C) 2012 Ata E Husain Bohra <ata.husain@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 esxStorageBackendISCSI;
+
+#endif /* __ESX_STORAGE_BACKEND_ISCSI_H__ */
index 52f46b4c229cffd2947782f54e81d3594744b320..e6c09aae68850228ded1381d135fb5bf85ea0bbe 100644 (file)
@@ -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
 
  */
 enum {
     VMFS = 0,
+    ISCSI,
     LAST_BACKEND
 };
 
 static virStorageDriverPtr backends[] = {
-    &esxStorageBackendVMFS
+    &esxStorageBackendVMFS,
+    &esxStorageBackendISCSI
 };
 
 
@@ -386,9 +389,13 @@ 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, "[")) {
         return backends[VMFS]->volLookupByPath(conn, path);
+    } else if (STRPREFIX(path, "/")) {
+        return backends[ISCSI]->volLookupByPath(conn, path);
     } else {
         virReportError(VIR_ERR_INVALID_ARG,
                        _("Unexpected volume path format: %s"), path);
index 9fb2c11dafc3cd88026b00ba21fd0fc5034a9061..564b35cfd6ab35f7d8c314d9f718df855ee647e0 100644 (file)
@@ -2780,7 +2780,8 @@ esxVI_LookupVirtualMachineByUuid(esxVI_Context *ctx, const unsigned char *uuid,
     virUUIDFormat(uuid, uuid_string);
 
     if (esxVI_FindByUuid(ctx, ctx->datacenter->_reference, uuid_string,
-                         esxVI_Boolean_True, &managedObjectReference) < 0) {
+                         esxVI_Boolean_True, esxVI_Boolean_Undefined,
+                         &managedObjectReference) < 0) {
         return -1;
     }
 
@@ -4673,6 +4674,343 @@ esxVI_ProductVersionToDefaultVirtualHWVersion(esxVI_ProductVersion productVersio
 
 
 
+int
+esxVI_LookupHostInternetScsiHbaStaticTargetByName
+  (esxVI_Context *ctx, const char *name,
+   esxVI_HostInternetScsiHbaStaticTarget **target, esxVI_Occurrence occurrence)
+{
+    int result = -1;
+    esxVI_HostInternetScsiHba *hostInternetScsiHba = NULL;
+    esxVI_HostInternetScsiHbaStaticTarget *candidate = 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 (candidate = hostInternetScsiHba->configuredStaticTarget;
+         candidate != NULL; candidate = candidate->_next) {
+        if (STREQ(candidate->iScsiName, name)) {
+            break;
+        }
+    }
+
+    if (candidate == NULL) {
+        if (occurrence == esxVI_Occurrence_RequiredItem) {
+            virReportError(VIR_ERR_NO_STORAGE_POOL,
+                           _("Could not find storage pool with name: %s"), name);
+        }
+
+        goto cleanup;
+    }
+
+    if (esxVI_HostInternetScsiHbaStaticTarget_DeepCopy(target, candidate) < 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 ||
+        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 **scsiLunList)
+{
+    int result = -1;
+    esxVI_String *propertyNameList = NULL;
+    esxVI_ObjectContent *hostSystem = NULL;
+    esxVI_DynamicProperty *dynamicProperty;
+
+    if (esxVI_String_AppendValueToList(&propertyNameList,
+                                       "config.storageDevice.scsiLun") < 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;
+            }
+
+            break;
+        } else {
+            VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
+        }
+    }
+
+    result = 0;
+
+  cleanup:
+    esxVI_String_Free(&propertyNameList);
+    esxVI_ObjectContent_Free(&hostSystem);
+
+    return result;
+}
+
+
+
+int
+esxVI_LookupHostScsiTopologyLunListByTargetName
+  (esxVI_Context *ctx, const char *name,
+   esxVI_HostScsiTopologyLun **hostScsiTopologyLunList)
+{
+    int result = -1;
+    esxVI_DynamicProperty *dynamicProperty = NULL;
+    esxVI_ObjectContent *hostSystem = NULL;
+    esxVI_String *propertyNameList = NULL;
+    esxVI_HostScsiTopologyInterface *hostScsiInterfaceList = NULL;
+    esxVI_HostScsiTopologyInterface *hostScsiInterface = NULL;
+    esxVI_HostScsiTopologyTarget *hostScsiTopologyTarget = NULL;
+    bool found = false;
+    esxVI_HostInternetScsiTargetTransport *candidate = NULL;
+
+    if (hostScsiTopologyLunList == NULL || *hostScsiTopologyLunList != NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
+        return -1;
+    }
+
+    if (esxVI_String_AppendValueToList
+          (&propertyNameList,
+           "config.storageDevice.scsiTopology.adapter") < 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;
+            }
+
+            break;
+        } 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) {
+            candidate = esxVI_HostInternetScsiTargetTransport_DynamicCast
+                          (hostScsiTopologyTarget->transport);
+
+            if (candidate != NULL && STREQ(candidate->iScsiName, name)) {
+                found = true;
+                break;
+            }
+        }
+    }
+
+    if (!found || hostScsiTopologyTarget == NULL) {
+        goto cleanup;
+    }
+
+    if (hostScsiTopologyTarget->lun == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Target not found"));
+        goto cleanup;
+    }
+
+    if (esxVI_HostScsiTopologyLun_DeepCopyList(hostScsiTopologyLunList,
+                                               hostScsiTopologyTarget->lun) < 0) {
+        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;
+    esxVI_HostScsiTopologyInterface *hostScsiInterface = NULL;
+    esxVI_HostScsiTopologyTarget *hostScsiTopologyTarget = NULL;
+    esxVI_HostInternetScsiTargetTransport *candidate;
+    esxVI_HostScsiTopologyLun *hostScsiTopologyLun;
+    bool found = false;
+
+    if (poolName == NULL || *poolName != NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
+        return -1;
+    }
+
+    if (esxVI_String_AppendValueToList
+          (&propertyNameList,
+           "config.storageDevice.scsiTopology.adapter") < 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;
+            }
+
+            break;
+        } 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) {
+            candidate = esxVI_HostInternetScsiTargetTransport_DynamicCast
+                          (hostScsiTopologyTarget->transport);
+
+            if (candidate != NULL) {
+                /* iterate hostScsiTopologyLun list to find matching key */
+                for (hostScsiTopologyLun = hostScsiTopologyTarget->lun;
+                     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;
+}
+
+
 
 #define ESX_VI__TEMPLATE__PROPERTY__CAST_FROM_ANY_TYPE_IGNORE(_name)          \
     if (STREQ(dynamicProperty->name, #_name)) {                               \
index d7895a0013485e9f6066b9b7379635a3f02f5957..a121d1caa00ef85d974ea2596c531df6f8feb6eb 100644 (file)
@@ -526,7 +526,25 @@ int esxVI_WaitForTaskCompletion(esxVI_Context *ctx,
 int esxVI_ParseHostCpuIdInfo(esxVI_ParsedHostCpuIdInfo *parsedHostCpuIdInfo,
                              esxVI_HostCpuIdInfo *hostCpuIdInfo);
 
-int esxVI_ProductVersionToDefaultVirtualHWVersion(esxVI_ProductVersion productVersion);
+int esxVI_ProductVersionToDefaultVirtualHWVersion
+      (esxVI_ProductVersion productVersion);
+
+int esxVI_LookupHostInternetScsiHbaStaticTargetByName
+      (esxVI_Context *ctx, const char *name,
+       esxVI_HostInternetScsiHbaStaticTarget **target,
+       esxVI_Occurrence occurrence);
+
+int esxVI_LookupHostInternetScsiHba
+      (esxVI_Context *ctx, esxVI_HostInternetScsiHba **hostInternetScsiHba);
+
+int esxVI_LookupScsiLunList(esxVI_Context *ctx, esxVI_ScsiLun **scsiLunList);
+
+int esxVI_LookupHostScsiTopologyLunListByTargetName
+      (esxVI_Context *ctx, const char *name,
+       esxVI_HostScsiTopologyLun **hostScsiTopologyLunList);
+
+int esxVI_LookupStoragePoolNameByScsiLunKey(esxVI_Context *ctx, const char *key,
+                                            char **poolName);
 
 # include "esx_vi.generated.h"
 
index c4a3e56998005b222056e81ed3a115a9d46e5f1e..22c114e0aac372199eb9df73eb4c201b2a81068e 100644 (file)
@@ -58,6 +58,14 @@ enum AutoStartWaitHeartbeatSetting
 end
 
 
+enum FibreChannelPortType
+    fabric
+    loop
+    pointToPoint
+    unknown
+end
+
+
 enum ManagedEntityStatus
     gray
     green
@@ -144,6 +152,9 @@ object AboutInfo
     String                                   productLineId                  r
     String                                   apiType                        r
     String                                   apiVersion                     r
+    String                                   instanceUuid                   o
+    String                                   licenseProductName             o
+    String                                   licenseProductVersion          o
 end
 
 
@@ -184,6 +195,7 @@ object DatastoreInfo
     String                                   url                            r
     Long                                     freeSpace                      r
     Long                                     maxFileSize                    r
+    DateTime                                 timestamp                      o
 end
 
 
@@ -218,6 +230,12 @@ object EventArgument
 end
 
 
+object ExtendedElementDescription    extends ElementDescription
+    String                                   messageCatalogKeyPrefix        r
+    KeyAnyValue                              messageArg                     ol
+end
+
+
 object FileBackedVirtualDiskSpec     extends VirtualDiskSpec
     Long                                     capacityKb                     r
 end
@@ -227,6 +245,7 @@ object FileInfo
     String                                   path                           r
     Long                                     fileSize                       o
     DateTime                                 modification                   o
+    String                                   owner                          o
 end
 
 
@@ -238,6 +257,7 @@ object FileQueryFlags
     Boolean                                  fileType                       r
     Boolean                                  fileSize                       r
     Boolean                                  modification                   r
+    Boolean                                  fileOwner                      o
 end
 
 
@@ -263,6 +283,14 @@ object HostAutoStartManagerConfig
 end
 
 
+object HostBlockAdapterTargetTransport extends HostTargetTransport
+end
+
+
+object HostBlockHba                  extends HostHostBusAdapter
+end
+
+
 object HostConfigManager
     ManagedObjectReference                   cpuScheduler                   o
     ManagedObjectReference                   datastoreSystem                o
@@ -270,6 +298,7 @@ object HostConfigManager
     ManagedObjectReference                   storageSystem                  o
     ManagedObjectReference                   networkSystem                  o
     ManagedObjectReference                   vmotionSystem                  o
+    ManagedObjectReference                   virtualNicManager              o
     ManagedObjectReference                   serviceSystem                  o
     ManagedObjectReference                   firewallSystem                 o
     ManagedObjectReference                   advancedOption                 o
@@ -281,6 +310,9 @@ object HostConfigManager
     ManagedObjectReference                   bootDeviceSystem               o
     ManagedObjectReference                   firmwareSystem                 o
     ManagedObjectReference                   healthStatusSystem             o
+    ManagedObjectReference                   pciPassthruSystem              o
+    ManagedObjectReference                   licenseManager                 o
+    ManagedObjectReference                   kernelModuleSystem             o
 end
 
 
@@ -310,6 +342,32 @@ object HostDatastoreBrowserSearchSpec
 end
 
 
+object HostDevice
+    String                                   deviceName                     r
+    String                                   deviceType                     r
+end
+
+
+object HostDiskDimensionsLba
+    Int                                      blockSize                      r
+    Long                                     block                          r
+end
+
+
+object HostFibreChannelHba           extends HostHostBusAdapter
+    Long                                     portWorldWideName              r
+    Long                                     nodeWorldWideName              r
+    FibreChannelPortType                     portType                       r
+    Long                                     speed                          r
+end
+
+
+object HostFibreChannelTargetTransport extends HostTargetTransport
+    Long                                     portWorldWideName              r
+    Long                                     nodeWorldWideName              r
+end
+
+
 object HostFileSystemVolume
     String                                   type                           r
     String                                   name                           r
@@ -317,10 +375,169 @@ object HostFileSystemVolume
 end
 
 
+object HostHostBusAdapter
+    String                                   key                            o
+    String                                   device                         r
+    Int                                      bus                            r
+    String                                   status                         r
+    String                                   model                          r
+    String                                   driver                         o
+    String                                   pci                            o
+end
+
+
+object HostInternetScsiHba           extends HostHostBusAdapter
+    Boolean                                  isSoftwareBased                r
+    HostInternetScsiHbaDiscoveryCapabilities discoveryCapabilities          r
+    HostInternetScsiHbaDiscoveryProperties   discoveryProperties            r
+    HostInternetScsiHbaAuthenticationCapabilities authenticationCapabilities r
+    HostInternetScsiHbaAuthenticationProperties authenticationProperties    r
+    HostInternetScsiHbaDigestCapabilities    digestCapabilities             o
+    HostInternetScsiHbaDigestProperties      digestProperties               o
+    HostInternetScsiHbaIPCapabilities        ipCapabilities                 r
+    HostInternetScsiHbaIPProperties          ipProperties                   r
+    OptionDef                                supportedAdvancedOptions       i
+    HostInternetScsiHbaParamValue            advancedOptions                ol
+    String                                   iScsiName                      r
+    String                                   iScsiAlias                     o
+    HostInternetScsiHbaSendTarget            configuredSendTarget           ol
+    HostInternetScsiHbaStaticTarget          configuredStaticTarget         ol
+    Int                                      maxSpeedMb                     o
+    Int                                      currentSpeedMb                 o
+end
+
+
+object HostInternetScsiHbaAuthenticationCapabilities
+    Boolean                                  chapAuthSettable               r
+    Boolean                                  krb5AuthSettable               r
+    Boolean                                  srpAuthSettable                r
+    Boolean                                  spkmAuthSettable               r
+    Boolean                                  mutualChapSettable             o
+    Boolean                                  targetChapSettable             o
+    Boolean                                  targetMutualChapSettable       o
+end
+
+
+object HostInternetScsiHbaAuthenticationProperties
+    Boolean                                  chapAuthEnabled                r
+    String                                   chapName                       o
+    String                                   chapSecret                     o
+    String                                   chapAuthenticationType         o
+    Boolean                                  chapInherited                  o
+    String                                   mutualChapName                 o
+    String                                   mutualChapSecret               o
+    String                                   mutualChapAuthenticationType   o
+    Boolean                                  mutualChapInherited            o
+end
+
+
+object HostInternetScsiHbaDigestCapabilities
+    Boolean                                  headerDigestSettable           o
+    Boolean                                  dataDigestSettable             o
+    Boolean                                  targetHeaderDigestSettable     o
+    Boolean                                  targetDataDigestSettable       o
+end
+
+
+object HostInternetScsiHbaDigestProperties
+    String                                   headerDigestType               o
+    Boolean                                  headerDigestInherited          o
+    String                                   dataDigestType                 o
+    Boolean                                  dataDigestInherited            o
+end
+
+
+object HostInternetScsiHbaDiscoveryCapabilities
+    Boolean                                  iSnsDiscoverySettable          r
+    Boolean                                  slpDiscoverySettable           r
+    Boolean                                  staticTargetDiscoverySettable  r
+    Boolean                                  sendTargetsDiscoverySettable   r
+end
+
+
+object HostInternetScsiHbaDiscoveryProperties
+    Boolean                                  iSnsDiscoveryEnabled           r
+    String                                   iSnsDiscoveryMethod            o
+    String                                   iSnsHost                       o
+    Boolean                                  slpDiscoveryEnabled            r
+    String                                   slpDiscoveryMethod             o
+    String                                   slpHost                        o
+    Boolean                                  staticTargetDiscoveryEnabled   r
+    Boolean                                  sendTargetsDiscoveryEnabled    r
+end
+
+
+object HostInternetScsiHbaIPCapabilities
+    Boolean                                  addressSettable                r
+    Boolean                                  ipConfigurationMethodSettable  r
+    Boolean                                  subnetMaskSettable             r
+    Boolean                                  defaultGatewaySettable         r
+    Boolean                                  primaryDnsServerAddressSettable r
+    Boolean                                  alternateDnsServerAddressSettable r
+    Boolean                                  ipv6Supported                  o
+    Boolean                                  arpRedirectSettable            o
+    Boolean                                  mtuSettable                    o
+    Boolean                                  hostNameAsTargetAddress        o
+end
+
+
+object HostInternetScsiHbaIPProperties
+    String                                   mac                            o
+    String                                   address                        o
+    Boolean                                  dhcpConfigurationEnabled       r
+    String                                   subnetMask                     o
+    String                                   defaultGateway                 o
+    String                                   primaryDnsServerAddress        o
+    String                                   alternateDnsServerAddress      o
+    String                                   ipv6Address                    o
+    String                                   ipv6SubnetMask                 o
+    String                                   ipv6DefaultGateway             o
+    Boolean                                  arpRedirectEnabled             o
+    Int                                      mtu                            o
+    Boolean                                  jumboFramesEnabled             o
+end
+
+
+object HostInternetScsiHbaParamValue extends OptionValue
+    Boolean                                  isInherited                    o
+end
+
+
+object HostInternetScsiHbaSendTarget
+    String                                   address                        r
+    Int                                      port                           o
+    HostInternetScsiHbaAuthenticationProperties authenticationProperties    o
+    HostInternetScsiHbaDigestProperties      digestProperties               o
+    OptionDef                                supportedAdvancedOptions       i
+    HostInternetScsiHbaParamValue            advancedOptions                ol
+    String                                   parent                         o
+end
+
+
+object HostInternetScsiHbaStaticTarget
+    String                                   address                        r
+    Int                                      port                           o
+    String                                   iScsiName                      r
+    HostInternetScsiHbaAuthenticationProperties authenticationProperties    o
+    HostInternetScsiHbaDigestProperties      digestProperties               o
+    OptionDef                                supportedAdvancedOptions       i
+    HostInternetScsiHbaParamValue            advancedOptions                ol
+    String                                   parent                         o
+end
+
+
+object HostInternetScsiTargetTransport extends HostTargetTransport
+    String                                   iScsiName                      r
+    String                                   iScsiAlias                     r
+    String                                   address                        ol
+end
+
+
 object HostIpConfig
     Boolean                                  dhcp                           r
     String                                   ipAddress                      o
     String                                   subnetMask                     o
+    HostIpConfigIpV6AddressConfiguration     ipV6Config                     i
 end
 
 
@@ -395,6 +612,14 @@ object HostNicTeamingPolicy
 end
 
 
+object HostParallelScsiHba           extends HostHostBusAdapter
+end
+
+
+object HostParallelScsiTargetTransport extends HostTargetTransport
+end
+
+
 object HostPortGroup
     String                                   key                            o
     HostPortGroupPort                        port                           ol
@@ -419,12 +644,44 @@ object HostPortGroupSpec
 end
 
 
+object HostScsiDisk                  extends ScsiLun
+    HostDiskDimensionsLba                    capacity                       r
+    String                                   devicePath                     r
+end
+
+
 object HostScsiDiskPartition
     String                                   diskName                       r
     Int                                      partition                      r
 end
 
 
+object HostScsiTopologyInterface
+    String                                   key                            r
+    String                                   adapter                        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
     String                                   key                            r
@@ -450,6 +707,7 @@ end
 object HostVirtualSwitchBondBridge   extends HostVirtualSwitchBridge
     String                                   nicDevice                      rl
     HostVirtualSwitchBeaconConfig            beacon                         o
+    LinkDiscoveryProtocolConfig              linkDiscoveryProtocolConfig    i
 end
 
 
@@ -478,6 +736,7 @@ object HostVmfsVolume                extends HostFileSystemVolume
     String                                   uuid                           r
     HostScsiDiskPartition                    extent                         rl
     Boolean                                  vmfsUpgradable                 r
+    HostForceMountedInfo                     forceMountedInfo               i
 end
 
 
@@ -489,6 +748,12 @@ object IsoImageFileQuery             extends FileQuery
 end
 
 
+object KeyAnyValue
+    String                                   key                            r
+    AnyType                                  value                          r
+end
+
+
 object LocalDatastoreInfo            extends DatastoreInfo
     String                                   path                           o
 end
@@ -532,6 +797,12 @@ object OptionType
 end
 
 
+object OptionValue
+    String                                   key                            r
+    AnyType                                  value                          o
+end
+
+
 object PerfCounterInfo
     Int                                      key                            r
     ElementDescription                       nameInfo                       r
@@ -659,6 +930,45 @@ object ResourcePoolResourceUsage
 end
 
 
+object ScsiLun                       extends HostDevice
+    String                                   key                            o
+    String                                   uuid                           r
+    ScsiLunDescriptor                        descriptor                     ol
+    String                                   canonicalName                  o
+    String                                   displayName                    o
+    String                                   lunType                        r
+    String                                   vendor                         o
+    String                                   model                          o
+    String                                   revision                       o
+    Int                                      scsiLevel                      o
+    String                                   serialNumber                   o
+    ScsiLunDurableName                       durableName                    o
+    ScsiLunDurableName                       alternateName                  ol
+    Byte                                     standardInquiry                ol
+    Int                                      queueDepth                     o
+    String                                   operationalState               rl
+    ScsiLunCapabilities                      capabilities                   o
+end
+
+
+object ScsiLunCapabilities
+    Boolean                                  updateDisplayNameSupported     r
+end
+
+
+object ScsiLunDescriptor
+    String                                   quality                        r
+    String                                   id                             r
+end
+
+
+object ScsiLunDurableName
+    String                                   namespace                      r
+    Byte                                     namespaceId                    r
+    Byte                                     data                           ol
+end
+
+
 object SelectionSpec
     String                                   name                           o
 end
@@ -688,6 +998,16 @@ object ServiceContent
     ManagedObjectReference                   fileManager                    o
     ManagedObjectReference                   virtualDiskManager             o
     ManagedObjectReference                   virtualizationManager          o
+    ManagedObjectReference                   snmpSystem                     o
+    ManagedObjectReference                   vmProvisioningChecker          o
+    ManagedObjectReference                   vmCompatibilityChecker         o
+    ManagedObjectReference                   ovfManager                     o
+    ManagedObjectReference                   ipPoolManager                  o
+    ManagedObjectReference                   dvSwitchManager                o
+    ManagedObjectReference                   hostProfileManager             o
+    ManagedObjectReference                   clusterProfileManager          o
+    ManagedObjectReference                   complianceManager              o
+    ManagedObjectReference                   localizationManager            o
 end
 
 
@@ -700,6 +1020,7 @@ end
 object TaskInfo
     String                                   key                            r
     ManagedObjectReference                   task                           r
+    LocalizableMessage                       description                    i
     String                                   name                           o
     String                                   descriptionId                  r
     ManagedObjectReference                   entity                         o
@@ -716,6 +1037,9 @@ object TaskInfo
     DateTime                                 startTime                      o
     DateTime                                 completeTime                   o
     Int                                      eventChainId                   r
+    String                                   changeTag                      o
+    String                                   parentTaskKey                  o
+    String                                   rootTaskKey                    o
 end
 
 
@@ -763,9 +1087,14 @@ object VirtualMachineConfigSpec
     String                                   name                           o
     String                                   version                        o
     String                                   uuid                           o
+    String                                   instanceUuid                   o
     Long                                     npivNodeWorldWideName          ol
     Long                                     npivPortWorldWideName          ol
     String                                   npivWorldWideNameType          o
+    Short                                    npivDesiredNodeWwns            i
+    Short                                    npivDesiredPortWwns            i
+    Boolean                                  npivTemporaryDisabled          o
+    Boolean                                  npivOnNonRdmDisks              o
     String                                   npivWorldWideNameOp            o
     String                                   locationId                     o
     String                                   guestId                        o
@@ -778,6 +1107,9 @@ object VirtualMachineConfigSpec
     VirtualMachineDefaultPowerOpInfo         powerOpInfo                    i
     Int                                      numCPUs                        o
     Long                                     memoryMB                       o
+    Boolean                                  memoryHotAddEnabled            o
+    Boolean                                  cpuHotAddEnabled               o
+    Boolean                                  cpuHotRemoveEnabled            o
     VirtualDeviceConfigSpec                  deviceChange                   i
     ResourceAllocationInfo                   cpuAllocation                  o
     ResourceAllocationInfo                   memoryAllocation               o
@@ -788,6 +1120,11 @@ object VirtualMachineConfigSpec
     OptionValue                              extraConfig                    i
     String                                   swapPlacement                  o
     VirtualMachineBootOptions                bootOptions                    i
+    VmConfigSpec                             vAppConfig                     i
+    FaultToleranceConfigInfo                 ftInfo                         i
+    Boolean                                  vAppConfigRemoved              o
+    Boolean                                  vAssertsEnabled                o
+    Boolean                                  changeTrackingEnabled          o
 end
 
 
@@ -804,10 +1141,13 @@ object VirtualMachineSnapshotTree
     ManagedObjectReference                   vm                             r
     String                                   name                           r
     String                                   description                    r
+    Int                                      id                             o
     DateTime                                 createTime                     r
     VirtualMachinePowerState                 state                          r
     Boolean                                  quiesced                       r
+    String                                   backupManifest                 o
     VirtualMachineSnapshotTree               childSnapshotList              ol
+    Boolean                                  replaySupported                o
 end
 
 
@@ -838,6 +1178,7 @@ object VmDiskFileInfo                extends FileInfo
     Int                                      hardwareVersion                o
     String                                   controllerType                 o
     String                                   diskExtents                    ol
+    Boolean                                  thin                           o
 end
 
 
@@ -851,6 +1192,7 @@ object VmDiskFileQueryFilter
     String                                   diskType                       ol
     Int                                      matchHardwareVersion           ol
     String                                   controllerType                 ol
+    Boolean                                  thin                           o
 end
 
 
@@ -860,6 +1202,7 @@ object VmDiskFileQueryFlags
     Boolean                                  hardwareVersion                r
     Boolean                                  controllerType                 o
     Boolean                                  diskExtents                    o
+    Boolean                                  thin                           o
 end
 
 
@@ -1016,6 +1359,7 @@ method FindByUuid                    returns ManagedObjectReference         o
     ManagedObjectReference                   datacenter                     o
     String                                   uuid                           r
     Boolean                                  vmSearch                       r
+    Boolean                                  instanceUuid                   o
 end
 
 
@@ -1138,6 +1482,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
@@ -1147,6 +1497,7 @@ end
 method RevertToSnapshot_Task         returns ManagedObjectReference         r
     ManagedObjectReference                   _this                          r
     ManagedObjectReference                   host                           o
+    Boolean                                  suppressPowerOn                o
 end
 
 
index 2883ac0d97cd248c86a4afc8173a03975b4b99fd..af4e7e8abec7d8b35d4dbae8edd30111cd501ce3 100755 (executable)
@@ -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 |