/// <summary> /// Create a new <see cref="RecoveryPointMetadataFile"/> and write it to the given file. /// </summary> /// <returns>Task that represents the asynchronous operation.</returns> public static async Task <RecoveryPointMetadataFile> CreateAsync( string fileName, DateTime backupTime, Guid backupId, Guid parentBackupId, Guid backupChainId, Epoch epochOfLastBackupRecord, long lsnOfLastBackupRecord, string backupLocation, string parentBackupLocation, ServicePartitionInformation partitionInformation, string serviceManifestVersion, CancellationToken cancellationToken) { // Create the file with asynchronous flag and 4096 cache size (C# default). using (var filestream = FabricFile.Open( fileName, FileMode.CreateNew, FileAccess.Write, FileShare.Read, 4096, FileOptions.Asynchronous)) { BackupRestoreUtility.SetIoPriorityHint(filestream.SafeFileHandle, Kernel32Types.PRIORITY_HINT.IoPriorityHintLow); var recoveryPointMetadataFile = new RecoveryPointMetadataFile(fileName); recoveryPointMetadataFile.properties = new RecoveryPointMetadataFileProperties { BackupTime = backupTime, BackupLocation = backupLocation, ParentBackupLocation = parentBackupLocation, BackupId = backupId, ParentBackupId = parentBackupId, BackupChainId = backupChainId, EpochOfLastBackupRecord = epochOfLastBackupRecord, LsnOfLastBackupRecord = lsnOfLastBackupRecord, PartitionInformation = partitionInformation, ServiceManifestVersion = serviceManifestVersion, }; // Write the properties. var propertiesHandle = await FileBlock.WriteBlockAsync(filestream, writer => recoveryPointMetadataFile.properties.Write(writer)).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); // Write the footer. recoveryPointMetadataFile.footer = new FileFooter(propertiesHandle, Version); await FileBlock.WriteBlockAsync(filestream, writer => recoveryPointMetadataFile.footer.Write(writer)).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); // Flush to underlying stream. await filestream.FlushAsync(cancellationToken).ConfigureAwait(false); return(recoveryPointMetadataFile); } }
public static async Task <RecoveryPointMetadataFile> OpenAsync( Stream filestream, string recoveryPointMetadataFilePath, CancellationToken cancellationToken) { var recoveryPointMetadataFile = new RecoveryPointMetadataFile(recoveryPointMetadataFilePath); // Read and validate the Footer section. The footer is always at the end of the stream, minus space for the checksum. var footerHandle = new BlockHandle( filestream.Length - FileFooter.SerializedSize - sizeof(ulong), FileFooter.SerializedSize); recoveryPointMetadataFile.footer = await FileBlock.ReadBlockAsync( filestream, footerHandle, (reader, handle) => FileFooter.Read(reader, handle)).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); // Verify we know how to deserialize this version of the backup log file. if (recoveryPointMetadataFile.footer.Version != Version) { throw new InvalidDataException( string.Format( CultureInfo.CurrentCulture, SR.Error_BackupMetadata_Deserialized, recoveryPointMetadataFile.footer.Version, Version)); } // Read and validate the properties section. var propertiesHandle = recoveryPointMetadataFile.footer.PropertiesHandle; recoveryPointMetadataFile.properties = await FileBlock.ReadBlockAsync( filestream, propertiesHandle, (reader, handle) => FileProperties.Read <RecoveryPointMetadataFileProperties>(reader, handle)).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); return(recoveryPointMetadataFile); }