Calculates the minimum sizes required for various hard drives / partitions for the client imaging process
Exemplo n.º 1
0
 public ClientPartition(int hdToGet, string newHdSize, Models.ImageProfile imageProfile, string partitionPrefix)
 {
     _hdToGet      = hdToGet;
     _newHdSize    = (long)(Convert.ToInt64(newHdSize) * .99);
     _imageProfile = imageProfile;
     PrimaryAndExtendedPartitions = new List <Models.ClientPartition>();
     LogicalPartitions            = new List <Models.ClientPartition>();
     LogicalVolumes     = new List <ClientLogicalVolume>();
     VolumeGroupHelpers = new List <ClientVolumeGroupHelper>();
     _imageSchema       = new ClientPartitionHelper(_imageProfile).GetImageSchema();
 }
Exemplo n.º 2
0
        private string GenerateProcessArguments()
        {
            var isUnix = Environment.OSVersion.ToString().Contains("Unix");

            var schema = new ClientPartitionHelper(_imageProfile).GetImageSchema();

            var schemaCounter = -1;
            var multicastHdCounter = 0;
            string processArguments = null;
            foreach (var hd in schema.HardDrives)
            {
                schemaCounter++;
                if (!hd.Active) continue;
                multicastHdCounter++;

                var imagePath = Settings.PrimaryStoragePath + "images" + Path.DirectorySeparatorChar +
                                _imageProfile.Image.Name + Path.DirectorySeparatorChar + "hd" +
                                schemaCounter;

                var x = 0;
                foreach (var part in schema.HardDrives[schemaCounter].Partitions)
                {
                    if (!part.Active) continue;
                    string imageFile = null;
                    foreach (var ext in new[] {".ntfs", ".fat", ".extfs", ".hfsp", ".imager", ".winpe", ".xfs"})
                    {
                        try
                        {
                            imageFile =
                         Directory.GetFiles(
                             imagePath + Path.DirectorySeparatorChar, "part" + part.Number + ext + ".*")
                             .FirstOrDefault();
                        }
                        catch (Exception ex)
                        {
                            Logger.Log(ex.Message);
                            return null;

                        }

                        if (imageFile != null) break;

                        //Look for lvm
                        if (part.VolumeGroup == null) continue;
                        if (part.VolumeGroup.LogicalVolumes == null) continue;
                        foreach (var lv in part.VolumeGroup.LogicalVolumes.Where(lv => lv.Active))
                        {
                            try
                            {
                                imageFile =
                             Directory.GetFiles(
                                 imagePath + imagePath + Path.DirectorySeparatorChar, lv.VolumeGroup + "-" +
                                                                                      lv.Name + ext + ".*")
                                 .FirstOrDefault();
                            }
                            catch (Exception ex)
                            {
                                Logger.Log(ex.Message);
                                return null;
                            }

                        }
                    }

                    if (imageFile == null)
                        continue;
                    if (_imageProfile.Image.Environment == "winpe" &&
                        schema.HardDrives[schemaCounter].Table.ToLower() == "gpt")
                    {
                        if (part.Type.ToLower() == "system" || part.Type.ToLower() == "recovery" ||
                            part.Type.ToLower() == "reserved")
                            continue;
                    }
                    if (_imageProfile.Image.Environment == "winpe" &&
                        schema.HardDrives[schemaCounter].Table.ToLower() == "mbr")
                    {
                        if (part.Number == schema.HardDrives[schemaCounter].Boot && schema.HardDrives[schemaCounter].Partitions.Length > 1)
                            continue;
                    }
                    x++;

                    string minReceivers;
                    string senderArgs;
                    if (_isOnDemand)
                    {
                        senderArgs = Settings.SenderArgs;
                        if (!string.IsNullOrEmpty(_clientCount))
                            minReceivers = " --min-receivers " + _clientCount;
                        else
                            minReceivers = "";
                    }
                    else
                    {
                        senderArgs = string.IsNullOrEmpty(_imageProfile.SenderArguments)
                            ? Settings.SenderArgs
                            : _imageProfile.SenderArguments;
                        minReceivers = " --min-receivers " + _computers.Count;
                    }

                    string compAlg;
                    string stdout = "";
                    switch (Path.GetExtension(imageFile))
                    {
                        case ".lz4":
                            compAlg = isUnix ? "lz4 -d " : "lz4.exe\" -d ";
                            stdout = " - ";
                            break;
                        case ".gz":
                            compAlg = isUnix ? "gzip -c -d " : "gzip.exe\" -c -d ";
                            stdout = "";
                            break;
                        case ".uncp":
                            compAlg = "none";
                            break;
                        case ".wim":
                            compAlg = "none";
                            break;
                        default:
                            return null;
                    }

                    if (isUnix)
                    {
                        string prefix = null;
                        if(multicastHdCounter == 1)
                            prefix = x == 1 ? " -c \"" : " ; ";
                        else
                            prefix = " ; ";

                        if (compAlg == "none" || Settings.MulticastDecompression == "client")
                        {
                            processArguments += (prefix + "cat " + "\"" + imageFile + "\"" + " | udp-sender" +
                                                 " --portbase " + _multicastSession.Port + minReceivers + " " +
                                                 " --ttl 32 " +
                                                 senderArgs);
                        }

                        else
                        {
                            processArguments += (prefix + compAlg + "\"" + imageFile + "\"" + stdout + " | udp-sender" +
                                                 " --portbase " + _multicastSession.Port + minReceivers + " " +
                                                 " --ttl 32 " +
                                                 senderArgs);
                        }
                    }
                    else
                    {
                        var appPath = HttpContext.Current.Server.MapPath("~") + Path.DirectorySeparatorChar + "private" +
                                      Path.DirectorySeparatorChar + "apps" + Path.DirectorySeparatorChar;

                        string prefix = null;
                        if (multicastHdCounter == 1)
                            prefix = x == 1 ? " /c \"" : " & ";
                        else
                            prefix = " & ";

                        if (compAlg == "none" || Settings.MulticastDecompression == "client")
                        {
                            processArguments += (prefix + "\"" + appPath +
                                                 "udp-sender.exe" + "\"" + " --file " + "\"" + imageFile + "\"" +
                                                 " --portbase " + _multicastSession.Port + minReceivers + " " +
                                                 " --ttl 32 " +
                                                 senderArgs);
                        }
                        else
                        {
                            processArguments += (prefix + "\"" + appPath + compAlg + "\"" + imageFile + "\"" + stdout + " | " + "\"" + appPath +
                                                 "udp-sender.exe" + "\"" +
                                                 " --portbase " + _multicastSession.Port + minReceivers + " " +
                                                 " --ttl 32 " +
                                                 senderArgs);
                        }

                    }
                }
            }

            processArguments += "\"";
            return processArguments;
        }
Exemplo n.º 3
0
        public string GeneratePartitionScript()
        {
            imageProfile = BLL.ImageProfile.ReadProfile(profileId);
            ImageSchema = new ClientPartitionHelper(imageProfile).GetImageSchema();

            clientSchema = new ClientPartition(HdNumberToGet, NewHdSize, imageProfile, partitionPrefix).GenerateClientSchema();
            if (clientSchema == null) return "failed";

            //Handle moving from / to hard drives with different sector sizes ie 512 / 4096
            var activeCounter = HdNumberToGet;
            //Look for first active hd
            if (!ImageSchema.HardDrives[HdNumberToGet].Active)
            {
                while (activeCounter <= ImageSchema.HardDrives.Count())
                {
                    if (ImageSchema.HardDrives[activeCounter - 1].Active)
                    {
                        HdNumberToGet = activeCounter - 1;
                    }
                    activeCounter++;
                }
            }
            var LbsByte = Convert.ToInt32(ImageSchema.HardDrives[HdNumberToGet].Lbs); //logical block size in bytes
            if (LbsByte == 512 && clientBlockSize == 4096)
            {

                //fix calculations from 512 to 4096
                clientSchema.FirstPartitionStartSector = clientSchema.FirstPartitionStartSector/8;
                clientSchema.ExtendedPartitionHelper.AgreedSizeBlk = clientSchema.ExtendedPartitionHelper.AgreedSizeBlk/
                                                                     8;
                foreach (var partition in clientSchema.PrimaryAndExtendedPartitions)
                {
                    //efi partition on 4k drive cannot be smaller than this, and it is smaller on a 512 drive
                    if (partition.FsId.ToLower() == "ef00")
                        partition.Size = 66560;
                    else
                        partition.Size = partition.Size/8;
                    partition.Start = partition.Size/8;
                }

                foreach (var partition in clientSchema.LogicalPartitions)
                {
                    partition.Size = partition.Size / 8;
                    partition.Start = partition.Size / 8;
                }

                foreach (var lv in clientSchema.LogicalVolumes)
                {
                    lv.Size = lv.Size / 8;
                }

            }
            else if (LbsByte == 4096 && clientBlockSize == 512)
            {
                //fix calculations from 4096 to 512
                clientSchema.FirstPartitionStartSector = clientSchema.FirstPartitionStartSector * 8;
                clientSchema.ExtendedPartitionHelper.AgreedSizeBlk = clientSchema.ExtendedPartitionHelper.AgreedSizeBlk *
                                                                     8;
                foreach (var partition in clientSchema.PrimaryAndExtendedPartitions)
                {
                    partition.Size = partition.Size * 8;
                    partition.Start = partition.Size * 8;
                }

                foreach (var partition in clientSchema.LogicalPartitions)
                {
                    partition.Size = partition.Size * 8;
                    partition.Start = partition.Size * 8;
                }

                foreach (var lv in clientSchema.LogicalVolumes)
                {
                    lv.Size = lv.Size * 8;
                }
            }

            //otherwise both the original image block size and the destination hard block size are the same, no changes needed
            //End Handle moving from / to hard drives with different sector sizes

            if (imageProfile.Image.Environment == "linux" || string.IsNullOrEmpty(imageProfile.Image.Environment))
            {
                return LinuxLayout();
            }
            else if(imageProfile.Image.Environment == "macOS")
            {
                return OsxNbiLayout();
            }
            else if (imageProfile.Image.Environment == "winpe")
            {
                return WinPELayout();
            }
            else
            {
                return "failed";
            }
        }
Exemplo n.º 4
0
        public string GetOriginalLvm(int profileId, string clientHd, string hdToGet, string partitionPrefix)
        {
            string result = null;

            var imageProfile = BLL.ImageProfile.ReadProfile(profileId);
            var hdNumberToGet = Convert.ToInt32(hdToGet);
            var partitionHelper = new ClientPartitionHelper(imageProfile);
            var imageSchema = partitionHelper.GetImageSchema();
            foreach (var part in from part in imageSchema.HardDrives[hdNumberToGet].Partitions
                                 where part.Active
                                 where part.VolumeGroup != null
                                 where part.VolumeGroup.LogicalVolumes != null
                                 select part)
            {
                result = "pvcreate -u " + part.Uuid + " --norestorefile -yf " +
                         clientHd + partitionPrefix + part.VolumeGroup.PhysicalVolume[part.VolumeGroup.PhysicalVolume.Length - 1] + "\r\n";
                result += "vgcreate " + part.VolumeGroup.Name + " " + clientHd + partitionPrefix +
                          part.VolumeGroup.PhysicalVolume[part.VolumeGroup.PhysicalVolume.Length - 1] + " -yf" + "\r\n";
                result += "echo \"" + part.VolumeGroup.Uuid + "\" >>/tmp/vg-" + part.VolumeGroup.Name +
                          "\r\n";
                foreach (var lv in part.VolumeGroup.LogicalVolumes.Where(lv => lv.Active))
                {
                    result += "lvcreate --yes -L " + lv.Size + "s -n " + lv.Name + " " +
                              lv.VolumeGroup + "\r\n";
                    result += "echo \"" + lv.Uuid + "\" >>/tmp/" + lv.VolumeGroup + "-" +
                              lv.Name + "\r\n";
                }
                result += "vgcfgbackup -f /tmp/lvm-" + part.VolumeGroup.Name + "\r\n";
            }

            return result;
        }
Exemplo n.º 5
0
        public string CheckHdRequirements(int profileId, int clientHdNumber, string newHdSize, string imageSchemaDrives)
        {
            var result = new Services.Client.HardDriveSchema();
            
            var imageProfile = BLL.ImageProfile.ReadProfile(profileId);
            var partitionHelper = new ClientPartitionHelper(imageProfile);
            var imageSchema = partitionHelper.GetImageSchema();

            if (clientHdNumber > imageSchema.HardDrives.Count())
            {
                result.IsValid = "false";
                result.Message = "No Image Exists To Download To This Hard Drive.  There Are More" +
                                 "Hard Drive's Than The Original Image";

                return JsonConvert.SerializeObject(result);
            }

            var listSchemaDrives = new List<int>();
            if(!string.IsNullOrEmpty(imageSchemaDrives))
                listSchemaDrives.AddRange(imageSchemaDrives.Split(' ').Select(hd => Convert.ToInt32(hd)));         
            result.SchemaHdNumber = partitionHelper.NextActiveHardDrive(listSchemaDrives,clientHdNumber);
            
            if (result.SchemaHdNumber == -1)
            {
                result.IsValid = "false";
                result.Message = "Not Active Hard Drive Images Were Found To Deploy.";
                return JsonConvert.SerializeObject(result);
            }

            var newHdBytes = Convert.ToInt64(newHdSize);
            var minimumSize = partitionHelper.HardDrive(result.SchemaHdNumber,newHdBytes);
           
           
            if (minimumSize > newHdBytes)
            {
                Logger.Log("Error:  " + newHdBytes / 1024 / 1024 +
                           " MB Is Less Than The Minimum Required HD Size For This Image(" +
                           minimumSize / 1024 / 1024 + " MB)");

                result.IsValid = "false";
                result.Message = newHdBytes/1024/1024 +
                                 " MB Is Less Than The Minimum Required HD Size For This Image(" +
                                 minimumSize/1024/1024 + " MB)";
                return JsonConvert.SerializeObject(result);
            }
            if (minimumSize == newHdBytes)
            {
                result.IsValid = "original";
                result.PhysicalPartitions = partitionHelper.GetActivePartitions(result.SchemaHdNumber, imageProfile);
                result.PhysicalPartitionCount = partitionHelper.GetActivePartitionCount(result.SchemaHdNumber);
                result.PartitionType = imageSchema.HardDrives[result.SchemaHdNumber].Table;
                result.BootPartition = imageSchema.HardDrives[result.SchemaHdNumber].Boot;
                result.UsesLvm = partitionHelper.CheckForLvm(result.SchemaHdNumber);
                result.Guid = imageSchema.HardDrives[result.SchemaHdNumber].Guid;
                return JsonConvert.SerializeObject(result);
            }

            result.IsValid = "true";
            result.PhysicalPartitions = partitionHelper.GetActivePartitions(result.SchemaHdNumber, imageProfile);
            result.PhysicalPartitionCount = partitionHelper.GetActivePartitionCount(result.SchemaHdNumber);
            result.PartitionType = imageSchema.HardDrives[result.SchemaHdNumber].Table;
            result.BootPartition = imageSchema.HardDrives[result.SchemaHdNumber].Boot;
            result.UsesLvm = partitionHelper.CheckForLvm(result.SchemaHdNumber);
            result.Guid = imageSchema.HardDrives[result.SchemaHdNumber].Guid;
            return JsonConvert.SerializeObject(result);

        }
    public string GeneratePartitionScript()
        {
            var imageProfile = BLL.ImageProfile.ReadProfile(profileId);
            ImageSchema = new ClientPartitionHelper(imageProfile).GetImageSchema();
            string partitionScript = null;
          
            var clientSchema = new ClientPartition(HdNumberToGet,NewHdSize,imageProfile).GenerateClientSchema();
            if (clientSchema == null) return "failed";
            
           
            if (TaskType == "debug")
            {
                partitionScript = clientSchema.DebugStatus;
                if (clientSchema.PrimaryAndExtendedPartitions.Count == 0)
                    return partitionScript;
                try
                {
                    clientSchema.ExtendedPartitionHelper.AgreedSizeBlk = clientSchema.ExtendedPartitionHelper.AgreedSizeBlk * 512 / 1024 / 1024;
                }
                catch
                {
                    // ignored
                }
                foreach (var p in clientSchema.PrimaryAndExtendedPartitions)
                    p.Size = p.Size * 512 / 1024 / 1024;
                foreach (var p in clientSchema.LogicalPartitions)
                    p.Size = p.Size * 512 / 1024 / 1024;
                foreach (var p in clientSchema.LogicalVolumes)
                    p.Size = p.Size * 512 / 1024 / 1024;
            }

            //Create Menu
            if (ImageSchema.HardDrives[HdNumberToGet].Table.ToLower() == "mbr")
            {
                var counter = 0;
                var partCount = clientSchema.PrimaryAndExtendedPartitions.Count;

                string partitionCommands;
                partitionCommands = "fdisk " + ClientHd + " &>>/tmp/clientlog.log <<FDISK\r\n";
                if (Convert.ToInt32(clientSchema.PrimaryAndExtendedPartitions[0].Start) < 2048)
                    partitionCommands += "c\r\n";
               
                foreach (var part in clientSchema.PrimaryAndExtendedPartitions)
                {
                    counter++;
                    partitionCommands += "n\r\n";
                    switch (part.Type)
                    {
                        case "primary":
                            partitionCommands += "p\r\n";
                            break;
                        case "extended":
                            partitionCommands += "e\r\n";
                            break;
                    }

                    partitionCommands += part.Number + "\r\n";

                    if (counter == 1)
                        partitionCommands += clientSchema.FirstPartitionStartSector + "\r\n";
                    else
                        partitionCommands += "\r\n";
                    if (part.Type == "extended")
                        partitionCommands += "+" + (Convert.ToInt64(clientSchema.ExtendedPartitionHelper.AgreedSizeBlk) - 1) + "\r\n";
                    else //FDISK seems to include the starting sector in size so we need to subtract 1
                        partitionCommands += "+" + (Convert.ToInt64(part.Size) - 1) + "\r\n";

                    partitionCommands += "t\r\n";
                    if (counter == 1)
                        partitionCommands += part.FsId + "\r\n";
                    else
                    {
                        partitionCommands += part.Number + "\r\n";
                        partitionCommands += part.FsId + "\r\n";
                    }
                    if ((counter == 1 && part.IsBoot) || clientSchema.PrimaryAndExtendedPartitions.Count == 1)
                        partitionCommands += "a\r\n";
                    if (counter != 1 && part.IsBoot)
                    {
                        partitionCommands += "a\r\n";
                        partitionCommands += part.Number + "\r\n";
                    }
                    if ((counter != partCount || clientSchema.LogicalPartitions.Count != 0)) continue;
                    partitionCommands += "w\r\n";
                    partitionCommands += "FDISK\r\n";
                }


                var logicalCounter = 0;
                foreach (var logicalPart in clientSchema.LogicalPartitions)
                {
                    logicalCounter++;
                    partitionCommands += "n\r\n";

                    if (clientSchema.PrimaryAndExtendedPartitions.Count < 4)
                        partitionCommands += "l\r\n";


                    partitionCommands += "\r\n";

                    if (TaskType == "debug")
                        partitionCommands += "+" + (Convert.ToInt64(logicalPart.Size) - (logicalCounter * 1)) + "\r\n";
                    else
                        partitionCommands += "+" + (Convert.ToInt64(logicalPart.Size) - (logicalCounter * 2049)) + "\r\n";


                    partitionCommands += "t\r\n";

                    partitionCommands += logicalPart.Number + "\r\n";
                    partitionCommands += logicalPart.FsId + "\r\n";

                    if (logicalPart.IsBoot)
                    {
                        partitionCommands += "a\r\n";
                        partitionCommands += logicalPart.Number + "\r\n";
                    }
                    if (logicalCounter != clientSchema.LogicalPartitions.Count) continue;
                    partitionCommands += "w\r\n";
                    partitionCommands += "FDISK\r\n";
                }
                partitionScript += partitionCommands;
            }
            else
            {
                var counter = 0;
                var partCount = clientSchema.PrimaryAndExtendedPartitions.Count;

                var partitionCommands = "gdisk " + ClientHd + " &>>/tmp/clientlog.log <<GDISK\r\n";

                bool isApple = false;
                foreach (var part in clientSchema.PrimaryAndExtendedPartitions)
                {
                    if (part.FsType.Contains("hfs"))
                    {
                        isApple = true;
                        break;
                    }
                }
                if (clientSchema.FirstPartitionStartSector < 2048 && isApple) //osx cylinder boundary is 8
                {
                    partitionCommands += "x\r\nl\r\n8\r\nm\r\n";
                }
                foreach (var part in clientSchema.PrimaryAndExtendedPartitions)
                {
                    counter++;

                    partitionCommands += "n\r\n";

                    partitionCommands += part.Number + "\r\n";
                    if (counter == 1)
                        partitionCommands += clientSchema.FirstPartitionStartSector + "\r\n";
                    else
                        partitionCommands += "\r\n";
                    //GDISK seems to NOT include the starting sector in size so don't subtract 1 like in FDISK
                    partitionCommands += "+" + Convert.ToInt64(part.Size) + "\r\n";


                    partitionCommands += part.FsId + "\r\n";


                    if ((counter != partCount)) continue;
                    partitionCommands += "w\r\n";
                    partitionCommands += "y\r\n";
                    partitionCommands += "GDISK\r\n";
                }
                partitionScript += partitionCommands;
            }


            foreach (var part in from part in ImageSchema.HardDrives[HdNumberToGet].Partitions
                                 where part.Active
                                 where part.VolumeGroup != null
                                 where part.VolumeGroup.LogicalVolumes != null
                                 select part)
            {
                partitionScript += "echo \"pvcreate -u " + part.Uuid + " --norestorefile -yf " +
                                       ClientHd + partitionPrefix + part.VolumeGroup.PhysicalVolume[part.VolumeGroup.PhysicalVolume.Length - 1] +
                                       "\" >>/tmp/lvmcommands \r\n";
                partitionScript += "echo \"vgcreate " + part.VolumeGroup.Name + " " + ClientHd + partitionPrefix +
                                       part.VolumeGroup.PhysicalVolume[part.VolumeGroup.PhysicalVolume.Length - 1] + " -yf" +
                                       "\" >>/tmp/lvmcommands \r\n";
                partitionScript += "echo \"" + part.VolumeGroup.Uuid + "\" >>/tmp/vg-" + part.VolumeGroup.Name +
                                       " \r\n";
                foreach (var lv in part.VolumeGroup.LogicalVolumes)
                {
                    foreach (var rlv in clientSchema.LogicalVolumes)
                    {
                        if (lv.Name != rlv.Name || lv.VolumeGroup != rlv.Vg) continue;
                        if (TaskType == "debug")
                        {
                            partitionScript += "echo \"lvcreate --yes -L " +
                                                   rlv.Size + "mb -n " +
                                                   rlv.Name + " " + rlv.Vg +
                                                   "\" >>/tmp/lvmcommands \r\n";
                        }
                        else
                        {
                            partitionScript += "echo \"lvcreate --yes -L " +
                                                   ((Convert.ToInt64(rlv.Size) - 8192)) + "s -n " +
                                                   rlv.Name + " " + rlv.Vg +
                                                   "\" >>/tmp/lvmcommands \r\n";
                        }
                        partitionScript += "echo \"" + rlv.Uuid + "\" >>/tmp/" + rlv.Vg +
                                               "-" + rlv.Name + "\r\n";
                    }
                }
                partitionScript += "echo \"vgcfgbackup -f /tmp/lvm-" + part.VolumeGroup.Name +
                                       "\" >>/tmp/lvmcommands\r\n";
            }

         
            return partitionScript;
        }
Exemplo n.º 7
0
 public static string MinimumClientSizeForGridView(int profileId, int hdNumber)
 {
     try
     {   
         var profile = BLL.ImageProfile.ReadProfile(profileId);
         var fltClientSize = new ClientPartitionHelper(profile).HardDrive(hdNumber, 1) / 1024f / 1024f / 1024f;
         return Math.Abs(fltClientSize) < 0.1f ? "< 100M" : fltClientSize.ToString("#.##") + " GB";
     }
     catch
     {
         return "N/A";
     }
 }
Exemplo n.º 8
0
        private bool LogicalVolumeLayout()
        {
            var upSizeLock = new Dictionary <string, long>();

            //Try to resize lv to fit inside newly created lvm
            foreach (var volumeGroup in VolumeGroupHelpers)
            {
                //Tell the volume group it has a size of the physical volume to work with * 99% to account for errors to allow alittle over
                //volumeGroup.AgreedPvSizeBlk = Convert.ToInt64(volumeGroup.AgreedPvSizeBlk * .99);
                foreach (var partition in _imageSchema.HardDrives[HdNumberToGet].Partitions)
                {
                    //Find the partition this volume group belongs to
                    if (_imageSchema.HardDrives[HdNumberToGet].Name + partition.Prefix + partition.Number != volumeGroup.Pv)
                    {
                        continue;
                    }
                    var singleLvVerified = false;

                    double percentCounter = -.1;


                    while (!singleLvVerified)
                    {
                        percentCounter += .1;
                        double totalPvPercentage = 0;
                        LogicalVolumes.Clear();
                        if (!partition.Active)
                        {
                            continue;
                        }

                        var isError = false;
                        foreach (var lv in partition.VolumeGroup.LogicalVolumes)
                        {
                            if (!lv.Active)
                            {
                                continue;
                            }

                            var clientPartitionLv = new ClientLogicalVolume
                            {
                                Name   = lv.Name,
                                Vg     = lv.VolumeGroup,
                                Uuid   = lv.Uuid,
                                VgUuid = volumeGroup.Uuid,
                                FsType = lv.FsType
                            };


                            var    logicalVolumeHelper         = new ClientPartitionHelper(_imageProfile).LogicalVolume(lv, LbsByte, _newHdSize, HdNumberToGet);
                            double percentOfPvForThisLv        = (double)logicalVolumeHelper.MinSizeBlk / volumeGroup.AgreedPvSizeBlk;
                            var    tmpClientPartitionSizeLvBlk = logicalVolumeHelper.MinSizeBlk;

                            if (volumeGroup.IsFusion)
                            {
                                clientPartitionLv.Size = 0;
                                LogicalVolumes.Add(clientPartitionLv);
                                singleLvVerified = true;
                                continue;
                            }

                            if (upSizeLock.ContainsKey(lv.Name))
                            {
                                tmpClientPartitionSizeLvBlk = upSizeLock[lv.Name];
                            }
                            else
                            {
                                if (logicalVolumeHelper.IsDynamicSize)
                                {
                                    clientPartitionLv.SizeIsDynamic = true;
                                    var percentOfOrigDrive = Convert.ToInt64(lv.Size) /
                                                             (double)
                                                             (Convert.ToInt64(
                                                                  _imageSchema.HardDrives[HdNumberToGet].Size));

                                    if (Convert.ToInt64(NewHdBlk * percentOfOrigDrive) < logicalVolumeHelper.MinSizeBlk)
                                    {
                                        //This will never work because each loop only gets smaller
                                        tmpClientPartitionSizeLvBlk =
                                            Convert.ToInt64((NewHdBlk * (percentOfOrigDrive + (percentCounter / 100))));

                                        if (logicalVolumeHelper.MinSizeBlk < tmpClientPartitionSizeLvBlk)
                                        {
                                            upSizeLock.Add(lv.Name, tmpClientPartitionSizeLvBlk);
                                        }
                                    }
                                    else
                                    {
                                        if (percentOfOrigDrive - (percentCounter / 100) <= 0)
                                        {
                                            tmpClientPartitionSizeLvBlk =
                                                Convert.ToInt64(NewHdBlk * percentOfOrigDrive);
                                        }
                                        else
                                        {
                                            tmpClientPartitionSizeLvBlk =
                                                Convert.ToInt64(NewHdBlk *
                                                                (percentOfOrigDrive - (percentCounter / 100)));
                                        }
                                    }
                                    percentOfPvForThisLv = (double)(tmpClientPartitionSizeLvBlk) /
                                                           volumeGroup.AgreedPvSizeBlk;
                                }
                            }


                            if (logicalVolumeHelper.MinSizeBlk > tmpClientPartitionSizeLvBlk)
                            {
                                isError = true;
                                break;
                            }


                            clientPartitionLv.Size = tmpClientPartitionSizeLvBlk;
                            totalPvPercentage     += percentOfPvForThisLv;
                            LogicalVolumes.Add(clientPartitionLv);
                        }

                        //Could not determine a partition layout that works with this hard drive
                        if (isError && percentCounter > 99)
                        {
                            return(false);
                        }

                        //This partition size doesn't work, continuation of break from earlier
                        if (isError)
                        {
                            continue;
                        }


                        if (totalPvPercentage <= 1)
                        {
                            long totalAllocatedBlk     = 0;
                            var  dynamicPartitionCount = 0;
                            //If totalPercentage is too far below 1 try to increase size of available resizable partitions
                            if (totalPvPercentage < .95)
                            {
                                foreach (var lv in LogicalVolumes)
                                {
                                    totalAllocatedBlk += Convert.ToInt64(lv.Size);
                                    if (lv.SizeIsDynamic)
                                    {
                                        dynamicPartitionCount++;
                                    }
                                }
                                var totalUnallocated = volumeGroup.AgreedPvSizeBlk - totalAllocatedBlk;
                                if (dynamicPartitionCount > 0)
                                {
                                    foreach (var lv in LogicalVolumes.Where(lv => lv.SizeIsDynamic))
                                    {
                                        lv.Size = lv.Size + (totalUnallocated / dynamicPartitionCount);
                                    }
                                }
                            }
                            singleLvVerified = true;
                        }

                        //Theoretically should never hit this, but added to prevent infinite loop
                        if (percentCounter > 100)
                        {
                            return(false);
                        }
                    }
                }
            }
            return(true);
        }
Exemplo n.º 9
0
        private bool LogicalPartitionLayout()
        {
            // Try to resize logical to fit inside newly created extended
            double percentCounter            = -.1;
            var    upSizeLock                = new Dictionary <string, long>();
            var    logicalPartLayoutVerified = false;

            while (!logicalPartLayoutVerified)
            {
                percentCounter += .1;
                var isError = false;
                LogicalPartitions.Clear();
                double totalExtendedPercentage = 0;

                var partCounter = -1;
                foreach (var part in _imageSchema.HardDrives[HdNumberToGet].Partitions)
                {
                    partCounter++;
                    if (part.Type.ToLower() != "logical")
                    {
                        continue;
                    }

                    var clientPartition = new Models.ClientPartition
                    {
                        IsBoot = BootPart == part.Number,
                        Number = part.Number,
                        Start  = part.Start,
                        Type   = part.Type,
                        FsId   = part.FsId,
                        Uuid   = part.Uuid,
                        Guid   = part.Guid,
                        FsType = part.FsType
                    };

                    var logicalPartitionHelper = new ClientPartitionHelper(_imageProfile).Partition(HdNumberToGet, partCounter, _newHdSize);

                    var percentOfExtendedForThisPartition = (double)logicalPartitionHelper.MinSizeBlk / ExtendedPartitionHelper.AgreedSizeBlk;
                    var tmpClientPartitionSizeBlk         = logicalPartitionHelper.MinSizeBlk;

                    if (upSizeLock.ContainsKey(part.Number))
                    {
                        tmpClientPartitionSizeBlk = upSizeLock[part.Number];
                    }
                    else
                    {
                        if (logicalPartitionHelper.IsDynamicSize)
                        {
                            clientPartition.SizeIsDynamic = true;
                            var percentOfOrigDrive = Convert.ToInt64(part.Size) /
                                                     (double)
                                                     (Convert.ToInt64(_imageSchema.HardDrives[HdNumberToGet].Size));

                            if (Convert.ToInt64(NewHdBlk * percentOfOrigDrive) < logicalPartitionHelper.MinSizeBlk)
                            {
                                //This will never work because each loop only gets smaller
                                tmpClientPartitionSizeBlk =
                                    Convert.ToInt64((NewHdBlk * (percentOfOrigDrive + (percentCounter / 100))));

                                if (logicalPartitionHelper.MinSizeBlk < tmpClientPartitionSizeBlk)
                                {
                                    upSizeLock.Add(part.Number, tmpClientPartitionSizeBlk);
                                }
                            }
                            else
                            {
                                tmpClientPartitionSizeBlk = percentOfOrigDrive - (percentCounter / 100) <= 0
                                    ? Convert.ToInt64(NewHdBlk * percentOfOrigDrive)
                                    : Convert.ToInt64(NewHdBlk * (percentOfOrigDrive - (percentCounter / 100)));

                                percentOfExtendedForThisPartition = (double)(tmpClientPartitionSizeBlk) /
                                                                    ExtendedPartitionHelper.AgreedSizeBlk;
                            }
                        }
                    }

                    if (logicalPartitionHelper.MinSizeBlk > tmpClientPartitionSizeBlk)
                    {
                        isError = true;
                        break;
                    }

                    totalExtendedPercentage += percentOfExtendedForThisPartition;
                    clientPartition.Size     = tmpClientPartitionSizeBlk;

                    LogicalPartitions.Add(clientPartition);

                    if (logicalPartitionHelper.PartitionHasVolumeGroup)
                    {
                        logicalPartitionHelper.VolumeGroupHelper.AgreedPvSizeBlk = tmpClientPartitionSizeBlk;
                        VolumeGroupHelpers.Add(logicalPartitionHelper.VolumeGroupHelper);
                    }
                }

                //Could not determine a partition layout that works with this hard drive
                if (isError && percentCounter > 99)
                {
                    Logger.Log(JsonConvert.SerializeObject(PrimaryAndExtendedPartitions));
                    Logger.Log(JsonConvert.SerializeObject(LogicalPartitions));
                    return(false);
                }

                //This partition size doesn't work, continuation of break from earlier
                if (isError)
                {
                    continue;
                }


                if (totalExtendedPercentage <= 1)
                {
                    long totalAllocatedBlk     = 0;
                    var  dynamicPartitionCount = 0;
                    //If totalPercentage is too far below 1 try to increase size of available resizable partitions
                    if (totalExtendedPercentage < .98)
                    {
                        foreach (var partition in LogicalPartitions)
                        {
                            totalAllocatedBlk += Convert.ToInt64(partition.Size);
                            if (partition.SizeIsDynamic)
                            {
                                dynamicPartitionCount++;
                            }
                        }
                        var totalUnallocated = ExtendedPartitionHelper.AgreedSizeBlk - totalAllocatedBlk;
                        if (dynamicPartitionCount > 0)
                        {
                            foreach (
                                var partition in LogicalPartitions.Where(partition => partition.SizeIsDynamic))
                            {
                                partition.Size =
                                    partition.Size + (totalUnallocated / dynamicPartitionCount);
                            }
                        }
                    }
                    logicalPartLayoutVerified = true;
                }

                //Theoretically should never hit this, but added to prevent infinite loop
                if (percentCounter > 100)
                {
                    return(false);
                }
            }

            return(true);
        }
Exemplo n.º 10
0
        private bool PrimaryAndExtendedPartitionLayout()
        {
            //Try to determine a layout for each primary or extended partition that will be able to fit logical partitions
            //or logical volumes in.  Also if the partition is logical and is the physical volume for a volume group determine
            // a size that will work for all logical volumes
            ExtendedPartitionHelper = new ClientPartitionHelper(_imageProfile).ExtendedPartition(HdNumberToGet, _newHdSize);
            var upSizeLock = new Dictionary <string, long>();

            double percentCounter          = -.1;
            var    partitionLayoutVerified = false;

            while (!partitionLayoutVerified)
            {
                //percentCounter++;

                percentCounter += .1;
                var    isError           = false;
                double totalHdPercentage = 0;

                PrimaryAndExtendedPartitions.Clear();
                VolumeGroupHelpers.Clear();
                FirstPartitionStartSector = Convert.ToInt32(_imageSchema.HardDrives[HdNumberToGet].Partitions[0].Start);
                var partCounter = -1;

                foreach (var schemaPartition in _imageSchema.HardDrives[HdNumberToGet].Partitions)
                {
                    partCounter++;

                    //Determine what sector the first partition should start at
                    if (Convert.ToInt32(schemaPartition.Start) < FirstPartitionStartSector)
                    {
                        FirstPartitionStartSector = Convert.ToInt32(schemaPartition.Start);
                    }

                    if (!schemaPartition.Active)
                    {
                        continue;
                    }
                    if (schemaPartition.Type.ToLower() == "logical")
                    {
                        continue;
                    }

                    var clientPartition = new Models.ClientPartition
                    {
                        IsBoot = BootPart == schemaPartition.Number,
                        Number = schemaPartition.Number,
                        Start  = schemaPartition.Start,
                        Type   = schemaPartition.Type,
                        FsId   = schemaPartition.FsId,
                        Uuid   = schemaPartition.Uuid,
                        Guid   = schemaPartition.Guid,
                        FsType = schemaPartition.FsType
                    };


                    var  partitionHelper             = new ClientPartitionHelper(_imageProfile).Partition(HdNumberToGet, partCounter, _newHdSize);
                    var  percentOfHdForThisPartition = (double)partitionHelper.MinSizeBlk / NewHdBlk;
                    long tmpClientPartitionSizeBlk   = partitionHelper.MinSizeBlk;


                    if (partitionHelper.IsDynamicSize)
                    {
                        clientPartition.SizeIsDynamic = true;
                        var percentOfOrigDrive = Convert.ToInt64(schemaPartition.Size) /
                                                 (double)(Convert.ToInt64(_imageSchema.HardDrives[HdNumberToGet].Size));

                        //Change the resized partition size based off original percentage and percentCounter loop
                        //This is the active part of the loop that lowers the partition size based on each iteration

                        //If a partition's used space is almost maxed out to the size of the partition this can cause
                        //problems with calculations.


                        if (upSizeLock.ContainsKey(schemaPartition.Number))
                        {
                            tmpClientPartitionSizeBlk = upSizeLock[schemaPartition.Number];
                        }

                        else
                        {
                            if (Convert.ToInt64(NewHdBlk * percentOfOrigDrive) < partitionHelper.MinSizeBlk)
                            {
                                //This will never work because each loop only gets smaller

                                tmpClientPartitionSizeBlk =
                                    Convert.ToInt64((NewHdBlk * (percentOfOrigDrive + (percentCounter / 100))));
                                if (partitionHelper.MinSizeBlk < tmpClientPartitionSizeBlk)
                                {
                                    upSizeLock.Add(schemaPartition.Number, tmpClientPartitionSizeBlk);
                                }
                            }
                            else
                            {
                                tmpClientPartitionSizeBlk = percentOfOrigDrive - (percentCounter / 100) <= 0
                                    ? Convert.ToInt64(NewHdBlk * (percentOfOrigDrive))
                                    : Convert.ToInt64((NewHdBlk * (percentOfOrigDrive - (percentCounter / 100))));
                            }
                        }
                        //Add the percent of this partition used to the total percent used to make sure we don't go over
                        //100% of the size of the new drive.

                        //Each logical partition requires and extra 1 mb added to the size of the extended partition.
                        if (clientPartition.Type.ToLower() == "extended")
                        {
                            percentOfHdForThisPartition = ((double)(tmpClientPartitionSizeBlk) +
                                                           (((1048576 / LbsByte) * ExtendedPartitionHelper.LogicalCount) + (1048576 / LbsByte))) /
                                                          NewHdBlk;
                        }
                        else
                        {
                            percentOfHdForThisPartition = (double)(tmpClientPartitionSizeBlk) / NewHdBlk;
                        }
                    }


                    if (partitionHelper.MinSizeBlk > tmpClientPartitionSizeBlk)
                    {
                        isError = true;
                        break;
                    }

                    if (clientPartition.Type.ToLower() == "extended")
                    {
                        ExtendedPartitionHelper.AgreedSizeBlk = tmpClientPartitionSizeBlk;
                    }

                    if (partitionHelper.PartitionHasVolumeGroup)
                    {
                        partitionHelper.VolumeGroupHelper.AgreedPvSizeBlk = tmpClientPartitionSizeBlk;
                        VolumeGroupHelpers.Add(partitionHelper.VolumeGroupHelper);
                    }

                    clientPartition.Size = tmpClientPartitionSizeBlk;
                    totalHdPercentage   += percentOfHdForThisPartition;
                    PrimaryAndExtendedPartitions.Add(clientPartition);
                }


                //Could not determine a partition layout that works with this hard drive
                if (isError && percentCounter > 99)
                {
                    return(false);
                }

                //This partition size doesn't work, continuation of break from earlier
                if (isError)
                {
                    continue;
                }

                DebugStatus += percentCounter + "\r\n";
                if (totalHdPercentage <= 1)
                {
                    //if totalPercentage is < 1 then layout has been verified to work
                    partitionLayoutVerified = true;

                    //If totalPercentage is too far below 1 try to increase size of available resizable partitions
                    long totalAllocatedBlk     = 0;
                    var  dynamicPartitionCount = 0;
                    if (totalHdPercentage < .98)
                    {
                        foreach (var partition in PrimaryAndExtendedPartitions)
                        {
                            totalAllocatedBlk += Convert.ToInt64(partition.Size);
                            if (partition.SizeIsDynamic)
                            {
                                dynamicPartitionCount++;
                            }
                        }
                        var totalUnallocated = NewHdBlk - totalAllocatedBlk;
                        if (dynamicPartitionCount > 0)
                        {
                            foreach (
                                var partition in
                                PrimaryAndExtendedPartitions.Where(partition => partition.SizeIsDynamic))
                            {
                                partition.Size = partition.Size + (totalUnallocated / dynamicPartitionCount);
                                if (partition.Type.ToLower() == "extended")
                                {
                                    ExtendedPartitionHelper.AgreedSizeBlk = Convert.ToInt64(partition.Size);
                                }
                                for (var i = 0; i < VolumeGroupHelpers.Count(); i++)
                                {
                                    if (_imageSchema.HardDrives[HdNumberToGet].Name + partition.Number == VolumeGroupHelpers[i].Pv)
                                    {
                                        VolumeGroupHelpers[i].AgreedPvSizeBlk = Convert.ToInt64(partition.Size);
                                    }
                                }
                            }
                        }
                    }
                }

                //Theoretically should never hit this, but added to prevent infinite loop
                if (percentCounter > 100)
                {
                    return(false);
                }
            }

            return(true);
        }