Пример #1
0
        /// <summary>
        /// Deserializes the metadata (footer, properties, etc.) for this checkpoint file.
        /// </summary>
        private async Task ReadMetadataAsync()
        {
            Stream filestream = null;

            try
            {
                filestream = this.ReaderPool.AcquireStream();

                // 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);
                this.Footer =
                    await FileBlock.ReadBlockAsync(filestream, footerHandle, (sectionReader, sectionHandle) => FileFooter.Read(sectionReader, sectionHandle)).ConfigureAwait(false);

                // Verify we know how to deserialize this version of the checkpoint file.
                if (this.Footer.Version != FileVersion)
                {
                    throw new InvalidDataException(SR.Error_KeyCheckpointFile_Deserialized);
                }

                // Read and validate the Properties section.
                var propertiesHandle = this.Footer.PropertiesHandle;
                this.Properties =
                    await
                    FileBlock.ReadBlockAsync(
                        filestream,
                        propertiesHandle,
                        (sectionReader, sectionHandle) => FilePropertySection.Read <KeyCheckpointFileProperties>(sectionReader, sectionHandle)).ConfigureAwait(false);
            }
            finally
            {
                this.ReaderPool.ReleaseStream(filestream, true);
            }
        }
Пример #2
0
        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);
        }
Пример #3
0
        public static async Task WriteAsync(MetadataTable metadataTable, Stream stream)
        {
            // Write all metadata to disk.
            var properties = await WriteDiskMetadataAsync(metadataTable.Table, stream).ConfigureAwait(false);

            properties.CheckpointLSN = metadataTable.CheckpointLSN;

            // Write the Properties.
            var propertiesHandle = await FileBlock.WriteBlockAsync(stream, (sectionWriter) => properties.Write(sectionWriter)).ConfigureAwait(false);

            // Write the Footer.
            var footer = new FileFooter(propertiesHandle, FileVersion);
            await FileBlock.WriteBlockAsync(stream, (sectionWriter) => footer.Write(sectionWriter)).ConfigureAwait(false);

            // Finally, flush to disk.
            await stream.FlushAsync().ConfigureAwait(false);
        }
Пример #4
0
        private FileFooter ReadFileFooter(byte[] fileData, int fileHeaderFooterOffset)
        {
            const int FooterRecordByteLength = 36;
            const int NumSetLists            = 8;
            const int NumOtherRecords        = 4;

            // note there will be other footer records if IRs are used.
            const int MinimumFooterLength = (NumSetLists + NumOtherRecords) * FooterRecordByteLength;

            if (fileHeaderFooterOffset > fileData.Length - MinimumFooterLength)
            {
                throw new FileFooterSmallException();
            }

            var recordCount = (fileData.Length - fileHeaderFooterOffset) / FooterRecordByteLength;

            if (fileHeaderFooterOffset + (recordCount * FooterRecordByteLength) != fileData.Length)
            {
                throw new FileFooterBadException();
            }

            var result = new FileFooter();

            var enc = new UTF8Encoding();

            for (int n = 0; n < recordCount; ++n)
            {
                var startOffset = fileHeaderFooterOffset + (n * FooterRecordByteLength);

                var title       = enc.GetString(fileData, startOffset, 4);
                var sectionType = GetSectionType(title);

                result.Records.Add(new FileFooterRecord
                {
                    Title              = title,
                    SectionType        = sectionType,
                    Description        = GetFooterRecordDescription(sectionType),
                    StartSectionOffset = BitConverter.ToInt32(fileData, startOffset + 4),
                    SectionLength      = BitConverter.ToInt32(fileData, startOffset + 12),
                    IsSectionDeflated  = BitConverter.ToInt32(fileData, startOffset + 20) == 1,
                    InflatedLength     = BitConverter.ToInt32(fileData, startOffset + 24),
                });
            }

            return(result);
        }
Пример #5
0
        /// <summary>
        /// A Flush indicates that all keys have been written to the checkpoint file (via AddItemAsync), so
        /// the checkpoint file can finish flushing any remaining in-memory buffered data, write any extra
        /// metadata (e.g. properties and footer), and flush to disk.
        /// </summary>
        /// <param name="fileStream"></param>
        /// <param name="memoryBuffer"></param>
        /// <returns></returns>
        public async Task FlushAsync(Stream fileStream, InMemoryBinaryWriter memoryBuffer)
        {
            // If there's any buffered keys in memory, flush them to disk first.
            if (memoryBuffer.BaseStream.Position > 0)
            {
                await this.FlushMemoryBufferAsync(fileStream, memoryBuffer).ConfigureAwait(false);
            }

            // Update the Properties.
            this.Properties.KeysHandle = new BlockHandle(0, fileStream.Position);

            // Write the Properties.
            var propertiesHandle = await FileBlock.WriteBlockAsync(fileStream, (sectionWriter) => this.Properties.Write(sectionWriter)).ConfigureAwait(false);

            // Write the Footer.
            this.Footer = new FileFooter(propertiesHandle, FileVersion);
            await FileBlock.WriteBlockAsync(fileStream, (sectionWriter) => this.Footer.Write(sectionWriter)).ConfigureAwait(false);

            // Finally, flush to disk.
            await fileStream.FlushAsync().ConfigureAwait(false);
        }
Пример #6
0
        private void ReadHeaderAndFooter(byte[] fileData)
        {
            FileHeader = ReadFileHeader(fileData);
            FileFooter = ReadFileFooter(fileData, FileHeader.FooterOffset);

            var enc = new UTF8Encoding();

            // backup description...
            var backupDescriptionRecord = FileFooter.Records.SingleOrDefault(x => x.Title == DescriptionCode);

            if (backupDescriptionRecord != null)
            {
                FileHeader.BackupDescription = enc.GetString(
                    fileData,
                    backupDescriptionRecord.StartSectionOffset,
                    backupDescriptionRecord.SectionLength);
            }

            // names of set lists...
            var setListNamesRecord = FileFooter.Records.SingleOrDefault(x => x.Title == SetListNamesCode);

            if (setListNamesRecord != null)
            {
                var setListNames = enc.GetString(
                    fileData,
                    setListNamesRecord.StartSectionOffset,
                    setListNamesRecord.SectionLength);

                var tokens = setListNames.Split('\0');

                foreach (var token in tokens)
                {
                    if (!string.IsNullOrWhiteSpace(token))
                    {
                        FileHeader.SetListNames.Add(token);
                    }
                }
            }
        }
Пример #7
0
        /// <summary>
        /// A Flush indicates that all values have been written to the checkpoint file (via AddItemAsync), so
        /// the checkpoint file can finish flushing any remaining in-memory buffered data, write any extra
        /// metadata (e.g. properties and footer), and flush to disk.
        /// </summary>
        /// <param name="fileStream"></param>
        /// <param name="memoryBuffer"></param>
        /// <returns></returns>
        public async Task FlushAsync(Stream fileStream, InMemoryBinaryWriter memoryBuffer)
        {
            // If there's any buffered values in memory, flush them to disk first.
            if (memoryBuffer.BaseStream.Position > 0)
            {
                await this.WriteToFileBufferAsync(fileStream, memoryBuffer).ConfigureAwait(false);
            }

            Diagnostics.Assert(fileStream.Position % DefaultBlockAlignmentSize == 0, this.traceType, "Value checkpoint file is incorrectly block aligned at the end.");

            // Update the Properties.
            this.Properties.ValuesHandle = new BlockHandle(0, fileStream.Position);

            // Write the Properties.
            var propertiesHandle = await FileBlock.WriteBlockAsync(fileStream, (sectionWriter) => this.Properties.Write(sectionWriter)).ConfigureAwait(false);

            // Write the Footer.
            this.Footer = new FileFooter(propertiesHandle, FileVersion);
            await FileBlock.WriteBlockAsync(fileStream, (sectionWriter) => this.Footer.Write(sectionWriter)).ConfigureAwait(false);

            // Finally, flush to disk.
            await fileStream.FlushAsync().ConfigureAwait(false);
        }
Пример #8
0
        /// <summary>
        /// Deserializes the metadata (footer, properties, etc.) for this checkpoint file.
        /// </summary>
        private async Task ReadMetadataAsync()
        {
            Stream filestream = null;

            try
            {
                filestream = this.ReaderPool.AcquireStream();

                var snapFileStream = filestream as FileStream;
                Diagnostics.Assert(snapFileStream != null, this.traceType, "fileStream must be a FileStream");
                Microsoft.ServiceFabric.Replicator.Utility.SetIoPriorityHint(snapFileStream.SafeFileHandle, this.priorityHint);

                // 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);
                this.Footer =
                    await FileBlock.ReadBlockAsync(filestream, footerHandle, (sectionReader, sectionHandle) => FileFooter.Read(sectionReader, sectionHandle)).ConfigureAwait(false);

                // Verify we know how to deserialize this version of the checkpoint file.
                if (this.Footer.Version != FileVersion)
                {
                    throw new InvalidDataException(SR.Error_ValueCheckpoint_Deserialized);
                }

                // Read and validate the Properties section.
                var propertiesHandle = this.Footer.PropertiesHandle;
                this.Properties =
                    await
                    FileBlock.ReadBlockAsync(
                        filestream,
                        propertiesHandle,
                        (sectionReader, sectionHandle) => FilePropertySection.Read <ValueCheckpointFileProperties>(sectionReader, sectionHandle)).ConfigureAwait(false);
            }
            finally
            {
                this.ReaderPool.ReleaseStream(filestream, true);
            }
        }
Пример #9
0
        /// <summary>
        ///
        /// </summary>
        /// <remarks>Exposed for testability.</remarks>
        internal static async Task PopulateMetadataAsync(MetadataTable metadataTable, Stream stream, string traceType)
        {
            // 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(stream.Length - FileFooter.SerializedSize - sizeof(ulong), FileFooter.SerializedSize);
            var footer       = await FileBlock.ReadBlockAsync(stream, footerHandle, (sectionReader, sectionHandle) => FileFooter.Read(sectionReader, sectionHandle)).ConfigureAwait(false);

            // Verify we know how to deserialize this version of the file.
            if (footer.Version != FileVersion)
            {
                throw new InvalidDataException(SR.Error_MetadataManager_Deserialized);
            }

            // Read and validate the Properties section.
            var propertiesHandle = footer.PropertiesHandle;
            var properties       =
                await
                FileBlock.ReadBlockAsync(
                    stream,
                    propertiesHandle,
                    (sectionReader, sectionHandle) => FilePropertySection.Read <MetadataManagerFileProperties>(sectionReader, sectionHandle)).ConfigureAwait(false);

            // Read disk metadata into memory.
            await ReadDiskMetadataAsync(metadataTable.Table, stream, properties, traceType).ConfigureAwait(false);

            metadataTable.CheckpointLSN = properties.CheckpointLSN;
        }
Пример #10
0
        internal static async Task ValidateAsync(string path, string traceType)
        {
            // MCoskun: Open of metadata file's IO priority is not set.
            // Reason: USed during CompleteCheckpoint which can block copy and backup.
            using (var stream = FabricFile.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous))
            {
                // 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(stream.Length - FileFooter.SerializedSize - sizeof(ulong), FileFooter.SerializedSize);
                var footer       = await FileBlock.ReadBlockAsync(stream, footerHandle, (sectionReader, sectionHandle) => FileFooter.Read(sectionReader, sectionHandle)).ConfigureAwait(false);

                // Verify we know how to deserialize this version of the file.
                if (footer.Version != FileVersion)
                {
                    throw new InvalidDataException(SR.Error_MetadataManager_Deserialized);
                }

                // Read and validate the Properties section.
                var propertiesHandle = footer.PropertiesHandle;
                var properties       = await FileBlock.ReadBlockAsync(
                    stream,
                    propertiesHandle,
                    (sectionReader, sectionHandle) => FilePropertySection.Read <MetadataManagerFileProperties>(sectionReader, sectionHandle)).ConfigureAwait(false);
            }
        }