[libvirt] [PATCHv5 0/2] Implementation of virConnectListAllDomains() for esx and hyperv

This is the rest of the virConnectListAllDomains() that is not yet merged. I've rebased it to current upstream and bumped the version numbers. Peter Krempa (2): hyperv: Add implementation for virConnectListAllDomains() esx: Add implementation for virConnectListAllDomains() src/esx/esx_driver.c | 195 ++++++++++++++++++++++++++++++++++++++++++++ src/hyperv/hyperv_driver.c | 136 ++++++++++++++++++++++++++++++ 2 files changed, 331 insertions(+), 0 deletions(-) -- 1.7.8.6

Hyperv doesn't use the common virDomainObj implementation so this patch adds a separate implementation. This driver supports all currently added flags for filtering although some of those don't make sense with this driver (no support yet) and thus produce no output when used. --- src/hyperv/hyperv_driver.c | 136 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 136 insertions(+), 0 deletions(-) diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index 664b435..ad36e49 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -42,6 +42,7 @@ #include "hyperv_util.h" #include "hyperv_wmi.h" #include "openwsman.h" +#include "virdomainlist.h" #define VIR_FROM_THIS VIR_FROM_HYPERV @@ -1259,6 +1260,140 @@ hypervDomainManagedSaveRemove(virDomainPtr domain, unsigned int flags) } +#define MATCH(FLAG) (flags & (FLAG)) +static int +hypervListAllDomains(virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags) +{ + hypervPrivate *priv = conn->privateData; + virBuffer query = VIR_BUFFER_INITIALIZER; + Msvm_ComputerSystem *computerSystemList = NULL; + Msvm_ComputerSystem *computerSystem = NULL; + size_t ndoms; + virDomainPtr domain; + virDomainPtr *doms = NULL; + int count = 0; + int ret = -1; + int i; + + virCheckFlags(VIR_CONNECT_LIST_FILTERS_ALL, -1); + + /* check for filter combinations that return no results: + * persistent: all hyperv guests are persistent + * snapshot: the driver does not support snapshot management + * autostart: the driver does not support autostarting guests + */ + if ((MATCH(VIR_CONNECT_LIST_DOMAINS_TRANSIENT) && + !MATCH(VIR_CONNECT_LIST_DOMAINS_PERSISTENT)) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_AUTOSTART) && + !MATCH(VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART)) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT) && + !MATCH(VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT))) { + if (domains && + VIR_ALLOC_N(*domains, 1) < 0) + goto no_memory; + + ret = 0; + goto cleanup; + } + + virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT); + virBufferAddLit(&query, "where "); + virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_VIRTUAL); + + /* construct query with filter depending on flags */ + if (!(flags & VIR_CONNECT_LIST_DOMAINS_ACTIVE && + flags & VIR_CONNECT_LIST_DOMAINS_INACTIVE)) { + if (flags & VIR_CONNECT_LIST_DOMAINS_ACTIVE) { + virBufferAddLit(&query, "and "); + virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_ACTIVE); + } + if (flags & VIR_CONNECT_LIST_DOMAINS_INACTIVE) { + virBufferAddLit(&query, "and "); + virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_INACTIVE); + } + } + + if (hypervGetMsvmComputerSystemList(priv, &query, + &computerSystemList) < 0) + goto cleanup; + + if (domains) { + if (VIR_ALLOC_N(doms, 1) < 0) + goto no_memory; + ndoms = 1; + } + + for (computerSystem = computerSystemList; computerSystem != NULL; + computerSystem = computerSystem->next) { + + /* filter by domain state */ + if (MATCH(VIR_CONNECT_LIST_FILTERS_STATE)) { + int st = hypervMsvmComputerSystemEnabledStateToDomainState(computerSystem); + if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_RUNNING) && + st == VIR_DOMAIN_RUNNING) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_PAUSED) && + st == VIR_DOMAIN_PAUSED) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_SHUTOFF) && + st == VIR_DOMAIN_SHUTOFF) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_OTHER) && + (st != VIR_DOMAIN_RUNNING && + st != VIR_DOMAIN_PAUSED && + st != VIR_DOMAIN_SHUTOFF)))) + continue; + } + + /* managed save filter */ + if (MATCH(VIR_CONNECT_LIST_FILTERS_MANAGEDSAVE)) { + bool mansave = computerSystem->data->EnabledState == + MSVM_COMPUTERSYSTEM_ENABLEDSTATE_SUSPENDED; + + if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE) && mansave) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE) && !mansave))) + continue; + } + + if (!doms) { + count++; + continue; + } + + if (VIR_RESIZE_N(doms, ndoms, count, 2) < 0) + goto no_memory; + + if (hypervMsvmComputerSystemToDomain(conn, computerSystem, + &domain) < 0) + goto cleanup; + + doms[count++] = domain; + } + + if (doms) + *domains = doms; + doms = NULL; + ret = count; + +cleanup: + if (doms) { + for (i = 0; i < count; ++i) { + if (doms[i]) + virDomainFree(doms[i]); + } + } + + VIR_FREE(doms); + hypervFreeObject(priv, (hypervObject *)computerSystemList); + return ret; + +no_memory: + virReportOOMError(); + goto cleanup; +} +#undef MATCH + + + static virDriver hypervDriver = { .no = VIR_DRV_HYPERV, @@ -1270,6 +1405,7 @@ static virDriver hypervDriver = { .nodeGetInfo = hypervNodeGetInfo, /* 0.9.5 */ .listDomains = hypervListDomains, /* 0.9.5 */ .numOfDomains = hypervNumberOfDomains, /* 0.9.5 */ + .listAllDomains = hypervListAllDomains, /* 0.9.14 */ .domainLookupByID = hypervDomainLookupByID, /* 0.9.5 */ .domainLookupByUUID = hypervDomainLookupByUUID, /* 0.9.5 */ .domainLookupByName = hypervDomainLookupByName, /* 0.9.5 */ -- 1.7.8.6

Esx doesn't use the common virDomainObj implementation so this patch adds a separate implementation. This driver supports all currently defined filtering flags, but as with other drivers some combinations yield a empty result list. --- src/esx/esx_driver.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 195 insertions(+), 0 deletions(-) diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index 47957cc..7d4ac12 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -45,6 +45,7 @@ #include "esx_vi_methods.h" #include "esx_util.h" #include "viruri.h" +#include "virdomainlist.h" #define VIR_FROM_THIS VIR_FROM_ESX @@ -5053,6 +5054,199 @@ esxDomainGetMemoryParameters(virDomainPtr domain, virTypedParameterPtr params, return result; } +#define MATCH(FLAG) (flags & (FLAG)) +static int +esxListAllDomains(virConnectPtr conn, + virDomainPtr **domains, + unsigned int flags) +{ + int ret = -1; + esxPrivate *priv = conn->privateData; + virDomainPtr dom; + virDomainPtr *doms = NULL; + size_t ndoms = 0; + esxVI_ObjectContent *virtualMachineList = NULL; + esxVI_ObjectContent *virtualMachine = NULL; + esxVI_String *propertyNameList = NULL; + esxVI_AutoStartDefaults *autostart_defaults = NULL; + esxVI_VirtualMachinePowerState powerState; + esxVI_AutoStartPowerInfo *powerInfoList = NULL; + esxVI_AutoStartPowerInfo *powerInfo = NULL; + esxVI_VirtualMachineSnapshotTree *rootSnapshotTreeList = NULL; + char *name = NULL; + int id; + unsigned char uuid[VIR_UUID_BUFLEN]; + int count = 0; + int snapshotCount; + bool autostart; + int state; + + virCheckFlags(VIR_CONNECT_LIST_FILTERS_ALL, -1); + + /* check for flags that would produce empty output lists: + * - persistence: all esx machines are persistent + * - managed save: esx doesn't support managed save + */ + 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))) { + if (domains && + VIR_ALLOC_N(*domains, 1) < 0) + goto no_memory; + + ret = 0; + goto cleanup; + } + + if (esxVI_EnsureSession(priv->primary) < 0) + return -1; + + /* check system default autostart value */ + if (MATCH(VIR_CONNECT_LIST_FILTERS_AUTOSTART)) { + if (esxVI_LookupAutoStartDefaults(priv->primary, + &autostart_defaults) < 0) + goto cleanup; + + if (esxVI_LookupAutoStartPowerInfoList(priv->primary, + &powerInfoList) < 0) + goto cleanup; + } + + if (esxVI_String_AppendValueToList(&propertyNameList, + "runtime.powerState") < 0 || + esxVI_LookupVirtualMachineList(priv->primary, propertyNameList, + &virtualMachineList) < 0) + goto cleanup; + + if (domains) { + if (VIR_ALLOC_N(doms, 1) < 0) + goto no_memory; + ndoms = 1; + } + + for (virtualMachine = virtualMachineList; virtualMachine != NULL; + virtualMachine = virtualMachine->_next) { + + VIR_FREE(name); + + if (esxVI_GetVirtualMachineIdentity(virtualMachine, &id, &name, uuid) < 0 || + esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) + goto cleanup; + + /* filter by active state */ + if (MATCH(VIR_CONNECT_LIST_FILTERS_ACTIVE) && + !((MATCH(VIR_CONNECT_LIST_DOMAINS_ACTIVE) && + powerState != esxVI_VirtualMachinePowerState_PoweredOff) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_INACTIVE) && + powerState == esxVI_VirtualMachinePowerState_PoweredOff))) + continue; + + /* filter by snapshot existence */ + if (MATCH(VIR_CONNECT_LIST_FILTERS_SNAPSHOT)) { + 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) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT) && + snapshotCount == 0))) + continue; + } + + /* filter by autostart */ + if (MATCH(VIR_CONNECT_LIST_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; + + break; + } + } + + autostart = autostart && + autostart_defaults->enabled == esxVI_Boolean_True; + + if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_AUTOSTART) && + autostart) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART) && + !autostart))) + goto cleanup; + } + + /* filter by domain state */ + if (MATCH(VIR_CONNECT_LIST_FILTERS_STATE)) { + state = esxVI_VirtualMachinePowerState_ConvertToLibvirt(powerState); + if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_RUNNING) && + state == VIR_DOMAIN_RUNNING) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_PAUSED) && + state == VIR_DOMAIN_PAUSED) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_SHUTOFF) && + state == VIR_DOMAIN_SHUTOFF) || + (MATCH(VIR_CONNECT_LIST_DOMAINS_OTHER) && + (state != VIR_DOMAIN_RUNNING && + state != VIR_DOMAIN_PAUSED && + state != VIR_DOMAIN_SHUTOFF)))) + goto cleanup; + } + + /* just count the machines */ + if (!doms) { + count++; + continue; + } + + if (!(dom = virGetDomain(conn, name, uuid))) + goto no_memory; + + /* 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; + } + + if (doms) + *domains = doms; + doms = NULL; + ret = count; + +cleanup: + if (doms) { + for (id = 0; id < count; id++) { + if (doms[id]) + virDomainFree(doms[id]); + } + } + VIR_FREE(doms); + VIR_FREE(name); + esxVI_String_Free(&propertyNameList); + esxVI_ObjectContent_Free(&virtualMachineList); + return ret; + +no_memory: + virReportOOMError(); + goto cleanup; +} +#undef MATCH static virDriver esxDriver = { @@ -5068,6 +5262,7 @@ static virDriver esxDriver = { .getCapabilities = esxGetCapabilities, /* 0.7.1 */ .listDomains = esxListDomains, /* 0.7.0 */ .numOfDomains = esxNumberOfDomains, /* 0.7.0 */ + .listAllDomains = esxListAllDomains, /* 0.9.14 */ .domainLookupByID = esxDomainLookupByID, /* 0.7.0 */ .domainLookupByUUID = esxDomainLookupByUUID, /* 0.7.0 */ .domainLookupByName = esxDomainLookupByName, /* 0.7.0 */ -- 1.7.8.6
participants (1)
-
Peter Krempa