Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

SERVER-7061 mongos can use invalid ptr to master conn when setShardVe…

…rsion fails
  • Loading branch information...
commit 5cc8a693a48f3885df6e77f5ce0f2abf0789d499 1 parent 6be65ad
Randolph Tan renctan authored monkey101 committed
Showing with 16 additions and 4 deletions.
  1. +6 −0 src/mongo/client/dbclient_rs.h
  2. +10 −4 src/mongo/s/shard_version.cpp
6 src/mongo/client/dbclient_rs.h
View
@@ -448,6 +448,12 @@ namespace mongo {
// ---- access raw connections ----
+ /**
+ * WARNING: this method is very dangerous - this object can decide to free the
+ * returned master connection any time.
+ *
+ * @return the reference to the address that points to the master connection.
+ */
DBClientConnection& masterConn();
DBClientConnection& slaveConn();
14 src/mongo/s/shard_version.cpp
View
@@ -232,6 +232,8 @@ namespace mongo {
<< " version: " << version << " manager: " << manager.get()
<< endl;
+ const string versionableServerAddress(conn->getServerAddress());
+
BSONObj result;
if ( setShardVersion( *conn , ns , version , authoritative , result ) ) {
// success!
@@ -246,7 +248,9 @@ namespace mongo {
massert( 10428 , "need_authoritative set but in authoritative mode already" , ! authoritative );
if ( ! authoritative ) {
- checkShardVersion( conn , ns , refManager, 1 , tryNumber + 1 );
+ // use the original connection and get a fresh versionable connection
+ // since conn can be invalidated (or worse, freed) after the failure
+ checkShardVersion(conn_in, ns, refManager, 1, tryNumber + 1);
return true;
}
@@ -268,13 +272,15 @@ namespace mongo {
const int maxNumTries = 7;
if ( tryNumber < maxNumTries ) {
LOG( tryNumber < ( maxNumTries / 2 ) ? 1 : 0 )
- << "going to retry checkShardVersion host: " << conn->getServerAddress() << " " << result << endl;
+ << "going to retry checkShardVersion host: " << versionableServerAddress << " " << result << endl;
sleepmillis( 10 * tryNumber );
- checkShardVersion( conn , ns , refManager, true , tryNumber + 1 );
+ // use the original connection and get a fresh versionable connection
+ // since conn can be invalidated (or worse, freed) after the failure
+ checkShardVersion(conn_in, ns, refManager, true, tryNumber + 1);
return true;
}
- string errmsg = str::stream() << "setShardVersion failed host: " << conn->getServerAddress() << " " << result;
+ string errmsg = str::stream() << "setShardVersion failed host: " << versionableServerAddress << " " << result;
log() << " " << errmsg << endl;
massert( 10429 , errmsg , 0 );
return true;
Please sign in to comment.
Something went wrong with that request. Please try again.