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
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 \
}
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,
--- /dev/null
+
+/*
+ * 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 */
+};
--- /dev/null
+
+/*
+ * 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__ */
#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
};
*
* 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);
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;
}
+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)) { \
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"
end
+enum FibreChannelPortType
+ fabric
+ loop
+ pointToPoint
+ unknown
+end
+
+
enum ManagedEntityStatus
gray
green
String productLineId r
String apiType r
String apiVersion r
+ String instanceUuid o
+ String licenseProductName o
+ String licenseProductVersion o
end
String url r
Long freeSpace r
Long maxFileSize r
+ DateTime timestamp o
end
end
+object ExtendedElementDescription extends ElementDescription
+ String messageCatalogKeyPrefix r
+ KeyAnyValue messageArg ol
+end
+
+
object FileBackedVirtualDiskSpec extends VirtualDiskSpec
Long capacityKb r
end
String path r
Long fileSize o
DateTime modification o
+ String owner o
end
Boolean fileType r
Boolean fileSize r
Boolean modification r
+ Boolean fileOwner o
end
end
+object HostBlockAdapterTargetTransport extends HostTargetTransport
+end
+
+
+object HostBlockHba extends HostHostBusAdapter
+end
+
+
object HostConfigManager
ManagedObjectReference cpuScheduler o
ManagedObjectReference datastoreSystem o
ManagedObjectReference storageSystem o
ManagedObjectReference networkSystem o
ManagedObjectReference vmotionSystem o
+ ManagedObjectReference virtualNicManager o
ManagedObjectReference serviceSystem o
ManagedObjectReference firewallSystem o
ManagedObjectReference advancedOption o
ManagedObjectReference bootDeviceSystem o
ManagedObjectReference firmwareSystem o
ManagedObjectReference healthStatusSystem o
+ ManagedObjectReference pciPassthruSystem o
+ ManagedObjectReference licenseManager o
+ ManagedObjectReference kernelModuleSystem o
end
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
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
end
+object HostParallelScsiHba extends HostHostBusAdapter
+end
+
+
+object HostParallelScsiTargetTransport extends HostTargetTransport
+end
+
+
object HostPortGroup
String key o
HostPortGroupPort port ol
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
object HostVirtualSwitchBondBridge extends HostVirtualSwitchBridge
String nicDevice rl
HostVirtualSwitchBeaconConfig beacon o
+ LinkDiscoveryProtocolConfig linkDiscoveryProtocolConfig i
end
String uuid r
HostScsiDiskPartition extent rl
Boolean vmfsUpgradable r
+ HostForceMountedInfo forceMountedInfo i
end
end
+object KeyAnyValue
+ String key r
+ AnyType value r
+end
+
+
object LocalDatastoreInfo extends DatastoreInfo
String path o
end
end
+object OptionValue
+ String key r
+ AnyType value o
+end
+
+
object PerfCounterInfo
Int key r
ElementDescription nameInfo r
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
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
object TaskInfo
String key r
ManagedObjectReference task r
+ LocalizableMessage description i
String name o
String descriptionId r
ManagedObjectReference entity o
DateTime startTime o
DateTime completeTime o
Int eventChainId r
+ String changeTag o
+ String parentTaskKey o
+ String rootTaskKey o
end
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
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
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
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
Int hardwareVersion o
String controllerType o
String diskExtents ol
+ Boolean thin o
end
String diskType ol
Int matchHardwareVersion ol
String controllerType ol
+ Boolean thin o
end
Boolean hardwareVersion r
Boolean controllerType o
Boolean diskExtents o
+ Boolean thin o
end
ManagedObjectReference datacenter o
String uuid r
Boolean vmSearch r
+ Boolean instanceUuid o
end
end
+method RescanHba
+ ManagedObjectReference _this r
+ String hbaDevice r
+end
+
+
method RetrieveProperties returns ObjectContent ol
ManagedObjectReference _this:propertyCollector r
PropertyFilterSpec specSet rl
method RevertToSnapshot_Task returns ManagedObjectReference r
ManagedObjectReference _this r
ManagedObjectReference host o
+ Boolean suppressPowerOn o
end
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 |
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 |