[PATCH 0/6] hyperv: implement vCPU APIs

Here's a GitLab merge request, if you'd prefer to review it there: https://gitlab.com/iammattcoleman/libvirt/-/merge_requests/10 Matt Coleman (6): domain: introduce constants for virVcpuInfo->cpu state values hyperv: implement domainGetVcpus hyperv: implement domainGetVcpusFlags hyperv: implement domainGetMaxVcpus hyperv: implement domainSetVcpus and domainSetVcpusFlags news: implement vCPU APIs in the Hyper-V driver NEWS.rst | 8 +- include/libvirt/libvirt-domain.h | 16 ++- src/hyperv/hyperv_driver.c | 180 +++++++++++++++++++++++++++++++ 3 files changed, 200 insertions(+), 4 deletions(-) -- 2.27.0

Signed-off-by: Matt Coleman <matt@datto.com> --- include/libvirt/libvirt-domain.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index b3310729bf..d52733190f 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -1915,10 +1915,24 @@ struct _virVcpuInfo { unsigned int number; /* virtual CPU number */ int state; /* value from virVcpuState */ unsigned long long cpuTime; /* CPU time used, in nanoseconds */ - int cpu; /* real CPU number, or -1 if offline */ + int cpu; /* real CPU number, or one of the VIR_VCPU_INFO_CPU_* constants */ }; typedef virVcpuInfo *virVcpuInfoPtr; +/** + * VIR_VCPU_INFO_CPU_OFFLINE: + * + * The VCPU is offline. + */ +# define VIR_VCPU_INFO_CPU_OFFLINE -1 + +/** + * VIR_VCPU_INFO_CPU_UNAVAILABLE: + * + * The hypervisor does not expose real CPU information for VCPUs. + */ +# define VIR_VCPU_INFO_CPU_UNAVAILABLE -2 + /* Flags for controlling virtual CPU hot-plugging. */ typedef enum { /* See virDomainModificationImpact for these flags. */ -- 2.27.0

On 11/12/20 12:51 PM, Matt Coleman wrote:
Signed-off-by: Matt Coleman <matt@datto.com> --- include/libvirt/libvirt-domain.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index b3310729bf..d52733190f 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -1915,10 +1915,24 @@ struct _virVcpuInfo { unsigned int number; /* virtual CPU number */ int state; /* value from virVcpuState */ unsigned long long cpuTime; /* CPU time used, in nanoseconds */ - int cpu; /* real CPU number, or -1 if offline */ + int cpu; /* real CPU number, or one of the VIR_VCPU_INFO_CPU_* constants */ }; typedef virVcpuInfo *virVcpuInfoPtr;
+/** + * VIR_VCPU_INFO_CPU_OFFLINE: + * + * The VCPU is offline. + */ +# define VIR_VCPU_INFO_CPU_OFFLINE -1 + +/** + * VIR_VCPU_INFO_CPU_UNAVAILABLE: + * + * The hypervisor does not expose real CPU information for VCPUs. + */ +# define VIR_VCPU_INFO_CPU_UNAVAILABLE -2 + /* Flags for controlling virtual CPU hot-plugging. */ typedef enum { /* See virDomainModificationImpact for these flags. */
How about making this an enum instead? diff --git c/include/libvirt/libvirt-domain.h w/include/libvirt/libvirt-domain.h index b3310729bf..a12a8e6625 100644 --- c/include/libvirt/libvirt-domain.h +++ w/include/libvirt/libvirt-domain.h @@ -1910,12 +1910,19 @@ typedef enum { # endif } virVcpuState; + +typedef enum { + VIR_VCPU_INFO_CPU_OFFLINE = -1, /* the vCPU is offline */ + VIR_VCPU_INFO_CPU_UNAVAILABLE = -2, /* the hypervisor does not expose real + CPU information for vCPUs. */ +} virVcpuHostCpuState; + typedef struct _virVcpuInfo virVcpuInfo; struct _virVcpuInfo { unsigned int number; /* virtual CPU number */ int state; /* value from virVcpuState */ unsigned long long cpuTime; /* CPU time used, in nanoseconds */ - int cpu; /* real CPU number, or -1 if offline */ + int cpu; /* real CPU number, or one of the virVcpuHostCpuState */ }; typedef virVcpuInfo *virVcpuInfoPtr; Michal

On Nov 12, 2020, at 8:46 AM, Michal Privoznik <mprivozn@redhat.com> wrote:
On 11/12/20 12:51 PM, Matt Coleman wrote:
+/** + * VIR_VCPU_INFO_CPU_OFFLINE: + * + * The VCPU is offline. + */ +# define VIR_VCPU_INFO_CPU_OFFLINE -1 + +/** + * VIR_VCPU_INFO_CPU_UNAVAILABLE: + * + * The hypervisor does not expose real CPU information for VCPUs. + */ +# define VIR_VCPU_INFO_CPU_UNAVAILABLE -2 + /* Flags for controlling virtual CPU hot-plugging. */ typedef enum { /* See virDomainModificationImpact for these flags. */
How about making this an enum instead?
Sounds good. I had done it this way based on the Hyper-V CPU details thread. I'll update it to use an enum. -- Matt

On 11/12/20 3:17 PM, Matt Coleman wrote:
On Nov 12, 2020, at 8:46 AM, Michal Privoznik <mprivozn@redhat.com> wrote:
On 11/12/20 12:51 PM, Matt Coleman wrote:
+/** + * VIR_VCPU_INFO_CPU_OFFLINE: + * + * The VCPU is offline. + */ +# define VIR_VCPU_INFO_CPU_OFFLINE -1 + +/** + * VIR_VCPU_INFO_CPU_UNAVAILABLE: + * + * The hypervisor does not expose real CPU information for VCPUs. + */ +# define VIR_VCPU_INFO_CPU_UNAVAILABLE -2 + /* Flags for controlling virtual CPU hot-plugging. */ typedef enum { /* See virDomainModificationImpact for these flags. */
How about making this an enum instead?
Sounds good. I had done it this way based on the Hyper-V CPU details thread. I'll update it to use an enum.
No need resend, I can fix that locally, if you agree. Michal

Co-authored-by: Sri Ramanujam <sramanujam@datto.com> Signed-off-by: Matt Coleman <matt@datto.com> --- src/hyperv/hyperv_driver.c | 56 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index 9fda0d6047..56d6da80e0 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -1078,6 +1078,61 @@ hypervDomainGetState(virDomainPtr domain, int *state, int *reason, } +static int +hypervDomainGetVcpus(virDomainPtr domain, + virVcpuInfoPtr info, + int maxinfo, + unsigned char *cpumaps, + int maplen) +{ + int count = 0; + int vcpu_number; + hypervPrivate *priv = domain->conn->privateData; + Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor *vproc = NULL; + + /* Hyper-V does not allow setting CPU affinity: all cores will be used */ + if (cpumaps && maplen > 0) + memset(cpumaps, 0xFF, maxinfo * maplen); + + for (vcpu_number = 0; vcpu_number < maxinfo; vcpu_number++) { + g_auto(virBuffer) query = VIR_BUFFER_INITIALIZER; + + /* Name format: <domain_name>:Hv VP <vCPU_number> */ + g_autofree char *vcpu_name = g_strdup_printf("%s:Hv VP %d", domain->name, vcpu_number); + + /* try to free objects from previous iteration */ + hypervFreeObject(priv, (hypervObject *)vproc); + vproc = NULL; + + /* get the info */ + virBufferEscapeSQL(&query, + WIN32_PERFRAWDATA_HVSTATS_HYPERVHYPERVISORVIRTUALPROCESSOR_WQL_SELECT + "WHERE Name = '%s'", + vcpu_name); + + if (hypervGetWmiClass(Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor, &vproc) < 0) + continue; + + /* fill structure info */ + info[vcpu_number].number = vcpu_number; + if (vproc) { + info[vcpu_number].state = VIR_VCPU_RUNNING; + info[vcpu_number].cpuTime = vproc->data->PercentTotalRunTime * 100; + info[vcpu_number].cpu = VIR_VCPU_INFO_CPU_UNAVAILABLE; + } else { + info[vcpu_number].state = VIR_VCPU_OFFLINE; + info[vcpu_number].cpuTime = 0LLU; + info[vcpu_number].cpu = VIR_VCPU_INFO_CPU_OFFLINE; + } + count++; + } + + hypervFreeObject(priv, (hypervObject *)vproc); + + return count; +} + + static char * hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags) { @@ -1875,6 +1930,7 @@ static virHypervisorDriver hypervHypervisorDriver = { .domainSetMemoryFlags = hypervDomainSetMemoryFlags, /* 3.6.0 */ .domainGetInfo = hypervDomainGetInfo, /* 0.9.5 */ .domainGetState = hypervDomainGetState, /* 0.9.5 */ + .domainGetVcpus = hypervDomainGetVcpus, /* 6.10.0 */ .domainGetXMLDesc = hypervDomainGetXMLDesc, /* 0.9.5 */ .connectListDefinedDomains = hypervConnectListDefinedDomains, /* 0.9.5 */ .connectNumOfDefinedDomains = hypervConnectNumOfDefinedDomains, /* 0.9.5 */ -- 2.27.0

Co-authored-by: Sri Ramanujam <sramanujam@datto.com> Signed-off-by: Matt Coleman <matt@datto.com> --- src/hyperv/hyperv_driver.c | 52 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index 56d6da80e0..3c436d9465 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -1078,6 +1078,57 @@ hypervDomainGetState(virDomainPtr domain, int *state, int *reason, } +static int +hypervDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags) +{ + int result = -1; + char uuid_string[VIR_UUID_STRING_BUFLEN]; + hypervPrivate *priv = domain->conn->privateData; + Msvm_ComputerSystem *computerSystem = NULL; + Msvm_ProcessorSettingData *proc_sd = NULL; + Msvm_VirtualSystemSettingData *vssd = NULL; + + virCheckFlags(VIR_DOMAIN_VCPU_LIVE | + VIR_DOMAIN_VCPU_CONFIG | + VIR_DOMAIN_VCPU_MAXIMUM, -1); + + virUUIDFormat(domain->uuid, uuid_string); + + /* Start by getting the Msvm_ComputerSystem */ + if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0) + goto cleanup; + + /* Check @flags to see if we are to query a running domain, and fail + * if that domain is not running */ + if (flags & VIR_DOMAIN_VCPU_LIVE && + computerSystem->data->EnabledState != MSVM_COMPUTERSYSTEM_ENABLEDSTATE_ENABLED) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("Domain is not active")); + goto cleanup; + } + + /* Check @flags to see if we are to return the maximum vCPU limit */ + if (flags & VIR_DOMAIN_VCPU_MAXIMUM) { + result = hypervConnectGetMaxVcpus(domain->conn, NULL); + goto cleanup; + } + + if (hypervGetMsvmVirtualSystemSettingDataFromUUID(priv, uuid_string, &vssd) < 0) + goto cleanup; + + if (hypervGetProcessorSD(priv, vssd->data->InstanceID, &proc_sd) < 0) + goto cleanup; + + result = proc_sd->data->VirtualQuantity; + + cleanup: + hypervFreeObject(priv, (hypervObject *)computerSystem); + hypervFreeObject(priv, (hypervObject *)vssd); + hypervFreeObject(priv, (hypervObject *)proc_sd); + + return result; +} + + static int hypervDomainGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, @@ -1930,6 +1981,7 @@ static virHypervisorDriver hypervHypervisorDriver = { .domainSetMemoryFlags = hypervDomainSetMemoryFlags, /* 3.6.0 */ .domainGetInfo = hypervDomainGetInfo, /* 0.9.5 */ .domainGetState = hypervDomainGetState, /* 0.9.5 */ + .domainGetVcpusFlags = hypervDomainGetVcpusFlags, /* 6.10.0 */ .domainGetVcpus = hypervDomainGetVcpus, /* 6.10.0 */ .domainGetXMLDesc = hypervDomainGetXMLDesc, /* 0.9.5 */ .connectListDefinedDomains = hypervConnectListDefinedDomains, /* 0.9.5 */ -- 2.27.0

Co-authored-by: Sri Ramanujam <sramanujam@datto.com> Signed-off-by: Matt Coleman <matt@datto.com> --- src/hyperv/hyperv_driver.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index 3c436d9465..0e35f18430 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -42,6 +42,11 @@ VIR_LOG_INIT("hyperv.hyperv_driver"); +/* + * Forward declarations + */ +static int hypervDomainIsActive(virDomainPtr domain); + /* * WMI utility functions * @@ -1184,6 +1189,16 @@ hypervDomainGetVcpus(virDomainPtr domain, } +static int +hypervDomainGetMaxVcpus(virDomainPtr dom) +{ + if (hypervDomainIsActive(dom)) + return hypervDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)); + else + return hypervConnectGetMaxVcpus(dom->conn, NULL); +} + + static char * hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags) { @@ -1983,6 +1998,7 @@ static virHypervisorDriver hypervHypervisorDriver = { .domainGetState = hypervDomainGetState, /* 0.9.5 */ .domainGetVcpusFlags = hypervDomainGetVcpusFlags, /* 6.10.0 */ .domainGetVcpus = hypervDomainGetVcpus, /* 6.10.0 */ + .domainGetMaxVcpus = hypervDomainGetMaxVcpus, /* 6.10.0 */ .domainGetXMLDesc = hypervDomainGetXMLDesc, /* 0.9.5 */ .connectListDefinedDomains = hypervConnectListDefinedDomains, /* 0.9.5 */ .connectNumOfDefinedDomains = hypervConnectNumOfDefinedDomains, /* 0.9.5 */ -- 2.27.0

On 11/12/20 12:51 PM, Matt Coleman wrote:
Co-authored-by: Sri Ramanujam <sramanujam@datto.com> Signed-off-by: Matt Coleman <matt@datto.com> --- src/hyperv/hyperv_driver.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index 3c436d9465..0e35f18430 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -42,6 +42,11 @@
VIR_LOG_INIT("hyperv.hyperv_driver");
+/* + * Forward declarations + */ +static int hypervDomainIsActive(virDomainPtr domain); +
I'm not a big fan of these declarations, because changing one place requires changing the other. Although in this case it doesn't matter really, because this declaration won't change as it's derived from public API. Anyway, might be worth shifting things around ..
/* * WMI utility functions * @@ -1184,6 +1189,16 @@ hypervDomainGetVcpus(virDomainPtr domain, }
+static int +hypervDomainGetMaxVcpus(virDomainPtr dom) +{ + if (hypervDomainIsActive(dom)) + return hypervDomainGetVcpusFlags(dom, (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)); + else + return hypervConnectGetMaxVcpus(dom->conn, NULL); +}
.. eg push this a bit further - after the hypervDomainIsActive() is implemented.
+ + static char * hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags) { @@ -1983,6 +1998,7 @@ static virHypervisorDriver hypervHypervisorDriver = { .domainGetState = hypervDomainGetState, /* 0.9.5 */ .domainGetVcpusFlags = hypervDomainGetVcpusFlags, /* 6.10.0 */ .domainGetVcpus = hypervDomainGetVcpus, /* 6.10.0 */ + .domainGetMaxVcpus = hypervDomainGetMaxVcpus, /* 6.10.0 */ .domainGetXMLDesc = hypervDomainGetXMLDesc, /* 0.9.5 */ .connectListDefinedDomains = hypervConnectListDefinedDomains, /* 0.9.5 */ .connectNumOfDefinedDomains = hypervConnectNumOfDefinedDomains, /* 0.9.5 */
Michal

On Nov 12, 2020, at 8:46 AM, Michal Privoznik <mprivozn@redhat.com> wrote:
On 11/12/20 12:51 PM, Matt Coleman wrote:
Co-authored-by: Sri Ramanujam <sramanujam@datto.com> Signed-off-by: Matt Coleman <matt@datto.com> --- src/hyperv/hyperv_driver.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index 3c436d9465..0e35f18430 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -42,6 +42,11 @@ VIR_LOG_INIT("hyperv.hyperv_driver"); +/* + * Forward declarations + */ +static int hypervDomainIsActive(virDomainPtr domain); +
I'm not a big fan of these declarations, because changing one place requires changing the other. Although in this case it doesn't matter really, because this declaration won't change as it's derived from public API. Anyway, might be worth shifting things around ..
I've been trying to keep the API implementations in the same order that they appear in _virHypervisorDriver, except for flipping some adjacent dependencies. It's helped me keep track of what is implemented and what remains, but I can stop doing that if you'd prefer to not have the forward declarations. -- Matt

On 11/12/20 3:15 PM, Matt Coleman wrote:
On Nov 12, 2020, at 8:46 AM, Michal Privoznik <mprivozn@redhat.com> wrote:
On 11/12/20 12:51 PM, Matt Coleman wrote:
Co-authored-by: Sri Ramanujam <sramanujam@datto.com> Signed-off-by: Matt Coleman <matt@datto.com> --- src/hyperv/hyperv_driver.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index 3c436d9465..0e35f18430 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -42,6 +42,11 @@ VIR_LOG_INIT("hyperv.hyperv_driver"); +/* + * Forward declarations + */ +static int hypervDomainIsActive(virDomainPtr domain); +
I'm not a big fan of these declarations, because changing one place requires changing the other. Although in this case it doesn't matter really, because this declaration won't change as it's derived from public API. Anyway, might be worth shifting things around ..
I've been trying to keep the API implementations in the same order that they appear in _virHypervisorDriver, except for flipping some adjacent dependencies. It's helped me keep track of what is implemented and what remains, but I can stop doing that if you'd prefer to not have the forward declarations.
Well, I think I can live with this one since there is an (esthetic) reason to it. Michal

On Nov 12, 2020, at 11:34 AM, Michal Privoznik <mprivozn@redhat.com> wrote:
Well, I think I can live with this one since there is an (esthetic) reason to it.
Since I wrote that email, I've looked at other drivers in the codebase and decided it's not worth it. I've eliminated the forward declaration (as well as the others that I introduced in subsequent commits that I haven't upstreamed yet). I'll be submitting a revised set of patches shortly. -- Matt

Co-authored-by: Sri Ramanujam <sramanujam@datto.com> Signed-off-by: Matt Coleman <matt@datto.com> --- src/hyperv/hyperv_driver.c | 56 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index 0e35f18430..3ee2705592 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -1083,6 +1083,60 @@ hypervDomainGetState(virDomainPtr domain, int *state, int *reason, } +static int +hypervDomainSetVcpusFlags(virDomainPtr domain, + unsigned int nvcpus, + unsigned int flags) +{ + int result = -1; + char uuid_string[VIR_UUID_STRING_BUFLEN]; + hypervPrivate *priv = domain->conn->privateData; + Msvm_VirtualSystemSettingData *vssd = NULL; + Msvm_ProcessorSettingData *proc_sd = NULL; + g_autoptr(GHashTable) vcpuResource = NULL; + g_autofree char *nvcpus_str = g_strdup_printf("%u", nvcpus); + + virCheckFlags(0, -1); + + virUUIDFormat(domain->uuid, uuid_string); + + if (hypervGetMsvmVirtualSystemSettingDataFromUUID(priv, uuid_string, &vssd) < 0) + goto cleanup; + + if (hypervGetProcessorSD(priv, vssd->data->InstanceID, &proc_sd) < 0) + goto cleanup; + + vcpuResource = hypervCreateEmbeddedParam(Msvm_ProcessorSettingData_WmiInfo); + if (!vcpuResource) + goto cleanup; + + if (hypervSetEmbeddedProperty(vcpuResource, "VirtualQuantity", nvcpus_str) < 0) + goto cleanup; + + if (hypervSetEmbeddedProperty(vcpuResource, "InstanceID", proc_sd->data->InstanceID) < 0) + goto cleanup; + + if (hypervMsvmVSMSModifyResourceSettings(priv, &vcpuResource, + Msvm_ProcessorSettingData_WmiInfo) < 0) + goto cleanup; + + result = 0; + + cleanup: + hypervFreeObject(priv, (hypervObject *)vssd); + hypervFreeObject(priv, (hypervObject *)proc_sd); + + return result; +} + + +static int +hypervDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus) +{ + return hypervDomainSetVcpusFlags(domain, nvcpus, 0); +} + + static int hypervDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags) { @@ -1996,6 +2050,8 @@ static virHypervisorDriver hypervHypervisorDriver = { .domainSetMemoryFlags = hypervDomainSetMemoryFlags, /* 3.6.0 */ .domainGetInfo = hypervDomainGetInfo, /* 0.9.5 */ .domainGetState = hypervDomainGetState, /* 0.9.5 */ + .domainSetVcpus = hypervDomainSetVcpus, /* 6.10.0 */ + .domainSetVcpusFlags = hypervDomainSetVcpusFlags, /* 6.10.0 */ .domainGetVcpusFlags = hypervDomainGetVcpusFlags, /* 6.10.0 */ .domainGetVcpus = hypervDomainGetVcpus, /* 6.10.0 */ .domainGetMaxVcpus = hypervDomainGetMaxVcpus, /* 6.10.0 */ -- 2.27.0

Signed-off-by: Matt Coleman <matt@datto.com> --- NEWS.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/NEWS.rst b/NEWS.rst index 8b60a5da11..3fd3ce4cb9 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -16,9 +16,11 @@ v6.10.0 (unreleased) * hyperv: implement new APIs The `virDomainGetMaxMemory()``, ``virDomainSetMaxMemory()``, - ``virDomainGetSchedulerType()``, ``virDomainGetSchedulerParameters()``, and - ``virDomainGetSchedulerParametersFlags()`` APIs have been implemented in - the Hyper-V driver. + ``virDomainGetSchedulerType()``, ``virDomainGetSchedulerParameters()``, + ``virDomainGetSchedulerParametersFlags()``, ``virDomainGetVcpus()``, + ``virDomainGetVcpusFlags()``, ``virDomainGetMaxVcpus()``, + ``virDomainSetVcpus()``, and ``virDomainSetVcpusFlags()`` APIs have been + implemented in the Hyper-V driver. * **Improvements** -- 2.27.0
participants (2)
-
Matt Coleman
-
Michal Privoznik