ESX Add esxNodeGetFreeMemory()

* src/esx/esx_driver.c: add esxNodeGetFreeMemory(), cache IP address
* src/esx/esx_vi.[ch]: refactor resource pool query into esxVI_GetResourcePool()
* src/esx/esx_vi_types.[ch]: bind VI type ResourcePoolResourceUsage
This commit is contained in:
Matthias Bolte 2009-09-23 14:09:44 +02:00 committed by Daniel Veillard
parent b92587bc56
commit ecd93b7541
5 changed files with 277 additions and 84 deletions

View File

@ -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 */

View File

@ -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;
}

View File

@ -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,

View File

@ -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
*/

View File

@ -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
*/