Co-authored-by: Sri Ramanujam <sramanujam(a)datto.com>
Signed-off-by: Matt Coleman <matt(a)datto.com>
---
src/hyperv/hyperv_driver.c | 77 ++++++++++++++++++++++++++
src/hyperv/hyperv_wmi_generator.input | 78 +++++++++++++++++++++++++++
2 files changed, 155 insertions(+)
diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index ef0a5249c7..0b28c1e94b 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -917,6 +917,81 @@ hypervDomainResume(virDomainPtr domain)
+static int
+hypervDomainShutdownFlags(virDomainPtr domain, unsigned int flags)
+{
+ int result = -1;
+ hypervPrivate *priv = domain->conn->privateData;
+ Msvm_ComputerSystem *computerSystem = NULL;
+ Msvm_ShutdownComponent *shutdown = NULL;
+ bool in_transition = false;
+ char uuid[VIR_UUID_STRING_BUFLEN];
+ g_auto(virBuffer) query = VIR_BUFFER_INITIALIZER;
+ hypervInvokeParamsListPtr params = NULL;
+ g_autofree char *selector = NULL;
+
+ virCheckFlags(0, -1);
+
+ virUUIDFormat(domain->uuid, uuid);
+
+ if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0)
+ goto cleanup;
+
+ if (!hypervIsMsvmComputerSystemActive(computerSystem, &in_transition) ||
+ in_transition) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Domain is not active or in state transition"));
+ goto cleanup;
+ }
+
+ virBufferEscapeSQL(&query,
+ MSVM_SHUTDOWNCOMPONENT_WQL_SELECT
+ "WHERE SystemName = '%s'", uuid);
+
+ if (hypervGetWmiClass(Msvm_ShutdownComponent, &shutdown) < 0 ||
+ !shutdown) {
+ virReportError(VIR_ERR_OPERATION_FAILED,
+ _("Could not get Msvm_ShutdownComponent for domain with UUID
'%s'"),
+ uuid);
+ goto cleanup;
+ }
+
+ selector = g_strdup_printf(
+
"CreationClassName=\"Msvm_ShutdownComponent\"&DeviceID=\"%s\"&"
+
"SystemCreationClassName=\"Msvm_ComputerSystem\"&SystemName=\"%s\"",
+ shutdown->data.common->DeviceID, uuid);
+
+ params = hypervCreateInvokeParamsList(priv, "InitiateShutdown", selector,
+ Msvm_ShutdownComponent_WmiInfo);
+
+ hypervAddSimpleParam(params, "Force", "False");
+ hypervAddSimpleParam(params, "Reason", _("Planned shutdown via
libvirt"));
+
+ if (hypervInvokeMethod(priv, params, NULL) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not shutdown domain with UUID '%s'"),
uuid);
+ goto cleanup;
+ }
+
+ result = 0;
+
+ cleanup:
+ hypervFreeObject(priv, (hypervObject *) computerSystem);
+ hypervFreeObject(priv, (hypervObject *) shutdown);
+
+ return result;
+}
+
+
+
+static int
+hypervDomainShutdown(virDomainPtr domain)
+{
+ return hypervDomainShutdownFlags(domain, 0);
+}
+
+
+
static int
hypervDomainReboot(virDomainPtr domain, unsigned int flags)
{
@@ -2014,6 +2089,8 @@ static virHypervisorDriver hypervHypervisorDriver = {
.domainLookupByName = hypervDomainLookupByName, /* 0.9.5 */
.domainSuspend = hypervDomainSuspend, /* 0.9.5 */
.domainResume = hypervDomainResume, /* 0.9.5 */
+ .domainShutdown = hypervDomainShutdown, /* 6.9.0 */
+ .domainShutdownFlags = hypervDomainShutdownFlags, /* 6.9.0 */
.domainReboot = hypervDomainReboot, /* 6.9.0 */
.domainReset = hypervDomainReset, /* 6.9.0 */
.domainDestroy = hypervDomainDestroy, /* 0.9.5 */
diff --git a/src/hyperv/hyperv_wmi_generator.input
b/src/hyperv/hyperv_wmi_generator.input
index bbca550790..1377138a12 100644
--- a/src/hyperv/hyperv_wmi_generator.input
+++ b/src/hyperv/hyperv_wmi_generator.input
@@ -1072,3 +1072,81 @@ class v2/Msvm_Keyboard
uint16 Password
boolean UnicodeSupported
end
+
+
+class Msvm_ShutdownComponent
+ string Caption
+ string Description
+ string ElementName
+ datetime InstallDate
+ string Name
+ uint16 OperationalStatus[]
+ string StatusDescriptions[]
+ string Status
+ uint16 HealthState
+ uint16 EnabledState
+ string OtherEnabledState
+ uint16 RequestedState
+ uint16 EnabledDefault
+ datetime TimeOfLastStateChange
+ string SystemCreationClassName
+ string SystemName
+ string CreationClassName
+ string DeviceID
+ boolean PowerManagementSupported
+ uint16 PowerManagementCapabilities[]
+ uint16 Availability
+ uint16 StatusInfo
+ uint32 LastErrorCode
+ string ErrorDescription
+ boolean ErrorCleared
+ string OtherIdentifyingInfo[]
+ uint64 PowerOnHours
+ uint64 TotalPowerOnHours
+ string IdentifyingDescriptions[]
+ uint16 AdditionalAvailability[]
+ uint64 MaxQuiesceTime
+ uint16 LocationIndicator
+end
+
+
+class v2/Msvm_ShutdownComponent
+ string InstanceID
+ string Caption
+ string Description
+ string ElementName
+ datetime InstallDate
+ string Name
+ uint16 OperationalStatus[]
+ string StatusDescriptions[]
+ string Status
+ uint16 HealthState
+ uint16 CommunicationStatus
+ uint16 DetailedStatus
+ uint16 OperatingStatus
+ uint16 PrimaryStatus
+ uint16 EnabledState
+ string OtherEnabledState
+ uint16 RequestedState
+ uint16 EnabledDefault
+ datetime TimeOfLastStateChange
+ uint16 AvailableRequestedStates[]
+ uint16 TransitioningToState
+ string SystemCreationClassName
+ string SystemName
+ string CreationClassName
+ string DeviceID
+ boolean PowerManagementSupported
+ uint16 PowerManagementCapabilities[]
+ uint16 Availability
+ uint16 StatusInfo
+ uint32 LastErrorCode
+ string ErrorDescription
+ boolean ErrorCleared
+ string OtherIdentifyingInfo[]
+ uint64 PowerOnHours
+ uint64 TotalPowerOnHours
+ string IdentifyingDescriptions[]
+ uint16 AdditionalAvailability[]
+ uint64 MaxQuiesceTime
+end
--
2.27.0