diff options
-rw-r--r-- | db/db.vcproj | 4 | ||||
-rw-r--r-- | db/repl/replset.cpp | 21 | ||||
-rw-r--r-- | db/repl/replset.h | 16 | ||||
-rw-r--r-- | util/hostandport.h | 75 |
4 files changed, 97 insertions, 19 deletions
diff --git a/db/db.vcproj b/db/db.vcproj index 6e79cf0cab7..78114a846e3 100644 --- a/db/db.vcproj +++ b/db/db.vcproj @@ -1905,6 +1905,10 @@ >
</File>
<File
+ RelativePath="..\util\hostandport.h"
+ >
+ </File>
+ <File
RelativePath=".\repl\replset.cpp"
>
</File>
diff --git a/db/repl/replset.cpp b/db/repl/replset.cpp index 65c006d79e5..8044dc0d0d8 100644 --- a/db/repl/replset.cpp +++ b/db/repl/replset.cpp @@ -17,38 +17,47 @@ #include "stdafx.h" #include "../cmdline.h" #include "replset.h" +#include "../../util/sock.h" namespace mongo { ReplSet *theReplSet = 0; ReplSet::ReplSet(string cfgString) { + cmdLine.port; + const char *p = cfgString.c_str(); const char *q = strchr(p, '/'); uassert(13093, "bad --replset config string format is: <setname>/<seedhost1>,<seedhost2>[,...]", q != 0 && p != q); _name = string(p, q-p); - set<RemoteServer> temp; - vector<RemoteServer> *seeds = new vector<RemoteServer>; + set<HostAndPort> temp; + vector<HostAndPort> *seeds = new vector<HostAndPort>; while( 1 ) { p = q + 1; q = strchr(p, ','); if( q == 0 ) q = strchr(p,0); uassert(13094, "bad --replset config string", p != q); const char *colon = strchr(p, ':'); - RemoteServer m; + HostAndPort m; if( colon && colon < q ) { int port = atoi(colon+1); uassert(13095, "bad --replset port #", port > 0); - m = RemoteServer(string(p,colon-p),port); + m = HostAndPort(string(p,colon-p),port); } else { // no port specified. - m = RemoteServer(string(p,q-p)); + m = HostAndPort(string(p,q-p)); } uassert(13096, "bad --replset config string - dups?", temp.count(m) == 0 ); // these uasserts leak seeds but that's ok temp.insert(m); - seeds->push_back(m); + + uassert(10000, "can't use localhost in replset host list", !m.isLocalHost()); + + if( m.isSelf() ) + log() << "replSet: ignoring seed " << m.toString() << " (=self)" << endl; + else + seeds->push_back(m); if( *q == 0 ) break; } diff --git a/db/repl/replset.h b/db/repl/replset.h index 88e9112b8c4..f2c5ebeab13 100644 --- a/db/repl/replset.h +++ b/db/repl/replset.h @@ -19,21 +19,11 @@ #pragma once #include "../../util/concurrency/list.h" +#include "../../util/hostandport.h" namespace mongo { - class ReplSet; - extern ReplSet *theReplSet; - - struct RemoteServer { - RemoteServer() : _port(-1) { } - RemoteServer(string h, int p = -1) : _host(h), _port(p) { } - bool operator<(const RemoteServer& r) const { return _host < r._host || (_host==r._host&&_port<r._port); } - private: - // invariant (except full obj assignment): - string _host; - int _port; - }; + extern class ReplSet *theReplSet; /* information about the entire repl set, such as the various servers in the set, and their state */ /* note: We currently do not free mem when the set goes away - it is assumed the replset is a @@ -51,7 +41,7 @@ namespace mongo { private: string _name; - const vector<RemoteServer> *_seeds; + const vector<HostAndPort> *_seeds; struct MemberInfo : public List1<MemberInfo>::Base { MemberInfo() : dead(false), lastHeartbeat(0) { } diff --git a/util/hostandport.h b/util/hostandport.h new file mode 100644 index 00000000000..f3f6cc3a26f --- /dev/null +++ b/util/hostandport.h @@ -0,0 +1,75 @@ +// hostandport.h + +/* Copyright 2009 10gen Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "sock.h" +#include "../db/cmdline.h" + +namespace mongo { + + /** helper for manipulating host:port connection endpoints. + */ + struct HostAndPort { + HostAndPort() : _port(-1) { } + + HostAndPort(string h, int p = -1) : _host(h), _port(p) { } + + bool operator<(const HostAndPort& r) const { return _host < r._host || (_host==r._host&&_port<r._port); } + + /* returns true if the host/port combo identifies this process instance. */ + bool isSelf() const; + + bool isLocalHost() const; + + string toString(); + private: + // invariant (except full obj assignment): + string _host; + int _port; + }; + + /** returns true if strings share a common starting prefix */ + inline bool sameStart(const char *p, const char *q) { + while( 1 ) { + if( *p == 0 || *q == 0 ) + return true; + if( *p != *q ) + break; + p++; q++; + } + return false; + } + + inline bool HostAndPort::isSelf() const { + if( _port != cmdLine.port ) + return false; + assert( _host != "localhost" && _host != "127.0.0.1" ); + return sameStart(getHostName().c_str(), _host.c_str()); + } + + inline string HostAndPort::toString() { + stringstream ss; + ss << _host << ':' << _port; + return ss.str(); + } + + inline bool HostAndPort::isLocalHost() const { + return _host == "localhost" || _host == "127.0.0.1"; + } + +} |