public static ulong CreateSimpleVolume(DiskGroupDatabase database, DiskExtent extent) { List <DatabaseRecord> records = new List <DatabaseRecord>(); VolumeRecord volumeRecord = new VolumeRecord(); volumeRecord.Id = database.AllocateNewRecordID(); volumeRecord.Name = GetNextSimpleVolumeName(database.VolumeRecords); volumeRecord.VolumeTypeString = "gen"; volumeRecord.StateString = "ACTIVE"; volumeRecord.ReadPolicy = ReadPolicyName.Select; volumeRecord.VolumeNumber = GetNextVolumeNumber(database.VolumeRecords); volumeRecord.VolumeFlags = VolumeFlags.Writeback | VolumeFlags.DefaultUnknown; volumeRecord.NumberOfComponents = 1; volumeRecord.SizeLBA = (ulong)PublicRegionHelper.TranslateToPublicRegionSizeLBA(extent.TotalSectors, extent.BytesPerSector); volumeRecord.PartitionType = PartitionType.RAW; volumeRecord.VolumeGuid = Guid.NewGuid(); records.Add(volumeRecord); ComponentRecord componentRecord = new ComponentRecord(); componentRecord.Id = database.AllocateNewRecordID(); componentRecord.Name = volumeRecord.Name + "-01"; componentRecord.StateString = "ACTIVE"; componentRecord.ExtentLayout = ExtentLayoutName.Concatenated; componentRecord.NumberOfExtents = 1; componentRecord.VolumeId = volumeRecord.VolumeId; componentRecord.HasStripedExtentsFlag = false; componentRecord.NumberOfColumns = 0; records.Add(componentRecord); // we should update the disk record PrivateHeader privateHeader = PrivateHeader.ReadFromDisk(extent.Disk); DiskRecord diskRecord = database.FindDiskByDiskGuid(privateHeader.DiskGuid); diskRecord = (DiskRecord)diskRecord.Clone(); records.Add(diskRecord); ExtentRecord extentRecord = new ExtentRecord(); extentRecord.Name = GetNextExtentName(database.ExtentRecords, diskRecord.Name); extentRecord.DiskOffsetLBA = (ulong)PublicRegionHelper.TranslateToPublicRegionLBA(extent.FirstSector, privateHeader); extentRecord.SizeLBA = volumeRecord.SizeLBA; extentRecord.ComponentId = componentRecord.ComponentId; extentRecord.DiskId = diskRecord.DiskId; extentRecord.HasColumnIndexFlag = false; records.Add(extentRecord); database.UpdateDatabase(records); return(volumeRecord.VolumeId); }
public static ulong CreateRAID5Volume(DiskGroupDatabase database, List <DiskExtent> extents, bool isDegraded) { int numberOfColumns; if (isDegraded) { numberOfColumns = extents.Count + 1; } else { numberOfColumns = extents.Count; } List <DatabaseRecord> records = new List <DatabaseRecord>(); VolumeRecord volumeRecord = new VolumeRecord(); volumeRecord.Id = database.AllocateNewRecordID(); volumeRecord.Name = GetNextRAIDVolumeName(database.VolumeRecords); volumeRecord.VolumeTypeString = "raid5"; volumeRecord.StateString = "ACTIVE"; volumeRecord.ReadPolicy = ReadPolicyName.RAID; volumeRecord.VolumeNumber = GetNextVolumeNumber(database.VolumeRecords); volumeRecord.VolumeFlags = VolumeFlags.Writeback | VolumeFlags.Writecopy | VolumeFlags.DefaultUnknown; volumeRecord.NumberOfComponents = 1; volumeRecord.SizeLBA = (ulong)PublicRegionHelper.TranslateToPublicRegionSizeLBA(extents[0].TotalSectors * (numberOfColumns - 1), extents[0].BytesPerSector); volumeRecord.PartitionType = PartitionType.RAW; volumeRecord.VolumeGuid = Guid.NewGuid(); records.Add(volumeRecord); ComponentRecord componentRecord = new ComponentRecord(); componentRecord.Id = database.AllocateNewRecordID(); componentRecord.Name = volumeRecord.Name + "-01"; componentRecord.StateString = "ACTIVE"; componentRecord.ExtentLayout = ExtentLayoutName.RAID5; componentRecord.NumberOfExtents = (uint)numberOfColumns; componentRecord.VolumeId = volumeRecord.VolumeId; componentRecord.HasStripedExtentsFlag = true; componentRecord.StripeSizeLBA = 128; // 64KB - the default componentRecord.NumberOfColumns = (uint)numberOfColumns; records.Add(componentRecord); for (int index = 0; index < extents.Count; index++) { DiskExtent extent = extents[index]; // we should update the disk records PrivateHeader privateHeader = PrivateHeader.ReadFromDisk(extent.Disk); DiskRecord diskRecord = database.FindDiskByDiskGuid(privateHeader.DiskGuid); diskRecord = (DiskRecord)diskRecord.Clone(); records.Add(diskRecord); ExtentRecord extentRecord = new ExtentRecord(); extentRecord.Name = GetNextExtentName(database.ExtentRecords, diskRecord.Name); extentRecord.DiskOffsetLBA = (ulong)PublicRegionHelper.TranslateToPublicRegionLBA(extent.FirstSector, privateHeader); extentRecord.SizeLBA = (ulong)PublicRegionHelper.TranslateToPublicRegionSizeLBA(extent.TotalSectors, extent.BytesPerSector); extentRecord.ComponentId = componentRecord.ComponentId; extentRecord.DiskId = diskRecord.DiskId; extentRecord.HasColumnIndexFlag = (index > 0); extentRecord.ColumnIndex = (uint)index; // zero based records.Add(extentRecord); } if (isDegraded) { // we have to make-up a disk // The DiskFlags and ExtentFlags are not necessary (they will be added later anyway when the disk group is reimported) DiskRecord diskRecord = new DiskRecord(); diskRecord.Id = database.AllocateNewRecordID(); diskRecord.Name = "Miss" + new Random().Next(100); diskRecord.DiskGuid = Guid.NewGuid(); diskRecord.DiskFlags = DiskFlags.Detached; records.Add(diskRecord); ExtentRecord extentRecord = new ExtentRecord(); extentRecord.Name = diskRecord.Name + "-01"; extentRecord.ExtentFlags = ExtentFlags.Recover; extentRecord.SizeLBA = (ulong)PublicRegionHelper.TranslateToPublicRegionSizeLBA(extents[0].TotalSectors, extents[0].BytesPerSector); extentRecord.ComponentId = componentRecord.ComponentId; extentRecord.DiskId = diskRecord.DiskId; extentRecord.HasColumnIndexFlag = true; extentRecord.ColumnIndex = (uint)extents.Count; // zero based records.Add(extentRecord); } database.UpdateDatabase(records); return(volumeRecord.VolumeId); }