public void FabricDirectory_GetFilesNegative()
        {
            LogHelper.Log("FabricDirectory.GetFiles {0}", BadPath);
            var res = FabricDirectory.GetFiles(BadPath);

            Assert.AreEqual(0, res.Length);
        }
        /// <summary>
        /// Simply reads the folder to populate the backup folder.
        /// This API does not trim or validate the backup folder.
        /// Note: Using List instead of SortedList to allow same keys added to the List, this is due to
        /// replicate backup log record may throw transient exception, then user may re-try the
        /// BackupAsync call and leads to same backups uploaded again. In this case, add to SortedList
        /// will fail since same key is not allowed.
        /// </summary>
        /// <param name="cancellationToken">Cancellation token.</param>
        /// <returns>Task that represents the asynchronous work.</returns>
        /// <exception cref="FabricMissingFullBackupException">A valid full backup folder to be the head of the backup chain could not be found.</exception>
        /// <exception cref="ArgumentException">The relevant folder is not a valid full backup folder.</exception>
        /// <exception cref="InvalidDataException">There is a corruption in the file.</exception>
        internal async Task ReadAsync(CancellationToken cancellationToken)
        {
            string[] list = FabricDirectory.GetFiles(
                this.backupFolder,
                Replicator.Constants.ReplicatorBackupMetadataFileName,
                SearchOption.AllDirectories);
            if (list.Length != 1)
            {
                // Note that we are returning full backup missing if there is no full backup or if there is more than full backup.
                // If this is confusing, we could change this to ArgumentException since it already is in the set of possible exceptions.
                throw new FabricMissingFullBackupException(SR.Error_BackupFolderInfo_MissingFullBackup);
            }

            string fullBackupDirectoryName = Path.GetDirectoryName(list[0]);

            await this.AddFullBackupFolderAsync(fullBackupDirectoryName, cancellationToken).ConfigureAwait(false);

            string[] incrementalBackupMetadataFilePaths = FabricDirectory.GetFiles(
                this.backupFolder,
                Replicator.Constants.ReplicatorIncrementalBackupMetadataFileName,
                SearchOption.AllDirectories);
            foreach (string path in incrementalBackupMetadataFilePaths)
            {
                string incrementalBackupDirectory = Path.GetDirectoryName(path);
                await this.AddIncrementalBackupFolderAsync(incrementalBackupDirectory, cancellationToken).ConfigureAwait(false);
            }
        }
        private bool IsStagingFolderNeededForCopy(string sourceFolder)
        {
            if (FileShareAccessAccountType.None != this.accessInfo.AccountType)
            {
                // We are impersonating in order to copy files to destination.
                // Check if we can access the source folder while impersonating.
                bool sourceAccessDeniedUnderImpersonation = false;
                using (WindowsIdentity identity = this.GetIdentityToImpersonate())
                {
#if DotNetCoreClr
                    WindowsIdentity.RunImpersonated(identity.AccessToken, () =>
#else
                    using (WindowsImpersonationContext impersonationCtx = identity.Impersonate())
#endif
                    {
                        try
                        {
                            // Use Directory.GetFiles directly instead of using FabricDirectory.GetFiles
                            // because the latter fails silently and returns an empty array if access is 
                            // denied.
                            FabricDirectory.GetFiles(sourceFolder);
                        }
                        catch (UnauthorizedAccessException)
                        {
                            // We are unable to access the source folder while impersonating.
                            // Hence we need a staging folder, which we can access while 
                            // impersonating.
                            sourceAccessDeniedUnderImpersonation = true;
                        }
                    }
Beispiel #4
0
        /// <summary>
        /// Copy Folder method called by the CopyItem delegate to dequeue a folder copy item
        /// This method enumerates the folder enqueues all its children and dequeues the current item
        /// </summary>
        /// <param name="sourceDir">
        /// Source folder to be copied
        /// </param>
        /// <param name="destinationDir">
        /// Destination folder
        /// </param>
        private void CopyFolder(string sourceDir, string destinationDir)
        {
            // create the destination folder if it doesn't exist
            if (!FabricDirectory.Exists(destinationDir))
            {
                FabricDirectory.CreateDirectory(destinationDir);
            }

            // Enumerate source and queue up work items for each child folder
            var directoryNames = FabricDirectory.GetDirectories(
                sourceDir,
                "*",
                false, // full path
                SearchOption.TopDirectoryOnly);

            var fileNames = FabricDirectory.GetFiles(
                sourceDir,
                "*",
                false, // full path
                SearchOption.TopDirectoryOnly);

            foreach (var directoryName in directoryNames)
            {
                this.QueueCopyItem(sourceDir, destinationDir, directoryName, true);
            }

            foreach (var fileName in fileNames)
            {
                this.QueueCopyItem(sourceDir, destinationDir, fileName, false);
            }
        }
Beispiel #5
0
        private bool EnumerateFiles(object context)
        {
            var fileEnumerateInfo = (FileEnumerateInfo)context;;

            fileEnumerateInfo.Files = FabricDirectory.GetFiles(fileEnumerateInfo.DirectoryPath, fileEnumerateInfo.FileExtension, fileEnumerateInfo.SearchOptionEnum);
            return(true);
        }
 /// <summary>
 /// Retrieve files and folders under the current folder from SMB
 /// </summary>
 /// <param name="srcPath"> The SMB path </param>
 /// <param name="files">String array of file names in the folder</param>
 /// <param name="folders">String array of subfolder names in the folder</param>
 private static void GetFilesAndSubfoldersFromSMB(
     string srcPath,
     out string[] files,
     out string[] folders)
 {
     files   = FabricDirectory.GetFiles(srcPath);
     folders = FabricDirectory.GetDirectories(srcPath);
 }
        private IEnumerable <ImageStoreFile> GetAllFiles(string directory, string storeSource)
        {
            var fileFullNames = FabricDirectory.GetFiles(directory, "*", true, SearchOption.AllDirectories);

            foreach (var fileFullName in fileFullNames)
            {
                yield return(this.ConvertToImageStoreFile(fileFullName, storeSource));
            }
        }
Beispiel #8
0
        /// <summary>
        /// Generates checksum files for all service package sub-directories (i.e. code/config/data packages) and service manifests found under the application package root directory.
        /// </summary>
        /// <param name="appPackageRootDirectory">The application package root directory.</param>
        /// <param name="progressHandler">An optional handler for tracking progress of the checksum generation.</param>
        /// <param name="isImageStoreServiceEnabled">Should be set to true if the cluster's ImageStoreConnectionString is set to "fabric:ImageStore", false otherwise.</param>
        /// <remarks>
        /// <para>
        /// The cluster will automatically generate checksums during application type registration if they're not already part of the application package. This method can be used to incur the cost of checksum file generation while preparing the application package, which will reduce the cost of registering the application type package for large packages.
        /// </para>
        /// </remarks>
        public static void GenerateApplicationPackageChecksumFiles(
            string appPackageRootDirectory,
            IImageStoreProgressHandler progressHandler,
            bool isImageStoreServiceEnabled = true)
        {
            var layoutSpecification = BuildLayoutSpecification.Create();

            var files       = new List <string>();
            var directories = new List <string>();

            foreach (var servicePackageDirectory in FabricDirectory.GetDirectories(appPackageRootDirectory))
            {
                files.AddRange(FabricDirectory.GetFiles(servicePackageDirectory));
                directories.AddRange(FabricDirectory.GetDirectories(servicePackageDirectory));
            }

            int completedItems = 0;
            int totalItems     = files.Count + directories.Count;

            foreach (var file in files)
            {
                GenerateChecksumFile(file, layoutSpecification, isImageStoreServiceEnabled);

                try
                {
                    if (progressHandler != null)
                    {
                        progressHandler.UpdateProgress(++completedItems, totalItems, ProgressUnitType.Files);
                    }
                }
                catch (Exception)
                {
                    // Do not fail checksum processing if progress update fails
                }
            }

            foreach (var directory in directories)
            {
                GenerateChecksumFile(directory, layoutSpecification, isImageStoreServiceEnabled);

                try
                {
                    if (progressHandler != null)
                    {
                        progressHandler.UpdateProgress(++completedItems, totalItems, ProgressUnitType.Files);
                    }
                }
                catch (Exception)
                {
                    // Do not fail checksum processing if progress update fails
                }
            }
        }
Beispiel #9
0
        // ImageStoreService does not preserve file case when downloading. Hence the hash is always computed on
        // lower-cased dir/file name. This causes Test-ServiceFabricApplicationPackage to fail which has FileImageStore
        // as source but ImageStoreService as destination ImageStore. imageStoreServiceEnabled is passed in
        // so that we always use lowercase dir/file name to compute checksum when ImageStoreService is used and
        // support backward compatibility
        public static byte[] ComputeHashOnDirectory(string directory, bool imageStoreServiceEnabled)
        {
            List <Tuple <string, byte[], byte[]> > dirHashes  = new List <Tuple <string, byte[], byte[]> >();
            List <Tuple <string, byte[], byte[]> > fileHashes = new List <Tuple <string, byte[], byte[]> >();

            Parallel.Invoke(() => Parallel.ForEach(FabricDirectory.GetDirectories(directory), subDirectory =>
            {
                var subDirName                = Path.GetFileName(subDirectory.TrimEnd(new char[] { Path.DirectorySeparatorChar }));
                byte[] subDirectoryHash       = ComputeHashOnDirectory(subDirectory, imageStoreServiceEnabled);
                string subDirectoryNameString = imageStoreServiceEnabled ? subDirName.ToLower() : subDirName;
                byte[] subDirectoryName       = Encoding.GetEncoding(0).GetBytes(subDirectoryNameString);

                lock (dirHashes)
                {
                    dirHashes.Add(Tuple.Create(subDirectory, subDirectoryName, subDirectoryHash));
                }
            }),
                            () => Parallel.ForEach(FabricDirectory.GetFiles(directory), file =>
            {
                using (FileStream fileStream = FabricFile.Open(file, FileMode.Open, FileAccess.Read))
                {
                    byte[] fileHash       = ComputeHashOnStream(fileStream);
                    string fileNameString = imageStoreServiceEnabled ? Path.GetFileName(file).ToLower() : Path.GetFileName(file);
                    byte[] fileName       = Encoding.GetEncoding(0).GetBytes(fileNameString);

                    lock (fileHashes)
                    {
                        fileHashes.Add(Tuple.Create(file, fileName, fileHash));
                    }
                }
            }));

            using (Stream hashStream = new MemoryStream())
            {
                foreach (var t in dirHashes.OrderBy(t => t.Item1))
                {
                    hashStream.Write(t.Item2, 0, t.Item2.Length);
                    hashStream.Write(t.Item3, 0, t.Item3.Length);
                }

                foreach (var t in fileHashes.OrderBy(t => t.Item1))
                {
                    hashStream.Write(t.Item2, 0, t.Item2.Length);
                    hashStream.Write(t.Item3, 0, t.Item3.Length);
                }

                hashStream.Seek(0, SeekOrigin.Begin);

                return(ComputeHashOnStream(hashStream));
            }
        }
        public static void RemoveFabricAssemblies(string localApplicationPackagePath)
        {
            var filePaths = FabricDirectory.GetFiles(localApplicationPackagePath, "*.dll", true, SearchOption.AllDirectories);

            foreach (var filePath in filePaths)
            {
                var fileName = Path.GetFileName(filePath);
                if (fabricAssemblies.Contains(fileName, StringComparer.OrdinalIgnoreCase))
                {
                    FabricFile.Delete(filePath, deleteReadonly: true);
                    ImageBuilder.TraceSource.WriteWarning(TraceType, "File {0} has been removed from the ApplicationPackage since fabric assemblies are not allowed.", filePath);
                }
            }
        }
        private void EstimateTotalByteCount(string dirFullPath)
        {
            var fileFullPaths = FabricDirectory.GetFiles(dirFullPath, "*", true, SearchOption.AllDirectories);

            this.totalFileCountEstimate += fileFullPaths.Length;
            foreach (var fileFullPath in fileFullPaths)
            {
                this.totalByteCountEstimate += FabricFile.GetSize(fileFullPath);

                this.UpdateProgressEstimatingPackageSizeDetails();
            }

            this.totalFileCountEstimate += FabricDirectory.GetDirectories(dirFullPath, "*", SearchOption.AllDirectories).Length;
            ++this.totalFileCountEstimate;
        }
        private string[] GetBootstrapTraceFileNames(string fileNamePrefix, string fileSuffix)
        {
            // Build the pattern of the trace file name using wildcards
            var fileNameWithWildcard = string.Format(
                CultureInfo.InvariantCulture,
                "{0}*{1}",
                fileNamePrefix,
                fileSuffix);

            // Get all file names that match the pattern
            var bootstrapTraceFileNames = FabricDirectory.GetFiles(
                this.traceDirectory,
                fileNameWithWildcard);

            return(bootstrapTraceFileNames);
        }
        private IEnumerable <string> GetAllFileFullNames(string dir, TimeSpan timeout)
        {
            TimeoutHelper helper = timeout == TimeSpan.MaxValue ? null : new TimeoutHelper(timeout);

            var fileFullNames = FabricDirectory.GetFiles(dir, "*", true, SearchOption.AllDirectories);

            foreach (var fileFullName in fileFullNames)
            {
                yield return(fileFullName);

                if (helper != null)
                {
                    helper.ThrowIfExpired();
                }
            }
        }
        private ImageStoreContent GetFilesAndSubFolders(string directory, string storeSource, TimeSpan timeout)
        {
            TimeoutHelper helper = timeout == TimeSpan.MaxValue ? null : new TimeoutHelper(timeout);

            var directoryFullNames = FabricDirectory.GetDirectories(directory);
            var fileFullNames      = FabricDirectory.GetFiles(directory);

            var content = new ImageStoreContent();

            foreach (var fileFullName in fileFullNames)
            {
                if (content.Files == null)
                {
                    content.Files = new List <ImageStoreFile>();
                }

                content.Files.Add(this.ConvertToImageStoreFile(fileFullName, storeSource));

                if (helper != null)
                {
                    helper.ThrowIfExpired();
                }
            }

            foreach (var directoryFullName in directoryFullNames)
            {
                if (content.Folders == null)
                {
                    content.Folders = new List <ImageStoreFolder>();
                }

                content.Folders.Add(new ImageStoreFolder(
                                        this.GetStoreRelativePathFromFullName(directoryFullName, storeSource),
                                        this.GetFileCount(directoryFullName)));

                if (helper != null)
                {
                    helper.ThrowIfExpired();
                }
            }

            return(content);
        }
        private static void ValidateXCopyPackageAndGetVersion(string packagePath, out string codeVersion)
        {
            foreach (string childFolder in ChildFoldersInXcopyPackage)
            {
                string newPath = Path.Combine(packagePath, childFolder);
                if (!FabricDirectory.Exists(newPath))
                {
                    ImageBuilderUtility.TraceAndThrowValidationError(
                        FabricProvisionOperation.TraceType,
                        StringResources.ImageStoreError_ChildFolderDoesNotExist_Formatted,
                        childFolder,
                        packagePath);
                }
            }

            codeVersion = "0.0.0.0";
            var fabricExeCollection = FabricDirectory.GetFiles(packagePath, "fabric.exe", true, SearchOption.AllDirectories);

            if (fabricExeCollection.Count() == 0)
            {
                ImageBuilderUtility.TraceAndThrowValidationError(
                    FabricProvisionOperation.TraceType,
                    StringResources.ImageStoreError_FabricExeNotFound);
            }

            // Build number in version might have leading 0's i.e. 3.0.00123.0
            // This causes issues during download, hence trimming the leading 0's
#if DotNetCoreClrLinux
            var versionString = FileVersionInfo.GetVersionInfo(fabricExeCollection.First()).ProductVersion;
#else
            var versionString = FabricFile.GetVersionInfo(fabricExeCollection.First());
#endif
            Version productVersion = null;
            if (!Version.TryParse(versionString, out productVersion))
            {
                ImageBuilderUtility.TraceAndThrowValidationError(
                    FabricProvisionOperation.TraceType,
                    StringResources.ImageStoreError_InvalidProductVersion,
                    versionString);
            }

            codeVersion = productVersion.ToString();
        }
Beispiel #16
0
        internal static void GetFilesMatchingPattern(string directory, string pattern, out string[] files)
        {
            PatternMatchingParameters patternMatchingParam = new PatternMatchingParameters
            {
                Directory = directory,
                Pattern   = pattern
            };

            Utility.PerformIOWithRetries(
                ctx =>
            {
                PatternMatchingParameters param = ctx;
                param.Files = FabricDirectory.GetFiles(
                    param.Directory,
                    param.Pattern);
            },
                patternMatchingParam);

            files = patternMatchingParam.Files;
        }
Beispiel #17
0
        public static void RemoveReadOnlyFlag(string path)
        {
            if (FabricDirectory.Exists(path))
            {
                var fileFullPaths = FabricDirectory.GetFiles(path, "*", true, SearchOption.AllDirectories);

                foreach (var file in fileFullPaths)
                {
                    FabricFile.RemoveReadOnlyAttribute(file);
                }
            }
            else if (FabricFile.Exists(path))
            {
                FabricFile.RemoveReadOnlyAttribute(path);
            }
            else
            {
                return;
            }
        }
Beispiel #18
0
        private WinFabricManifestManager InitializeWinFabManifestManager()
        {
            // Figure out which Windows Fabric manifests we have.
            // Try the repository first ...
            string manifestFileDirectory;

            try
            {
                manifestFileDirectory = EtlProcessor.WinfabManifestRepository.RepositoryPath;
            }
            catch (Exception)
            {
                // If we couldn't access the repository for any reason, fall back to
                // the manifests that we shipped with.
                string assemblyLocation = Process.GetCurrentProcess().MainModule.FileName;
                manifestFileDirectory = Path.GetDirectoryName(assemblyLocation);
            }

            string[] manifestFiles = FabricDirectory.GetFiles(manifestFileDirectory, "*.man");

            WinFabricManifestManager manifestManager = null;

            try
            {
                manifestManager = new WinFabricManifestManager(
                    manifestFiles,
                    this.LoadManifest,
                    this.etwManifestCache.UnloadManifest);
            }
            catch (Exception e)
            {
                this.traceSource.WriteError(
                    this.logSourceId,
                    "Exception encountered while identifying the Windows Fabric manifests available. Exception information: {0}",
                    e);
                return(manifestManager);
            }

            if (!manifestManager.FabricManifests.Any())
            {
                this.traceSource.WriteError(
                    this.logSourceId,
                    "No Fabric manifests were found.");
            }

            if (!manifestManager.LeaseLayerManifests.Any())
            {
                this.traceSource.WriteError(
                    this.logSourceId,
                    "No lease layer manifests were found.");
            }

            if (!manifestManager.KtlManifests.Any())
            {
                this.traceSource.WriteError(
                    this.logSourceId,
                    "No KTL manifests were found.");
            }

            return(manifestManager);
        }
Beispiel #19
0
 internal static IEnumerable <string> GetCheckpointFiles(string workDirectory)
 {
     return(FabricDirectory.GetFiles(workDirectory, "*" + CheckpointFileExtension, SearchOption.TopDirectoryOnly));
 }
Beispiel #20
0
        public void FabricFile_EndToEndPositive()
        {
            var folderPath = this.testPath;

            folderPath = this.ExtendPath(folderPath);

            var filePath = Path.Combine(folderPath, this.testFileName);

            Assert.IsTrue(filePath.Length > 260);

            LogHelper.Log("FabricDirectory.Create {0}", folderPath);
            FabricDirectory.CreateDirectory(folderPath);

            LogHelper.Log("FabricFile.Create {0}", filePath);
            using (StreamWriter streamWriter = new StreamWriter(FabricFile.Create(filePath)))
            {
                LogHelper.Log("Write {0}", this.testString);
                streamWriter.WriteLine(this.testString);
            }

            LogHelper.Log("FabricDirectory.GetDirectories {0}", this.testPath);
            var result = FabricDirectory.GetDirectories(this.testPath);

            Assert.AreEqual(1, result.Length);

            LogHelper.Log("FabricDirectory.GetFiles {0}", this.testPath);
            result = FabricDirectory.GetFiles(this.testPath);
            Assert.AreEqual(0, result.Length);

            LogHelper.Log("FabricDirectory.GetFiles {0}, AllDirectories", this.testPath);
            result = FabricDirectory.GetFiles(this.testPath, "*", SearchOption.AllDirectories);
            Assert.AreEqual(1, result.Length);

            LogHelper.Log("FabricDirectory.GetDirectories {0}", folderPath);
            result = FabricDirectory.GetDirectories(folderPath);
            Assert.AreEqual(0, result.Length);

            LogHelper.Log("FabricDirectory.GetFiles {0}", folderPath);
            result = FabricDirectory.GetFiles(folderPath);
            Assert.AreEqual(1, result.Length);

            LogHelper.Log("FabricFile.Open {0}", filePath);
            using (StreamReader streamReader = new StreamReader(FabricFile.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.None)))
            {
                string actual = streamReader.ReadLine();
                LogHelper.Log("Read {0}", actual);
                Assert.AreEqual(this.testString, actual);
            }

            LogHelper.Log("FabricFile.GetSize {0}", filePath);
            long size = FabricFile.GetSize(filePath);

            Assert.IsTrue(size > 0);

            LogHelper.Log("FabricPath.GetDirectoryName {0}", filePath);
            string directoryName = FabricPath.GetDirectoryName(filePath);

            Assert.AreEqual(folderPath, directoryName);

            LogHelper.Log("FabricFile.GetLastWriteTime {0}", filePath);
            DateTime oldTime = FabricFile.GetLastWriteTime(filePath);

            Thread.Sleep(TimeSpan.FromSeconds(1));
            using (StreamWriter streamWriter = new StreamWriter(FabricFile.Open(filePath, FileMode.Open, FileAccess.Write)))
            {
                LogHelper.Log("Write {0}", this.testString);
                streamWriter.WriteLine(this.testString);
            }

            DateTime newTime = FabricFile.GetLastWriteTime(filePath);

            Assert.IsTrue(newTime > oldTime);
        }
        private Int32 GetFileCount(string directory)
        {
            var fileNames = FabricDirectory.GetFiles(directory, "*", false, SearchOption.AllDirectories);

            return(fileNames.Length);
        }
        /// <summary>
        /// Uploads the local source content to the image store at the remote destination.
        /// </summary>
        /// <param name="storeSource"> Location (relative to RootUri) from where to download the content. </param>
        /// <param name="storeDestination"> Location relative to RootUri where the content needs to be uploaded. </param>
        /// <param name="timeout">The timeout for copy content operation.</param>
        /// <param name="skipFiles">Files that do not need to be copied.</param>
        /// <param name="copyFlag">The copying control information to specify how file can be overwritten</param>
        /// <param name="checkMarkFile">Flag the specified the checkmark file.</param>
        public void CopyContent(string storeSource, string storeDestination, TimeSpan timeout, string[] skipFiles, CopyFlag copyFlag, bool checkMarkFile)
        {
            TimeoutHelper  helper     = timeout == TimeSpan.MaxValue ? null : new TimeoutHelper(timeout);
            FileReaderLock readerLock = null;

            try
            {
                string smbSourcePath      = this.ConvertTagToSMBPath(storeSource);
                string smbDestinationPath = this.ConvertTagToSMBPath(storeDestination);

                readerLock = new FileReaderLock(smbSourcePath);
                if (!readerLock.Acquire())
                {
                    throw new FabricTransientException(StringResources.Error_ImageStoreAcquireFileLockFailed, FabricErrorCode.ImageStoreAcquireFileLockFailed);
                }

                if (helper != null)
                {
                    helper.ThrowIfExpired();
                }

#if !DotNetCoreClr
                using (WindowsImpersonationContext impersonationContext = this.GetImpersonationContext())
#endif
                {
                    bool fabricDirectoryExists = FabricDirectory.Exists(smbSourcePath);
                    if (fabricDirectoryExists && skipFiles.Any())
                    {
                        string[] fileNames = FabricDirectory.GetFiles(smbSourcePath, "*", false, SearchOption.TopDirectoryOnly);
                        string[] filtered  = fileNames.Where(file => !skipFiles.Contains <string>(file)).ToArray <string>();

                        if (filtered.Count() < fileNames.Count())
                        {
                            foreach (string file in filtered)
                            {
                                CopyCallerHoldsReaderLock(Path.Combine(smbSourcePath, file), Path.Combine(smbDestinationPath, file), copyFlag, helper);
                            }
                        }
                        else
                        {
                            CopyCallerHoldsReaderLock(smbSourcePath, smbDestinationPath, copyFlag, helper);
                        }
                    }
                    else
                    {
                        bool fabricFileExist = FabricFile.Exists(smbSourcePath);
                        if ((!FabricFile.Exists(smbSourcePath)) &&
                            (!FabricDirectory.Exists(smbSourcePath)))
                        {
                            throw new IOException(string.Format(CultureInfo.CurrentCulture, StringResources.ImageStoreError_DoesNotExistError, smbSourcePath));
                        }

                        CopyCallerHoldsReaderLock(smbSourcePath, smbDestinationPath, copyFlag, helper);
                    }
                }
            }
            catch (IOException exception)
            {
                if (exception.GetType() == typeof(IOException))
                {
                    throw new FabricImageStoreIOException(exception);
                }
                else
                {
                    throw;
                }
            }
            finally
            {
                if (readerLock != null)
                {
                    readerLock.Dispose();
                }
            }
        }
        internal bool Update(Dictionary <string, ServicePackageTableRecord> servicePackageTable, EtwEventTimestamp latestDataTimestamp)
        {
            // Create a new temp file
            string tempFilePath = Utility.GetTempFileName();

            string backupFilePath = string.Empty;

            try
            {
                // Open the temp file
                StreamWriter writer = null;
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        FileStream file = FabricFile.Open(tempFilePath, FileMode.Create, FileAccess.Write);
#if !DotNetCoreClrLinux
                        Helpers.SetIoPriorityHint(file.SafeFileHandle, Kernel32Types.PRIORITY_HINT.IoPriorityHintVeryLow);
#endif
                        writer = new StreamWriter(file);
                    });
                }
                catch (Exception e)
                {
                    Utility.TraceSource.WriteExceptionAsError(
                        TraceType,
                        e,
                        "Failed to open temp file {0}.",
                        tempFilePath);
                    return(false);
                }

                try
                {
                    // Write the version information to the backup file
                    try
                    {
                        Utility.PerformIOWithRetries(
                            () =>
                        {
                            writer.WriteLine(BackupFileVersionString);
                        });
                    }
                    catch (Exception e)
                    {
                        Utility.TraceSource.WriteExceptionAsError(
                            TraceType,
                            e,
                            "Failed to write version information to temp file {0}.",
                            tempFilePath);
                        return(false);
                    }

                    // Write the table records to the backup file
                    foreach (string tableKey in servicePackageTable.Keys)
                    {
                        string tableRecord = string.Concat(
                            servicePackageTable[tableKey].NodeName,
                            ", ",
                            servicePackageTable[tableKey].ApplicationInstanceId,
                            ", ",
                            servicePackageTable[tableKey].ApplicationRolloutVersion,
                            ", ",
                            servicePackageTable[tableKey].ServicePackageName,
                            ", ",
                            servicePackageTable[tableKey].ServiceRolloutVersion,
                            ", ",
                            servicePackageTable[tableKey].RunLayoutRoot);

                        try
                        {
                            Utility.PerformIOWithRetries(
                                () =>
                            {
                                writer.WriteLine(tableRecord);
                            });
                        }
                        catch (Exception e)
                        {
                            Utility.TraceSource.WriteExceptionAsError(
                                TraceType,
                                e,
                                "Failed to write record {0} to temp file {1}",
                                tableRecord,
                                tempFilePath);
                            return(false);
                        }
                    }
                }
                finally
                {
                    writer.Dispose();
                }

                // Compute the name of the backup file
                long   timstampBinary = latestDataTimestamp.Timestamp.ToBinary();
                string fileName       = string.Concat(
                    BackupFilePrefix,
                    timstampBinary.ToString("D20", CultureInfo.InvariantCulture),
                    "_",
                    latestDataTimestamp.Differentiator.ToString("D10", CultureInfo.InvariantCulture),
                    ".",
                    BackupFileExt);
                backupFilePath = Path.Combine(this.backupDirectory, fileName);

                // Copy the temp file as the new backup file
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        FabricFile.Copy(tempFilePath, backupFilePath, true);
                    });
                }
                catch (Exception e)
                {
                    Utility.TraceSource.WriteExceptionAsError(
                        TraceType,
                        e,
                        "Failed to copy file {0} to {1}",
                        tempFilePath,
                        backupFilePath);
                    return(false);
                }

                Utility.TraceSource.WriteInfo(
                    TraceType,
                    "Backup file {0} created. The backup file is valid up to timestamp {1} ({2}, {3}).",
                    backupFilePath,
                    latestDataTimestamp.Timestamp,
                    latestDataTimestamp.Timestamp.Ticks,
                    latestDataTimestamp.Differentiator);
            }
            finally
            {
                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        FabricFile.Delete(tempFilePath);
                    });
                }
                catch (Exception e)
                {
                    Utility.TraceSource.WriteExceptionAsError(
                        TraceType,
                        e,
                        "Failed to delete temp file {0}",
                        tempFilePath);
                }
            }

            // Update the latest backup time
            this.LatestBackupTime = latestDataTimestamp;

            // Delete older backup files
            string backupFilePattern = string.Concat(
                BackupFilePrefix,
                "*.",
                BackupFileExt);
            string[] backupFiles = FabricDirectory.GetFiles(
                this.backupDirectory,
                backupFilePattern);
            foreach (string fileToDelete in backupFiles)
            {
                if (fileToDelete.Equals(
                        backupFilePath,
                        StringComparison.OrdinalIgnoreCase))
                {
                    // Don't delete the current backup file
                    continue;
                }

                try
                {
                    Utility.PerformIOWithRetries(
                        () =>
                    {
                        FabricFile.Delete(fileToDelete);
                    });
                }
                catch (Exception e)
                {
                    // Deletion is on a best-effort basis. Log an error and
                    // continue.
                    Utility.TraceSource.WriteExceptionAsError(
                        TraceType,
                        e,
                        "Failed to delete old backup file {0}",
                        fileToDelete);
                }
            }

            return(true);
        }
        public void OnEtwEventProcessingPeriodStop()
        {
            if (null == this.streamWriter)
            {
                // An error occurred during the creation of the buffered event
                // file. So just return immediately without doing anything.
                return;
            }

            // Close the buffered event file that we are currently working on.
            try
            {
                this.streamWriter.Dispose();
            }
            catch (System.Text.EncoderFallbackException ex)
            {
                // This can happen if the manifest file does not match the binary.
                // Write an error message and move on.
                this.TraceSource.WriteError(
                    this.LogSourceId,
                    "Exception occurred while closing buffered event file. Exception information: {0}",
                    ex);
            }

            // Make our buffered event files available for delivery to the consumer.
            // This includes:
            //  - the buffered event file that we wrote in this pass
            //  - any old buffered event files that we wrote in previous passes
            //    (and got interrupted before we could rename them for delivery to
            //    the consumer).
            string[] cacheFiles = FabricDirectory.GetFiles(
                this.etwEventCache,
                TempCacheFileNameSearchPattern);
            foreach (string cacheFile in cacheFiles)
            {
                try
                {
                    Utility.PerformIOWithRetries(
                        ctx =>
                    {
                        string fileName = ctx;
                        FabricFile.Move(
                            fileName,
                            Path.ChangeExtension(fileName, CacheFileNameExtension));
                    },
                        cacheFile);

                    this.TraceSource.WriteInfo(
                        this.LogSourceId,
                        "File containing filtered ETW events was renamed for delivery to consumer. Old name: {0}, new name: {1}.",
                        cacheFile,
                        Path.ChangeExtension(cacheFile, CacheFileNameExtension));
                }
                catch (Exception e)
                {
                    this.TraceSource.WriteExceptionAsError(
                        this.LogSourceId,
                        e,
                        "Buffered event file {0} could not be renamed for delivery to consumer.",
                        cacheFile);
                }
            }

            this.perfHelper.EtlReadPassEnd();
        }