diff options
author | Justin Clark-Casey (justincc) | 2012-08-20 20:24:54 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2012-08-24 21:52:21 +0100 |
commit | 3b972417167e2c5d3aa7b2d390a5be68e5509dc5 (patch) | |
tree | f9422c2103cf67345324dd7d22fe2f8570231340 | |
parent | Fix llDialog responses so that they can be heard throughout the region. This ... (diff) | |
download | opensim-SC_OLD-3b972417167e2c5d3aa7b2d390a5be68e5509dc5.zip opensim-SC_OLD-3b972417167e2c5d3aa7b2d390a5be68e5509dc5.tar.gz opensim-SC_OLD-3b972417167e2c5d3aa7b2d390a5be68e5509dc5.tar.bz2 opensim-SC_OLD-3b972417167e2c5d3aa7b2d390a5be68e5509dc5.tar.xz |
Add --force flag to "kick user" console command to allow bypassing of recent race condition checks.
This is to allow a second attempt to remove an avatar even if "show connections" shows them as already inactive (i.e. close has already been attempted once).
You should only attempt --force if a normal kick fails.
This is partly for diagnostics as we have seen some connections occasionally remain on lbsa plaza even if they are registered as inactive.
This is not a permanent solution and may not work anyway - the ultimate solution is to stop this problem from happening in the first place.
14 files changed, 70 insertions, 23 deletions
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index d5952c4..8a63bff 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs | |||
@@ -1033,7 +1033,21 @@ namespace OpenSim.Framework | |||
1033 | 1033 | ||
1034 | void InPacket(object NewPack); | 1034 | void InPacket(object NewPack); |
1035 | void ProcessInPacket(Packet NewPack); | 1035 | void ProcessInPacket(Packet NewPack); |
1036 | |||
1037 | /// <summary> | ||
1038 | /// Close this client | ||
1039 | /// </summary> | ||
1036 | void Close(); | 1040 | void Close(); |
1041 | |||
1042 | /// <summary> | ||
1043 | /// Close this client | ||
1044 | /// </summary> | ||
1045 | /// <param name='force'> | ||
1046 | /// If true, attempts the close without checking active status. You do not want to try this except as a last | ||
1047 | /// ditch attempt where Active == false but the ScenePresence still exists. | ||
1048 | /// </param> | ||
1049 | void Close(bool force); | ||
1050 | |||
1037 | void Kick(string message); | 1051 | void Kick(string message); |
1038 | 1052 | ||
1039 | /// <summary> | 1053 | /// <summary> |
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 6bbab35..1fc11f5 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs | |||
@@ -35,6 +35,7 @@ using System.Text; | |||
35 | using System.Text.RegularExpressions; | 35 | using System.Text.RegularExpressions; |
36 | using System.Timers; | 36 | using System.Timers; |
37 | using log4net; | 37 | using log4net; |
38 | using NDesk.Options; | ||
38 | using Nini.Config; | 39 | using Nini.Config; |
39 | using OpenMetaverse; | 40 | using OpenMetaverse; |
40 | using OpenSim.Framework; | 41 | using OpenSim.Framework; |
@@ -310,8 +311,11 @@ namespace OpenSim | |||
310 | "Change the scale of a named prim", HandleEditScale); | 311 | "Change the scale of a named prim", HandleEditScale); |
311 | 312 | ||
312 | m_console.Commands.AddCommand("Users", false, "kick user", | 313 | m_console.Commands.AddCommand("Users", false, "kick user", |
313 | "kick user <first> <last> [message]", | 314 | "kick user <first> <last> [--force] [message]", |
314 | "Kick a user off the simulator", KickUserCommand); | 315 | "Kick a user off the simulator", |
316 | "The --force option will kick the user without any checks to see whether it's already in the process of closing\n" | ||
317 | + "Only use this option if you are sure the avatar is inactive and a normal kick user operation does not removed them", | ||
318 | KickUserCommand); | ||
315 | 319 | ||
316 | m_console.Commands.AddCommand("Users", false, "show users", | 320 | m_console.Commands.AddCommand("Users", false, "show users", |
317 | "show users [full]", | 321 | "show users [full]", |
@@ -453,11 +457,17 @@ namespace OpenSim | |||
453 | /// <param name="cmdparams">name of avatar to kick</param> | 457 | /// <param name="cmdparams">name of avatar to kick</param> |
454 | private void KickUserCommand(string module, string[] cmdparams) | 458 | private void KickUserCommand(string module, string[] cmdparams) |
455 | { | 459 | { |
456 | if (cmdparams.Length < 4) | 460 | bool force = false; |
461 | |||
462 | OptionSet options = new OptionSet().Add("f|force", delegate (string v) { force = v != null; }); | ||
463 | |||
464 | List<string> mainParams = options.Parse(cmdparams); | ||
465 | |||
466 | if (mainParams.Count < 4) | ||
457 | return; | 467 | return; |
458 | 468 | ||
459 | string alert = null; | 469 | string alert = null; |
460 | if (cmdparams.Length > 4) | 470 | if (mainParams.Count > 4) |
461 | alert = String.Format("\n{0}\n", String.Join(" ", cmdparams, 4, cmdparams.Length - 4)); | 471 | alert = String.Format("\n{0}\n", String.Join(" ", cmdparams, 4, cmdparams.Length - 4)); |
462 | 472 | ||
463 | IList agents = SceneManager.GetCurrentSceneAvatars(); | 473 | IList agents = SceneManager.GetCurrentSceneAvatars(); |
@@ -466,8 +476,8 @@ namespace OpenSim | |||
466 | { | 476 | { |
467 | RegionInfo regionInfo = presence.Scene.RegionInfo; | 477 | RegionInfo regionInfo = presence.Scene.RegionInfo; |
468 | 478 | ||
469 | if (presence.Firstname.ToLower().Contains(cmdparams[2].ToLower()) && | 479 | if (presence.Firstname.ToLower().Contains(mainParams[2].ToLower()) && |
470 | presence.Lastname.ToLower().Contains(cmdparams[3].ToLower())) | 480 | presence.Lastname.ToLower().Contains(mainParams[3].ToLower())) |
471 | { | 481 | { |
472 | MainConsole.Instance.Output( | 482 | MainConsole.Instance.Output( |
473 | String.Format( | 483 | String.Format( |
@@ -480,7 +490,7 @@ namespace OpenSim | |||
480 | else | 490 | else |
481 | presence.ControllingClient.Kick("\nThe OpenSim manager kicked you out.\n"); | 491 | presence.ControllingClient.Kick("\nThe OpenSim manager kicked you out.\n"); |
482 | 492 | ||
483 | presence.Scene.IncomingCloseAgent(presence.UUID); | 493 | presence.Scene.IncomingCloseAgent(presence.UUID, force); |
484 | } | 494 | } |
485 | } | 495 | } |
486 | 496 | ||
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs index cd70410..d604cf6 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs | |||
@@ -94,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests | |||
94 | UUID spId = TestHelpers.ParseTail(0x1); | 94 | UUID spId = TestHelpers.ParseTail(0x1); |
95 | 95 | ||
96 | SceneHelpers.AddScenePresence(m_scene, spId); | 96 | SceneHelpers.AddScenePresence(m_scene, spId); |
97 | m_scene.IncomingCloseAgent(spId); | 97 | m_scene.IncomingCloseAgent(spId, false); |
98 | 98 | ||
99 | // TODO: Add more assertions for the other aspects of event queues | 99 | // TODO: Add more assertions for the other aspects of event queues |
100 | Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0)); | 100 | Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0)); |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 22b3d35..148d0e0 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -487,16 +487,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
487 | 487 | ||
488 | #region Client Methods | 488 | #region Client Methods |
489 | 489 | ||
490 | /// <summary> | ||
491 | /// Close down the client view | ||
492 | /// </summary> | ||
493 | public void Close() | 490 | public void Close() |
494 | { | 491 | { |
492 | Close(false); | ||
493 | } | ||
494 | |||
495 | public void Close(bool force) | ||
496 | { | ||
495 | // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. | 497 | // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. |
496 | // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. | 498 | // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. |
497 | lock (CloseSyncLock) | 499 | lock (CloseSyncLock) |
498 | { | 500 | { |
499 | if (!IsActive) | 501 | // We still perform a force close inside the sync lock since this is intended to attempt close where |
502 | // there is some unidentified connection problem, not where we have issues due to deadlock | ||
503 | if (!IsActive && !force) | ||
500 | return; | 504 | return; |
501 | 505 | ||
502 | IsActive = false; | 506 | IsActive = false; |
@@ -11989,7 +11993,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11989 | { | 11993 | { |
11990 | Kick(reason); | 11994 | Kick(reason); |
11991 | Thread.Sleep(1000); | 11995 | Thread.Sleep(1000); |
11992 | Close(); | 11996 | Disconnect(); |
11993 | } | 11997 | } |
11994 | 11998 | ||
11995 | public void Disconnect() | 11999 | public void Disconnect() |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 6e7a414..5d82d2c 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | |||
@@ -461,7 +461,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
461 | 461 | ||
462 | SceneObjectGroup rezzedAtt = presence.GetAttachments()[0]; | 462 | SceneObjectGroup rezzedAtt = presence.GetAttachments()[0]; |
463 | 463 | ||
464 | scene.IncomingCloseAgent(presence.UUID); | 464 | scene.IncomingCloseAgent(presence.UUID, false); |
465 | 465 | ||
466 | // Check that we can't retrieve this attachment from the scene. | 466 | // Check that we can't retrieve this attachment from the scene. |
467 | Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null); | 467 | Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null); |
@@ -641,4 +641,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
641 | // Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects"); | 641 | // Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects"); |
642 | // } | 642 | // } |
643 | } | 643 | } |
644 | } \ No newline at end of file | 644 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 46738f6..c63b0a4 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -644,7 +644,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
644 | // an agent cannot teleport back to this region if it has teleported away. | 644 | // an agent cannot teleport back to this region if it has teleported away. |
645 | Thread.Sleep(2000); | 645 | Thread.Sleep(2000); |
646 | 646 | ||
647 | sp.Scene.IncomingCloseAgent(sp.UUID); | 647 | sp.Scene.IncomingCloseAgent(sp.UUID, false); |
648 | } | 648 | } |
649 | else | 649 | else |
650 | { | 650 | { |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index 09a3bd6..1e52d37 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs | |||
@@ -312,7 +312,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
312 | // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", | 312 | // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", |
313 | // s.RegionInfo.RegionName, destination.RegionHandle); | 313 | // s.RegionInfo.RegionName, destination.RegionHandle); |
314 | 314 | ||
315 | Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id); }); | 315 | Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id, false); }); |
316 | return true; | 316 | return true; |
317 | } | 317 | } |
318 | 318 | ||
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 40cfb72..b2592d4 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -4083,16 +4083,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
4083 | /// <summary> | 4083 | /// <summary> |
4084 | /// Tell a single agent to disconnect from the region. | 4084 | /// Tell a single agent to disconnect from the region. |
4085 | /// </summary> | 4085 | /// </summary> |
4086 | /// <param name="regionHandle"></param> | ||
4087 | /// <param name="agentID"></param> | 4086 | /// <param name="agentID"></param> |
4088 | public bool IncomingCloseAgent(UUID agentID) | 4087 | /// <param name="force"> |
4088 | /// Force the agent to close even if it might be in the middle of some other operation. You do not want to | ||
4089 | /// force unless you are absolutely sure that the agent is dead and a normal close is not working. | ||
4090 | /// </param> | ||
4091 | public bool IncomingCloseAgent(UUID agentID, bool force) | ||
4089 | { | 4092 | { |
4090 | //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); | 4093 | //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); |
4091 | 4094 | ||
4092 | ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); | 4095 | ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); |
4093 | if (presence != null) | 4096 | if (presence != null) |
4094 | { | 4097 | { |
4095 | presence.ControllingClient.Close(); | 4098 | presence.ControllingClient.Close(force); |
4096 | return true; | 4099 | return true; |
4097 | } | 4100 | } |
4098 | 4101 | ||
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs index 5758869..5faf131 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs | |||
@@ -141,7 +141,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
141 | TestScene scene = new SceneHelpers().SetupScene(); | 141 | TestScene scene = new SceneHelpers().SetupScene(); |
142 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); | 142 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); |
143 | 143 | ||
144 | scene.IncomingCloseAgent(sp.UUID); | 144 | scene.IncomingCloseAgent(sp.UUID, false); |
145 | 145 | ||
146 | Assert.That(scene.GetScenePresence(sp.UUID), Is.Null); | 146 | Assert.That(scene.GetScenePresence(sp.UUID), Is.Null); |
147 | Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null); | 147 | Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null); |
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index bae25cd..e93bd7c 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs | |||
@@ -886,6 +886,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
886 | 886 | ||
887 | public void Close() | 887 | public void Close() |
888 | { | 888 | { |
889 | Close(false); | ||
890 | } | ||
891 | |||
892 | public void Close(bool force) | ||
893 | { | ||
889 | Disconnect(); | 894 | Disconnect(); |
890 | } | 895 | } |
891 | 896 | ||
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 67989ba..a8e4d90 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | |||
@@ -901,6 +901,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
901 | 901 | ||
902 | public void Close() | 902 | public void Close() |
903 | { | 903 | { |
904 | Close(false); | ||
905 | } | ||
906 | |||
907 | public void Close(bool force) | ||
908 | { | ||
904 | // Remove ourselves from the scene | 909 | // Remove ourselves from the scene |
905 | m_scene.RemoveClient(AgentId, false); | 910 | m_scene.RemoveClient(AgentId, false); |
906 | } | 911 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 859ee93..8b6f76b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | |||
@@ -2881,7 +2881,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2881 | avatar.SpeedModifier = (float)SpeedModifier; | 2881 | avatar.SpeedModifier = (float)SpeedModifier; |
2882 | } | 2882 | } |
2883 | 2883 | ||
2884 | public void osKickAvatar(string FirstName,string SurName,string alert) | 2884 | public void osKickAvatar(string FirstName, string SurName, string alert) |
2885 | { | 2885 | { |
2886 | CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); | 2886 | CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); |
2887 | m_host.AddScriptLPS(1); | 2887 | m_host.AddScriptLPS(1); |
@@ -2895,7 +2895,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2895 | sp.ControllingClient.Kick(alert); | 2895 | sp.ControllingClient.Kick(alert); |
2896 | 2896 | ||
2897 | // ...and close on our side | 2897 | // ...and close on our side |
2898 | sp.Scene.IncomingCloseAgent(sp.UUID); | 2898 | sp.Scene.IncomingCloseAgent(sp.UUID, false); |
2899 | } | 2899 | } |
2900 | }); | 2900 | }); |
2901 | } | 2901 | } |
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 89c4f11..bb8b935 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs | |||
@@ -934,6 +934,11 @@ namespace OpenSim.Tests.Common.Mock | |||
934 | 934 | ||
935 | public void Close() | 935 | public void Close() |
936 | { | 936 | { |
937 | Close(false); | ||
938 | } | ||
939 | |||
940 | public void Close(bool force) | ||
941 | { | ||
937 | // Fire the callback for this connection closing | 942 | // Fire the callback for this connection closing |
938 | // This is necesary to get the presence detector to notice that a client has logged out. | 943 | // This is necesary to get the presence detector to notice that a client has logged out. |
939 | if (OnConnectionClosed != null) | 944 | if (OnConnectionClosed != null) |
diff --git a/prebuild.xml b/prebuild.xml index b4f4464..1765899 100644 --- a/prebuild.xml +++ b/prebuild.xml | |||
@@ -1760,6 +1760,7 @@ | |||
1760 | <Reference name="System.Core"/> | 1760 | <Reference name="System.Core"/> |
1761 | <Reference name="System.Xml"/> | 1761 | <Reference name="System.Xml"/> |
1762 | <Reference name="Mono.Addins" path="../../../bin/"/> | 1762 | <Reference name="Mono.Addins" path="../../../bin/"/> |
1763 | <Reference name="NDesk.Options" path="../../../bin/"/> | ||
1763 | <Reference name="OpenMetaverseTypes" path="../../../bin/"/> | 1764 | <Reference name="OpenMetaverseTypes" path="../../../bin/"/> |
1764 | <Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/> | 1765 | <Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/> |
1765 | <Reference name="OpenMetaverse" path="../../../bin/"/> | 1766 | <Reference name="OpenMetaverse" path="../../../bin/"/> |