On 05/07/2010 02:02 PM, Matthias Bolte wrote:
Add VIR_STORAGE_POOL_INACCESSIBLE to denote a running but
inaccessible
storage pool. For example an NFS pool is inaccessible when the NFS
server is currently unreachable.
Add CIFS to the list of network file systems because ESX distinguishes
between NFS and CIFS.
Alter the esxVI_ProductVersion enum in a way that allows to check for
product type by masking.
Make esxVI_*_CastFromAnyType dynamically dispatched in order to handle
the DatastoreInfo type and inheriting types properly.
Allow esxVI_X_DynamicCast to be called successfully on objects with
type X. This is necessary for handling DatastoreInfo and inheriting
types properly.
This seems like a lot of things; can any of it be split into smaller
patches (perhaps one patch for dynamic dispatch, and another patch for
plugging in ESX storage pool handling)?
+static int
+esxNumberOfStoragePools(virConnectPtr conn)
+{
+ int result = 0;
+ esxPrivate *priv = conn->storagePrivateData;
+ esxVI_ObjectContent *datastoreList = NULL;
+ esxVI_ObjectContent *datastore = NULL;
+
+ if (esxVI_EnsureSession(priv->host) < 0) {
+ goto failure;
+ }
+
+ if (esxVI_LookupObjectContentByType(priv->host, priv->host->datacenter,
+ "Datastore", NULL,
esxVI_Boolean_True,
+ &datastoreList) < 0) {
+ goto failure;
+ }
+
+ for (datastore = datastoreList; datastore != NULL;
+ datastore = datastore->_next) {
+ ++result;
+ }
+
+ cleanup:
+ esxVI_ObjectContent_Free(&datastoreList);
+
+ return result;
+
+ failure:
+ result = -1;
+
+ goto cleanup;
That logic looks bad, with a goto jumping backwards. Since there is no
other goto cleanup, you might as well inline the result=-1 into the
failure paths, and have a single label. Or better yet, since
datastoreList is NULL unless esxVI_LooupObjectContentByType succeeded,
you can write this function without any gotos:
if esxVI_EnsureSession(priv->host) < 0) {
return -1;
}
...
+
+static int
+esxListStoragePools(virConnectPtr conn, char **const names, int maxnames)
+{
+ esxPrivate *priv = conn->storagePrivateData;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_DynamicProperty *dynamicProperty = NULL;
+ esxVI_ObjectContent *datastoreList = NULL;
+ esxVI_ObjectContent *datastore = NULL;
+ int count = 0;
+ int i;
+
+ if (names == NULL || maxnames < 0) {
+ ESX_ERROR(VIR_ERR_INVALID_ARG, "%s", _("Invalid
argument"));
+ return -1;
+ }
+
+ if (maxnames == 0) {
+ return 0;
+ }
+
+ if (esxVI_EnsureSession(priv->host) < 0) {
+ goto failure;
+ }
+
+ if (esxVI_String_AppendValueToList(&propertyNameList,
+ "summary.name") < 0 ||
+ esxVI_LookupObjectContentByType(priv->host, priv->host->datacenter,
+ "Datastore", propertyNameList,
+ esxVI_Boolean_True,
+ &datastoreList) < 0) {
+ goto failure;
+ }
+
+ for (datastore = datastoreList; datastore != NULL;
+ datastore = datastore->_next) {
+ for (dynamicProperty = datastore->propSet; dynamicProperty != NULL;
+ dynamicProperty = dynamicProperty->_next) {
+ if (STREQ(dynamicProperty->name, "summary.name")) {
+ if (esxVI_AnyType_ExpectType(dynamicProperty->val,
+ esxVI_Type_String) < 0) {
+ goto failure;
+ }
+
+ names[count] = strdup(dynamicProperty->val->string);
+
+ if (names[count] == NULL) {
+ virReportOOMError();
+ goto failure;
+ }
+
+ ++count;
+ break;
+ } else {
+ VIR_WARN("Unexpected '%s' property",
dynamicProperty->name);
+ }
+ }
+ }
+
+ cleanup:
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&datastoreList);
+
+ return count;
+
+ failure:
+ for (i = 0; i < count; ++i) {
+ VIR_FREE(names[i]);
+ }
+
+ count = -1;
+
+ goto cleanup;
Here, I think you need to keep one label, but think it can be written
with one instead of two, by tracking two variables instead of one:
{
int count = 0;
bool success = false;
if (something fails)
goto cleanup;
...
success = true;
cleanup:
if (!success) {
for (i = 0; i < count; ++i)
VIR_FREE(names[i]);
count = -1;
}
esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&datastoreList);
return count;
}
+
+static int
+esxStoragePoolRefresh(virStoragePoolPtr pool,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ int result = 0;
+ esxPrivate *priv = pool->conn->storagePrivateData;
+ esxVI_ObjectContent *datastore = NULL;
Is it worth a virCheckFlags() here?
+
+ if (esxVI_EnsureSession(priv->host) < 0) {
+ goto failure;
+ }
+
+ if (esxVI_LookupDatastoreByName(priv->host, pool->name, NULL, &datastore,
+ esxVI_Occurrence_RequiredItem) < 0 ||
+ esxVI_RefreshDatastore(priv->host, datastore->obj) < 0) {
+ goto failure;
+ }
+
+ cleanup:
+ esxVI_ObjectContent_Free(&datastore);
+
+ return result;
+
+ failure:
+ result = -1;
+
+ goto cleanup;
Another one of those reverse gotos that could be cleaned up.
+
+
+static char *
+esxStoragePoolGetXMLDesc(virStoragePoolPtr pool, unsigned int flags)
+{
...
+ /* See vSphere API documentation about HostDatastoreSystem
for details */
+ if ((localInfo = esxVI_LocalDatastoreInfo_DynamicCast(info)) != NULL) {
+ def.type = VIR_STORAGE_POOL_DIR;
+ def.target.path = localInfo->path;
+ } else if ((nasInfo = esxVI_NasDatastoreInfo_DynamicCast(info)) != NULL) {
+ def.type = VIR_STORAGE_POOL_NETFS;
+ def.source.host.name = nasInfo->nas->remoteHost;
+ def.source.dir = nasInfo->nas->remotePath;
+
+ if (STRCASEEQ(nasInfo->nas->type, "NFS")) {
+ def.source.format = VIR_STORAGE_POOL_NETFS_NFS;
+ } else if (STRCASEEQ(nasInfo->nas->type, "CIFS")) {
+ def.source.format = VIR_STORAGE_POOL_NETFS_CIFS;
+ } else {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Datastore has unexpected type '%s'"),
+ nasInfo->nas->type);
+ goto failure;
+ }
+ } else if ((vmfsInfo = esxVI_VmfsDatastoreInfo_DynamicCast(info)) != NULL) {
+ def.type = VIR_STORAGE_POOL_FS;
+ /* FIXME */
Details on what needs fixing?
+++ b/src/esx/esx_vi.c
@@ -1530,6 +1530,114 @@ esxVI_GetVirtualMachineQuestionInfo
@@ -2161,7 +2269,7 @@ esxVI_LookupDatastoreByName(esxVI_Context *ctx, const char *name,
esxVI_ObjectContent *candidate = NULL;
esxVI_DynamicProperty *dynamicProperty = NULL;
esxVI_Boolean accessible = esxVI_Boolean_Undefined;
- size_t offset = strlen("/vmfs/volumes/");
+ int offset = 14; /* = strlen("/vmfs/volumes/") */
Why the change from size_t to int? Although it probably doesn't affect
code.
+++ b/src/esx/esx_vi.h
@@ -98,11 +98,14 @@ enum _esxVI_APIVersion {
enum _esxVI_ProductVersion {
esxVI_ProductVersion_Undefined = 0,
- esxVI_ProductVersion_GSX20,
- esxVI_ProductVersion_ESX35,
- esxVI_ProductVersion_ESX40,
- esxVI_ProductVersion_VPX25,
- esxVI_ProductVersion_VPX40
+ esxVI_ProductVersion_GSX = 0x1000,
+ esxVI_ProductVersion_GSX20 = 0x1001,
+ esxVI_ProductVersion_ESX = 0x2000,
+ esxVI_ProductVersion_ESX35 = 0x2001,
+ esxVI_ProductVersion_ESX40 = 0x2002,
+ esxVI_ProductVersion_VPX = 0x4000,
+ esxVI_ProductVersion_VPX25 = 0x4001,
+ esxVI_ProductVersion_VPX40 = 0x4002
Is it worth documenting the convention you used here, in case someone
has to add to the enum later on?
--
Eric Blake eblake(a)redhat.com +1-801-349-2682
Libvirt virtualization library
http://libvirt.org