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(); }
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; }
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"; } }
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; }
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; }
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"; } }
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); }
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); }
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); }