예제 #1
0
        public static MountedDiskInfo GetMountedDiskInfo(string serverName, int driveNumber)
        {
            MountedDiskInfo diskInfo = new MountedDiskInfo { DiskNumber = driveNumber };

            // find mounted disk using VDS
            AdvancedDisk advancedDisk = null;
            Pack diskPack = null;

            // first attempt
            Thread.Sleep(3000);
            HostedSolutionLog.LogInfo("Trying to find mounted disk - first attempt");
            FindVdsDisk(serverName, diskInfo.DiskNumber, out advancedDisk, out diskPack);

            // second attempt
            if (advancedDisk == null)
            {
                Thread.Sleep(20000);
                HostedSolutionLog.LogInfo("Trying to find mounted disk - second attempt");
                FindVdsDisk(serverName, diskInfo.DiskNumber, out advancedDisk, out diskPack);
            }

            if (advancedDisk == null)
                throw new Exception("Could not find mounted disk");

            // Set disk address
            diskInfo.DiskAddress = advancedDisk.DiskAddress;
            var addressParts = diskInfo.DiskAddress.ParseExact("Port{0}Path{1}Target{2}Lun{3}");
            var portNumber = addressParts[0];
            var targetId = addressParts[2];
            var lun = addressParts[3];

            // check if DiskPart must be used to bring disk online and clear read-only flag
            bool useDiskPartToClearReadOnly = false;
            if (ConfigurationManager.AppSettings[Constants.CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG] != null)
                useDiskPartToClearReadOnly = Boolean.Parse(ConfigurationManager.AppSettings[Constants.CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG]);

            // determine disk index for DiskPart
            Wmi cimv2 = new Wmi(serverName, Constants.WMI_CIMV2_NAMESPACE);
            ManagementObject objDisk = cimv2.GetWmiObject("win32_diskdrive",
                "Model='Msft Virtual Disk SCSI Disk Device' and ScsiTargetID={0} and ScsiLogicalUnit={1} and scsiPort={2}",
                targetId, lun, portNumber);

            if (useDiskPartToClearReadOnly)
            {
                // *** Clear Read-Only and bring disk online with DiskPart ***
                HostedSolutionLog.LogInfo("Clearing disk Read-only flag and bringing disk online");

                if (objDisk != null)
                {
                    // disk found
                    // run DiskPart
                    string diskPartResult = RunDiskPart(serverName, String.Format(@"select disk {0}
attributes disk clear readonly
online disk
exit", Convert.ToInt32(objDisk["Index"])));

                    HostedSolutionLog.LogInfo("DiskPart Result: " + diskPartResult);
                }
            }
            else
            {
                // *** Clear Read-Only and bring disk online with VDS ***
                // clear Read-Only
                if ((advancedDisk.Flags & DiskFlags.ReadOnly) == DiskFlags.ReadOnly)
                {
                    HostedSolutionLog.LogInfo("Clearing disk Read-only flag");
                    advancedDisk.ClearFlags(DiskFlags.ReadOnly);
                    while ((advancedDisk.Flags & DiskFlags.ReadOnly) == DiskFlags.ReadOnly)
                    {
                        Thread.Sleep(100);
                        advancedDisk.Refresh();
                    }
                }

                // bring disk ONLINE
                if (advancedDisk.Status == DiskStatus.Offline)
                {
                    HostedSolutionLog.LogInfo("Bringing disk online");
                    advancedDisk.Online();
                    while (advancedDisk.Status == DiskStatus.Offline)
                    {
                        Thread.Sleep(100);
                        advancedDisk.Refresh();
                    }
                }
            }

            // small pause after getting disk online
            Thread.Sleep(3000);

            // get disk again
            FindVdsDisk(serverName, diskInfo.DiskNumber, out advancedDisk, out diskPack);

            // find volumes using VDS
            List<string> volumes = new List<string>();
            HostedSolutionLog.LogInfo("Querying disk volumes with VDS");
            foreach (Volume volume in diskPack.Volumes)
            {
                string letter = volume.DriveLetter.ToString();
                if (letter != "")
                    volumes.Add(letter);
            }

            // find volumes using WMI
            if (volumes.Count == 0 && objDisk != null)
            {
                HostedSolutionLog.LogInfo("Querying disk volumes with WMI");
                foreach (ManagementObject objPartition in objDisk.GetRelated("Win32_DiskPartition"))
                {
                    foreach (ManagementObject objVolume in objPartition.GetRelated("Win32_LogicalDisk"))
                    {
                        volumes.Add(objVolume["Name"].ToString().TrimEnd(':'));
                    }
                }
            }

            HostedSolutionLog.LogInfo("Volumes found: " + volumes.Count);

            // Set volumes
            diskInfo.DiskVolumes = volumes.ToArray();

            return diskInfo;
        }
예제 #2
0
        public MountedDiskInfo MountVirtualHardDisk(string vhdPath)
        {
            ManagementObject objImgSvc = GetImageManagementService();

            // get method params
            ManagementBaseObject inParams = objImgSvc.GetMethodParameters("Mount");
            inParams["Path"] = FileUtils.EvaluateSystemVariables(vhdPath);

            ManagementBaseObject outParams = (ManagementBaseObject)objImgSvc.InvokeMethod("Mount", inParams, null);
            JobResult result = CreateJobResultFromWmiMethodResults(outParams);

            // load storage job
            if (result.ReturnValue != ReturnCode.JobStarted)
                throw new Exception("Failed to start Mount job with the following error: " + result.ReturnValue); ;

            ManagementObject objJob = wmi.GetWmiObject("msvm_StorageJob", "InstanceID = '{0}'", result.Job.Id);

            if (!JobCompleted(result.Job))
                throw new Exception("Failed to complete Mount job with the following error: " + result.Job.ErrorDescription);

            try
            {
                List<string> volumes = new List<string>();

                // load output data
                ManagementObject objImage = wmi.GetRelatedWmiObject(objJob, "Msvm_MountedStorageImage");

                int pathId = Convert.ToInt32(objImage["PathId"]);
                int portNumber = Convert.ToInt32(objImage["PortNumber"]);
                int targetId = Convert.ToInt32(objImage["TargetId"]);
                int lun = Convert.ToInt32(objImage["Lun"]);

                string diskAddress = String.Format("Port{0}Path{1}Target{2}Lun{3}", portNumber, pathId, targetId, lun);

                Log.WriteInfo("Disk address: " + diskAddress);

                // find mounted disk using VDS
                Vds.Advanced.AdvancedDisk advancedDisk = null;
                Vds.Pack diskPack = null;

                // first attempt
                System.Threading.Thread.Sleep(3000);
                Log.WriteInfo("Trying to find mounted disk - first attempt");
                FindVdsDisk(diskAddress, out advancedDisk, out diskPack);

                // second attempt
                if (advancedDisk == null)
                {
                    System.Threading.Thread.Sleep(20000);
                    Log.WriteInfo("Trying to find mounted disk - second attempt");
                    FindVdsDisk(diskAddress, out advancedDisk, out diskPack);
                }

                if (advancedDisk == null)
                    throw new Exception("Could not find mounted disk");

                // check if DiskPart must be used to bring disk online and clear read-only flag
                bool useDiskPartToClearReadOnly = false;
                if (ConfigurationManager.AppSettings[CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG] != null)
                    useDiskPartToClearReadOnly = Boolean.Parse(ConfigurationManager.AppSettings[CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG]);

                // determine disk index for DiskPart
                Wmi cimv2 = new Wmi(ServerNameSettings, WMI_CIMV2_NAMESPACE);
                ManagementObject objDisk = cimv2.GetWmiObject("win32_diskdrive",
                    "Model='Msft Virtual Disk SCSI Disk Device' and ScsiTargetID={0} and ScsiLogicalUnit={1} and scsiPort={2}",
                    targetId, lun, portNumber);

                if (useDiskPartToClearReadOnly)
                {
                    // *** Clear Read-Only and bring disk online with DiskPart ***
                    Log.WriteInfo("Clearing disk Read-only flag and bringing disk online");

                    if (objDisk != null)
                    {
                        // disk found
                        // run DiskPart
                        string diskPartResult = RunDiskPart(String.Format(@"select disk {0}
attributes disk clear readonly
online disk
exit", Convert.ToInt32(objDisk["Index"])));

                        Log.WriteInfo("DiskPart Result: " + diskPartResult);
                    }
                }
                else
                {
                    // *** Clear Read-Only and bring disk online with VDS ***
                    // clear Read-Only
                    if ((advancedDisk.Flags & Vds.DiskFlags.ReadOnly) == Vds.DiskFlags.ReadOnly)
                    {
                        Log.WriteInfo("Clearing disk Read-only flag");
                        advancedDisk.ClearFlags(Vds.DiskFlags.ReadOnly);
                        while ((advancedDisk.Flags & Vds.DiskFlags.ReadOnly) == Vds.DiskFlags.ReadOnly)
                        {
                            System.Threading.Thread.Sleep(100);
                            advancedDisk.Refresh();
                        }
                    }

                    // bring disk ONLINE
                    if (advancedDisk.Status == Vds.DiskStatus.Offline)
                    {
                        Log.WriteInfo("Bringing disk online");
                        advancedDisk.Online();
                        while (advancedDisk.Status == Vds.DiskStatus.Offline)
                        {
                            System.Threading.Thread.Sleep(100);
                            advancedDisk.Refresh();
                        }
                    }
                }

                // small pause after getting disk online
                System.Threading.Thread.Sleep(3000);

                // get disk again
                FindVdsDisk(diskAddress, out advancedDisk, out diskPack);

                // find volumes using VDS
                Log.WriteInfo("Querying disk volumes with VDS");
                foreach (Vds.Volume volume in diskPack.Volumes)
                {
                    string letter = volume.DriveLetter.ToString();
                    if(letter != "")
                        volumes.Add(letter);
                }

                // find volumes using WMI
                if (volumes.Count == 0 && objDisk != null)
                {
                    Log.WriteInfo("Querying disk volumes with WMI");
                    foreach (ManagementObject objPartition in objDisk.GetRelated("Win32_DiskPartition"))
                    {
                        foreach (ManagementObject objVolume in objPartition.GetRelated("Win32_LogicalDisk"))
                        {
                            volumes.Add(objVolume["Name"].ToString().TrimEnd(':'));
                        }
                    }
                }

                Log.WriteInfo("Volumes found: " + volumes.Count);

                // info object
                MountedDiskInfo info = new MountedDiskInfo();
                info.DiskAddress = diskAddress;
                info.DiskVolumes = volumes.ToArray();
                return info;
            }
            catch(Exception ex)
            {
                // unmount disk
                UnmountVirtualHardDisk(vhdPath);

                // throw error
                throw ex;
            }
        }
예제 #3
0
        public static MountedDiskInfo GetMountedDiskInfo(string serverName, int driveNumber)
        {
            MountedDiskInfo diskInfo = new MountedDiskInfo {
                DiskNumber = driveNumber
            };

            // find mounted disk using VDS
            AdvancedDisk advancedDisk = null;
            Pack         diskPack     = null;

            // first attempt
            Thread.Sleep(3000);
            HostedSolutionLog.LogInfo("Trying to find mounted disk - first attempt");
            FindVdsDisk(serverName, diskInfo.DiskNumber, out advancedDisk, out diskPack);

            // second attempt
            if (advancedDisk == null)
            {
                Thread.Sleep(20000);
                HostedSolutionLog.LogInfo("Trying to find mounted disk - second attempt");
                FindVdsDisk(serverName, diskInfo.DiskNumber, out advancedDisk, out diskPack);
            }

            if (advancedDisk == null)
            {
                throw new Exception("Could not find mounted disk");
            }

            // Set disk address
            diskInfo.DiskAddress = advancedDisk.DiskAddress;
            var addressParts = diskInfo.DiskAddress.ParseExact("Port{0}Path{1}Target{2}Lun{3}");
            var portNumber   = addressParts[0];
            var targetId     = addressParts[2];
            var lun          = addressParts[3];

            // check if DiskPart must be used to bring disk online and clear read-only flag
            bool useDiskPartToClearReadOnly = false;

            if (ConfigurationManager.AppSettings[Constants.CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG] != null)
            {
                useDiskPartToClearReadOnly = Boolean.Parse(ConfigurationManager.AppSettings[Constants.CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG]);
            }

            // determine disk index for DiskPart
            Wmi cimv2 = new Wmi(serverName, Constants.WMI_CIMV2_NAMESPACE);
            ManagementObject objDisk = cimv2.GetWmiObject("win32_diskdrive",
                                                          "Model='Msft Virtual Disk SCSI Disk Device' and ScsiTargetID={0} and ScsiLogicalUnit={1} and scsiPort={2}",
                                                          targetId, lun, portNumber);

            if (useDiskPartToClearReadOnly)
            {
                // *** Clear Read-Only and bring disk online with DiskPart ***
                HostedSolutionLog.LogInfo("Clearing disk Read-only flag and bringing disk online");

                if (objDisk != null)
                {
                    // disk found
                    // run DiskPart
                    string diskPartResult = RunDiskPart(serverName, String.Format(@"select disk {0}
attributes disk clear readonly
online disk
exit", Convert.ToInt32(objDisk["Index"])));

                    HostedSolutionLog.LogInfo("DiskPart Result: " + diskPartResult);
                }
            }
            else
            {
                // *** Clear Read-Only and bring disk online with VDS ***
                // clear Read-Only
                if ((advancedDisk.Flags & DiskFlags.ReadOnly) == DiskFlags.ReadOnly)
                {
                    HostedSolutionLog.LogInfo("Clearing disk Read-only flag");
                    advancedDisk.ClearFlags(DiskFlags.ReadOnly);
                    while ((advancedDisk.Flags & DiskFlags.ReadOnly) == DiskFlags.ReadOnly)
                    {
                        Thread.Sleep(100);
                        advancedDisk.Refresh();
                    }
                }

                // bring disk ONLINE
                if (advancedDisk.Status == DiskStatus.Offline)
                {
                    HostedSolutionLog.LogInfo("Bringing disk online");
                    advancedDisk.Online();
                    while (advancedDisk.Status == DiskStatus.Offline)
                    {
                        Thread.Sleep(100);
                        advancedDisk.Refresh();
                    }
                }
            }

            // small pause after getting disk online
            Thread.Sleep(3000);

            // get disk again
            FindVdsDisk(serverName, diskInfo.DiskNumber, out advancedDisk, out diskPack);

            // find volumes using VDS
            List <string> volumes = new List <string>();

            HostedSolutionLog.LogInfo("Querying disk volumes with VDS");
            foreach (Volume volume in diskPack.Volumes)
            {
                string letter = volume.DriveLetter.ToString();
                if (letter != "")
                {
                    volumes.Add(letter);
                }
            }

            // find volumes using WMI
            if (volumes.Count == 0 && objDisk != null)
            {
                HostedSolutionLog.LogInfo("Querying disk volumes with WMI");
                foreach (ManagementObject objPartition in objDisk.GetRelated("Win32_DiskPartition"))
                {
                    foreach (ManagementObject objVolume in objPartition.GetRelated("Win32_LogicalDisk"))
                    {
                        volumes.Add(objVolume["Name"].ToString().TrimEnd(':'));
                    }
                }
            }

            HostedSolutionLog.LogInfo("Volumes found: " + volumes.Count);

            // Set volumes
            diskInfo.DiskVolumes = volumes.ToArray();

            return(diskInfo);
        }