diff options
Diffstat (limited to 'OpenSim/Services/FSAssetService/FSAssetService.cs')
-rw-r--r-- | OpenSim/Services/FSAssetService/FSAssetService.cs | 118 |
1 files changed, 94 insertions, 24 deletions
diff --git a/OpenSim/Services/FSAssetService/FSAssetService.cs b/OpenSim/Services/FSAssetService/FSAssetService.cs index 1bab687..bf7ddff 100644 --- a/OpenSim/Services/FSAssetService/FSAssetService.cs +++ b/OpenSim/Services/FSAssetService/FSAssetService.cs | |||
@@ -119,8 +119,8 @@ namespace OpenSim.Services.FSAssetService | |||
119 | 119 | ||
120 | // Get Database Connector from Asset Config (If present) | 120 | // Get Database Connector from Asset Config (If present) |
121 | string dllName = assetConfig.GetString("StorageProvider", string.Empty); | 121 | string dllName = assetConfig.GetString("StorageProvider", string.Empty); |
122 | string m_ConnectionString = assetConfig.GetString("ConnectionString", string.Empty); | 122 | string connectionString = assetConfig.GetString("ConnectionString", string.Empty); |
123 | string m_Realm = assetConfig.GetString("Realm", "fsassets"); | 123 | string realm = assetConfig.GetString("Realm", "fsassets"); |
124 | 124 | ||
125 | int SkipAccessTimeDays = assetConfig.GetInt("DaysBetweenAccessTimeUpdates", 0); | 125 | int SkipAccessTimeDays = assetConfig.GetInt("DaysBetweenAccessTimeUpdates", 0); |
126 | 126 | ||
@@ -132,15 +132,15 @@ namespace OpenSim.Services.FSAssetService | |||
132 | if (dllName == String.Empty) | 132 | if (dllName == String.Empty) |
133 | dllName = dbConfig.GetString("StorageProvider", String.Empty); | 133 | dllName = dbConfig.GetString("StorageProvider", String.Empty); |
134 | 134 | ||
135 | if (m_ConnectionString == String.Empty) | 135 | if (connectionString == String.Empty) |
136 | m_ConnectionString = dbConfig.GetString("ConnectionString", String.Empty); | 136 | connectionString = dbConfig.GetString("ConnectionString", String.Empty); |
137 | } | 137 | } |
138 | 138 | ||
139 | // No databse connection found in either config | 139 | // No databse connection found in either config |
140 | if (dllName.Equals(String.Empty)) | 140 | if (dllName.Equals(String.Empty)) |
141 | throw new Exception("No StorageProvider configured"); | 141 | throw new Exception("No StorageProvider configured"); |
142 | 142 | ||
143 | if (m_ConnectionString.Equals(String.Empty)) | 143 | if (connectionString.Equals(String.Empty)) |
144 | throw new Exception("Missing database connection string"); | 144 | throw new Exception("Missing database connection string"); |
145 | 145 | ||
146 | // Create Storage Provider | 146 | // Create Storage Provider |
@@ -150,7 +150,7 @@ namespace OpenSim.Services.FSAssetService | |||
150 | throw new Exception(string.Format("Could not find a storage interface in the module {0}", dllName)); | 150 | throw new Exception(string.Format("Could not find a storage interface in the module {0}", dllName)); |
151 | 151 | ||
152 | // Initialize DB And perform any migrations required | 152 | // Initialize DB And perform any migrations required |
153 | m_DataConnector.Initialise(m_ConnectionString, m_Realm, SkipAccessTimeDays); | 153 | m_DataConnector.Initialise(connectionString, realm, SkipAccessTimeDays); |
154 | 154 | ||
155 | // Setup Fallback Service | 155 | // Setup Fallback Service |
156 | string str = assetConfig.GetString("FallbackService", string.Empty); | 156 | string str = assetConfig.GetString("FallbackService", string.Empty); |
@@ -232,7 +232,7 @@ namespace OpenSim.Services.FSAssetService | |||
232 | 232 | ||
233 | private void Writer() | 233 | private void Writer() |
234 | { | 234 | { |
235 | m_log.Info("[FSASSETS]: Writer started"); | 235 | m_log.Info("[ASSET]: Writer started"); |
236 | 236 | ||
237 | while (true) | 237 | while (true) |
238 | { | 238 | { |
@@ -246,33 +246,98 @@ namespace OpenSim.Services.FSAssetService | |||
246 | string hash = Path.GetFileNameWithoutExtension(files[i]); | 246 | string hash = Path.GetFileNameWithoutExtension(files[i]); |
247 | string s = HashToFile(hash); | 247 | string s = HashToFile(hash); |
248 | string diskFile = Path.Combine(m_FSBase, s); | 248 | string diskFile = Path.Combine(m_FSBase, s); |
249 | bool pathOk = false; | ||
249 | 250 | ||
250 | Directory.CreateDirectory(Path.GetDirectoryName(diskFile)); | 251 | // The cure for chicken bones! |
251 | try | 252 | while(true) |
252 | { | 253 | { |
253 | byte[] data = File.ReadAllBytes(files[i]); | 254 | try |
254 | |||
255 | using (GZipStream gz = new GZipStream(new FileStream(diskFile + ".gz", FileMode.Create), CompressionMode.Compress)) | ||
256 | { | 255 | { |
257 | gz.Write(data, 0, data.Length); | 256 | // Try to make the directory we need for this file |
258 | gz.Close(); | 257 | Directory.CreateDirectory(Path.GetDirectoryName(diskFile)); |
258 | pathOk = true; | ||
259 | break; | ||
259 | } | 260 | } |
260 | File.Delete(files[i]); | 261 | catch (System.IO.IOException) |
261 | 262 | { | |
262 | //File.Move(files[i], diskFile); | 263 | // Creating the directory failed. This can't happen unless |
264 | // a part of the path already exists as a file. Sadly the | ||
265 | // SRAS data contains such files. | ||
266 | string d = Path.GetDirectoryName(diskFile); | ||
267 | |||
268 | // Test each path component in turn. If we can successfully | ||
269 | // make a directory, the level below must be the chicken bone. | ||
270 | while (d.Length > 0) | ||
271 | { | ||
272 | Console.WriteLine(d); | ||
273 | try | ||
274 | { | ||
275 | Directory.CreateDirectory(Path.GetDirectoryName(d)); | ||
276 | } | ||
277 | catch (System.IO.IOException) | ||
278 | { | ||
279 | d = Path.GetDirectoryName(d); | ||
280 | |||
281 | // We failed making the directory and need to | ||
282 | // go up a bit more | ||
283 | continue; | ||
284 | } | ||
285 | |||
286 | // We succeeded in making the directory and (d) is | ||
287 | // the chicken bone | ||
288 | break; | ||
289 | } | ||
290 | |||
291 | // Is the chicken alive? | ||
292 | if (d.Length > 0) | ||
293 | { | ||
294 | Console.WriteLine(d); | ||
295 | |||
296 | FileAttributes attr = File.GetAttributes(d); | ||
297 | |||
298 | if ((attr & FileAttributes.Directory) == 0) | ||
299 | { | ||
300 | // The chicken bone should be resolved. | ||
301 | // Return to writing the file. | ||
302 | File.Delete(d); | ||
303 | continue; | ||
304 | } | ||
305 | } | ||
306 | } | ||
307 | // Could not resolve, skipping | ||
308 | m_log.ErrorFormat("[ASSET]: Could not resolve path creation error for {0}", diskFile); | ||
309 | break; | ||
263 | } | 310 | } |
264 | catch(System.IO.IOException e) | 311 | |
312 | if (pathOk) | ||
265 | { | 313 | { |
266 | if (e.Message.StartsWith("Win32 IO returned ERROR_ALREADY_EXISTS")) | 314 | try |
315 | { | ||
316 | byte[] data = File.ReadAllBytes(files[i]); | ||
317 | |||
318 | using (GZipStream gz = new GZipStream(new FileStream(diskFile + ".gz", FileMode.Create), CompressionMode.Compress)) | ||
319 | { | ||
320 | gz.Write(data, 0, data.Length); | ||
321 | gz.Close(); | ||
322 | } | ||
267 | File.Delete(files[i]); | 323 | File.Delete(files[i]); |
268 | else | 324 | |
269 | throw; | 325 | //File.Move(files[i], diskFile); |
326 | } | ||
327 | catch(System.IO.IOException e) | ||
328 | { | ||
329 | if (e.Message.StartsWith("Win32 IO returned ERROR_ALREADY_EXISTS")) | ||
330 | File.Delete(files[i]); | ||
331 | else | ||
332 | throw; | ||
333 | } | ||
270 | } | 334 | } |
271 | } | 335 | } |
336 | |||
272 | int totalTicks = System.Environment.TickCount - tickCount; | 337 | int totalTicks = System.Environment.TickCount - tickCount; |
273 | if (totalTicks > 0) // Wrap? | 338 | if (totalTicks > 0) // Wrap? |
274 | { | 339 | { |
275 | m_log.InfoFormat("[FSASSETS]: Write cycle complete, {0} files, {1} ticks, avg {2:F2}", files.Length, totalTicks, (double)totalTicks / (double)files.Length); | 340 | m_log.InfoFormat("[ASSET]: Write cycle complete, {0} files, {1} ticks, avg {2:F2}", files.Length, totalTicks, (double)totalTicks / (double)files.Length); |
276 | } | 341 | } |
277 | } | 342 | } |
278 | 343 | ||
@@ -292,20 +357,25 @@ namespace OpenSim.Services.FSAssetService | |||
292 | if (hash == null || hash.Length < 10) | 357 | if (hash == null || hash.Length < 10) |
293 | return "junkyard"; | 358 | return "junkyard"; |
294 | 359 | ||
360 | /* | ||
361 | * The code below is the OSGrid code. | ||
362 | * This should probably become a config option. | ||
363 | */ | ||
364 | /* | ||
295 | return Path.Combine(hash.Substring(0, 3), | 365 | return Path.Combine(hash.Substring(0, 3), |
296 | Path.Combine(hash.Substring(3, 3))); | 366 | Path.Combine(hash.Substring(3, 3))); |
367 | */ | ||
368 | |||
297 | /* | 369 | /* |
298 | * The below is what core would normally use. | 370 | * The below is what core would normally use. |
299 | * This is modified to work in OSGrid, as seen | 371 | * This is modified to work in OSGrid, as seen |
300 | * above, because the SRAS data is structured | 372 | * above, because the SRAS data is structured |
301 | * that way. | 373 | * that way. |
302 | */ | 374 | */ |
303 | /* | ||
304 | return Path.Combine(hash.Substring(0, 2), | 375 | return Path.Combine(hash.Substring(0, 2), |
305 | Path.Combine(hash.Substring(2, 2), | 376 | Path.Combine(hash.Substring(2, 2), |
306 | Path.Combine(hash.Substring(4, 2), | 377 | Path.Combine(hash.Substring(4, 2), |
307 | hash.Substring(6, 4)))); | 378 | hash.Substring(6, 4)))); |
308 | */ | ||
309 | } | 379 | } |
310 | 380 | ||
311 | private bool AssetExists(string hash) | 381 | private bool AssetExists(string hash) |