aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services/FSAssetService/FSAssetService.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Services/FSAssetService/FSAssetService.cs199
1 files changed, 146 insertions, 53 deletions
diff --git a/OpenSim/Services/FSAssetService/FSAssetService.cs b/OpenSim/Services/FSAssetService/FSAssetService.cs
index aba8b33..ca2f459 100644
--- a/OpenSim/Services/FSAssetService/FSAssetService.cs
+++ b/OpenSim/Services/FSAssetService/FSAssetService.cs
@@ -76,6 +76,8 @@ namespace OpenSim.Services.FSAssetService
76 protected int m_missingAssets = 0; 76 protected int m_missingAssets = 0;
77 protected int m_missingAssetsFS = 0; 77 protected int m_missingAssetsFS = 0;
78 protected string m_FSBase; 78 protected string m_FSBase;
79 protected bool m_useOsgridFormat = false;
80 protected bool m_showStats = true;
79 81
80 private static bool m_Initialized; 82 private static bool m_Initialized;
81 private bool m_MainInstance; 83 private bool m_MainInstance;
@@ -113,34 +115,34 @@ namespace OpenSim.Services.FSAssetService
113 } 115 }
114 116
115 IConfig assetConfig = config.Configs[configName]; 117 IConfig assetConfig = config.Configs[configName];
116 118
117 if (assetConfig == null) 119 if (assetConfig == null)
118 throw new Exception("No AssetService configuration"); 120 throw new Exception("No AssetService configuration");
119 121
120 // Get Database Connector from Asset Config (If present) 122 // Get Database Connector from Asset Config (If present)
121 string dllName = assetConfig.GetString("StorageProvider", string.Empty); 123 string dllName = assetConfig.GetString("StorageProvider", string.Empty);
122 string m_ConnectionString = assetConfig.GetString("ConnectionString", string.Empty); 124 string connectionString = assetConfig.GetString("ConnectionString", string.Empty);
123 string m_Realm = assetConfig.GetString("Realm", "fsassets"); 125 string realm = assetConfig.GetString("Realm", "fsassets");
124 126
125 int SkipAccessTimeDays = assetConfig.GetInt("DaysBetweenAccessTimeUpdates", 0); 127 int SkipAccessTimeDays = assetConfig.GetInt("DaysBetweenAccessTimeUpdates", 0);
126 128
127 // If not found above, fallback to Database defaults 129 // If not found above, fallback to Database defaults
128 IConfig dbConfig = config.Configs["DatabaseService"]; 130 IConfig dbConfig = config.Configs["DatabaseService"];
129 131
130 if (dbConfig != null) 132 if (dbConfig != null)
131 { 133 {
132 if (dllName == String.Empty) 134 if (dllName == String.Empty)
133 dllName = dbConfig.GetString("StorageProvider", String.Empty); 135 dllName = dbConfig.GetString("StorageProvider", String.Empty);
134 136
135 if (m_ConnectionString == String.Empty) 137 if (connectionString == String.Empty)
136 m_ConnectionString = dbConfig.GetString("ConnectionString", String.Empty); 138 connectionString = dbConfig.GetString("ConnectionString", String.Empty);
137 } 139 }
138 140
139 // No databse connection found in either config 141 // No databse connection found in either config
140 if (dllName.Equals(String.Empty)) 142 if (dllName.Equals(String.Empty))
141 throw new Exception("No StorageProvider configured"); 143 throw new Exception("No StorageProvider configured");
142 144
143 if (m_ConnectionString.Equals(String.Empty)) 145 if (connectionString.Equals(String.Empty))
144 throw new Exception("Missing database connection string"); 146 throw new Exception("Missing database connection string");
145 147
146 // Create Storage Provider 148 // Create Storage Provider
@@ -150,11 +152,11 @@ namespace OpenSim.Services.FSAssetService
150 throw new Exception(string.Format("Could not find a storage interface in the module {0}", dllName)); 152 throw new Exception(string.Format("Could not find a storage interface in the module {0}", dllName));
151 153
152 // Initialize DB And perform any migrations required 154 // Initialize DB And perform any migrations required
153 m_DataConnector.Initialise(m_ConnectionString, m_Realm, SkipAccessTimeDays); 155 m_DataConnector.Initialise(connectionString, realm, SkipAccessTimeDays);
154 156
155 // Setup Fallback Service 157 // Setup Fallback Service
156 string str = assetConfig.GetString("FallbackService", string.Empty); 158 string str = assetConfig.GetString("FallbackService", string.Empty);
157 159
158 if (str != string.Empty) 160 if (str != string.Empty)
159 { 161 {
160 object[] args = new object[] { config }; 162 object[] args = new object[] { config };
@@ -183,6 +185,11 @@ namespace OpenSim.Services.FSAssetService
183 throw new Exception("Configuration error"); 185 throw new Exception("Configuration error");
184 } 186 }
185 187
188 m_useOsgridFormat = assetConfig.GetBoolean("UseOsgridFormat", m_useOsgridFormat);
189
190 // Default is to show stats to retain original behaviour
191 m_showStats = assetConfig.GetBoolean("ShowConsoleStats", m_showStats);
192
186 if (m_MainInstance) 193 if (m_MainInstance)
187 { 194 {
188 string loader = assetConfig.GetString("DefaultAssetLoader", string.Empty); 195 string loader = assetConfig.GetString("DefaultAssetLoader", string.Empty);
@@ -197,13 +204,17 @@ namespace OpenSim.Services.FSAssetService
197 Store(a, false); 204 Store(a, false);
198 }); 205 });
199 } 206 }
200 207
201 m_WriterThread = new Thread(Writer); 208 m_WriterThread = new Thread(Writer);
202 m_WriterThread.Start(); 209 m_WriterThread.Start();
203 m_StatsThread = new Thread(Stats); 210
204 m_StatsThread.Start(); 211 if (m_showStats)
212 {
213 m_StatsThread = new Thread(Stats);
214 m_StatsThread.Start();
215 }
205 } 216 }
206 217
207 m_log.Info("[FSASSETS]: FS asset service enabled"); 218 m_log.Info("[FSASSETS]: FS asset service enabled");
208 } 219 }
209 220
@@ -212,7 +223,7 @@ namespace OpenSim.Services.FSAssetService
212 while (true) 223 while (true)
213 { 224 {
214 Thread.Sleep(60000); 225 Thread.Sleep(60000);
215 226
216 lock (m_statsLock) 227 lock (m_statsLock)
217 { 228 {
218 if (m_readCount > 0) 229 if (m_readCount > 0)
@@ -220,6 +231,7 @@ namespace OpenSim.Services.FSAssetService
220 double avg = (double)m_readTicks / (double)m_readCount; 231 double avg = (double)m_readTicks / (double)m_readCount;
221// if (avg > 10000) 232// if (avg > 10000)
222// Environment.Exit(0); 233// Environment.Exit(0);
234 m_log.InfoFormat("[FSASSETS]: Read stats: {0} files, {1} ticks, avg {2:F2}, missing {3}, FS {4}", m_readCount, m_readTicks, (double)m_readTicks / (double)m_readCount, m_missingAssets, m_missingAssetsFS);
223 } 235 }
224 m_readCount = 0; 236 m_readCount = 0;
225 m_readTicks = 0; 237 m_readTicks = 0;
@@ -231,7 +243,7 @@ namespace OpenSim.Services.FSAssetService
231 243
232 private void Writer() 244 private void Writer()
233 { 245 {
234 m_log.Info("[FSASSETS]: Writer started"); 246 m_log.Info("[ASSET]: Writer started");
235 247
236 while (true) 248 while (true)
237 { 249 {
@@ -245,33 +257,98 @@ namespace OpenSim.Services.FSAssetService
245 string hash = Path.GetFileNameWithoutExtension(files[i]); 257 string hash = Path.GetFileNameWithoutExtension(files[i]);
246 string s = HashToFile(hash); 258 string s = HashToFile(hash);
247 string diskFile = Path.Combine(m_FSBase, s); 259 string diskFile = Path.Combine(m_FSBase, s);
260 bool pathOk = false;
248 261
249 Directory.CreateDirectory(Path.GetDirectoryName(diskFile)); 262 // The cure for chicken bones!
250 try 263 while(true)
251 { 264 {
252 byte[] data = File.ReadAllBytes(files[i]); 265 try
253
254 using (GZipStream gz = new GZipStream(new FileStream(diskFile + ".gz", FileMode.Create), CompressionMode.Compress))
255 { 266 {
256 gz.Write(data, 0, data.Length); 267 // Try to make the directory we need for this file
257 gz.Close(); 268 Directory.CreateDirectory(Path.GetDirectoryName(diskFile));
269 pathOk = true;
270 break;
258 } 271 }
259 File.Delete(files[i]); 272 catch (System.IO.IOException)
260 273 {
261 //File.Move(files[i], diskFile); 274 // Creating the directory failed. This can't happen unless
275 // a part of the path already exists as a file. Sadly the
276 // SRAS data contains such files.
277 string d = Path.GetDirectoryName(diskFile);
278
279 // Test each path component in turn. If we can successfully
280 // make a directory, the level below must be the chicken bone.
281 while (d.Length > 0)
282 {
283 Console.WriteLine(d);
284 try
285 {
286 Directory.CreateDirectory(Path.GetDirectoryName(d));
287 }
288 catch (System.IO.IOException)
289 {
290 d = Path.GetDirectoryName(d);
291
292 // We failed making the directory and need to
293 // go up a bit more
294 continue;
295 }
296
297 // We succeeded in making the directory and (d) is
298 // the chicken bone
299 break;
300 }
301
302 // Is the chicken alive?
303 if (d.Length > 0)
304 {
305 Console.WriteLine(d);
306
307 FileAttributes attr = File.GetAttributes(d);
308
309 if ((attr & FileAttributes.Directory) == 0)
310 {
311 // The chicken bone should be resolved.
312 // Return to writing the file.
313 File.Delete(d);
314 continue;
315 }
316 }
317 }
318 // Could not resolve, skipping
319 m_log.ErrorFormat("[ASSET]: Could not resolve path creation error for {0}", diskFile);
320 break;
262 } 321 }
263 catch(System.IO.IOException e) 322
323 if (pathOk)
264 { 324 {
265 if (e.Message.StartsWith("Win32 IO returned ERROR_ALREADY_EXISTS")) 325 try
326 {
327 byte[] data = File.ReadAllBytes(files[i]);
328
329 using (GZipStream gz = new GZipStream(new FileStream(diskFile + ".gz", FileMode.Create), CompressionMode.Compress))
330 {
331 gz.Write(data, 0, data.Length);
332 gz.Close();
333 }
266 File.Delete(files[i]); 334 File.Delete(files[i]);
267 else 335
268 throw; 336 //File.Move(files[i], diskFile);
337 }
338 catch(System.IO.IOException e)
339 {
340 if (e.Message.StartsWith("Win32 IO returned ERROR_ALREADY_EXISTS"))
341 File.Delete(files[i]);
342 else
343 throw;
344 }
269 } 345 }
270 } 346 }
347
271 int totalTicks = System.Environment.TickCount - tickCount; 348 int totalTicks = System.Environment.TickCount - tickCount;
272 if (totalTicks > 0) // Wrap? 349 if (totalTicks > 0) // Wrap?
273 { 350 {
274 m_log.InfoFormat("[FSASSETS]: Write cycle complete, {0} files, {1} ticks, avg {2:F2}", files.Length, totalTicks, (double)totalTicks / (double)files.Length); 351 m_log.InfoFormat("[ASSET]: Write cycle complete, {0} files, {1} ticks, avg {2:F2}", files.Length, totalTicks, (double)totalTicks / (double)files.Length);
275 } 352 }
276 } 353 }
277 354
@@ -291,20 +368,27 @@ namespace OpenSim.Services.FSAssetService
291 if (hash == null || hash.Length < 10) 368 if (hash == null || hash.Length < 10)
292 return "junkyard"; 369 return "junkyard";
293 370
294 return Path.Combine(hash.Substring(0, 3), 371 if (m_useOsgridFormat)
295 Path.Combine(hash.Substring(3, 3))); 372 {
296 /* 373 /*
297 * The below is what core would normally use. 374 * The code below is the OSGrid code.
298 * This is modified to work in OSGrid, as seen 375 */
299 * above, because the SRAS data is structured 376 return Path.Combine(hash.Substring(0, 3),
300 * that way. 377 Path.Combine(hash.Substring(3, 3)));
301 */ 378 }
302 /* 379 else
303 return Path.Combine(hash.Substring(0, 2), 380 {
304 Path.Combine(hash.Substring(2, 2), 381 /*
305 Path.Combine(hash.Substring(4, 2), 382 * The below is what core would normally use.
306 hash.Substring(6, 4)))); 383 * This is modified to work in OSGrid, as seen
307 */ 384 * above, because the SRAS data is structured
385 * that way.
386 */
387 return Path.Combine(hash.Substring(0, 2),
388 Path.Combine(hash.Substring(2, 2),
389 Path.Combine(hash.Substring(4, 2),
390 hash.Substring(6, 4))));
391 }
308 } 392 }
309 393
310 private bool AssetExists(string hash) 394 private bool AssetExists(string hash)
@@ -365,7 +449,7 @@ namespace OpenSim.Services.FSAssetService
365 Store(asset); 449 Store(asset);
366 } 450 }
367 } 451 }
368 if (asset == null) 452 if (asset == null && m_showStats)
369 { 453 {
370 // m_log.InfoFormat("[FSASSETS]: Asset {0} not found", id); 454 // m_log.InfoFormat("[FSASSETS]: Asset {0} not found", id);
371 m_missingAssets++; 455 m_missingAssets++;
@@ -393,8 +477,11 @@ namespace OpenSim.Services.FSAssetService
393 } 477 }
394 } 478 }
395 if (asset == null) 479 if (asset == null)
396 m_missingAssetsFS++; 480 {
397 // m_log.InfoFormat("[FSASSETS]: Asset {0}, hash {1} not found in FS", id, hash); 481 if (m_showStats)
482 m_missingAssetsFS++;
483 // m_log.InfoFormat("[FSASSETS]: Asset {0}, hash {1} not found in FS", id, hash);
484 }
398 else 485 else
399 { 486 {
400 // Deal with bug introduced in Oct. 20 (1eb3e6cc43e2a7b4053bc1185c7c88e22356c5e8) 487 // Deal with bug introduced in Oct. 20 (1eb3e6cc43e2a7b4053bc1185c7c88e22356c5e8)
@@ -408,10 +495,13 @@ namespace OpenSim.Services.FSAssetService
408 } 495 }
409 } 496 }
410 497
411 lock (m_statsLock) 498 if (m_showStats)
412 { 499 {
413 m_readTicks += Environment.TickCount - startTime; 500 lock (m_statsLock)
414 m_readCount++; 501 {
502 m_readTicks += Environment.TickCount - startTime;
503 m_readCount++;
504 }
415 } 505 }
416 506
417 // Deal with bug introduced in Oct. 20 (1eb3e6cc43e2a7b4053bc1185c7c88e22356c5e8) 507 // Deal with bug introduced in Oct. 20 (1eb3e6cc43e2a7b4053bc1185c7c88e22356c5e8)
@@ -578,6 +668,9 @@ namespace OpenSim.Services.FSAssetService
578 668
579 if (!m_DataConnector.Store(asset.Metadata, hash)) 669 if (!m_DataConnector.Store(asset.Metadata, hash))
580 { 670 {
671 if (asset.Metadata.Type == -2)
672 return asset.ID;
673
581 return UUID.Zero.ToString(); 674 return UUID.Zero.ToString();
582 } 675 }
583 else 676 else
@@ -630,7 +723,7 @@ namespace OpenSim.Services.FSAssetService
630 AssetBase asset = Get(args[2], out hash); 723 AssetBase asset = Get(args[2], out hash);
631 724
632 if (asset == null || asset.Data.Length == 0) 725 if (asset == null || asset.Data.Length == 0)
633 { 726 {
634 MainConsole.Instance.Output("Asset not found"); 727 MainConsole.Instance.Output("Asset not found");
635 return; 728 return;
636 } 729 }
@@ -672,7 +765,7 @@ namespace OpenSim.Services.FSAssetService
672 AssetBase asset = Get(args[2]); 765 AssetBase asset = Get(args[2]);
673 766
674 if (asset == null || asset.Data.Length == 0) 767 if (asset == null || asset.Data.Length == 0)
675 { 768 {
676 MainConsole.Instance.Output("Asset not found"); 769 MainConsole.Instance.Output("Asset not found");
677 return; 770 return;
678 } 771 }