예제 #1
0
        /// <summary>
        /// Checks that
        ///   - a sideband file for a given process exists
        ///   - the sideband file is not corrupt (its checksum checks out)
        ///   - the process metadata recorded in the sideband file matches the metadata expected for this process
        /// </summary>
        private bool ValidateSidebandFileForProcess(Process process)
        {
            var sidebandFile = GetSidebandFile(process);

            if (!FileUtilities.FileExistsNoFollow(sidebandFile))
            {
                return(failed(SidebandIntegrityCheckFailReason.FileNotFound));
            }

            using (var reader = new SidebandReader(sidebandFile))
            {
                if (!reader.ReadHeader(ignoreChecksum: false))
                {
                    return(failed(SidebandIntegrityCheckFailReason.ChecksumMismatch));
                }

                var metadata = reader.ReadMetadata();
                var expected = PipExecutor.CreateSidebandMetadata(Scheduler, process);
                if (!metadata.Equals(expected))
                {
                    return(failed(SidebandIntegrityCheckFailReason.MetadataMismatch, $"Expected: {expected}.  Actual: {metadata}"));
                }

                return(true);
            }

            bool failed(SidebandIntegrityCheckFailReason reason, string details = "")
            {
                Logger.Log.SidebandIntegrityCheckForProcessFailed(LoggingContext, process.FormattedSemiStableHash, sidebandFile, reason.ToString(), details);
                return(false);
            }
        }
예제 #2
0
        private void InvalidateSidebandFile(string sidebandFile, SidebandIntegrityCheckFailReason kind)
        {
            XAssert.FileExists(sidebandFile, "Sideband file for pipA not found.");
            switch (kind)
            {
            case SidebandIntegrityCheckFailReason.FileNotFound:
                AssertDeleteFile(sidebandFile, "Could not delete sideband file for pipA.");
                break;

            case SidebandIntegrityCheckFailReason.ChecksumMismatch:
                File.WriteAllText(path: sidebandFile, contents: "bogus sideband file");
                break;

            case SidebandIntegrityCheckFailReason.MetadataMismatch:
                SidebandMetadata alteredMetadata;
                // read the header and the metadata from the original
                using (var reader = new SidebandReader(sidebandFile))
                {
                    XAssert.IsTrue(reader.ReadHeader(ignoreChecksum: false));
                    var originalMetadata = reader.ReadMetadata();
                    alteredMetadata = new SidebandMetadata(originalMetadata.PipSemiStableHash + 1, originalMetadata.StaticPipFingerprint);
                }
                // overwrite the original with a different metadata file where PiPSemiStableHash is different than in the original
                using (var writer = new SidebandWriter(alteredMetadata, sidebandFile, null))
                {
                    writer.EnsureHeaderWritten();
                }
                break;

            default:
                XAssert.Fail($"Unknown kind: {kind}");
                break;
            }
        }
예제 #3
0
        /// <summary>
        /// Reads in parallel all writes recorded in given sideband files (<paramref name="sidebandFiles"/>).
        /// The task of reading paths from a single sideband file is delegated to <see cref="SidebandReader.ReadSidebandFile"/>.
        /// Exceptions of type <see cref="IOException"/> and <see cref="BuildXLException"/> are caught, logged, and ignored.
        /// </summary>
        internal string[] TryReadAllRecordedWrites(IReadOnlyList <string> sidebandFiles)
        {
            try
            {
                return(sidebandFiles
                       .AsParallel(Context)
                       .SelectMany(tryReadSidebandFile)
                       .ToArray());
            }
            catch (OperationCanceledException)
            {
                // No specific handling needed for cancellations. Build session will terminate
                return(CollectionUtilities.EmptyArray <string>());
            }

            IEnumerable <string> tryReadSidebandFile(string filename)
            {
                try
                {
                    return(SidebandReader.ReadSidebandFile(filename, ignoreChecksum: true));
                }
                catch (Exception e) when(e is BuildXLException || e is IOException || e is OperationCanceledException)
                {
                    Processes.Tracing.Logger.Log.CannotReadSidebandFileWarning(LoggingContext, filename, e.Message);
                    return(CollectionUtilities.EmptyArray <string>());
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Checks that
        ///   - a sideband file for a given process exists
        ///   - the sideband file is not corrupt (its checksum checks out)
        ///   - the process metadata recorded in the sideband file matches the metadata expected for this process
        /// Returns true on success and the sideband state in the out parameter
        /// </summary>
        private bool TryGetAndValidateSidebandStateForProcess(Process process, out IReadOnlyCollection <AbsolutePath> paths)
        {
            var sidebandFile = GetSidebandFile(process);

            paths = null;
            if (!FileUtilities.FileExistsNoFollow(sidebandFile))
            {
                return(failed(SidebandIntegrityCheckFailReason.FileNotFound));
            }

            using (var reader = new SidebandReader(sidebandFile))
            {
                if (!reader.ReadHeader(ignoreChecksum: false))
                {
                    return(failed(SidebandIntegrityCheckFailReason.ChecksumMismatch));
                }

                var metadata = reader.ReadMetadata();
                var expected = PipExecutor.CreateSidebandMetadata(Scheduler, process);
                if (!metadata.Equals(expected))
                {
                    return(failed(SidebandIntegrityCheckFailReason.MetadataMismatch, $"Expected: {expected}.  Actual: {metadata}"));
                }

                paths = reader.ReadRecordedPaths().Select(p => AbsolutePath.Create(Context.PathTable, p)).ToHashSet();
                return(true);
            }

            bool failed(SidebandIntegrityCheckFailReason reason, string details = "")
            {
                Logger.Log.SidebandIntegrityCheckForProcessFailed(LoggingContext, process.FormattedSemiStableHash, sidebandFile, reason.ToString(), details);
                return(false);
            }
        }
예제 #5
0
 private bool TryReadSidebandFile(string filename, out SidebandMetadata metadata, out IEnumerable <string> paths)
 {
     try
     {
         // We ignore the checksum because even when the sideband file is compromised,
         // it is possible to call <see cref="ReadRecordedPaths"/> which will then try to recover
         // as many recorded paths as possible.
         (paths, metadata) = SidebandReader.ReadSidebandFile(filename, ignoreChecksum: true);
         return(true);
     }
     catch (Exception e) when(e is BuildXLException || e is IOException || e is OperationCanceledException)
     {
         Processes.Tracing.Logger.Log.CannotReadSidebandFileWarning(LoggingContext, filename, e.Message);
         metadata = null;
         paths    = null;
         return(false);
     }
 }