Skip to content

Commit 8e4a51c

Browse files
committed
CXX-236 Backport server r2.6.1..r2.6.2 changes
1 parent 1c5860f commit 8e4a51c

13 files changed

+571
-16
lines changed

SConstruct

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,8 @@ add_option("mongod-concurrency-level", "Concurrency level, \"global\" or \"db\""
299299

300300
add_option('build-fast-and-loose', "NEVER for production builds", 0, False)
301301

302+
add_option('disable-warnings-as-errors', "Don't add -Werror to compiler command line", 0, False)
303+
302304
add_option('propagate-shell-environment',
303305
"Pass shell environment to sub-processes (NEVER for production builds)",
304306
0, False)
@@ -840,7 +842,9 @@ if nix:
840842
"-Winvalid-pch"] )
841843
# env.Append( " -Wconversion" ) TODO: this doesn't really work yet
842844
if linux or darwin:
843-
env.Append( CCFLAGS=["-Werror", "-pipe"] )
845+
env.Append( CCFLAGS=["-pipe"] )
846+
if not has_option("disable-warnings-as-errors"):
847+
env.Append( CCFLAGS=["-Werror"] )
844848

845849
env.Append( CPPDEFINES=["_FILE_OFFSET_BITS=64"] )
846850
env.Append( CXXFLAGS=["-Wnon-virtual-dtor", "-Woverloaded-virtual"] )

src/mongo/base/error_codes.err

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ error_code("IndexOptionsConflict", 85 )
8787
error_code("IndexKeySpecsConflict", 86 )
8888

8989
# Non-sequential error codes (for compatibility only)
90+
error_code("NetworkTimeout", 89)
9091
error_code("NotMaster", 10107) #this comes from assert_util.h
9192
error_code("DuplicateKey", 11000)
9293
error_code("InterruptedAtShutdown", 11600)
@@ -95,7 +96,7 @@ error_code("OutOfDiskSpace", 14031 )
9596
error_code("BackgroundOperationInProgressForDatabase", 12586);
9697
error_code("BackgroundOperationInProgressForNamespace", 12587);
9798

98-
error_class("NetworkError", ["HostUnreachable", "HostNotFound"])
99+
error_class("NetworkError", ["HostUnreachable", "HostNotFound", "NetworkTimeout"])
99100
error_class("Interruption", ["Interrupted", "InterruptedAtShutdown", "ExceededTimeLimit"])
100101
error_class("IndexCreationError", ["CannotCreateIndex", "IndexOptionsConflict",
101102
"IndexKeySpecsConflict", "IndexAlreadyExists"])

src/mongo/bson/bsonobjbuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,7 @@ namespace mongo {
793793
return _b.subarrayStart( num() );
794794
}
795795

796-
// These should only be used where you really need interface compatability with BSONObjBuilder
796+
// These should only be used where you really need interface compatibility with BSONObjBuilder
797797
// Currently they are only used by update.cpp and it should probably stay that way
798798
BufBuilder &subobjStart( const StringData& name ) {
799799
fill( name );

src/mongo/client/dbclientinterface.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ namespace mongo {
191191
*/
192192
class MONGO_CLIENT_API ConnectionString {
193193
public:
194+
194195
enum ConnectionType { INVALID , MASTER , PAIR , SET , SYNC, CUSTOM };
195196

196197
ConnectionString() {
@@ -295,6 +296,11 @@ namespace mongo {
295296
return _connectHook;
296297
}
297298

299+
// Allows ConnectionStrings to be stored more easily in sets/maps
300+
bool operator<(const ConnectionString& other) const {
301+
return _string < other._string;
302+
}
303+
298304
//
299305
// FOR TESTING ONLY - useful to be able to directly mock a connection string without
300306
// including the entire client library.

src/mongo/client/syncclusterconnection.cpp

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -291,22 +291,47 @@ namespace mongo {
291291
return isOk( info );
292292
}
293293

294+
void SyncClusterConnection::attachQueryHandler( QueryHandler* handler ) {
295+
_customQueryHandler.reset( handler );
296+
}
297+
294298
auto_ptr<DBClientCursor> SyncClusterConnection::_queryOnActive(const string &ns, Query query, int nToReturn, int nToSkip,
295299
const BSONObj *fieldsToReturn, int queryOptions, int batchSize ) {
296300

301+
if ( _customQueryHandler && _customQueryHandler->canHandleQuery( ns, query ) ) {
302+
303+
LOG( 2 ) << "custom query handler used for query on " << ns << ": "
304+
<< query.toString() << endl;
305+
306+
return _customQueryHandler->handleQuery( _connAddresses,
307+
ns,
308+
query,
309+
nToReturn,
310+
nToSkip,
311+
fieldsToReturn,
312+
queryOptions,
313+
batchSize );
314+
}
315+
297316
for ( size_t i=0; i<_conns.size(); i++ ) {
298317
try {
299318
auto_ptr<DBClientCursor> cursor =
300319
_conns[i]->query( ns , query , nToReturn , nToSkip , fieldsToReturn , queryOptions , batchSize );
301320
if ( cursor.get() )
302321
return cursor;
303-
log() << "query failed to: " << _conns[i]->toString() << " no data" << endl;
322+
323+
log() << "query on " << ns << ": " << query.toString() << " failed to: "
324+
<< _conns[i]->toString() << " no data" << endl;
304325
}
305326
catch ( std::exception& e ) {
306-
log() << "query failed to: " << _conns[i]->toString() << " exception: " << e.what() << endl;
327+
328+
log() << "query on " << ns << ": " << query.toString() << " failed to: "
329+
<< _conns[i]->toString() << " exception: " << e.what() << endl;
307330
}
308331
catch ( ... ) {
309-
log() << "query failed to: " << _conns[i]->toString() << " exception" << endl;
332+
333+
log() << "query on " << ns << ": " << query.toString() << " failed to: "
334+
<< _conns[i]->toString() << " exception" << endl;
310335
}
311336
}
312337
throw UserException( 8002 , str::stream() << "all servers down/unreachable when querying: " << _address );

src/mongo/client/syncclusterconnection.h

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ namespace mongo {
4747
using DBClientBase::update;
4848
using DBClientBase::remove;
4949

50+
class QueryHandler;
51+
5052
/**
5153
* @param commaSeparated should be 3 hosts comma separated
5254
*/
@@ -116,6 +118,13 @@ namespace mongo {
116118
virtual void setRunCommandHook(DBClientWithCommands::RunCommandHookFunc func);
117119
virtual void setPostRunCommandHook(DBClientWithCommands::PostRunCommandHookFunc func);
118120

121+
/**
122+
* Allow custom query processing through an external (e.g. mongos-only) service.
123+
*
124+
* Takes ownership of attached handler.
125+
*/
126+
void attachQueryHandler( QueryHandler* handler );
127+
119128
protected:
120129
virtual void _auth(const BSONObj& params);
121130

@@ -132,14 +141,47 @@ namespace mongo {
132141
string _address;
133142
vector<string> _connAddresses;
134143
vector<DBClientConnection*> _conns;
135-
map<string,int> _lockTypes;
136-
mongo::mutex _mutex;
137144

138145
vector<BSONObj> _lastErrors;
139146

147+
// Optionally attached by user
148+
scoped_ptr<QueryHandler> _customQueryHandler;
149+
150+
mongo::mutex _mutex;
151+
map<string,int> _lockTypes;
152+
// End mutex
153+
140154
double _socketTimeout;
141155
};
142156

157+
/**
158+
* Interface for custom query processing for the SCC.
159+
* Allows plugging different host query behaviors for different types of queries.
160+
*/
161+
class SyncClusterConnection::QueryHandler {
162+
public:
163+
164+
virtual ~QueryHandler() {};
165+
166+
/**
167+
* Returns true if the query can be processed using this handler.
168+
*/
169+
virtual bool canHandleQuery( const string& ns, Query query ) = 0;
170+
171+
/**
172+
* Returns a cursor on one of the hosts with the desired results for the query.
173+
* May throw or return an empty auto_ptr on failure.
174+
*/
175+
virtual auto_ptr<DBClientCursor> handleQuery( const vector<string>& hosts,
176+
const string &ns,
177+
Query query,
178+
int nToReturn,
179+
int nToSkip,
180+
const BSONObj *fieldsToReturn,
181+
int queryOptions,
182+
int batchSize ) = 0;
183+
};
184+
143185
class MONGO_CLIENT_API UpdateNotTheSame : public UserException {
144186
public:
145187
UpdateNotTheSame( int code , const string& msg , const vector<string>& addrs , const vector<BSONObj>& lastErrors )

src/mongo/db/jsobj.cpp

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -211,26 +211,38 @@ namespace mongo {
211211
if (format == Strict) {
212212
Date_t d = date();
213213
s << "{ \"$date\" : ";
214-
if (static_cast<long long>(d.millis) < 0) {
215-
s << "{ \"$numberLong\" : \"" << static_cast<long long>(d.millis) << "\" }";
214+
// The two cases in which we cannot convert Date_t::millis to an ISO Date string are
215+
// when the date is too large to format (SERVER-13760), and when the date is before
216+
// the epoch (SERVER-11273). Since Date_t internally stores millis as an unsigned
217+
// long long, despite the fact that it is logically signed (SERVER-8573), this check
218+
// handles both the case where Date_t::millis is too large, and the case where
219+
// Date_t::millis is negative (before the epoch).
220+
if (d.isFormatable()) {
221+
s << "\"" << dateToISOStringLocal(date()) << "\"";
216222
}
217223
else {
218-
s << "\"" << dateToISOStringLocal(date()) << "\"";
224+
s << "{ \"$numberLong\" : \"" << static_cast<long long>(d.millis) << "\" }";
219225
}
220226
s << " }";
221227
}
222228
else {
223229
s << "Date( ";
224230
if (pretty) {
225231
Date_t d = date();
226-
if (static_cast<long long>(d.millis) < 0) {
232+
// The two cases in which we cannot convert Date_t::millis to an ISO Date string
233+
// are when the date is too large to format (SERVER-13760), and when the date is
234+
// before the epoch (SERVER-11273). Since Date_t internally stores millis as an
235+
// unsigned long long, despite the fact that it is logically signed
236+
// (SERVER-8573), this check handles both the case where Date_t::millis is too
237+
// large, and the case where Date_t::millis is negative (before the epoch).
238+
if (d.isFormatable()) {
239+
s << "\"" << dateToISOStringLocal(date()) << "\"";
240+
}
241+
else {
227242
// FIXME: This is not parseable by the shell, since it may not fit in a
228243
// float
229244
s << d.millis;
230245
}
231-
else {
232-
s << "\"" << dateToISOStringLocal(date()) << "\"";
233-
}
234246
}
235247
else {
236248
s << date().asInt64();

src/mongo/dbtests/jsontests.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,14 @@ namespace JsonTests {
405405
built.jsonString( Strict ) );
406406
ASSERT_EQUALS( "{ \"a\" : Date( 0 ) }", built.jsonString( TenGen ) );
407407
ASSERT_EQUALS( "{ \"a\" : Date( 0 ) }", built.jsonString( JS ) );
408+
409+
// Test dates above our maximum formattable date. See SERVER-13760.
410+
BSONObjBuilder b2;
411+
b2.appendDate("a", 32535262800000ULL);
412+
BSONObj built2 = b2.done();
413+
ASSERT_EQUALS(
414+
"{ \"a\" : { \"$date\" : { \"$numberLong\" : \"32535262800000\" } } }",
415+
built2.jsonString( Strict ) );
408416
}
409417

410418
private:

src/mongo/util/net/ssl_manager.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,15 @@ namespace mongo {
634634
}
635635

636636
bool SSLManager::_setupCA(SSL_CTX* context, const std::string& caFile) {
637+
// Set the list of CAs sent to clients
638+
STACK_OF (X509_NAME) * certNames = SSL_load_client_CA_file(caFile.c_str());
639+
if (certNames == NULL) {
640+
error() << "cannot read certificate authority file: " << caFile << " " <<
641+
getSSLErrorMessage(ERR_get_error()) << endl;
642+
return false;
643+
}
644+
SSL_CTX_set_client_CA_list(context, certNames);
645+
637646
// Load trusted CA
638647
if (SSL_CTX_load_verify_locations(context, caFile.c_str(), NULL) != 1) {
639648
error() << "cannot read certificate authority file: " << caFile << " " <<

src/mongo/util/time_support.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@ extern "C" time_t timegm(struct tm *const tmp);
4949

5050
namespace mongo {
5151

52+
bool Date_t::isFormatable() const {
53+
if (sizeof(time_t) == sizeof(int32_t)) {
54+
return millis < 2147483647000ULL; // "2038-01-19T03:14:07Z"
55+
}
56+
else {
57+
return millis < 32535215999000ULL; // "3000-12-31T23:59:59Z"
58+
}
59+
}
60+
5261
// jsTime_virtual_skew is just for testing. a test command manipulates it.
5362
long long jsTime_virtual_skew = 0;
5463
boost::thread_specific_ptr<long long> jsTime_virtual_thread_skew;
@@ -118,6 +127,7 @@ namespace mongo {
118127
}
119128

120129
static inline std::string _dateToISOString(Date_t date, bool local) {
130+
invariant(date.isFormatable());
121131
const int bufSize = 32;
122132
char buf[bufSize];
123133
struct tm t;

src/mongo/util/time_support.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ namespace mongo {
4444
int64_t asInt64() const {
4545
return static_cast<int64_t>(millis);
4646
}
47+
bool isFormatable() const;
4748
};
4849

4950
// uses ISO 8601 dates without trailing Z

0 commit comments

Comments
 (0)