From 0995fedcaca9a921488929ee40f68c71fbba7a70 Mon Sep 17 00:00:00 2001
From: Sean McNamara
Date: Mon, 2 May 2011 04:32:31 -0400
Subject: AutoBackupModule: Implement per-region settings in Regions.ini.
---
.../World/AutoBackup/AutoBackupModule.cs | 291 +++++++++++++--------
1 file changed, 186 insertions(+), 105 deletions(-)
(limited to 'OpenSim/Region')
diff --git a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs
index 4a9615d..ce9a448 100644
--- a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs
+++ b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs
@@ -55,7 +55,7 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
///
/// AutoBackupModule: save OAR region backups to disk periodically
- ///
+ ///
///
/// Config Settings Documentation.
/// At the TOP LEVEL, e.g. in OpenSim.ini, we have the following options:
@@ -96,7 +96,7 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
/// AutoBackupAgentThreshold: int. Default: 10. Upper bound on # of agents in region required for BusyCheck heuristics to pass.
/// If the number of agents is greater than this value, don't take a backup right now
/// Save memory by setting low initial capacities. Minimizes impact in common cases of all regions using same interval, and instances hosting 1 ~ 4 regions.
- /// Also helps if you don't want AutoBackup at all.
+ /// Also helps if you don't want AutoBackup at all.
///
public class AutoBackupModule : ISharedRegionModule
{
@@ -110,17 +110,18 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
new Dictionary>(1);
private readonly Dictionary m_timers = new Dictionary(1);
+ private delegate T DefaultGetter(string settingName, T defaultValue);
private bool m_enabled;
- ///
- /// Whether the shared module should be enabled at all. NOT the same as m_Enabled in AutoBackupModuleState!
+ ///
+ /// Whether the shared module should be enabled at all. NOT the same as m_Enabled in AutoBackupModuleState!
///
private bool m_closed;
private IConfigSource m_configSource;
- ///
- /// Required by framework.
+ ///
+ /// Required by framework.
///
public bool IsSharedModule
{
@@ -129,25 +130,25 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
#region ISharedRegionModule Members
- ///
- /// Identifies the module to the system.
+ ///
+ /// Identifies the module to the system.
///
string IRegionModuleBase.Name
{
get { return "AutoBackupModule"; }
}
- ///
- /// We don't implement an interface, this is a single-use module.
+ ///
+ /// We don't implement an interface, this is a single-use module.
///
Type IRegionModuleBase.ReplaceableInterface
{
get { return null; }
}
- ///
- /// Called once in the lifetime of the module at startup.
- ///
+ ///
+ /// Called once in the lifetime of the module at startup.
+ ///
/// The input config source for OpenSim.ini.
void IRegionModuleBase.Initialise(IConfigSource source)
{
@@ -184,8 +185,8 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
m_log.Debug(abms.ToString());
}
- ///
- /// Called once at de-init (sim shutting down).
+ ///
+ /// Called once at de-init (sim shutting down).
///
void IRegionModuleBase.Close()
{
@@ -198,17 +199,17 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
this.StopAllTimers();
}
- ///
- /// Currently a no-op for AutoBackup because we have to wait for region to be fully loaded.
- ///
+ ///
+ /// Currently a no-op for AutoBackup because we have to wait for region to be fully loaded.
+ ///
///
void IRegionModuleBase.AddRegion(Scene scene)
{
}
- ///
- /// Here we just clean up some resources and stop the OAR backup (if any) for the given scene.
- ///
+ ///
+ /// Here we just clean up some resources and stop the OAR backup (if any) for the given scene.
+ ///
/// The scene (region) to stop performing AutoBackup on.
void IRegionModuleBase.RemoveRegion(Scene scene)
{
@@ -237,10 +238,10 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
}
}
- ///
- /// Most interesting/complex code paths in AutoBackup begin here.
- /// We read lots of Nini config, maybe set a timer, add members to state tracking Dictionaries, etc.
- ///
+ ///
+ /// Most interesting/complex code paths in AutoBackup begin here.
+ /// We read lots of Nini config, maybe set a timer, add members to state tracking Dictionaries, etc.
+ ///
/// The scene to (possibly) perform AutoBackup on.
void IRegionModuleBase.RegionLoaded(Scene scene)
{
@@ -260,8 +261,8 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
m_log.Debug((abms == null ? "DEFAULT" : abms.ToString()));
}
- ///
- /// Currently a no-op.
+ ///
+ /// Currently a no-op.
///
void ISharedRegionModule.PostInitialise()
{
@@ -269,12 +270,12 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
#endregion
- ///
- /// Set up internal state for a given scene. Fairly complex code.
- /// When this method returns, we've started auto-backup timers, put members in Dictionaries, and created a State object for this scene.
- ///
- /// The scene to look at.
- /// Whether this call is intended to figure out what we consider the "default" config (applied to all regions unless overridden by per-region settings).
+ ///
+ /// Set up internal state for a given scene. Fairly complex code.
+ /// When this method returns, we've started auto-backup timers, put members in Dictionaries, and created a State object for this scene.
+ ///
+ /// The scene to look at.
+ /// Whether this call is intended to figure out what we consider the "default" config (applied to all regions unless overridden by per-region settings).
/// An AutoBackupModuleState contains most information you should need to know relevant to auto-backup, as applicable to a single region.
private AutoBackupModuleState ParseConfig(IScene scene, bool parseDefault)
{
@@ -299,16 +300,16 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
}
// Read the config settings and set variables.
+ IConfig regionConfig = (scene != null ? scene.Config.Configs[sRegionName] : null);
IConfig config = this.m_configSource.Configs["AutoBackupModule"];
if (config == null)
{
// defaultState would be disabled too if the section doesn't exist.
state = this.m_defaultState;
- m_log.Info("[AUTO BACKUP]: Region " + sRegionLabel + " is NOT AutoBackup enabled.");
return state;
}
- bool tmpEnabled = config.GetBoolean(prepend + "AutoBackup", this.m_defaultState.Enabled);
+ bool tmpEnabled = ResolveBoolean("AutoBackup", this.m_defaultState.Enabled, config, regionConfig);
if (state == null && tmpEnabled != this.m_defaultState.Enabled)
//Varies from default state
{
@@ -332,8 +333,8 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
// Borrow an existing timer if one exists for the same interval; otherwise, make a new one.
double interval =
- config.GetDouble(prepend + "AutoBackupInterval", this.m_defaultState.IntervalMinutes)*
- 60000.0;
+ this.ResolveDouble("AutoBackupInterval", this.m_defaultState.IntervalMinutes,
+ config, regionConfig) * 60000.0;
if (state == null && interval != this.m_defaultState.IntervalMinutes*60000.0)
{
state = new AutoBackupModuleState();
@@ -400,8 +401,8 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
}
}
- bool tmpBusyCheck = config.GetBoolean(prepend + "AutoBackupBusyCheck",
- this.m_defaultState.BusyCheck);
+ bool tmpBusyCheck = ResolveBoolean("AutoBackupBusyCheck",
+ this.m_defaultState.BusyCheck, config, regionConfig);
if (state == null && tmpBusyCheck != this.m_defaultState.BusyCheck)
{
state = new AutoBackupModuleState();
@@ -413,8 +414,8 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
}
// Set file naming algorithm
- string stmpNamingType = config.GetString(prepend + "AutoBackupNaming",
- this.m_defaultState.NamingType.ToString());
+ string stmpNamingType = ResolveString("AutoBackupNaming",
+ this.m_defaultState.NamingType.ToString(), config, regionConfig);
NamingType tmpNamingType;
if (stmpNamingType.Equals("Time", StringComparison.CurrentCultureIgnoreCase))
{
@@ -445,8 +446,8 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
state.NamingType = tmpNamingType;
}
- string tmpScript = config.GetString(prepend + "AutoBackupScript",
- this.m_defaultState.Script);
+ string tmpScript = ResolveString("AutoBackupScript",
+ this.m_defaultState.Script, config, regionConfig);
if (state == null && tmpScript != this.m_defaultState.Script)
{
state = new AutoBackupModuleState();
@@ -457,7 +458,7 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
state.Script = tmpScript;
}
- string tmpBackupDir = config.GetString(prepend + "AutoBackupDir", ".");
+ string tmpBackupDir = ResolveString("AutoBackupDir", ".", config, regionConfig);
if (state == null && tmpBackupDir != this.m_defaultState.BackupDir)
{
state = new AutoBackupModuleState();
@@ -491,10 +492,90 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
return state;
}
- ///
- /// Called when any auto-backup timer expires. This starts the code path for actually performing a backup.
- ///
- ///
+ ///
+ /// 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);
+ }
+ }
+
+ ///
+ /// Helper function for ParseConfig.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private double ResolveDouble(string settingName, double defaultValue, IConfig global, IConfig local)
+ {
+ if (local != null)
+ {
+ return local.GetDouble(settingName, global.GetDouble(settingName, defaultValue));
+ }
+ else
+ {
+ return global.GetDouble(settingName, defaultValue);
+ }
+ }
+
+ ///
+ /// Helper function for ParseConfig.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private int ResolveInt(string settingName, int defaultValue, IConfig global, IConfig local)
+ {
+ if (local != null)
+ {
+ return local.GetInt(settingName, global.GetInt(settingName, defaultValue));
+ }
+ else
+ {
+ return global.GetInt(settingName, defaultValue);
+ }
+ }
+
+ ///
+ /// Helper function for ParseConfig.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private string ResolveString(string settingName, string defaultValue, IConfig global, IConfig local)
+ {
+ if (local != null)
+ {
+ return local.GetString(settingName, global.GetString(settingName, defaultValue));
+ }
+ else
+ {
+ return global.GetString(settingName, defaultValue);
+ }
+ }
+
+ ///
+ /// Called when any auto-backup timer expires. This starts the code path for actually performing a backup.
+ ///
+ ///
///
private void HandleElapsed(object sender, ElapsedEventArgs e)
{
@@ -554,9 +635,9 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
}
}
- ///
- /// Save an OAR, register for the callback for when it's done, then call the AutoBackupScript (if applicable).
- ///
+ ///
+ /// Save an OAR, register for the callback for when it's done, then call the AutoBackupScript (if applicable).
+ ///
///
private void DoRegionBackup(IScene scene)
{
@@ -585,25 +666,25 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
iram.ArchiveRegion(savePath, guid, null);
}
- ///
- /// Called by the Event Manager when the OnOarFileSaved event is fired.
- ///
- ///
+ ///
+ /// Called by the Event Manager when the OnOarFileSaved event is fired.
+ ///
+ ///
///
void EventManager_OnOarFileSaved(Guid guid, string message)
- {
- // Ignore if the OAR save is being done by some other part of the system
- if (m_pendingSaves.ContainsKey(guid))
- {
- AutoBackupModuleState abms = m_states[(m_pendingSaves[guid])];
- ExecuteScript(abms.Script, abms.LiveRequests[guid]);
- m_pendingSaves.Remove(guid);
- abms.LiveRequests.Remove(guid);
- }
+ {
+ // Ignore if the OAR save is being done by some other part of the system
+ if (m_pendingSaves.ContainsKey(guid))
+ {
+ AutoBackupModuleState abms = m_states[(m_pendingSaves[guid])];
+ ExecuteScript(abms.Script, abms.LiveRequests[guid]);
+ m_pendingSaves.Remove(guid);
+ abms.LiveRequests.Remove(guid);
+ }
}
/// This format may turn out to be too unwieldy to keep...
- /// Besides, that's what ctimes are for. But then how do I name each file uniquely without using a GUID?
+ /// Besides, that's what ctimes are for. But then how do I name each file uniquely without using a GUID?
/// Sequential numbers, right? We support those, too!
private static string GetTimeString()
{
@@ -642,12 +723,12 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
}
}
- ///
- /// If the time dilation right at this instant is less than the threshold specified in AutoBackupDilationThreshold (default 0.5),
- /// then we return false and trip the busy heuristic's "too busy" path (i.e. don't save an OAR).
- /// AutoBackupDilationThreshold is a _LOWER BOUND_. Lower Time Dilation is bad, so if you go lower than our threshold, it's "too busy".
- ///
- ///
+ ///
+ /// If the time dilation right at this instant is less than the threshold specified in AutoBackupDilationThreshold (default 0.5),
+ /// then we return false and trip the busy heuristic's "too busy" path (i.e. don't save an OAR).
+ /// AutoBackupDilationThreshold is a _LOWER BOUND_. Lower Time Dilation is bad, so if you go lower than our threshold, it's "too busy".
+ ///
+ ///
/// Returns true if we're not too busy; false means we've got worse time dilation than the threshold.
private bool RunTimeDilationHeuristic(IScene region)
{
@@ -657,12 +738,12 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
regionName + ".AutoBackupDilationThreshold", 0.5f);
}
- ///
- /// If the root agent count right at this instant is less than the threshold specified in AutoBackupAgentThreshold (default 10),
- /// then we return false and trip the busy heuristic's "too busy" path (i.e., don't save an OAR).
- /// AutoBackupAgentThreshold is an _UPPER BOUND_. Higher Agent Count is bad, so if you go higher than our threshold, it's "too busy".
- ///
- ///
+ ///
+ /// If the root agent count right at this instant is less than the threshold specified in AutoBackupAgentThreshold (default 10),
+ /// then we return false and trip the busy heuristic's "too busy" path (i.e., don't save an OAR).
+ /// AutoBackupAgentThreshold is an _UPPER BOUND_. Higher Agent Count is bad, so if you go higher than our threshold, it's "too busy".
+ ///
+ ///
/// Returns true if we're not too busy; false means we've got more agents on the sim than the threshold.
private bool RunAgentLimitHeuristic(IScene region)
{
@@ -685,12 +766,12 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
}
}
- ///
- /// Run the script or executable specified by the "AutoBackupScript" config setting.
- /// Of course this is a security risk if you let anyone modify OpenSim.ini and they want to run some nasty bash script.
- /// But there are plenty of other nasty things that can be done with an untrusted OpenSim.ini, such as running high threat level scripting functions.
- ///
- ///
+ ///
+ /// Run the script or executable specified by the "AutoBackupScript" config setting.
+ /// Of course this is a security risk if you let anyone modify OpenSim.ini and they want to run some nasty bash script.
+ /// But there are plenty of other nasty things that can be done with an untrusted OpenSim.ini, such as running high threat level scripting functions.
+ ///
+ ///
///
private static void ExecuteScript(string scriptName, string savePath)
{
@@ -719,10 +800,10 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
}
}
- ///
- /// Called if a running script process writes to stderr.
- ///
- ///
+ ///
+ /// Called if a running script process writes to stderr.
+ ///
+ ///
///
private static void HandleProcErrorDataReceived(object sender, DataReceivedEventArgs e)
{
@@ -730,8 +811,8 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
" is yacking on stderr: " + e.Data);
}
- ///
- /// Quickly stop all timers from firing.
+ ///
+ /// Quickly stop all timers from firing.
///
private void StopAllTimers()
{
@@ -742,11 +823,11 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
this.m_closed = true;
}
- ///
- /// Determine the next unique filename by number, for "Sequential" AutoBackupNamingType.
- ///
- ///
- ///
+ ///
+ /// Determine the next unique filename by number, for "Sequential" AutoBackupNamingType.
+ ///
+ ///
+ ///
///
private static string GetNextFile(string dirName, string regionName)
{
@@ -760,12 +841,12 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
return uniqueFile.FullName;
}
- ///
- /// Top-level method for creating an absolute path to an OAR backup file based on what naming scheme the user wants.
- ///
- /// Name of the region to save.
- /// Absolute or relative path to the directory where the file should reside.
- /// The naming scheme for the file name.
+ ///
+ /// Top-level method for creating an absolute path to an OAR backup file based on what naming scheme the user wants.
+ ///
+ /// Name of the region to save.
+ /// Absolute or relative path to the directory where the file should reside.
+ /// The naming scheme for the file name.
///
private static string BuildOarPath(string regionName, string baseDir, NamingType naming)
{
@@ -792,11 +873,11 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup
return null;
}
- ///
- /// Helper function for Sequential file naming type (see BuildOarPath and GetNextFile).
- ///
- ///
- ///
+ ///
+ /// Helper function for Sequential file naming type (see BuildOarPath and GetNextFile).
+ ///
+ ///
+ ///
///
private static long GetNextOarFileNumber(string dirName, string regionName)
{
--
cgit v1.1