sockets: Add a function to disable all listening sockets.
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.
This commit is contained in:
parent
ede89c2d54
commit
50ef39af82
9 changed files with 56 additions and 4 deletions
|
@ -195,6 +195,11 @@ GDBListener::name()
|
||||||
void
|
void
|
||||||
GDBListener::listen()
|
GDBListener::listen()
|
||||||
{
|
{
|
||||||
|
if (ListenSocket::allDisabled()) {
|
||||||
|
warn_once("Sockets disabled, not accepting gdb connections");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
while (!listener.listen(port, true)) {
|
while (!listener.listen(port, true)) {
|
||||||
DPRINTF(GDBMisc, "Can't bind port %d\n", port);
|
DPRINTF(GDBMisc, "Can't bind port %d\n", port);
|
||||||
port++;
|
port++;
|
||||||
|
|
|
@ -43,6 +43,23 @@
|
||||||
|
|
||||||
using namespace std;
|
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;
|
listening = true;
|
||||||
|
|
||||||
|
anyListening = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,14 @@
|
||||||
|
|
||||||
class ListenSocket
|
class ListenSocket
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
static bool listeningDisabled;
|
||||||
|
static bool anyListening;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void disableAll();
|
||||||
|
static bool allDisabled();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool listening;
|
bool listening;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
|
@ -50,8 +50,12 @@ using namespace TheISA;
|
||||||
|
|
||||||
namespace Trace {
|
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;
|
int port = 8000;
|
||||||
while(!native_listener.listen(port, true))
|
while(!native_listener.listen(port, true))
|
||||||
{
|
{
|
||||||
|
|
|
@ -130,6 +130,9 @@ EtherTap::EtherTap(const Params *p)
|
||||||
: EtherObject(p), event(NULL), socket(-1), buflen(p->bufsz), dump(p->dump),
|
: EtherObject(p), event(NULL), socket(-1), buflen(p->bufsz), dump(p->dump),
|
||||||
interface(NULL), txEvent(this)
|
interface(NULL), txEvent(this)
|
||||||
{
|
{
|
||||||
|
if (ListenSocket::allDisabled())
|
||||||
|
fatal("All listeners are disabled! EtherTap can't work!");
|
||||||
|
|
||||||
buffer = new char[buflen];
|
buffer = new char[buflen];
|
||||||
listener = new TapListener(this, p->port);
|
listener = new TapListener(this, p->port);
|
||||||
listener->listen();
|
listener->listen();
|
||||||
|
|
|
@ -125,6 +125,11 @@ Terminal::~Terminal()
|
||||||
void
|
void
|
||||||
Terminal::listen(int port)
|
Terminal::listen(int port)
|
||||||
{
|
{
|
||||||
|
if (ListenSocket::allDisabled()) {
|
||||||
|
warn_once("Sockets disabled, not accepting terminal connections");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
while (!listener.listen(port, true)) {
|
while (!listener.listen(port, true)) {
|
||||||
DPRINTF(Terminal,
|
DPRINTF(Terminal,
|
||||||
": can't bind address terminal port %d inuse PID %d\n",
|
": can't bind address terminal port %d inuse PID %d\n",
|
||||||
|
|
|
@ -182,3 +182,5 @@ def switchCpus(cpuList):
|
||||||
|
|
||||||
for old_cpu, new_cpu in cpuList:
|
for old_cpu, new_cpu in cpuList:
|
||||||
new_cpu.takeOverFrom(old_cpu)
|
new_cpu.takeOverFrom(old_cpu)
|
||||||
|
|
||||||
|
from internal.core import disableAllListeners
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
%{
|
%{
|
||||||
#include "python/swig/pyobject.hh"
|
#include "python/swig/pyobject.hh"
|
||||||
|
|
||||||
|
#include "base/socket.hh"
|
||||||
#include "sim/core.hh"
|
#include "sim/core.hh"
|
||||||
#include "sim/host.hh"
|
#include "sim/host.hh"
|
||||||
#include "sim/startup.hh"
|
#include "sim/startup.hh"
|
||||||
|
@ -42,6 +43,7 @@ extern const char *compileDate;
|
||||||
std::vector<std::string> compileFlags();
|
std::vector<std::string> compileFlags();
|
||||||
extern const char *hgRev;
|
extern const char *hgRev;
|
||||||
extern const char *hgDate;
|
extern const char *hgDate;
|
||||||
|
inline void disableAllListeners() { ListenSocket::disableAll(); }
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%include "stdint.i"
|
%include "stdint.i"
|
||||||
|
@ -53,6 +55,7 @@ void setOutputDir(const std::string &dir);
|
||||||
void setOutputFile(const std::string &file);
|
void setOutputFile(const std::string &file);
|
||||||
void SimStartup();
|
void SimStartup();
|
||||||
void doExitCleanup();
|
void doExitCleanup();
|
||||||
|
void disableAllListeners();
|
||||||
|
|
||||||
%immutable compileDate;
|
%immutable compileDate;
|
||||||
char *compileDate;
|
char *compileDate;
|
||||||
|
|
10
tests/run.py
10
tests/run.py
|
@ -26,7 +26,12 @@
|
||||||
#
|
#
|
||||||
# Authors: Steve Reinhardt
|
# 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
|
# single "path" arg encodes everything we need to know about test
|
||||||
(category, name, isa, opsys, config) = sys.argv[1].split('/')
|
(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
|
# set default maxtick... script can override
|
||||||
# -1 means run forever
|
# -1 means run forever
|
||||||
from m5 import MaxTick
|
maxtick = m5.MaxTick
|
||||||
maxtick = MaxTick
|
|
||||||
|
|
||||||
# tweak configuration for specific test
|
# tweak configuration for specific test
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue