esx: Fix and improve esxListAllDomains function

Avoid requesting information such as identity or power state when it
is not necessary.

Lookup virtual machine list with the required fields (configStatus,
name, and config.uuid) to make esxVI_GetVirtualMachineIdentity work.

No need to call esxVI_GetNumberOfSnapshotTrees. rootSnapshotTreeList
can be tested for emptiness by checking it for NULL.

esxVI_LookupRootSnapshotTreeList already does the error reporting,
don't overwrite it.

Check if autostart is enabled at all before looking up the individual
autostart setting of a virtual machine.

Reorder VIR_EXPAND_N(doms, ndoms, 1) to avoid leaking the result of
the call to virGetDomain if VIR_EXPAND_N fails.

Replace VIR_EXPAND_N by VIR_RESIZE_N to avoid quadratic scaling, as in
the Hyper-V version of the function.

If virGetDomain fails it already reports an error, don't overwrite it
with an OOM error.

All items in doms up to the count-th one are valid, no need to double
check before freeing them.

Finally, don't leak autoStartDefaults and powerInfoList.
(cherry picked from commit 5fc663d8be)
This commit is contained in:
Matthias Bolte 2012-09-09 12:31:16 +02:00 committed by Cole Robinson
parent 6f290666dc
commit f50a9b3be1

View File

@ -5010,13 +5010,15 @@ esxListAllDomains(virConnectPtr conn,
{
int ret = -1;
esxPrivate *priv = conn->privateData;
bool needIdentity;
bool needPowerState;
virDomainPtr dom;
virDomainPtr *doms = NULL;
size_t ndoms = 0;
esxVI_String *propertyNameList = NULL;
esxVI_ObjectContent *virtualMachineList = NULL;
esxVI_ObjectContent *virtualMachine = NULL;
esxVI_String *propertyNameList = NULL;
esxVI_AutoStartDefaults *autostart_defaults = NULL;
esxVI_AutoStartDefaults *autoStartDefaults = NULL;
esxVI_VirtualMachinePowerState powerState;
esxVI_AutoStartPowerInfo *powerInfoList = NULL;
esxVI_AutoStartPowerInfo *powerInfo = NULL;
@ -5025,7 +5027,6 @@ esxListAllDomains(virConnectPtr conn,
int id;
unsigned char uuid[VIR_UUID_BUFLEN];
int count = 0;
int snapshotCount;
bool autostart;
int state;
@ -5035,7 +5036,7 @@ esxListAllDomains(virConnectPtr conn,
* - persistence: all esx machines are persistent
* - managed save: esx doesn't support managed save
*/
if ((MATCH(VIR_CONNECT_LIST_DOMAINS_TRANSIENT) &&
if ((MATCH(VIR_CONNECT_LIST_DOMAINS_TRANSIENT) &&
!MATCH(VIR_CONNECT_LIST_DOMAINS_PERSISTENT)) ||
(MATCH(VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE) &&
!MATCH(VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE))) {
@ -5047,23 +5048,49 @@ esxListAllDomains(virConnectPtr conn,
goto cleanup;
}
if (esxVI_EnsureSession(priv->primary) < 0)
if (esxVI_EnsureSession(priv->primary) < 0)
return -1;
/* check system default autostart value */
if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_AUTOSTART)) {
if (esxVI_LookupAutoStartDefaults(priv->primary,
&autostart_defaults) < 0)
&autoStartDefaults) < 0) {
goto cleanup;
}
if (esxVI_LookupAutoStartPowerInfoList(priv->primary,
&powerInfoList) < 0)
goto cleanup;
if (autoStartDefaults->enabled == esxVI_Boolean_True) {
if (esxVI_LookupAutoStartPowerInfoList(priv->primary,
&powerInfoList) < 0) {
goto cleanup;
}
}
}
if (esxVI_String_AppendValueToList(&propertyNameList,
"runtime.powerState") < 0 ||
esxVI_LookupVirtualMachineList(priv->primary, propertyNameList,
needIdentity = MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_SNAPSHOT) ||
domains != NULL;
if (needIdentity) {
/* Request required data for esxVI_GetVirtualMachineIdentity */
if (esxVI_String_AppendValueListToList(&propertyNameList,
"configStatus\0"
"name\0"
"config.uuid\0") < 0) {
goto cleanup;
}
}
needPowerState = MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE) ||
MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE) ||
domains != NULL;
if (needPowerState) {
if (esxVI_String_AppendValueToList(&propertyNameList,
"runtime.powerState") < 0) {
goto cleanup;
}
}
if (esxVI_LookupVirtualMachineList(priv->primary, propertyNameList,
&virtualMachineList) < 0)
goto cleanup;
@ -5075,12 +5102,21 @@ esxListAllDomains(virConnectPtr conn,
for (virtualMachine = virtualMachineList; virtualMachine != NULL;
virtualMachine = virtualMachine->_next) {
if (needIdentity) {
VIR_FREE(name);
VIR_FREE(name);
if (esxVI_GetVirtualMachineIdentity(virtualMachine, &id,
&name, uuid) < 0) {
goto cleanup;
}
}
if (esxVI_GetVirtualMachineIdentity(virtualMachine, &id, &name, uuid) < 0 ||
esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0)
goto cleanup;
if (needPowerState) {
if (esxVI_GetVirtualMachinePowerState(virtualMachine,
&powerState) < 0) {
goto cleanup;
}
}
/* filter by active state */
if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE) &&
@ -5092,23 +5128,17 @@ esxListAllDomains(virConnectPtr conn,
/* filter by snapshot existence */
if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_SNAPSHOT)) {
esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotTreeList);
if (esxVI_LookupRootSnapshotTreeList(priv->primary, uuid,
&rootSnapshotTreeList) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Couldn't retrieve snapshot list for "
"domain '%s'"), name);
goto cleanup;
}
snapshotCount = esxVI_GetNumberOfSnapshotTrees(rootSnapshotTreeList,
true, false);
esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotTreeList);
if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT) &&
snapshotCount > 0) ||
rootSnapshotTreeList != NULL) ||
(MATCH(VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT) &&
snapshotCount == 0)))
rootSnapshotTreeList == NULL)))
continue;
}
@ -5116,19 +5146,18 @@ esxListAllDomains(virConnectPtr conn,
if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_AUTOSTART)) {
autostart = false;
for (powerInfo = powerInfoList; powerInfo != NULL;
powerInfo = powerInfo->_next) {
if (STREQ(powerInfo->key->value, virtualMachine->obj->value)) {
if (STRCASEEQ(powerInfo->startAction, "powerOn"))
autostart = true;
if (autoStartDefaults->enabled == esxVI_Boolean_True) {
for (powerInfo = powerInfoList; powerInfo != NULL;
powerInfo = powerInfo->_next) {
if (STREQ(powerInfo->key->value, virtualMachine->obj->value)) {
if (STRCASEEQ(powerInfo->startAction, "powerOn"))
autostart = true;
break;
break;
}
}
}
autostart = autostart &&
autostart_defaults->enabled == esxVI_Boolean_True;
if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_AUTOSTART) &&
autostart) ||
(MATCH(VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART) &&
@ -5139,6 +5168,7 @@ esxListAllDomains(virConnectPtr conn,
/* filter by domain state */
if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE)) {
state = esxVI_VirtualMachinePowerState_ConvertToLibvirt(powerState);
if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_RUNNING) &&
state == VIR_DOMAIN_RUNNING) ||
(MATCH(VIR_CONNECT_LIST_DOMAINS_PAUSED) &&
@ -5158,17 +5188,18 @@ esxListAllDomains(virConnectPtr conn,
continue;
}
if (!(dom = virGetDomain(conn, name, uuid)))
if (VIR_RESIZE_N(doms, ndoms, count, 2) < 0)
goto no_memory;
if (!(dom = virGetDomain(conn, name, uuid)))
goto cleanup;
/* Only running/suspended virtual machines have an ID != -1 */
if (powerState != esxVI_VirtualMachinePowerState_PoweredOff)
dom->id = id;
else
dom->id = -1;
if (VIR_EXPAND_N(doms, ndoms, 1) < 0)
goto no_memory;
doms[count++] = dom;
}
@ -5180,14 +5211,19 @@ esxListAllDomains(virConnectPtr conn,
cleanup:
if (doms) {
for (id = 0; id < count; id++) {
if (doms[id])
virDomainFree(doms[id]);
virDomainFree(doms[id]);
}
VIR_FREE(doms);
}
VIR_FREE(doms);
VIR_FREE(name);
esxVI_AutoStartDefaults_Free(&autoStartDefaults);
esxVI_AutoStartPowerInfo_Free(&powerInfoList);
esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&virtualMachineList);
esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotTreeList);
return ret;
no_memory: