sockets: Add a function to disable all listening sockets.
authorNathan Binkert <nate@binkert.org>
Mon, 4 Aug 2008 01:19:55 +0000 (18:19 -0700)
committerNathan Binkert <nate@binkert.org>
Mon, 4 Aug 2008 01:19:55 +0000 (18:19 -0700)
When invoking several copies of m5 on the same machine at the same
time, there can be a race for TCP ports for the terminal connections
or remote gdb.  Expose a function to disable those ports, and have the
regression scripts disable them.  There are some SimObjects that have
no other function than to be used with ports (NativeTrace and
EtherTap), so they will panic if the ports are disabled.

src/base/remote_gdb.cc
src/base/socket.cc
src/base/socket.hh
src/cpu/nativetrace.cc
src/dev/ethertap.cc
src/dev/terminal.cc
src/python/m5/simulate.py
src/python/swig/core.i
tests/run.py

index 51293e1185b2036d1aa718d09408e14493989834..06e04e19ea78a59a577082349797b32ecdce7bdb 100644 (file)
@@ -195,6 +195,11 @@ GDBListener::name()
 void
 GDBListener::listen()
 {
+    if (ListenSocket::allDisabled()) {
+        warn_once("Sockets disabled, not accepting gdb connections");
+        return;
+    }
+
     while (!listener.listen(port, true)) {
         DPRINTF(GDBMisc, "Can't bind port %d\n", port);
         port++;
index adcc48735f3dc3c0fa836536f3972c3e18c42913..bcc5236b097ea7eb426c26c8f93945a74ef47a4c 100644 (file)
 
 using namespace std;
 
+bool ListenSocket::listeningDisabled = false;
+bool ListenSocket::anyListening = false;
+
+void
+ListenSocket::disableAll()
+{
+    if (anyListening)
+        panic("Too late to disable all listeners, already have a listener");
+    listeningDisabled = true;
+}
+
+bool
+ListenSocket::allDisabled()
+{
+    return listeningDisabled;
+}
+
 ////////////////////////////////////////////////////////////////////////
 //
 //
@@ -92,6 +109,7 @@ ListenSocket::listen(int port, bool reuse)
 
     listening = true;
 
+    anyListening = true;
     return true;
 }
 
index 8e55eae721f88ae6fa41950c3490e78da87c5fd4..942318e45a8d2b70098678536abf8f4fd4aaa9ff 100644 (file)
 
 class ListenSocket
 {
+  protected:
+    static bool listeningDisabled;
+    static bool anyListening;
+
+  public:
+    static void disableAll();
+    static bool allDisabled();
+
   protected:
     bool listening;
     int fd;
index 7152602fe8c8a02f8f0b101ad49128fb424a83a0..c23a9e4ade12481c076d951fd19414b5103192ce 100644 (file)
@@ -50,8 +50,12 @@ using namespace TheISA;
 
 namespace Trace {
 
-NativeTrace::NativeTrace(const Params *p) : InstTracer(p)
+NativeTrace::NativeTrace(const Params *p)
+    : InstTracer(p)
 {
+    if (ListenSocket::allDisabled())
+        fatal("All listeners are disabled!");
+
     int port = 8000;
     while(!native_listener.listen(port, true))
     {
index 81b84d179b551a9aa448b7c48e474e1f5e0fd0a6..c7b292c8a878f3fc7c1d125a8d5c6f2960abbe62 100644 (file)
@@ -130,6 +130,9 @@ EtherTap::EtherTap(const Params *p)
     : EtherObject(p), event(NULL), socket(-1), buflen(p->bufsz), dump(p->dump),
       interface(NULL), txEvent(this)
 {
+    if (ListenSocket::allDisabled())
+        fatal("All listeners are disabled! EtherTap can't work!");
+
     buffer = new char[buflen];
     listener = new TapListener(this, p->port);
     listener->listen();
index 47f280ad3b09831bed62ef224f08a2473a9d0cb5..58371a2bdb1c82b85cab49eeca16e9c6b11f0c1b 100644 (file)
@@ -125,6 +125,11 @@ Terminal::~Terminal()
 void
 Terminal::listen(int port)
 {
+    if (ListenSocket::allDisabled()) {
+        warn_once("Sockets disabled, not accepting terminal connections");
+        return;
+    }
+
     while (!listener.listen(port, true)) {
         DPRINTF(Terminal,
                 ": can't bind address terminal port %d inuse PID %d\n",
index 3d91da3683a4ffeb86792de0f58c006d8574690c..e4dbd57848f079ea1579285b92e41a0e925f327a 100644 (file)
@@ -182,3 +182,5 @@ def switchCpus(cpuList):
 
     for old_cpu, new_cpu in cpuList:
         new_cpu.takeOverFrom(old_cpu)
+
+from internal.core import disableAllListeners
index 53d992ac6c30bea53541b7b71412974858f101f1..3d360c01714f7ed56f4dffcb4b9edaae63438df3 100644 (file)
@@ -34,6 +34,7 @@
 %{
 #include "python/swig/pyobject.hh"
 
+#include "base/socket.hh"
 #include "sim/core.hh"
 #include "sim/host.hh"
 #include "sim/startup.hh"
@@ -42,6 +43,7 @@ extern const char *compileDate;
 std::vector<std::string> compileFlags();
 extern const char *hgRev;
 extern const char *hgDate;
+inline void disableAllListeners() { ListenSocket::disableAll(); }
 %}
 
 %include "stdint.i"
@@ -53,6 +55,7 @@ void setOutputDir(const std::string &dir);
 void setOutputFile(const std::string &file);
 void SimStartup();
 void doExitCleanup();
+void disableAllListeners();
 
 %immutable compileDate;
 char *compileDate;
index 9b77ff9d2bf2b7d657fb45664de92552be301811..aadc16b93338105fcfd64fcdc1bf59ca2f65ae23 100644 (file)
 #
 # Authors: Steve Reinhardt
 
-import os, sys
+import os
+import sys
+import m5
+
+# Since we're in batch mode, dont allow tcp socket connections
+m5.disableAllListeners()
 
 # single "path" arg encodes everything we need to know about test
 (category, name, isa, opsys, config) = sys.argv[1].split('/')
@@ -57,8 +62,7 @@ execfile(os.path.join(tests_root, 'configs', config + '.py'))
 
 # set default maxtick... script can override
 # -1 means run forever
-from m5 import MaxTick
-maxtick = MaxTick
+maxtick = m5.MaxTick
 
 # tweak configuration for specific test