Beispiel #1
0
        public void LoadConfigFile(string configFile)
        {
            Log.Trace(@"Loading config file {0}", configFile);

            ConfigErrors.Clear();

            ConfigWarnings.Clear();

            ConfigPath = configFile;

            if (Read())
            {
                DoValidation();
            }
            else
            {
                ConfigErrors.Add($"Failed to read the configuration file {configFile}");
            }
        }
Beispiel #2
0
        /// <summary>
        /// Reads the config file
        /// </summary>
        /// <returns>an empty string if no exception occurs</returns>
        public bool Read()
        {
            Log.Trace(@"ConfigFileHelper.Read() ...");

            try
            {
                if (!ConfigFileExists)
                {
                    return(false);
                }

                bool isConfigRead = true;

                ParityFile1 = string.Empty;
                ParityFile2 = string.Empty;
                ZParityFile = string.Empty;
                ParityFile3 = string.Empty;
                ParityFile4 = string.Empty;
                ParityFile5 = string.Empty;
                ParityFile6 = string.Empty;

                ConfigErrors.Clear();

                ConfigWarnings.Clear();

                ContentFiles.Clear();

                SnapShotSources.Clear();

                ExcludePatterns.Clear();

                IncludePatterns.Clear();

                BlockSizeKB = Constants.DefaultBlockSize;

                AutoSaveGB = Constants.DefaultAutoSave;

                foreach (string line in File.ReadLines(ConfigPath))
                {
                    string lineStart = line.Trim();

                    if (string.IsNullOrWhiteSpace(lineStart) || lineStart.StartsWith(@"#"))
                    {
                        continue;
                    }

                    // Not a comment so process the line

                    // split the line by the first space encountered
                    string[] configItem = lineStart.Split(new[] { ' ' }, 2);
                    Log.Trace(@"configItem [{0}]", string.Join(" ", configItem));
                    string configItemName = configItem[0] ?? string.Empty;
                    Log.Trace(@"configItemName [{0}]", configItemName);
                    string configItemValue = (configItem.Length > 1) ? configItem[1] : string.Empty;
                    Log.Trace(@"configItemValue [{0}]", configItemValue);

                    // ignore the line if it is not an a recognized setting
                    if (!validConfigNames.Contains(configItemName))
                    {
                        continue;
                    }
                    Log.Trace(@"configItemName found in validConfigNames");

                    switch (configItemName)
                    {
                    case @"parity":
                        ParityFile1 = configItemValue;
                        break;

                    case @"q-parity":
                        Log.Warn(@"'q-parity' entry in config file will be changed to '2-parity' when config is saved");
                        ParityFile2 = configItemValue;
                        break;

                    case @"2-parity":
                        // handle legacy 'q-parity' entry by giving it priority over any '2-parity' entry; saving config will rename 'q-parity' to '2-parity' and leave the path unchanged
                        if (string.IsNullOrEmpty(ParityFile2))
                        {
                            ParityFile2 = configItemValue;
                        }
                        break;

                    case @"z-parity":
                        // #WARNING! Your CPU doesn't have a fast implementation for triple parity.
                        // #WARNING! It's recommended to switch to 'z-parity' instead than '3-parity'.
                        ZParityFile = configItemValue;
                        ParityFile3 = string.Empty;
                        break;

                    case @"3-parity":
                        if (string.IsNullOrWhiteSpace(ZParityFile))
                        {
                            ParityFile3 = configItemValue;
                        }
                        break;

                    case @"4-parity":
                        ParityFile4 = configItemValue;
                        break;

                    case @"5-parity":
                        ParityFile5 = configItemValue;
                        break;

                    case @"6-parity":
                        ParityFile6 = configItemValue;
                        break;

                    case @"content":
                        ContentFiles.Add(configItemValue);
                        break;

                    case @"disk":
                    case @"data":     // Handle older configs
                    {
                        // get the data name, d1,d2,d3 etc
                        string diskName = configItemValue.Split(' ')[0];

                        // get the path
                        int diskSplitIndex = configItemValue.IndexOf(' ');

                        string diskPath = configItemValue.Substring(diskSplitIndex + 1);

                        // special handling of data sources since order preservation is extremely important
                        if (!string.IsNullOrEmpty(diskName) && !string.IsNullOrEmpty(diskPath))
                        {
                            SnapShotSources.Add(new SnapShotSource {
                                    Name = diskName, DirSource = diskPath
                                });
                        }
                    }
                    break;

                    case @"exclude":
                        ExcludePatterns.Add(configItemValue);
                        break;

                    case @"include":
                        IncludePatterns.Add(configItemValue);
                        break;

                    case @"block_size":
                        BlockSizeKB = uint.Parse(configItemValue);
                        if (BlockSizeKB < Constants.MinBlockSize || BlockSizeKB > Constants.MaxBlockSize)
                        {
                            isConfigRead = false;
                        }
                        break;

                    case @"autosave":
                        AutoSaveGB = uint.Parse(configItemValue);
                        // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                        if (AutoSaveGB < Constants.MinAutoSave || AutoSaveGB > Constants.MaxAutoSave)
                        {
                            isConfigRead = false;
                        }
                        break;

                    case @"nohidden":
                        Nohidden = true;
                        break;
                    }
                }

                return(isConfigRead);
            }
            catch (Exception ex)
            {
                Log.Error(ex);
                return(false);
            }
        }
Beispiel #3
0
        private void DoValidation()
        {
            if (string.IsNullOrEmpty(ConfigPath))
            {
                ConfigErrors.Add(@"Config validation failed. There is no config file set.");
                Log.Error(@"Config validation failed. There is no config file set.");
                return;
            }

            Log.Debug("validating config file {0}", ConfigPath);

            // RULE: at least one data source must be specified
            if (!SnapShotSources.Any())
            {
                ConfigErrors.Add("At least one data source must be specified. Check the value for \"d1\" \r\n");
            }

            // RULE: the first parity location must not be empty
            if (string.IsNullOrEmpty(ParityFile1))
            {
                ConfigErrors.Add("The first parity location must not be empty. Check the value for \"parity\"");
            }

            // RULE: number of content files must be at least the (number of parity files + 1)
            if (ContentFiles.Count < ParityPaths.Count + 1)
            {
                ConfigErrors.Add($"The number of content files must be at least one greater than the number of parity files. There should be at least {ParityPaths.Count + 1} content files.");
            }

            // RULE: check that devices are not repeated
            if (!IsRulePassDevicesMustNotRepeat(DataSourcePaths))
            {
                ConfigErrors.Add("Devices for Source and Parity must be unique. Check the values for data and parity");
            }

            // RULE: data paths must be accessible
            foreach (SnapShotSource source in DataSourcePaths)
            {
                // test if path exists
                if (!Directory.Exists(source.DirSource))
                {
                    ConfigErrors.Add($"Source is inaccessible or does not exist: {source.DirSource}");
                }
            }

            // RULE: parity devices should be greater or equal to data devices
            ByteSize largestSourceDevice  = new ByteSize(StorageUtil.GetDriveSizes(DataSourcePaths).Max());
            ByteSize smallestParityDevice = new ByteSize(StorageUtil.GetDriveSizes(ParityPaths).Min());

            if (largestSourceDevice > smallestParityDevice)
            {
                ConfigWarnings.Add($@"One or more data devices [{largestSourceDevice}] are larger than the smallest parity device [{smallestParityDevice}]. All parity devices should be equal or greater in size than all data devices.");
            }

            // RULE: blockSize valid value
            if (BlockSizeKB < 1 || BlockSizeKB > 16384)
            {
                ConfigErrors.Add(@"The blockSize value is invalid and must be between 1 and 16384");
            }

            // RULE: autoSave valid value
            if (AutoSaveGB > Constants.MaxAutoSave)
            {
                ConfigErrors.Add($"The autoSave value is invalid and must be between {Constants.MinAutoSave} and {Constants.MaxAutoSave}");
            }

            if (!IsValid)
            {
                Log.Error(@"The configuration file is not valid. See errors below:");

                foreach (string error in ConfigErrors)
                {
                    Log.Error(@" - {0}", error);
                }
            }
        }