CLOUDSTACK-6400: [hyper-v] [vmsync] fixed occasionally VM is not deleted from back-end when it is stopped from Hyper-V manager and then destroyed-expunged from CS and returning only power VMs for vmsync
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/3ec7497e Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/3ec7497e Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/3ec7497e Branch: refs/heads/master Commit: 3ec7497e1ebcaa65a8cbd24c27326356355ac8cc Parents: 0aa6cc6 Author: Anshul Gangwar <anshul.gang...@citrix.com> Authored: Mon Apr 14 01:22:42 2014 -0700 Committer: Devdeep Singh <devd...@gmail.com> Committed: Tue Apr 15 14:36:55 2014 +0530 ---------------------------------------------------------------------- .../HypervResource/HypervResourceController.cs | 37 ++++++++++-- .../HypervResource/IWmiCallsV2.cs | 1 + .../ServerResource/HypervResource/WmiCallsV2.cs | 59 ++++++++++++++++++-- 3 files changed, 87 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ec7497e/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs index ca3c206..52307af 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs @@ -2302,18 +2302,43 @@ namespace HypervResource logger.Info(CloudStackTypes.HostVmStateReportCommand + Utils.CleanString(cmd.ToString())); string details = null; - Dictionary<string, string>[] hostVmStateReport = null; + List<Dictionary<string, string>> hostVmStateReport = new List<Dictionary<string, string>>(); try { var vmCollection = wmiCallsV2.GetComputerSystemCollection(); - hostVmStateReport = new Dictionary<string, string>[vmCollection.Count]; - int i = 0; foreach (ComputerSystem vm in vmCollection) { - var dict = new Dictionary<string, string>(); - dict.Add(vm.ElementName, EnabledState.ToCloudStackPowerState(vm.EnabledState)); - hostVmStateReport[i++] = dict; + if (EnabledState.ToCloudStackPowerState(vm.EnabledState).Equals("PowerOn")) + { + var dict = new Dictionary<string, string>(); + dict.Add(vm.ElementName, EnabledState.ToCloudStackPowerState(vm.EnabledState)); + hostVmStateReport.Add(dict); + } + if (EnabledState.ToCloudStackPowerState(vm.EnabledState).Equals("PowerOff")) + { + string note = wmiCallsV2.GetVmNote((wmiCallsV2.GetVmSettings(vm)).Path); + if (note != null && note.Contains("CloudStack")) + { + if (!note.Contains("creating")) + { + try + { + wmiCallsV2.DestroyVm(vm.ElementName); + } + catch (Exception ex) + { + logger.Error("Failed to delete stopped VMs due to " + ex.Message); + } + } + else + { + var dict = new Dictionary<string, string>(); + dict.Add(vm.ElementName, "PowerOn"); + hostVmStateReport.Add(dict); + } + } + } } } catch (Exception sysEx) http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ec7497e/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs index 8c682ad..c5e5bf3 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs @@ -69,6 +69,7 @@ namespace HypervResource void patchSystemVmIso(string vmName, string systemVmIso); void SetState(ComputerSystem vm, ushort requiredState); Dictionary<String, VmState> GetVmSync(String privateIpAddress); + string GetVmNote(System.Management.ManagementPath sysPath); void ModifyVmVLan(string vmName, uint vlanid, string mac); void ModifyVmVLan(string vmName, uint vlanid, uint pos); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ec7497e/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs index c10aaa3..4795073 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs @@ -489,6 +489,8 @@ namespace HypervResource logger.DebugFormat("Starting VM {0}", vmName); SetState(newVm, RequiredState.Enabled); + // Mark the VM as created by cloudstack tag + TagVm(newVm); // we need to reboot to get the hv kvp daemon get started vr gets configured. if (vmName.StartsWith("r-") || vmName.StartsWith("s-") || vmName.StartsWith("v-")) @@ -1514,9 +1516,6 @@ namespace HypervResource logger.DebugFormat("Setting network rate limit to {0}", limit); var vmVirtMgmtSvc = GetVirtualisationSystemManagementService(); - // EthernetSwitchPortBandwidthSettingData.GetInstances(); - - // Create NIC resource by cloning the default NIC var bandwidthSettings = EthernetSwitchPortBandwidthSettingData.GetInstances(vmVirtMgmtSvc.Scope, "InstanceID LIKE \"%Default\""); // Assert @@ -1703,6 +1702,31 @@ namespace HypervResource } } + private static void ModifySystemSetting(VirtualSystemManagementService vmMgmtSvc, string systemSettings) + { + // Resource settings are changed through the management service + System.Management.ManagementPath jobPath; + + var ret_val = vmMgmtSvc.ModifySystemSettings( + systemSettings, + out jobPath); + + // If the Job is done asynchronously + if (ret_val == ReturnCode.Started) + { + JobCompleted(jobPath); + } + else if (ret_val != ReturnCode.Completed) + { + var errMsg = string.Format( + "Failed to update system setting {0}", + ReturnCode.ToString(ret_val)); + var ex = new WmiException(errMsg); + logger.Error(errMsg, ex); + throw ex; + } + } + public void DeleteHostKvpItem(ComputerSystem vm, string key) { // Obtain controller for Hyper-V virtualisation subsystem @@ -1740,6 +1764,16 @@ namespace HypervResource } } + public Boolean TagVm(ComputerSystem vm) + { + VirtualSystemManagementService vmMgmtSvc = GetVirtualisationSystemManagementService(); + VirtualSystemSettingData vmSettings = GetVmSettings(vm); + + vmSettings.LateBoundObject["Notes"] = new string[] { "Created by CloudStack, do not edit. \n" }; + ModifySystemSetting(vmMgmtSvc, vmSettings.LateBoundObject.GetText(TextFormat.CimDtd20)); + return true; + } + private static ComputerSystem CreateDefaultVm(VirtualSystemManagementService vmMgmtSvc, string name) { // Tweak default settings by basing new VM on default global setting object @@ -1750,6 +1784,7 @@ namespace HypervResource vs_gs_data.LateBoundObject["ElementName"] = name; vs_gs_data.LateBoundObject["AutomaticStartupAction"] = startupAction.ToString(); vs_gs_data.LateBoundObject["AutomaticShutdownAction"] = stopAction.ToString(); + vs_gs_data.LateBoundObject["Notes"] = new string[] { "CloudStack creating VM, do not edit. \n" }; System.Management.ManagementPath jobPath; System.Management.ManagementPath defined_sys; @@ -2455,6 +2490,22 @@ namespace HypervResource vmProcessorInfo.Add(summaryInfo.ElementName, vmInfo); } } + + public string GetVmNote(System.Management.ManagementPath sysPath) + { + uint[] requestedInfo = new uint[] { 3 }; + System.Management.ManagementPath[] vmPaths = new System.Management.ManagementPath[] { sysPath }; + var vmsvc = GetVirtualisationSystemManagementService(); + System.Management.ManagementBaseObject[] sysSummary; + vmsvc.GetSummaryInformation(requestedInfo, vmPaths, out sysSummary); + foreach (var summary in sysSummary) + { + var summaryInfo = new SummaryInformation(summary); + return summaryInfo.Notes; + } + + return null; + } } public class WmiException : Exception @@ -2694,7 +2745,7 @@ namespace HypervResource public static string ToCloudStackPowerState(UInt16 value) { - string result = "Unknown"; + string result = "PowerUnknown"; switch (value) { case Enabled: result = "PowerOn"; break;