aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2012-08-20 20:24:54 +0100
committerJustin Clark-Casey (justincc)2012-08-20 20:24:54 +0100
commitbcbd450fe441e94d6c0f547055b4e95f75a5b0d0 (patch)
treead92a6256830933073261fe0f715b006fd94c341
parentFix scripted detach of temp attachments (diff)
downloadopensim-SC_OLD-bcbd450fe441e94d6c0f547055b4e95f75a5b0d0.zip
opensim-SC_OLD-bcbd450fe441e94d6c0f547055b4e95f75a5b0d0.tar.gz
opensim-SC_OLD-bcbd450fe441e94d6c0f547055b4e95f75a5b0d0.tar.bz2
opensim-SC_OLD-bcbd450fe441e94d6c0f547055b4e95f75a5b0d0.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.
-rw-r--r--OpenSim/Framework/IClientAPI.cs14
-rw-r--r--OpenSim/Region/Application/OpenSim.cs24
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs14
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs9
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs5
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs4
-rw-r--r--OpenSim/Tests/Common/Mock/TestClient.cs5
-rw-r--r--prebuild.xml1
14 files changed, 69 insertions, 22 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;
35using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers; 36using System.Timers;
37using log4net; 37using log4net;
38using NDesk.Options;
38using Nini.Config; 39using Nini.Config;
39using OpenMetaverse; 40using OpenMetaverse;
40using OpenSim.Framework; 41using 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 1d13f75..82c6390 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);
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 d2d6aba..ad74189 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -4116,16 +4116,19 @@ namespace OpenSim.Region.Framework.Scenes
4116 /// <summary> 4116 /// <summary>
4117 /// Tell a single agent to disconnect from the region. 4117 /// Tell a single agent to disconnect from the region.
4118 /// </summary> 4118 /// </summary>
4119 /// <param name="regionHandle"></param>
4120 /// <param name="agentID"></param> 4119 /// <param name="agentID"></param>
4121 public bool IncomingCloseAgent(UUID agentID) 4120 /// <param name="force">
4121 /// Force the agent to close even if it might be in the middle of some other operation. You do not want to
4122 /// force unless you are absolutely sure that the agent is dead and a normal close is not working.
4123 /// </param>
4124 public bool IncomingCloseAgent(UUID agentID, bool force)
4122 { 4125 {
4123 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 4126 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
4124 4127
4125 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); 4128 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
4126 if (presence != null) 4129 if (presence != null)
4127 { 4130 {
4128 presence.ControllingClient.Close(); 4131 presence.ControllingClient.Close(force);
4129 return true; 4132 return true;
4130 } 4133 }
4131 4134
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 8936cb2..1e8b51b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -2877,7 +2877,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2877 avatar.SpeedModifier = (float)SpeedModifier; 2877 avatar.SpeedModifier = (float)SpeedModifier;
2878 } 2878 }
2879 2879
2880 public void osKickAvatar(string FirstName,string SurName,string alert) 2880 public void osKickAvatar(string FirstName, string SurName, string alert)
2881 { 2881 {
2882 CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); 2882 CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar");
2883 m_host.AddScriptLPS(1); 2883 m_host.AddScriptLPS(1);
@@ -2891,7 +2891,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2891 sp.ControllingClient.Kick(alert); 2891 sp.ControllingClient.Kick(alert);
2892 2892
2893 // ...and close on our side 2893 // ...and close on our side
2894 sp.Scene.IncomingCloseAgent(sp.UUID); 2894 sp.Scene.IncomingCloseAgent(sp.UUID, false);
2895 } 2895 }
2896 }); 2896 });
2897 } 2897 }
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/"/>