diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index 1ef894f42a..aac41ba5af 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -139,7 +139,8 @@ static virDrvOpenStatus esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) { esxPrivate *priv = NULL; - char ipAddress[NI_MAXHOST] = ""; + char hostIpAddress[NI_MAXHOST] = ""; + char vCenterIpAddress[NI_MAXHOST] = ""; char *url = NULL; char *vCenter = NULL; int noVerify = 0; // boolean @@ -189,13 +190,13 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) goto failure; } - if (esxUtil_ResolveHostname(conn, conn->uri->server, ipAddress, + if (esxUtil_ResolveHostname(conn, conn->uri->server, hostIpAddress, NI_MAXHOST) < 0) { goto failure; } if (vCenter != NULL && - esxUtil_ResolveHostname(conn, vCenter, ipAddress, + esxUtil_ResolveHostname(conn, vCenter, vCenterIpAddress, NI_MAXHOST) < 0) { goto failure; } @@ -256,8 +257,8 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) goto failure; } - if (esxVI_Context_Connect(conn, priv->host, url, username, - password, noVerify) < 0) { + if (esxVI_Context_Connect(conn, priv->host, url, hostIpAddress, + username, password, noVerify) < 0) { goto failure; } @@ -309,8 +310,9 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) goto failure; } - if (esxVI_Context_Connect(conn, priv->vCenter, url, username, - password, noVerify) < 0) { + if (esxVI_Context_Connect(conn, priv->vCenter, url, + vCenterIpAddress, username, password, + noVerify) < 0) { goto failure; } @@ -2835,9 +2837,6 @@ esxDomainMigratePerform(virDomainPtr domain, esxVI_ObjectContent *virtualMachine = NULL; esxVI_String *propertyNameList = NULL; esxVI_ObjectContent *hostSystem = NULL; - esxVI_DynamicProperty *dynamicProperty = NULL; - esxVI_ManagedObjectReference *managedObjectReference = NULL; - esxVI_ObjectContent *computeResource = NULL; esxVI_ManagedObjectReference *resourcePool = NULL; esxVI_Event *eventList = NULL; esxVI_ManagedObjectReference *task = NULL; @@ -2887,69 +2886,13 @@ esxDomainMigratePerform(virDomainPtr domain, if (esxVI_String_AppendValueToList(domain->conn, &propertyNameList, "parent") < 0 || - esxVI_LookupHostSystemByIp(domain->conn, priv->vCenter, - hostIpAddress, propertyNameList, - &hostSystem) < 0) { + esxVI_LookupHostSystemByIp(domain->conn, priv->vCenter, hostIpAddress, + propertyNameList, &hostSystem) < 0) { goto failure; } - for (dynamicProperty = hostSystem->propSet; dynamicProperty != NULL; - dynamicProperty = dynamicProperty->_next) { - if (STREQ(dynamicProperty->name, "parent")) { - if (esxVI_ManagedObjectReference_CastFromAnyType - (domain->conn, dynamicProperty->val, &managedObjectReference, - "ComputeResource") < 0) { - goto failure; - } - - break; - } else { - VIR_WARN("Unexpected '%s' property", dynamicProperty->name); - } - } - - if (managedObjectReference == NULL) { - ESX_ERROR(domain->conn, VIR_ERR_INTERNAL_ERROR, - "Could not retrieve compute resource of host system"); - goto failure; - } - - esxVI_String_Free(&propertyNameList); - - if (esxVI_String_AppendValueToList(domain->conn, &propertyNameList, - "resourcePool") < 0 || - esxVI_GetObjectContent(domain->conn, priv->vCenter, - managedObjectReference, "ComputeResource", - propertyNameList, esxVI_Boolean_False, - &computeResource) < 0) { - goto failure; - } - - if (computeResource == NULL) { - ESX_ERROR(domain->conn, VIR_ERR_INTERNAL_ERROR, - "Could not retrieve compute resource of host system"); - goto failure; - } - - for (dynamicProperty = computeResource->propSet; dynamicProperty != NULL; - dynamicProperty = dynamicProperty->_next) { - if (STREQ(dynamicProperty->name, "resourcePool")) { - if (esxVI_ManagedObjectReference_CastFromAnyType - (domain->conn, dynamicProperty->val, &resourcePool, - "ResourcePool") < 0) { - goto failure; - } - - break; - } else { - VIR_WARN("Unexpected '%s' property", dynamicProperty->name); - } - } - - if (resourcePool == NULL) { - ESX_ERROR(domain->conn, VIR_ERR_INTERNAL_ERROR, - "Could not retrieve resource pool of compute resource of " - "host system"); + if (esxVI_GetResourcePool(domain->conn, priv->vCenter, hostSystem, + &resourcePool) < 0) { goto failure; } @@ -3000,8 +2943,6 @@ esxDomainMigratePerform(virDomainPtr domain, esxVI_ObjectContent_Free(&virtualMachine); esxVI_String_Free(&propertyNameList); esxVI_ObjectContent_Free(&hostSystem); - esxVI_ManagedObjectReference_Free(&managedObjectReference); - esxVI_ObjectContent_Free(&computeResource); esxVI_ManagedObjectReference_Free(&resourcePool); esxVI_Event_Free(&eventList); esxVI_ManagedObjectReference_Free(&task); @@ -3028,6 +2969,91 @@ esxDomainMigrateFinish(virConnectPtr dconn, const char *dname, +static unsigned long long +esxNodeGetFreeMemory(virConnectPtr conn) +{ + unsigned long long result = 0; + esxPrivate *priv = (esxPrivate *)conn->privateData; + esxVI_String *propertyNameList = NULL; + esxVI_ObjectContent *hostSystem = NULL; + esxVI_ManagedObjectReference *managedObjectReference = NULL; + esxVI_ObjectContent *resourcePool = NULL; + esxVI_DynamicProperty *dynamicProperty = NULL; + esxVI_ResourcePoolResourceUsage *resourcePoolResourceUsage = NULL; + + if (priv->phantom) { + ESX_ERROR(conn, VIR_ERR_OPERATION_INVALID, + "Not possible with a phantom connection"); + goto failure; + } + + if (esxVI_EnsureSession(conn, priv->host) < 0) { + goto failure; + } + + /* Lookup host system with its resource pool */ + if (esxVI_String_AppendValueToList(conn, &propertyNameList, "parent") < 0 || + esxVI_LookupHostSystemByIp(conn, priv->host, priv->host->ipAddress, + propertyNameList, &hostSystem) < 0) { + goto failure; + } + + if (esxVI_GetResourcePool(conn, priv->host, hostSystem, + &managedObjectReference) < 0) { + goto failure; + } + + esxVI_String_Free(&propertyNameList); + + /* Get memory usage of resource pool */ + if (esxVI_String_AppendValueToList(conn, &propertyNameList, + "runtime.memory") < 0 || + esxVI_GetObjectContent(conn, priv->host, managedObjectReference, + "ResourcePool", propertyNameList, + esxVI_Boolean_False, &resourcePool) < 0) { + goto failure; + } + + for (dynamicProperty = resourcePool->propSet; dynamicProperty != NULL; + dynamicProperty = dynamicProperty->_next) { + if (STREQ(dynamicProperty->name, "runtime.memory")) { + if (esxVI_ResourcePoolResourceUsage_CastFromAnyType + (conn, dynamicProperty->val, + &resourcePoolResourceUsage) < 0) { + goto failure; + } + + break; + } else { + VIR_WARN("Unexpected '%s' property", dynamicProperty->name); + } + } + + if (resourcePoolResourceUsage == NULL) { + ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR, + "Could not retrieve memory usage of resource pool"); + goto failure; + } + + result = resourcePoolResourceUsage->unreservedForVm->value; + + cleanup: + esxVI_String_Free(&propertyNameList); + esxVI_ObjectContent_Free(&hostSystem); + esxVI_ManagedObjectReference_Free(&managedObjectReference); + esxVI_ObjectContent_Free(&resourcePool); + esxVI_ResourcePoolResourceUsage_Free(&resourcePoolResourceUsage); + + return result; + + failure: + result = 0; + + goto cleanup; +} + + + static virDriver esxDriver = { VIR_DRV_ESX, "ESX", @@ -3088,7 +3114,7 @@ static virDriver esxDriver = { NULL, /* domainBlockPeek */ NULL, /* domainMemoryPeek */ NULL, /* nodeGetCellsFreeMemory */ - NULL, /* nodeGetFreeMemory */ + esxNodeGetFreeMemory, /* nodeGetFreeMemory */ NULL, /* domainEventRegister */ NULL, /* domainEventDeregister */ NULL, /* domainMigratePrepare2 */ diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c index a77cfda358..29443dbf8e 100644 --- a/src/esx/esx_vi.c +++ b/src/esx/esx_vi.c @@ -115,6 +115,7 @@ ESX_VI__TEMPLATE__ALLOC(Context); ESX_VI__TEMPLATE__FREE(Context, { VIR_FREE(item->url); + VIR_FREE(item->ipAddress); if (item->curl_handle != NULL) { curl_easy_cleanup(item->curl_handle); @@ -189,21 +190,23 @@ _esxVI_CURL_Debug(CURL *curl ATTRIBUTE_UNUSED, curl_infotype type, int esxVI_Context_Connect(virConnectPtr conn, esxVI_Context *ctx, const char *url, - const char *username, const char *password, int noVerify) + const char *ipAddress, const char *username, + const char *password, int noVerify) { int result = 0; esxVI_String *propertyNameList = NULL; esxVI_ObjectContent *datacenterList = NULL; esxVI_DynamicProperty *dynamicProperty = NULL; - if (ctx == NULL || url == NULL || username == NULL || password == NULL || - ctx->url != NULL || ctx->service != NULL || ctx->curl_handle != NULL || - ctx->curl_headers != NULL) { + if (ctx == NULL || url == NULL || ipAddress == NULL || username == NULL || + password == NULL || ctx->url != NULL || ctx->service != NULL || + ctx->curl_handle != NULL || ctx->curl_headers != NULL) { ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument"); goto failure; } - if (esxVI_String_DeepCopyValue(conn, &ctx->url, url) < 0) { + if (esxVI_String_DeepCopyValue(conn, &ctx->url, url) < 0 || + esxVI_String_DeepCopyValue(conn, &ctx->ipAddress, ipAddress) < 0) { goto failure; } @@ -1477,9 +1480,96 @@ esxVI_GetVirtualMachineIdentity(virConnectPtr conn, +int esxVI_GetResourcePool(virConnectPtr conn, esxVI_Context *ctx, + esxVI_ObjectContent *hostSystem, + esxVI_ManagedObjectReference **resourcePool) +{ + int result = 0; + esxVI_String *propertyNameList = NULL; + esxVI_DynamicProperty *dynamicProperty = NULL; + esxVI_ManagedObjectReference *managedObjectReference = NULL; + esxVI_ObjectContent *computeResource = NULL; + + if (resourcePool == NULL || *resourcePool != NULL) { + ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument"); + return -1; + } + + for (dynamicProperty = hostSystem->propSet; dynamicProperty != NULL; + dynamicProperty = dynamicProperty->_next) { + if (STREQ(dynamicProperty->name, "parent")) { + if (esxVI_ManagedObjectReference_CastFromAnyType + (conn, dynamicProperty->val, &managedObjectReference, + "ComputeResource") < 0) { + goto failure; + } + + break; + } else { + VIR_WARN("Unexpected '%s' property", dynamicProperty->name); + } + } + + if (managedObjectReference == NULL) { + ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, + "Could not retrieve compute resource of host system"); + goto failure; + } + + if (esxVI_String_AppendValueToList(conn, &propertyNameList, + "resourcePool") < 0 || + esxVI_GetObjectContent(conn, ctx, managedObjectReference, + "ComputeResource", propertyNameList, + esxVI_Boolean_False, &computeResource) < 0) { + goto failure; + } + + if (computeResource == NULL) { + ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, + "Could not retrieve compute resource of host system"); + goto failure; + } + + for (dynamicProperty = computeResource->propSet; dynamicProperty != NULL; + dynamicProperty = dynamicProperty->_next) { + if (STREQ(dynamicProperty->name, "resourcePool")) { + if (esxVI_ManagedObjectReference_CastFromAnyType + (conn, dynamicProperty->val, resourcePool, + "ResourcePool") < 0) { + goto failure; + } + + break; + } else { + VIR_WARN("Unexpected '%s' property", dynamicProperty->name); + } + } + + if ((*resourcePool) == NULL) { + ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, + "Could not retrieve resource pool of compute resource"); + goto failure; + } + + cleanup: + esxVI_String_Free(&propertyNameList); + esxVI_ManagedObjectReference_Free(&managedObjectReference); + esxVI_ObjectContent_Free(&computeResource); + + return result; + + failure: + result = -1; + + goto cleanup; +} + + + int esxVI_LookupHostSystemByIp(virConnectPtr conn, esxVI_Context *ctx, - const char *ip, esxVI_String *propertyNameList, + const char *ipAddress, + esxVI_String *propertyNameList, esxVI_ObjectContent **hostSystem) { int result = 0; @@ -1490,8 +1580,8 @@ esxVI_LookupHostSystemByIp(virConnectPtr conn, esxVI_Context *ctx, return -1; } - if (esxVI_FindByIp(conn, ctx, ctx->datacenter, ip, esxVI_Boolean_False, - &managedObjectReference) < 0) { + if (esxVI_FindByIp(conn, ctx, ctx->datacenter, ipAddress, + esxVI_Boolean_False, &managedObjectReference) < 0) { goto failure; } diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h index e60ac7f1c1..2aeea552a3 100644 --- a/src/esx/esx_vi.h +++ b/src/esx/esx_vi.h @@ -65,6 +65,7 @@ enum _esxVI_ProductVersion { struct _esxVI_Context { char *url; + char *ipAddress; CURL *curl_handle; struct curl_slist *curl_headers; virMutex curl_lock; @@ -83,8 +84,9 @@ struct _esxVI_Context { int esxVI_Context_Alloc(virConnectPtr conn, esxVI_Context **ctx); void esxVI_Context_Free(esxVI_Context **ctx); int esxVI_Context_Connect(virConnectPtr conn, esxVI_Context *ctx, - const char *url, const char *username, - const char *password, int noVerify); + const char *ipAddress, const char *url, + const char *username, const char *password, + int noVerify); int esxVI_Context_Download(virConnectPtr conn, esxVI_Context *ctx, const char *url, char **content); int esxVI_Context_Execute(virConnectPtr conn, esxVI_Context *ctx, @@ -214,8 +216,13 @@ int esxVI_GetVirtualMachineIdentity(virConnectPtr conn, esxVI_ObjectContent *virtualMachine, int *id, char **name, unsigned char *uuid); +int esxVI_GetResourcePool(virConnectPtr conn, esxVI_Context *ctx, + esxVI_ObjectContent *hostSystem, + esxVI_ManagedObjectReference **resourcePool); + int esxVI_LookupHostSystemByIp(virConnectPtr conn, esxVI_Context *ctx, - const char *ip, esxVI_String *propertyNameList, + const char *ipAddress, + esxVI_String *propertyNameList, esxVI_ObjectContent **hostSystem); int esxVI_LookupVirtualMachineByUuid(virConnectPtr conn, esxVI_Context *ctx, diff --git a/src/esx/esx_vi_types.c b/src/esx/esx_vi_types.c index 68b7994742..1c6e112b74 100644 --- a/src/esx/esx_vi_types.c +++ b/src/esx/esx_vi_types.c @@ -2164,6 +2164,48 @@ ESX_VI__TEMPLATE__SERIALIZE(ResourceAllocationInfo, +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * VI Type: ResourcePoolResourceUsage + */ + +/* esxVI_ResourcePoolResourceUsage_Alloc */ +ESX_VI__TEMPLATE__ALLOC(ResourcePoolResourceUsage); + +/* esxVI_ResourcePoolResourceUsage_Free */ +ESX_VI__TEMPLATE__FREE(ResourcePoolResourceUsage, +{ + esxVI_Long_Free(&item->reservationUsed); + esxVI_Long_Free(&item->reservationUsedForVm); + esxVI_Long_Free(&item->unreservedForPool); + esxVI_Long_Free(&item->unreservedForVm); + esxVI_Long_Free(&item->overallUsage); + esxVI_Long_Free(&item->maxUsage); +}); + +/* esxVI_ResourcePoolResourceUsage_CastFromAnyType */ +ESX_VI__TEMPLATE__CAST_FROM_ANY_TYPE(ResourcePoolResourceUsage); + +/* esxVI_ResourcePoolResourceUsage_Deserialize */ +ESX_VI__TEMPLATE__DESERIALIZE(ResourcePoolResourceUsage, +{ + ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(Long, reservationUsed); + ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(Long, reservationUsedForVm); + ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(Long, unreservedForPool); + ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(Long, unreservedForVm); + ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(Long, overallUsage); + ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(Long, maxUsage); +}, +{ + ESX_VI__TEMPLATE__PROPERTY__REQUIRED(reservationUsed); + ESX_VI__TEMPLATE__PROPERTY__REQUIRED(reservationUsedForVm); + ESX_VI__TEMPLATE__PROPERTY__REQUIRED(unreservedForPool); + ESX_VI__TEMPLATE__PROPERTY__REQUIRED(unreservedForVm); + ESX_VI__TEMPLATE__PROPERTY__REQUIRED(overallUsage); + ESX_VI__TEMPLATE__PROPERTY__REQUIRED(maxUsage); +}); + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VI Type: VirtualMachineConfigSpec */ diff --git a/src/esx/esx_vi_types.h b/src/esx/esx_vi_types.h index 2e69601e45..1599b05ea1 100644 --- a/src/esx/esx_vi_types.h +++ b/src/esx/esx_vi_types.h @@ -85,6 +85,7 @@ typedef struct _esxVI_ServiceContent esxVI_ServiceContent; typedef struct _esxVI_UpdateSet esxVI_UpdateSet; typedef struct _esxVI_SharesInfo esxVI_SharesInfo; typedef struct _esxVI_ResourceAllocationInfo esxVI_ResourceAllocationInfo; +typedef struct _esxVI_ResourcePoolResourceUsage esxVI_ResourcePoolResourceUsage; typedef struct _esxVI_VirtualMachineConfigSpec esxVI_VirtualMachineConfigSpec; typedef struct _esxVI_Event esxVI_Event; typedef struct _esxVI_UserSession esxVI_UserSession; @@ -901,6 +902,33 @@ int esxVI_ResourceAllocationInfo_Serialize +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * VI Type: ResourcePoolResourceUsage + */ + +struct _esxVI_ResourcePoolResourceUsage { + esxVI_Long *reservationUsed; /* required */ + esxVI_Long *reservationUsedForVm; /* required */ + esxVI_Long *unreservedForPool; /* required */ + esxVI_Long *unreservedForVm; /* required */ + esxVI_Long *overallUsage; /* required */ + esxVI_Long *maxUsage; /* required */ +}; + +int esxVI_ResourcePoolResourceUsage_Alloc + (virConnectPtr conn, + esxVI_ResourcePoolResourceUsage **resourcePoolResourceUsage); +void esxVI_ResourcePoolResourceUsage_Free + (esxVI_ResourcePoolResourceUsage **resourcePoolResourceUsage); +int esxVI_ResourcePoolResourceUsage_CastFromAnyType + (virConnectPtr conn, esxVI_AnyType *anyType, + esxVI_ResourcePoolResourceUsage **resourcePoolResourceUsage); +int esxVI_ResourcePoolResourceUsage_Deserialize + (virConnectPtr conn, xmlNodePtr node, + esxVI_ResourcePoolResourceUsage **resourcePoolResourceUsage); + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VI Type: VirtualMachineConfigSpec */