none
PRB - Hyper-V/WMI locks VM after it is created RRS feed

  • Question

  • PRB - Hyper-V/WMI locks VM after it is created.

    Please help,

    First off, I posted this issue in MSDN Forums, and they ultimately said go to the technet forums. So I did.

    The technet forum people said, no, go back to msdn:
    http://social.technet.microsoft.com/Forums/en-US/winserverhyperv/thread/aa5a5fd0-95ec-419d-86f4-6bd2e6fdf802/

    So I do not know where to go with this issue, it involves C#, ASP.NET, Hyper-V and WMI.

    The issue:

    I'm using code below to create a VM. The following code creates a VM on a remote Hyper-V server. But after it completes, the VM is locked, and can not be deleted, unless a reboot is done on the Hyper-V Server. Please understand, I do not want a "Delet VM" solution. I am saying, that the Hyper-V Manager can not delete a VM I create through this code, because something locks it. The lock is on one or more of the VM's XML file(s) it appears, inside the Hyper-V's VM storage directy, typically as such: c:\ProgramData\Microsoft\Windows\Hyper-V\Virtual Machines\~~~~.xml. The lock stays until I reboot the Hyper-V machine. Note, after the VM is created, it is not "Turned On". IE, it is in the "Off" state, and thus it is not running which of course would indicate a file lock on its own files.

    Again the issue is not to delete a VM, but to ensure the lock on the VM (and its files) get released properly.

    What is causing this? Is there any EXTREME measure that can be taken programmtically to 100% remove the lock? That is, from the remote machine invoking the WMI to tell the Hyper-V release the VM?

    The machines I used for this was the remote machine was Windows Server 2008 R1 (x86), to the Hyper-V machine being a windows Server 2008 R2 (x64).

    The code ------------------------------------------------------------
     

     

    ManagementScope ManagementScope_Temp = null;

    try
    {
      ConnectionOptions ConnectionOptions_Temp = new ConnectionOptions();
      ConnectionOptions_Temp.Username  = "GOD"; // Has access to anything and everything..
      ConnectionOptions_Temp.Authority = "ntlmdomain:MyHyperVServer";
      ConnectionOptions_Temp.Password  = "~~SECRET~~";

      ManagementScope_Temp = new ManagementScope
      (
        "\\\\MyHyperVServer\\root\\virtualization",
        ConnectionOptions_Temp
      );

      ManagementScope_Temp.Connect();

      string csRET;

      ManagementObject ManagementObject_GlobalSettingData = null;
      ManagementBaseObject ManagementBaseObject_InParams = null;
      ManagementObject ManagementObject_VSMS = null;
      ManagementObjectCollection ManagementObjectCollection_DMI = null;
      ManagementObject ManagementObject_DefaultMemory = null;
      ManagementBaseObject_OutParams = null;

      try
      {
        ManagementObject_VSMS = GetServiceObject
        (
          ManagementScope_Param, "Msvm_VirtualSystemManagementService"
        );

        ManagementBaseObject_InParams = (ManagementBaseObject)
        (
          ManagementObject_VSMS.GetMethodParameters
          (
            "DefineVirtualSystem"
          )
        );

        ManagementBaseObject_InParams["ResourcesettingData"] = null;
        ManagementBaseObject_InParams["Sourcesetting"] = null;
        string csInstanceSettingData;

        csRET = GetVirtualSystemGlobalSettingDataInstance
        (
          ManagementScope_Param, out ManagementObject_GlobalSettingData
        );

        if (csRET != "RET=OK")
        {
          return csRET;
        }

        ManagementObject_GlobalSettingData["ElementName"] = "My VM";
        csInstanceSettingData = ManagementObject_GlobalSettingData.GetText(TextFormat.CimDtd20);
        ManagementBaseObject_InParams["SystemSettingData"] = csInstanceSettingData;

        ManagementBaseObject_OutParams = (ManagementBaseObject)
        (
          ManagementObject_VSMS.InvokeMethod
          (
            "DefineVirtualSystem", ManagementBaseObject_InParams, null
          )
        );
      }
      catch (Exception e)
      {
        return "RET=ERR";
      }
      finally
      {
        if (!IsNull(ManagementObject_GlobalSettingData))
        {
          try { ManagementObject_GlobalSettingData.Dispose(); } catch(Exception) { }
          ManagementObject_GlobalSettingData = null;
        }

        if (!IsNull(ManagementBaseObject_InParams))
        {
          try { ManagementBaseObject_InParams.Dispose(); } catch(Exception) { }
          ManagementBaseObject_InParams = null;
        }

        if (!IsNull(ManagementObjectCollection_DMI))
        {
          try { ManagementObjectCollection_DMI.Dispose(); } catch(Exception) { }
          ManagementObjectCollection_DMI = null;
        }

        if (!IsNull(ManagementObject_VSMS))
        {
          try { ManagementObject_VSMS.Dispose(); } catch(Exception) { }
          ManagementObject_VSMS = null;
        }
      }

      ManagementObject ManagementObject_Job = null;

      try
      {
        string csJobPath = CSStr(ManagementBaseObject_OutParams["Job"]);
        ManagementObject_Job = new ManagementObject
        (
          ManagementScope_Temp, new ManagementPath(csJobPath), null
        );

        while
        (
          (UInt16) ManagementObject_Job["JobState"] == JobState.Starting
          ||
          (UInt16) ManagementObject_Job["JobState"] == JobState.Running
        )
        {
          if (uiTIMEOUT > 0)
          {
            return "RET=OK LA=TIMEOUT";
          }

          System.Threading.Thread.Sleep(100);
          ManagementObject_Job.Get();
        }

        uiJobState = (UInt16) ManagementObject_Job["JobState"];

        if (uiJobState != JobState.Completed)
        {
          UInt16 uiJobErrorCode = (UInt16) ManagementObject_Job["ErrorCode"];
          string csErrorDescription = CSStr(ManagementObject_Job["ErrorDescription"]);
          return "RET=ERR ERR=JOB-FAILED";
        }
      }
      catch (Exception e)
      {
        return "RET=ERR ERR=EXCEPTION";
      }
      finally
      {
        if (!IsNull(ManagementObject_Job))
        {
          try { ManagementObject_Job.Dispose(); } catch(Exception) {}
          ManagementObject_Job = null;
        }
      }

      return "RET=OK";
    }
    catch(Exception e)
    {
    }
    finally
    {
      if (ManagementScope_Temp != null)
      {
        ManagementScope_Param.Path = null; // Disconnect the scope...
        ManagementScope_Temp = null;
      }
    }

    -------------------------- The results....
    At this point, this program ends. The Hyper-V Manager shows the VM created. Attempts to delete the VM from Hyper-V Manager returns an error:

     "My VM" failed to delete configuration: General access denied" (0x80070005) (Virtual machine ID ~~~~~~~~)


    ---------------------- Support functions used in the above code -----------------------------------------------------

        public static ManagementObjectCollection GetServiceObjectCollection
        (
          ManagementScope ManagementScope_Param, string csServiceName
        )
        {
          ManagementPath ManagementPath_WMI = null;
          ManagementClass ManagementClass_Service = null;
          ManagementObjectCollection ManagementObjectCollection_Services = null;

          try
          {
            ManagementPath_WMI = new ManagementPath(csServiceName);
            ManagementClass_Service = new ManagementClass(ManagementScope_Param, ManagementPath_WMI, null);
            ManagementObjectCollection_Services = ManagementClass_Service.GetInstances();
            return ManagementObjectCollection_Services;
          }
          catch (Exception e)
          {
            if (IsBlank(e.Message))
            {
            }
          }
          finally
          {
            if (!IsNull(ManagementClass_Service))
            {
              try { ManagementClass_Service.Dispose(); } catch(Exception) {}
              ManagementClass_Service = null;
            }
          }

          return null;
        }

        public static string GetVirtualSystemGlobalSettingDataInstance
        (
          ManagementScope ManagementScope_Param,
          out ManagementObject ManagementObject_GlobalSettingData
        )
        {
          ManagementPath ManagementPath_SettingPath = null;
          ManagementClass ManagementClass_GlobalSettingClass = null;
          ManagementObject_GlobalSettingData = null;

          try
          {
            ManagementPath_SettingPath = new ManagementPath
            (
              "Msvm_VirtualSystemGlobalsettingData"
            );
            ManagementClass_GlobalSettingClass = new ManagementClass
            (
              ManagementScope_Param, ManagementPath_SettingPath, null
            );
            ManagementObject_GlobalSettingData = ManagementClass_GlobalSettingClass.CreateInstance();
          }
          catch (Exception e)
          {
            return "RET=ERR";
          }
          finally
          {
            if (!IsNull(ManagementClass_GlobalSettingClass))
            {
              try { ManagementClass_GlobalSettingClass.Dispose(); } catch(Exception) { }
              ManagementClass_GlobalSettingClass = null;
            }
          }

          return "RET=OK";
        }

     

    Wednesday, January 27, 2010 2:16 PM