diff options
-rw-r--r-- | src/mongo/client/dbclient_rs.h | 6 | ||||
-rw-r--r-- | src/mongo/s/shard_version.cpp | 14 |
2 files changed, 16 insertions, 4 deletions
diff --git a/src/mongo/client/dbclient_rs.h b/src/mongo/client/dbclient_rs.h index a74fa7902a3..213ee0dad25 100644 --- a/src/mongo/client/dbclient_rs.h +++ b/src/mongo/client/dbclient_rs.h @@ -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(); diff --git a/src/mongo/s/shard_version.cpp b/src/mongo/s/shard_version.cpp index 7d0ef93da8f..ee959795027 100644 --- a/src/mongo/s/shard_version.cpp +++ b/src/mongo/s/shard_version.cpp @@ -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; |