/// <summary> /// Calculates the minimum block size required for a single partition, taking into account any children partitions. /// </summary> public PartitionHelper Partition(int hdNumberToGet, int partNumberToGet, long newHdSize) { var partition = _imageSchema.HardDrives[hdNumberToGet].Partitions[partNumberToGet]; var partitionHelper = new PartitionHelper { MinSizeBlk = 0 }; var extendedPartitionHelper = new ExtendedPartitionHelper(); if (partition.Type.ToLower() == "extended") extendedPartitionHelper = ExtendedPartition(hdNumberToGet, newHdSize); partitionHelper.VolumeGroupHelper = VolumeGroup(hdNumberToGet, partNumberToGet, newHdSize); var lbsByte = _imageSchema.HardDrives[hdNumberToGet].Lbs; var imagePath = Settings.PrimaryStoragePath + Path.DirectorySeparatorChar + "images" + Path.DirectorySeparatorChar + _imageProfile.Image.Name + Path.DirectorySeparatorChar + "hd" + hdNumberToGet; //Look if any volume groups are present for this partition. If so set the volumesize for the volume group to the minimum size //required for the volume group. Volume groups are always treated as resizable even if none of the individual //logical volumes are resizable if (partitionHelper.VolumeGroupHelper.Pv != null) { partitionHelper.PartitionHasVolumeGroup = true; partition.VolumeSize = (partitionHelper.VolumeGroupHelper.MinSizeBlk * lbsByte / 1024 / 1024); } if (partition.ForceFixedSize) { partitionHelper.MinSizeBlk = partition.Size; partitionHelper.IsDynamicSize = false; } //Use partition size that user has set for the partition, if it is set. else if (!string.IsNullOrEmpty(partition.CustomSize) && !string.IsNullOrEmpty(partition.CustomSizeUnit)) { long customSizeBytes = 0; switch (partition.CustomSizeUnit) { case "MB": customSizeBytes = Convert.ToInt64(partition.CustomSize) * 1024 * 1024; break; case "GB": customSizeBytes = Convert.ToInt64(partition.CustomSize) * 1024 * 1024 * 1024; break; case "%": double hdPercent = Convert.ToDouble(partition.CustomSize) / 100; customSizeBytes = Convert.ToInt64(hdPercent * newHdSize); break; } partitionHelper.MinSizeBlk = customSizeBytes / lbsByte; partitionHelper.IsDynamicSize = false; } //If partition is not resizable. Determine partition size. Also if the partition is less than 5 gigs assume it is that // size for a reason, do not resize it even if it is marked as a resizable partition else if ((partition.VolumeSize == 0 && partition.Type.ToLower() != "extended") || (partition.Type.ToLower() == "extended" && extendedPartitionHelper.IsOnlySwap) || partition.Size * lbsByte <= 5368709120 || partition.FsType == "swap") { partitionHelper.MinSizeBlk = partition.Size; partitionHelper.IsDynamicSize = false; } //If resizable determine what percent of drive partition was originally and match that to the new drive //while making sure the min size is still less than the resized size. else { partitionHelper.IsDynamicSize = true; if (partition.Type.ToLower() == "extended") partitionHelper.MinSizeBlk = extendedPartitionHelper.MinSizeBlk; else if (partitionHelper.VolumeGroupHelper.Pv != null) { partitionHelper.MinSizeBlk = partitionHelper.VolumeGroupHelper.MinSizeBlk; } else { string imageFile = null; foreach (var ext in new[] { "ntfs", "fat", "extfs", "hfsp", "imager", "xfs" }) { try { imageFile = Directory.GetFiles( imagePath + Path.DirectorySeparatorChar, "part" + partition.Number + "." + ext + ".*") .FirstOrDefault(); } catch (Exception ex) { Logger.Log(ex.Message); } if (imageFile != null) break; } if (Path.GetExtension(imageFile) == ".wim") partitionHelper.MinSizeBlk = (partition.UsedMb * 1024 * 1024) / lbsByte; else { //The resize value and used_mb value are calculated during upload by two different methods //Use the one that is bigger just in case. if (partition.VolumeSize > partition.UsedMb) partitionHelper.MinSizeBlk = partition.VolumeSize * 1024 * 1024 / lbsByte; else partitionHelper.MinSizeBlk = (partition.UsedMb * 1024 * 1024) / lbsByte; } } } return partitionHelper; }
/// <summary> /// Calculates the minimum block size required for a single logical volume, assuming the logical volume cannot have any /// children. /// </summary> public PartitionHelper LogicalVolume(Models.ImageSchema.LogicalVolume lv, int lbsByte, long newHdSize, int hdNumberToGet) { var logicalVolumeHelper = new PartitionHelper {MinSizeBlk = 0}; if (lv.ForceFixedSize) { logicalVolumeHelper.MinSizeBlk = lv.Size; logicalVolumeHelper.IsDynamicSize = false; } else if (!string.IsNullOrEmpty(lv.CustomSize) && !string.IsNullOrEmpty(lv.CustomSizeUnit)) { long customSizeBytes = 0; switch (lv.CustomSizeUnit) { case "MB": customSizeBytes = Convert.ToInt64(lv.CustomSize)*1024*1024; break; case "GB": customSizeBytes = Convert.ToInt64(lv.CustomSize) * 1024 * 1024 * 1024; break; case "%": double hdPercent = Convert.ToDouble(lv.CustomSize) / 100; customSizeBytes = Convert.ToInt64(hdPercent * newHdSize); break; } logicalVolumeHelper.MinSizeBlk = customSizeBytes / lbsByte; logicalVolumeHelper.IsDynamicSize = false; } else { var imagePath = Settings.PrimaryStoragePath + Path.DirectorySeparatorChar + "images" + Path.DirectorySeparatorChar + _imageProfile.Image.Name + Path.DirectorySeparatorChar + "hd" + hdNumberToGet; logicalVolumeHelper.IsDynamicSize = true; string imageFile = null; foreach (var ext in new[] { "ntfs", "fat", "extfs", "hfsp", "imager", "xfs" }) { try { imageFile = Directory.GetFiles( imagePath + Path.DirectorySeparatorChar, lv.VolumeGroup + "-" + lv.Name + "." + ext + ".*") .FirstOrDefault(); } catch (Exception ex) { Logger.Log(ex.Message); } if (imageFile != null) break; } if (Path.GetExtension(imageFile) == ".wim") logicalVolumeHelper.MinSizeBlk = (lv.UsedMb * 1024 * 1024) / lbsByte; if (lv.VolumeSize > lv.UsedMb) logicalVolumeHelper.MinSizeBlk = lv.VolumeSize*1024*1024/lbsByte; else logicalVolumeHelper.MinSizeBlk = lv.UsedMb*1024*1024/lbsByte; } return logicalVolumeHelper; }