diff --git a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs index 05321cdb23..a14d8194ad 100644 --- a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs +++ b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs @@ -66,7 +66,10 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup /// if false module is disable and all rest is ignored /// AutoBackupInterval: Double, non-negative value. Default: 720 (12 hours). /// The number of minutes between each backup attempt. - /// + /// AutoBackupDir: String. Default: "." (the current directory). + /// A directory (absolute or relative) where backups should be saved. + /// AutoBackupKeepFilesForDays remove files older than this number of days. 0 disables + /// /// Next can be set on OpenSim.ini, as default, and or per region in Regions.ini /// Region-specific settings take precedence. /// @@ -86,10 +89,8 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup /// AutoBackupNaming: string. Default: Time. /// One of three strings (case insensitive): /// "Time": Current timestamp is appended to file name. An existing file will never be overwritten. - /// "Sequential": A number is appended to the file name. So if RegionName_x.oar exists, we'll save to RegionName_{x+1}.oar next. An existing file will never be overwritten. - /// "Overwrite": Always save to file named "${AutoBackupDir}/RegionName.oar", even if we have to overwrite an existing file. - /// AutoBackupDir: String. Default: "." (the current directory). - /// A directory (absolute or relative) where backups should be saved. + /// "Sequential": A number is appended to the file name. So if RegionName_x.oar exists, we'll save to RegionName_{x+1}.oar next. An existing file will never be overwritten. + /// "Overwrite": Always save to file named "${AutoBackupDir}/RegionName.oar", even if we have to overwrite an existing file. /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AutoBackupModule")] public class AutoBackupModule : ISharedRegionModule @@ -106,6 +107,10 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup private List m_Scenes = new List (); private Timer m_masterTimer; private bool m_busy; + private int m_KeepFilesForDays = -1; + private string m_backupDir; + private bool m_doneFirst; + private double m_baseInterval; private IConfigSource m_configSource; @@ -154,15 +159,19 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup if(!m_enabled) return; - m_log.Info("[AUTO BACKUP]: AutoBackupModule enabled"); - m_masterTimer = new Timer(43200000); - m_masterTimer.Elapsed += HandleElapsed; - m_masterTimer.AutoReset = false; + ParseDefaultConfig(moduleConfig); + if(!m_enabled) + return; - ParseDefaultConfig(); m_log.Debug("[AUTO BACKUP]: Default config:"); m_log.Debug(m_defaultState.ToString()); + m_log.Info("[AUTO BACKUP]: AutoBackupModule enabled"); + m_masterTimer = new Timer(); + m_masterTimer.Interval = m_baseInterval; + m_masterTimer.Elapsed += HandleElapsed; + m_masterTimer.AutoReset = false; + m_console = MainConsole.Instance; m_console.Commands.AddCommand ( @@ -251,7 +260,6 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup /// void ISharedRegionModule.PostInitialise() { - } #endregion @@ -261,18 +269,19 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup if (!m_enabled) return; - if(m_busy) - { - MainConsole.Instance.OutputFormat ("Already doing a backup, please try later"); - return; - } - if (args.Length != 2) { MainConsole.Instance.OutputFormat ("Usage: dooarbackup "); return; } + if(m_busy) + { + MainConsole.Instance.OutputFormat ("Already doing a backup, please try later"); + return; + } + + m_masterTimer.Stop(); m_busy = true; bool found = false; @@ -289,13 +298,13 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup { if(name == "ALL") { - m_masterTimer.Stop(); for(int i = 0; i < scenes.Length; i++) { s = scenes[i]; DoRegionBackup(s); + if (!m_enabled) + return; } - m_busy = false; return; } @@ -305,37 +314,56 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup if (s.Name == name) { found = true; - m_masterTimer.Stop(); DoRegionBackup(s); break; } } - } catch { } - + } + catch { } + finally + { + if (m_enabled) + m_masterTimer.Start(); + m_busy = false; + } if (!found) MainConsole.Instance.OutputFormat ("No such region {0}. Nothing to backup", name); - m_busy = false; } - private void ParseDefaultConfig() - { - IConfig config = m_configSource.Configs["AutoBackupModule"]; - if (config == null) - return; + private void ParseDefaultConfig(IConfig config) + { + + m_backupDir = "."; + string backupDir = config.GetString("AutoBackupDir", "."); + if (backupDir != ".") + { + try + { + DirectoryInfo dirinfo = new DirectoryInfo(backupDir); + if (!dirinfo.Exists) + dirinfo.Create(); + } + catch (Exception e) + { + m_enabled = false; + m_log.WarnFormat("[AUTO BACKUP]: Error accessing backup folder {0}. Module disabled. {1}", + backupDir, e); + return; + } + } + m_backupDir = backupDir; - // Borrow an existing timer if one exists for the same interval; otherwise, make a new one. double interval = config.GetDouble("AutoBackupInterval", 720); interval *= 60000.0; - m_masterTimer.Interval = interval; + m_baseInterval = interval; + + // How long to keep backup files in days, 0 Disables this feature + m_KeepFilesForDays = config.GetInt("AutoBackupKeepFilesForDays",m_KeepFilesForDays); m_defaultState.Enabled = config.GetBoolean("AutoBackup", m_defaultState.Enabled); - // Included Option To Skip Assets m_defaultState.SkipAssets = config.GetBoolean("AutoBackupSkipAssets",m_defaultState.SkipAssets); - // How long to keep backup files in days, 0 Disables this feature - m_defaultState.KeepFilesForDays = config.GetInt("AutoBackupKeepFilesForDays",m_defaultState.KeepFilesForDays); - // Set file naming algorithm string stmpNamingType = config.GetString("AutoBackupNaming", m_defaultState.NamingType.ToString()); NamingType tmpNamingType; @@ -354,25 +382,6 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup m_defaultState.Script = config.GetString("AutoBackupScript", m_defaultState.Script); - string backupDir = config.GetString("AutoBackupDir", "."); - if (backupDir != ".") - { - try - { - DirectoryInfo dirinfo = new DirectoryInfo(backupDir); - if (!dirinfo.Exists) - dirinfo.Create(); - } - catch (Exception e) - { - m_log.Warn( - "[AUTO BACKUP]: BAD NEWS. You won't be able to save backups to directory " + - backupDir + - " because it doesn't exist or there's a permissions issue with it. Here's the exception.", - e); - } - } - m_defaultState.BackupDir = backupDir; } /// @@ -388,11 +397,9 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup return null; string sRegionName; - string sRegionLabel; AutoBackupModuleState state = null; sRegionName = scene.RegionInfo.RegionName; - sRegionLabel = sRegionName; // Read the config settings and set variables. IConfig regionConfig = scene.Config.Configs[sRegionName]; @@ -406,9 +413,6 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup // Included Option To Skip Assets state.SkipAssets = regionConfig.GetBoolean("AutoBackupSkipAssets", m_defaultState.SkipAssets); - // How long to keep backup files in days, 0 Disables this feature - state.KeepFilesForDays = regionConfig.GetInt("AutoBackupKeepFilesForDays", m_defaultState.KeepFilesForDays); - // Set file naming algorithm string stmpNamingType = regionConfig.GetString("AutoBackupNaming", m_defaultState.NamingType.ToString()); NamingType tmpNamingType; @@ -420,58 +424,16 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup tmpNamingType = NamingType.Overwrite; else { - m_log.Warn("Unknown naming type specified for region " + sRegionLabel + ": " + + m_log.Warn("Unknown naming type specified for region " + sRegionName + ": " + stmpNamingType); tmpNamingType = NamingType.Time; } m_defaultState.NamingType = tmpNamingType; state.Script = regionConfig.GetString("AutoBackupScript", m_defaultState.Script); - - string tmpBackupDir = regionConfig.GetString("AutoBackupDir", "."); - // Let's give the user some convenience and auto-mkdir - if (tmpBackupDir != "." && tmpBackupDir != m_defaultState.BackupDir) - { - try - { - DirectoryInfo dirinfo = new DirectoryInfo(state.BackupDir); - if (!dirinfo.Exists) - { - dirinfo.Create(); - } - } - catch (Exception e) - { - m_log.Warn( - "[AUTO BACKUP]: BAD NEWS. You won't be able to save backups to directory " + - state.BackupDir + - " because it doesn't exist or there's a permissions issue with it:", - e); - } - } - state.BackupDir = tmpBackupDir; return state; } - /// - /// Helper function for ParseConfig. - /// - /// - /// - /// - /// - /// - private bool ResolveBoolean(string settingName, bool defaultValue, IConfig global, IConfig local) - { - if(local != null) - { - return local.GetBoolean(settingName, global.GetBoolean(settingName, defaultValue)); - } - else - { - return global.GetBoolean(settingName, defaultValue); - } - } /// /// Called when any auto-backup timer expires. This starts the code path for actually performing a backup. @@ -484,6 +446,9 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup return; m_busy = true; + if(m_doneFirst && m_KeepFilesForDays > 0) + RemoveOldFiles(); + foreach (IScene scene in m_Scenes) { if (!m_enabled) @@ -496,6 +461,8 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup m_masterTimer.Start(); m_busy = false; } + + m_doneFirst = true; } /// @@ -526,7 +493,7 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup return; string savePath = BuildOarPath(scene.RegionInfo.RegionName, - state.BackupDir, + m_backupDir, state.NamingType); if (savePath == null) { @@ -548,26 +515,32 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup } // For the given state, remove backup files older than the states KeepFilesForDays property - private void RemoveOldFiles(AutoBackupModuleState state) + private void RemoveOldFiles() { - // 0 Means Disabled, Keep Files Indefinitely - if (state.KeepFilesForDays > 0) + string[] files; + try { - string[] files = Directory.GetFiles(state.BackupDir, "*.oar"); - DateTime CuttOffDate = DateTime.Now.AddDays(0 - state.KeepFilesForDays); + files = Directory.GetFiles(m_backupDir, "*.oar"); + } + catch (Exception Ex) + { + m_log.Error("[AUTO BACKUP]: Error reading backup folder " + m_backupDir + ": " + Ex.Message); + return; + } - foreach (string file in files) + DateTime CuttOffDate = DateTime.Now.AddDays(-m_KeepFilesForDays); + + foreach (string file in files) + { + try { - try - { - FileInfo fi = new FileInfo(file); - if (fi.CreationTime < CuttOffDate) - fi.Delete(); - } - catch (Exception Ex) - { - m_log.Error("[AUTO BACKUP]: Error deleting old backup file '" + file + "': " + Ex.Message); - } + FileInfo fi = new FileInfo(file); + if (fi.CreationTime < CuttOffDate) + fi.Delete(); + } + catch (Exception Ex) + { + m_log.Error("[AUTO BACKUP]: Error deleting old backup file '" + file + "': " + Ex.Message); } } } diff --git a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs index be5f2ae37c..fb87677d62 100644 --- a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs +++ b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs @@ -41,21 +41,17 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup public AutoBackupModuleState() { Enabled = false; - BackupDir = "."; SkipAssets = false; NamingType = NamingType.Time; Script = null; - KeepFilesForDays = 0; } public AutoBackupModuleState(AutoBackupModuleState copyFrom) { Enabled = copyFrom.Enabled; - BackupDir = copyFrom.BackupDir; SkipAssets = copyFrom.SkipAssets; NamingType = copyFrom.NamingType; Script = copyFrom.Script; - KeepFilesForDays = copyFrom.KeepFilesForDays; } public bool Enabled @@ -76,30 +72,17 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup set; } - public string BackupDir - { - get; - set; - } - public NamingType NamingType { get; set; } - public int KeepFilesForDays - { - get; - set; - } - public new string ToString() { string retval = ""; retval += "[AUTO BACKUP]: AutoBackup: " + (Enabled ? "ENABLED" : "DISABLED") + "\n"; retval += "[AUTO BACKUP]: Naming Type: " + NamingType.ToString() + "\n"; - retval += "[AUTO BACKUP]: Backup Dir: " + BackupDir + "\n"; retval += "[AUTO BACKUP]: Script: " + Script + "\n"; return retval; }