From 60d0ecdaa140b34241e0be15a6e1c9a0581acf19 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Tue, 5 Jun 2012 14:20:58 +0200 Subject: [PATCH] hyperv: Add implementation for virConnectListAllDomains() 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 664b4356a9..65934c9377 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 */