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

Yet another respin updated and rebased to current head. Both drivers are compile tested but I don't have the infrastructure do a functional test. Peter Krempa (2): hyperv: Add implementation for virConnectListAllDomains() esx: Add implementation for virConnectListAllDomains() src/esx/esx_driver.c | 194 +++++++++++++++++++++++++++++++++++++++++++++ src/hyperv/hyperv_driver.c | 135 +++++++++++++++++++++++++++++++ 2 files changed, 329 insertions(+) -- 1.7.12

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 | 135 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index 664b435..65934c9 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -1259,6 +1259,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_DOMAINS_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_DOMAINS_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_DOMAINS_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 +1404,7 @@ static virDriver hypervDriver = { .nodeGetInfo = hypervNodeGetInfo, /* 0.9.5 */ .listDomains = hypervListDomains, /* 0.9.5 */ .numOfDomains = hypervNumberOfDomains, /* 0.9.5 */ + .listAllDomains = hypervListAllDomains, /* 0.10.2 */ .domainLookupByID = hypervDomainLookupByID, /* 0.9.5 */ .domainLookupByUUID = hypervDomainLookupByUUID, /* 0.9.5 */ .domainLookupByName = hypervDomainLookupByName, /* 0.9.5 */ -- 1.7.12

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 | 194 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index e57296a..b76a8e4 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -5002,6 +5002,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_DOMAINS_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_DOMAINS_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_DOMAINS_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_DOMAINS_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_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; + + 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_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) && + 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 = { @@ -5017,6 +5210,7 @@ static virDriver esxDriver = { .getCapabilities = esxGetCapabilities, /* 0.7.1 */ .listDomains = esxListDomains, /* 0.7.0 */ .numOfDomains = esxNumberOfDomains, /* 0.7.0 */ + .listAllDomains = esxListAllDomains, /* 0.10.2 */ .domainLookupByID = esxDomainLookupByID, /* 0.7.0 */ .domainLookupByUUID = esxDomainLookupByUUID, /* 0.7.0 */ .domainLookupByName = esxDomainLookupByName, /* 0.7.0 */ -- 1.7.12

On Fri, Aug 31, 2012 at 05:36:51PM +0200, Peter Krempa wrote:
Yet another respin updated and rebased to current head.
Both drivers are compile tested but I don't have the infrastructure do a functional test.
Peter Krempa (2): hyperv: Add implementation for virConnectListAllDomains() esx: Add implementation for virConnectListAllDomains()
src/esx/esx_driver.c | 194 +++++++++++++++++++++++++++++++++++++++++++++ src/hyperv/hyperv_driver.c | 135 +++++++++++++++++++++++++++++++ 2 files changed, 329 insertions(+)
I was hoping to see feedback on actual users, but since we are at v6 and nobody replied, let's push them and see ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On 09/06/12 07:24, Daniel Veillard wrote:
On Fri, Aug 31, 2012 at 05:36:51PM +0200, Peter Krempa wrote:
Yet another respin updated and rebased to current head.
Both drivers are compile tested but I don't have the infrastructure do a functional test.
Peter Krempa (2): hyperv: Add implementation for virConnectListAllDomains() esx: Add implementation for virConnectListAllDomains()
src/esx/esx_driver.c | 194 +++++++++++++++++++++++++++++++++++++++++++++ src/hyperv/hyperv_driver.c | 135 +++++++++++++++++++++++++++++++ 2 files changed, 329 insertions(+)
I was hoping to see feedback on actual users, but since we are at v6 and nobody replied, let's push them and see
ACK,
Yep, let's just test it in the wild :). I corrected a bug that would create empty lists on ESX if some filters were used that I found during a last self-review and pushed the series. Thanks. Peter
Daniel

2012/9/6 Peter Krempa <pkrempa@redhat.com>:
On 09/06/12 07:24, Daniel Veillard wrote:
On Fri, Aug 31, 2012 at 05:36:51PM +0200, Peter Krempa wrote:
Yet another respin updated and rebased to current head.
Both drivers are compile tested but I don't have the infrastructure do a functional test.
Peter Krempa (2): hyperv: Add implementation for virConnectListAllDomains() esx: Add implementation for virConnectListAllDomains()
src/esx/esx_driver.c | 194 +++++++++++++++++++++++++++++++++++++++++++++ src/hyperv/hyperv_driver.c | 135 +++++++++++++++++++++++++++++++ 2 files changed, 329 insertions(+)
I was hoping to see feedback on actual users, but since we are at v6 and nobody replied, let's push them and see
ACK,
Yep, let's just test it in the wild :). I corrected a bug that would create empty lists on ESX if some filters were used that I found during a last self-review and pushed the series. Thanks.
And here comes your in-the-wild testing :) Sorry for not taking care of this earlier. Both patches look quite well, but there are some small problems and possibilities for improvement. I've posted two patches for this: https://www.redhat.com/archives/libvir-list/2012-September/msg00486.html https://www.redhat.com/archives/libvir-list/2012-September/msg00485.html The Hyper-V patch is not runtime tested yet because I currently have some trouble getting my Hyper-V setup to work again. I'll report back on this once I get it running. -- Matthias Bolte http://photron.blogspot.com
participants (3)
-
Daniel Veillard
-
Matthias Bolte
-
Peter Krempa