/// <summary> /// Searches through the files in the archive for the control file, and reads it. /// We must read the control file first, in order to know which regions are available. /// </summary> /// <remarks> /// In most cases the control file *is* first, since that's how we create archives. However, /// it's possible that someone rewrote the archive externally so we can't rely on this fact. /// </remarks> /// <param name="archive"></param> /// <param name="dearchivedScenes"></param> private void FindAndLoadControlFile(out TarArchiveReader archive, out DearchiveScenesInfo dearchivedScenes) { archive = new TarArchiveReader(m_loadStream); dearchivedScenes = new DearchiveScenesInfo(); string filePath; byte[] data; TarArchiveReader.TarEntryType entryType; bool firstFile = true; while ((data = archive.ReadEntry(out filePath, out entryType)) != null) { if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType) continue; if (filePath == ArchiveConstants.CONTROL_FILE_PATH) { LoadControlFile(filePath, data, dearchivedScenes); // Find which scenes are available in the simulator ArchiveScenesGroup simulatorScenes = new ArchiveScenesGroup(); SceneManager.Instance.ForEachScene(delegate(Scene scene2) { simulatorScenes.AddScene(scene2); }); simulatorScenes.CalcSceneLocations(); dearchivedScenes.SetSimulatorScenes(m_rootScene, simulatorScenes); // If the control file wasn't the first file then reset the read pointer if (!firstFile) { m_log.Warn("Control file wasn't the first file in the archive"); if (m_loadStream.CanSeek) { m_loadStream.Seek(0, SeekOrigin.Begin); } else if (m_loadPath != null) { archive.Close(); archive = null; m_loadStream.Close(); m_loadStream = null; m_loadStream = new GZipStream(ArchiveHelpers.GetStream(m_loadPath), CompressionMode.Decompress); archive = new TarArchiveReader(m_loadStream); } else { // There isn't currently a scenario where this happens, but it's best to add a check just in case throw new Exception("Error reading archive: control file wasn't the first file, and the input stream doesn't allow seeking"); } } return; } firstFile = false; } throw new Exception("Control file not found"); }
/// <summary> /// Archive the region requested. /// </summary> /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception> public void ArchiveRegion(Dictionary <string, object> options) { m_options = options; if (options.ContainsKey("all") && (bool)options["all"]) { MultiRegionFormat = true; } if (options.ContainsKey("noassets") && (bool)options["noassets"]) { SaveAssets = false; } if (options.TryGetValue("checkPermissions", out Object temp)) { FilterContent = (string)temp; } // Find the regions to archive ArchiveScenesGroup scenesGroup = new ArchiveScenesGroup(); if (MultiRegionFormat) { m_log.InfoFormat("[ARCHIVER]: Saving {0} regions", SceneManager.Instance.Scenes.Count); SceneManager.Instance.ForEachScene(delegate(Scene scene) { scenesGroup.AddScene(scene); }); } else { scenesGroup.AddScene(m_rootScene); } scenesGroup.CalcSceneLocations(); m_archiveWriter = new TarArchiveWriter(m_saveStream); try { // Write out control file. It should be first so that it will be found ASAP when loading the file. m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(scenesGroup)); m_log.InfoFormat("[ARCHIVER]: Added control file to archive."); // Archive the regions Dictionary <UUID, sbyte> assetUuids = new Dictionary <UUID, sbyte>(); HashSet <UUID> failedIDs = new HashSet <UUID>(); HashSet <UUID> uncertainAssetsUUIDs = new HashSet <UUID>(); scenesGroup.ForEachScene(delegate(Scene scene) { string regionDir = MultiRegionFormat ? scenesGroup.GetRegionDir(scene.RegionInfo.RegionID) : ""; ArchiveOneRegion(scene, regionDir, assetUuids, failedIDs, uncertainAssetsUUIDs); }); // Archive the assets if (SaveAssets) { m_log.DebugFormat("[ARCHIVER]: Saving {0} assets", assetUuids.Count); AssetsRequest ar = new AssetsRequest( new AssetsArchiver(m_archiveWriter), assetUuids, failedIDs.Count, m_rootScene.AssetService, m_rootScene.UserAccountService, m_rootScene.RegionInfo.ScopeID, options, null); ar.Execute(); assetUuids = null; } else { m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified"); // CloseArchive(string.Empty); } CloseArchive(string.Empty); } catch (Exception e) { CloseArchive(e.Message); throw; } GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.Default; }
/// <summary> /// Archive the region requested. /// </summary> /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception> public void ArchiveRegion(Dictionary<string, object> options) { m_options = options; if (options.ContainsKey("all") && (bool)options["all"]) MultiRegionFormat = true; if (options.ContainsKey("noassets") && (bool)options["noassets"]) SaveAssets = false; Object temp; if (options.TryGetValue("checkPermissions", out temp)) FilterContent = (string)temp; // Find the regions to archive ArchiveScenesGroup scenesGroup = new ArchiveScenesGroup(); if (MultiRegionFormat) { m_log.InfoFormat("[ARCHIVER]: Saving {0} regions", SceneManager.Instance.Scenes.Count); SceneManager.Instance.ForEachScene(delegate(Scene scene) { scenesGroup.AddScene(scene); }); } else { scenesGroup.AddScene(m_rootScene); } scenesGroup.CalcSceneLocations(); m_archiveWriter = new TarArchiveWriter(m_saveStream); try { // Write out control file. It should be first so that it will be found ASAP when loading the file. m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(scenesGroup)); m_log.InfoFormat("[ARCHIVER]: Added control file to archive."); // Archive the regions Dictionary<UUID, sbyte> assetUuids = new Dictionary<UUID, sbyte>(); scenesGroup.ForEachScene(delegate(Scene scene) { string regionDir = MultiRegionFormat ? scenesGroup.GetRegionDir(scene.RegionInfo.RegionID) : ""; ArchiveOneRegion(scene, regionDir, assetUuids); }); // Archive the assets if (SaveAssets) { m_log.DebugFormat("[ARCHIVER]: Saving {0} assets", assetUuids.Count); // Asynchronously request all the assets required to perform this archive operation AssetsRequest ar = new AssetsRequest( new AssetsArchiver(m_archiveWriter), assetUuids, m_rootScene.AssetService, m_rootScene.UserAccountService, m_rootScene.RegionInfo.ScopeID, options, ReceivedAllAssets); WorkManager.RunInThread(o => ar.Execute(), null, "Archive Assets Request"); // CloseArchive() will be called from ReceivedAllAssets() } else { m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified"); CloseArchive(string.Empty); } } catch (Exception e) { CloseArchive(e.Message); throw; } }
/// <summary> /// Archive the region requested. /// </summary> /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception> public void ArchiveRegion(Dictionary <string, object> options) { m_options = options; if (options.ContainsKey("all") && (bool)options["all"]) { MultiRegionFormat = true; } if (options.ContainsKey("noassets") && (bool)options["noassets"]) { SaveAssets = false; } Object temp; if (options.TryGetValue("checkPermissions", out temp)) { CheckPermissions = (string)temp; } // Find the regions to archive ArchiveScenesGroup scenesGroup = new ArchiveScenesGroup(); if (MultiRegionFormat) { m_log.InfoFormat("[ARCHIVER]: Saving {0} regions", SceneManager.Instance.Scenes.Count); SceneManager.Instance.ForEachScene(delegate(Scene scene) { scenesGroup.AddScene(scene); }); } else { scenesGroup.AddScene(m_rootScene); } scenesGroup.CalcSceneLocations(); m_archiveWriter = new TarArchiveWriter(m_saveStream); try { // Write out control file. It should be first so that it will be found ASAP when loading the file. m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(scenesGroup)); m_log.InfoFormat("[ARCHIVER]: Added control file to archive."); // Archive the regions Dictionary <UUID, AssetType> assetUuids = new Dictionary <UUID, AssetType>(); scenesGroup.ForEachScene(delegate(Scene scene) { string regionDir = MultiRegionFormat ? scenesGroup.GetRegionDir(scene.RegionInfo.RegionID) : ""; ArchiveOneRegion(scene, regionDir, assetUuids); }); // Archive the assets if (SaveAssets) { m_log.DebugFormat("[ARCHIVER]: Saving {0} assets", assetUuids.Count); // Asynchronously request all the assets required to perform this archive operation AssetsRequest ar = new AssetsRequest( new AssetsArchiver(m_archiveWriter), assetUuids, m_rootScene.AssetService, m_rootScene.UserAccountService, m_rootScene.RegionInfo.ScopeID, options, ReceivedAllAssets); Util.FireAndForget(o => ar.Execute()); // CloseArchive() will be called from ReceivedAllAssets() } else { m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified"); CloseArchive(string.Empty); } } catch (Exception e) { CloseArchive(e.Message); throw; } }