From 470ab9199ca8e5e6fd33c5668dc1d9403dbf2594 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 9 Jun 2022 14:42:21 +0100 Subject: [PATCH] mantis 9008: add extra lock on FSassets initialization, to be sure only one thread does run main spool thread. Add config option 'SecondaryInstance' to do the same in multiple process instances cases. If there are more than one spool thread there may be file assess collisions that may cause robust crash and or loss of assets. I could not test this. Please to so, and report on mantis 9008, Thanks. --- .../Services/FSAssetService/FSAssetService.cs | 95 +++++++++++-------- bin/Robust.HG.ini.example | 6 +- bin/Robust.ini.example | 4 + 3 files changed, 63 insertions(+), 42 deletions(-) diff --git a/OpenSim/Services/FSAssetService/FSAssetService.cs b/OpenSim/Services/FSAssetService/FSAssetService.cs index 45ff25909a..817b00887b 100644 --- a/OpenSim/Services/FSAssetService/FSAssetService.cs +++ b/OpenSim/Services/FSAssetService/FSAssetService.cs @@ -25,25 +25,21 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using System; -using System.Diagnostics; -using System.Collections.Generic; -using System.IO; -using System.IO.Compression; -using System.Text; -using System.Threading; -using System.Reflection; +using log4net; +using Nini.Config; +using OpenMetaverse; using OpenSim.Data; using OpenSim.Framework; using OpenSim.Framework.Serialization.External; -using OpenSim.Framework.Console; -using OpenSim.Server.Base; using OpenSim.Services.Base; using OpenSim.Services.Interfaces; -using Nini.Config; -using log4net; -using OpenMetaverse; +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Reflection; using System.Security.Cryptography; +using System.Threading; namespace OpenSim.Services.FSAssetService { @@ -78,8 +74,10 @@ namespace OpenSim.Services.FSAssetService protected bool m_useOsgridFormat = false; protected bool m_showStats = true; - private static bool m_Initialized; - private bool m_MainInstance; + private static bool m_mainInitialized; + private static object m_initLock = new object(); + + private bool m_isMainInstance; public FSAssetConnector(IConfigSource config) : this(config, "AssetService") @@ -88,29 +86,36 @@ namespace OpenSim.Services.FSAssetService public FSAssetConnector(IConfigSource config, string configName) : base(config) { - if (!m_Initialized) + lock(m_initLock) { - m_Initialized = true; - m_MainInstance = true; + if (!m_mainInitialized) + { + m_mainInitialized = true; + m_isMainInstance = true; - MainConsole.Instance.Commands.AddCommand("fs", false, - "show assets", "show assets", "Show asset stats", - HandleShowAssets); - MainConsole.Instance.Commands.AddCommand("fs", false, - "show digest", "show digest ", "Show asset digest", - HandleShowDigest); - MainConsole.Instance.Commands.AddCommand("fs", false, - "delete asset", "delete asset ", - "Delete asset from database", - HandleDeleteAsset); - MainConsole.Instance.Commands.AddCommand("fs", false, - "import", "import [ ]", - "Import legacy assets", - HandleImportAssets); - MainConsole.Instance.Commands.AddCommand("fs", false, - "force import", "force import
[ ]", - "Import legacy assets, overwriting current content", - HandleImportAssets); + MainConsole.Instance.Commands.AddCommand("fs", false, + "show assets", "show assets", "Show asset stats", + HandleShowAssets); + MainConsole.Instance.Commands.AddCommand("fs", false, + "show digest", "show digest ", "Show asset digest", + HandleShowDigest); + MainConsole.Instance.Commands.AddCommand("fs", false, + "delete asset", "delete asset ", + "Delete asset from database", + HandleDeleteAsset); + MainConsole.Instance.Commands.AddCommand("fs", false, + "import", "import
[ ]", + "Import legacy assets", + HandleImportAssets); + MainConsole.Instance.Commands.AddCommand("fs", false, + "force import", "force import
[ ]", + "Import legacy assets, overwriting current content", + HandleImportAssets); + } + else + { + m_isMainInstance = false; // yes redundant... + } } IConfig assetConfig = config.Configs[configName]; @@ -118,6 +123,11 @@ namespace OpenSim.Services.FSAssetService if (assetConfig == null) throw new Exception("No AssetService configuration"); + bool secondary = assetConfig.GetBoolean("SecondaryInstance", false); + lock (m_initLock) + m_isMainInstance = !secondary; + + // Get Database Connector from Asset Config (If present) string dllName = assetConfig.GetString("StorageProvider", string.Empty); string connectionString = assetConfig.GetString("ConnectionString", string.Empty); @@ -156,7 +166,7 @@ namespace OpenSim.Services.FSAssetService // Setup Fallback Service string str = assetConfig.GetString("FallbackService", string.Empty); - if (str != string.Empty) + if (str.Length > 0) { object[] args = new object[] { config }; m_FallbackService = LoadPlugin(str, args); @@ -189,7 +199,7 @@ namespace OpenSim.Services.FSAssetService // Default is to show stats to retain original behaviour m_showStats = assetConfig.GetBoolean("ShowConsoleStats", m_showStats); - if (m_MainInstance) + if (m_isMainInstance) { string loader = assetConfig.GetString("DefaultAssetLoader", string.Empty); if (loader != string.Empty) @@ -204,10 +214,13 @@ namespace OpenSim.Services.FSAssetService }); } - m_WriterThread = new Thread(Writer); - m_WriterThread.Start(); + if(m_WriterThread != null) + { + m_WriterThread = new Thread(Writer); + m_WriterThread.Start(); + } - if (m_showStats) + if (m_showStats && m_StatsThread != null) { m_StatsThread = new Thread(Stats); m_StatsThread.Start(); diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 0e924c8a08..3db37c0091 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -251,11 +251,15 @@ LocalServiceModule = "OpenSim.Services.AssetService.dll:AssetService" ;LocalServiceModule = "OpenSim.Services.FSAssetService.dll:FSAssetConnector" - ;; FSAsset Directories. Base directory, where final asset files are stored and Spool directory for temp files + ;; FSAssets Directories. Base directory, where final asset files are stored and Spool directory for temp files ;; These directories must be on the same physical filesystem ;BaseDirectory = "./fsassets/data" ;SpoolDirectory = "./fsassets/tmp" + ;; FSAssets only: if running several instances, only one can run some services, so others need to be set as secondary + ;; for secondary instances uncoment this line + ;SecondaryInstance = true + ;; Original service can be checked if FSAssets can not find an asset ;FallbackService = "OpenSim.Services.AssetService.dll:AssetService"; diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example index ee50dbf5e4..04c67a2de6 100644 --- a/bin/Robust.ini.example +++ b/bin/Robust.ini.example @@ -211,6 +211,10 @@ ;BaseDirectory = "./fsassets/data" ;SpoolDirectory = "./fsassets/tmp" + ;; FSAssets only: if running several instances, only one can run some services, so others need to be set as secondary + ;; for secondary instances uncoment this line + ;SecondaryInstance = true + ;; Original service can be checked if FSAssets can not find an asset ;FallbackService = "OpenSim.Services.AssetService.dll:AssetService";