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