Compare commits

...

17 Commits

Author SHA1 Message Date
Dan Pasette
ddb73290a4 post 2.4.3 2013-04-23 08:55:09 -04:00
Dan Pasette
fe1743177a BUMP 2.4.3 2013-04-22 10:48:39 -04:00
Dan Pasette
139e40b500 post 2.4.3-rc0 2013-04-19 10:09:25 -04:00
Dan Pasette
7d75e95bc0 BUMP 2.4.3-rc0 2013-04-18 19:15:44 -04:00
Mathias Stearn
716d31016d SERVER-9089 Check for NULL BSONHolder 2013-04-18 19:02:58 -04:00
Mathias Stearn
022affc651 SERVER-9385 Make sure _id fields are extracted from modified lazy V8 objects 2013-04-18 19:02:42 -04:00
Alberto Lerner
0b48ec01cb SERVER-9399 Create the right index of config.lockpings. 2013-04-18 17:45:30 -04:00
Eric Milkie
52c1e65d6f SERVER-9093 remove unit test in 2.4 branch (needs SERVER-8420) 2013-04-18 13:55:26 -04:00
Eric Milkie
0239789a5b SERVER-8420 add a tailcheck to detect cursor deadness 2013-04-18 12:11:38 -04:00
Spencer T Brody
e01102d1df SERVER-9093 Make copydb command work on mongos with auth
Conflicts:
	src/mongo/s/commands_public.cpp
2013-04-18 11:46:48 -04:00
Jason Rassi
036337a5c0 SERVER-9214 Change tolowerString argument type to StringData 2013-04-18 11:29:07 -04:00
Eric Milkie
be1e22fea5 SERVER-9214 initialize variable to placate compiler 2013-04-18 11:13:55 -04:00
Jason Rassi
37f2062420 SERVER-9214 Extract phrases from text searches as exact substrings 2013-04-18 11:13:43 -04:00
Eric Milkie
757fe510df SERVER-4739 compile mongos on Windows 2013-04-18 10:55:33 -04:00
Eric Milkie
9d5de58e4f SERVER-4739 use a thread for logRotate signal instead of a signal handler
Conflicts:
	src/mongo/db/db.cpp
	src/mongo/s/server.cpp
2013-04-18 10:24:54 -04:00
Eric Milkie
6397087303 SERVER-9307 initialize session id context to support session caching on the server
You must set the context in order for session caching to work.
This would normally fail silently without setting the context, but when you turn on
certificate validation and attempt to reuse a session, the attempt will actively fail and
return an error on the server.
The Java driver does make use of restartable sessions and is affected by this issue.
2013-04-18 10:19:59 -04:00
Eric Milkie
ccaf58fccf post 2.4.2 2013-04-18 10:18:34 -04:00
18 changed files with 139 additions and 79 deletions

View File

@@ -3,7 +3,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = MongoDB
PROJECT_NUMBER = 2.4.2
PROJECT_NUMBER = 2.4.4-pre-
OUTPUT_DIRECTORY = docs/doxygen
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English

16
jstests/server9385.js Normal file
View File

@@ -0,0 +1,16 @@
// SERVER-9385 ensure saving a document derived from bson->js conversion doesn't lose it's _id
t = db.server9385;
t.drop();
t.insert( { _id : 1, x : 1 } );
x = t.findOne();
x._id = 2;
t.save( x );
t.find().forEach( printjson );
assert.eq( 2, t.find().count() );
assert.eq( 2, t.find().itcount() );
assert( t.findOne( { _id : 1 } ), "original insert missing" );
assert( t.findOne( { _id : 2 } ), "save didn't work?" );

View File

@@ -164,7 +164,7 @@ namespace mongo {
// create index so remove is fast even with a lot of servers
if ( loops++ == 0 ) {
conn->ensureIndex( LockpingsType::ConfigNS, BSON( LockpingsType::ping(1) ) );
conn->ensureIndex( LockpingsType::ConfigNS, BSON( LockpingsType::ping() << 1 ) );
}
LOG( DistributedLock::logLvl - ( loops % 10 == 0 ? 1 : 0 ) ) << "cluster " << addr << " pinged successfully at " << pingTime

View File

@@ -762,7 +762,7 @@ namespace mongo {
// source DB.
ActionSet actions;
actions.addAction(ActionType::copyDBTarget);
out->push_back(Privilege(dbname, actions));
out->push_back(Privilege(dbname, actions)); // NOTE: dbname is always admin
}
virtual void help( stringstream &help ) const {
help << "copy a database from another host to this host\n";

View File

@@ -187,32 +187,6 @@ namespace mongo {
static int testCommandsEnabled;
};
// This will be registered instead of the real implementations of any commands that don't work
// when auth is enabled.
class NotWithAuthCmd : public Command {
public:
NotWithAuthCmd(const char* cmdName) : Command(cmdName) { }
virtual bool slaveOk() const { return true; }
virtual LockType locktype() const { return NONE; }
virtual bool requiresAuth() { return false; }
virtual void addRequiredPrivileges(const std::string& dbname,
const BSONObj& cmdObj,
std::vector<Privilege>* out) {}
virtual void help( stringstream &help ) const {
help << name << " is not supported when running with authentication enabled";
}
virtual bool run(const string&,
BSONObj& cmdObj,
int,
string& errmsg,
BSONObjBuilder& result,
bool fromRepl) {
errmsg = name + " is not supported when running with authentication enabled";
log() << errmsg << std::endl;
return false;
}
};
class CmdShutdown : public Command {
public:
virtual bool requiresAuth() { return true; }

View File

@@ -80,8 +80,8 @@ namespace mongo {
extern string repairpath;
static void setupSignalHandlers();
static void startInterruptThread();
void startReplication();
static void startSignalProcessingThread();
void exitCleanly( ExitCode code );
#ifdef _WIN32
@@ -1280,9 +1280,9 @@ static int mongoDbMain(int argc, char* argv[], char **envp) {
if (!initializeServerGlobalState())
::_exit(EXIT_FAILURE);
// Per SERVER-7434, startInterruptThread() must run after any forks
// Per SERVER-7434, startSignalProcessingThread() must run after any forks
// (initializeServerGlobalState()) and before creation of any other threads.
startInterruptThread();
startSignalProcessingThread();
dataFileSync.go();
@@ -1350,15 +1350,27 @@ namespace mongo {
}
sigset_t asyncSignals;
// The above signals will be processed by this thread only, in order to
// The signals in asyncSignals will be processed by this thread only, in order to
// ensure the db and log mutexes aren't held.
void interruptThread() {
int actualSignal;
sigwait( &asyncSignals, &actualSignal );
log() << "got signal " << actualSignal << " (" << strsignal( actualSignal )
<< "), will terminate after current cmd ends" << endl;
Client::initThread( "interruptThread" );
exitCleanly( EXIT_CLEAN );
void signalProcessingThread() {
while (true) {
int actualSignal = 0;
int status = sigwait( &asyncSignals, &actualSignal );
fassert(16781, status == 0);
switch (actualSignal) {
case SIGUSR1:
// log rotate signal
fassert(16782, rotateLogs());
break;
default:
// interrupt/terminate signal
Client::initThread( "signalProcessingThread" );
log() << "got signal " << actualSignal << " (" << strsignal( actualSignal )
<< "), will terminate after current cmd ends" << endl;
exitCleanly( EXIT_CLEAN );
break;
}
}
}
// this will be called in certain c++ error cases, for example if there are two active
@@ -1399,19 +1411,20 @@ namespace mongo {
setupSIGTRAPforGDB();
// asyncSignals is a global variable listing the signals that should be handled by the
// interrupt thread, once it is started via startInterruptThread().
// interrupt thread, once it is started via startSignalProcessingThread().
sigemptyset( &asyncSignals );
sigaddset( &asyncSignals, SIGHUP );
sigaddset( &asyncSignals, SIGINT );
sigaddset( &asyncSignals, SIGTERM );
sigaddset( &asyncSignals, SIGUSR1 );
set_terminate( myterminate );
set_new_handler( my_new_handler );
}
void startInterruptThread() {
void startSignalProcessingThread() {
verify( pthread_sigmask( SIG_SETMASK, &asyncSignals, 0 ) == 0 );
boost::thread it( interruptThread );
boost::thread it( signalProcessingThread );
}
#else // WIN32
@@ -1486,7 +1499,7 @@ namespace mongo {
_set_purecall_handler( myPurecallHandler );
}
void startInterruptThread() {}
void startSignalProcessingThread() {}
#endif // if !defined(_WIN32)

View File

@@ -230,8 +230,7 @@ namespace mongo {
out->push_back(Privilege(AuthorizationManager::SERVER_RESOURCE_NAME, actions));
}
virtual bool run(const string& ns, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
fassert(16175, rotateLogs());
return 1;
return rotateLogs();
}
} logRotateCmd;

View File

@@ -39,7 +39,7 @@ namespace mongo {
bool inNegation = false;
bool inPhrase = false;
str::stream phrase;
unsigned quoteOffset = 0;
Tokenizer i( _language, query );
while ( i.more() ) {
@@ -48,12 +48,6 @@ namespace mongo {
if ( t.type == Token::TEXT ) {
string s = t.data.toString();
if ( inPhrase ) {
if ( phrase.ss.len() > 0 )
phrase << ' ';
phrase << s;
}
if ( inPhrase && inNegation ) {
// don't add term
}
@@ -73,6 +67,10 @@ namespace mongo {
else if ( c == '"' ) {
if ( inPhrase ) {
// end of a phrase
unsigned phraseStart = quoteOffset + 1;
unsigned phraseLength = t.offset - phraseStart;
StringData phrase = StringData( query ).substr( phraseStart,
phraseLength );
if ( inNegation )
_negatedPhrases.push_back( tolowerString( phrase ) );
else
@@ -83,7 +81,7 @@ namespace mongo {
else {
// start of a phrase
inPhrase = true;
phrase.ss.reset();
quoteOffset = t.offset;
}
}
}

View File

@@ -57,6 +57,13 @@ namespace mongo {
ASSERT_EQUALS( "fun|phrase|test||||phrase test||", q.debugString() );
}
TEST( FTSQuery, Phrase2 ) {
FTSQuery q;
ASSERT( q.parse( "doing a \"phrase-test\" for fun", "english" ).isOK() );
ASSERT_EQUALS( 1U, q.getPhr().size() );
ASSERT_EQUALS( "phrase-test", q.getPhr()[0] );
}
TEST( FTSQuery, NegPhrase1 ) {
FTSQuery q;
ASSERT( q.parse( "doing a -\"phrase test\" for fun", "english" ).isOK() );

View File

@@ -193,14 +193,10 @@ namespace mongo {
static void ignoreSignal( int sig ) {}
static void rotateLogsOrDie(int sig) {
fassert(16176, rotateLogs());
}
void setupCoreSignals() {
#if !defined(_WIN32)
verify( signal(SIGUSR1 , rotateLogsOrDie ) != SIG_ERR );
verify( signal(SIGHUP , ignoreSignal ) != SIG_ERR );
verify( signal(SIGUSR2, ignoreSignal ) != SIG_ERR );
#endif
}

View File

@@ -857,6 +857,9 @@ namespace replset {
}
try {
// haveCursor() does not necessarily tell us if we have a non-dead cursor, so we check
// tailCheck() as well; see SERVER-8420
slave->reader.tailCheck();
if (!slave->reader.haveCursor()) {
if (!slave->reader.connect(id, slave->slave->id(), target->fullName())) {
// error message logged in OplogReader::connect

View File

@@ -522,12 +522,18 @@ namespace mongo {
class CopyDBCmd : public PublicGridCommand {
public:
CopyDBCmd() : PublicGridCommand( "copydb" ) {}
virtual bool adminOnly() const {
return true;
}
virtual void addRequiredPrivileges(const std::string& dbname,
const BSONObj& cmdObj,
std::vector<Privilege>* out) {
// Should never get here because this command shouldn't get registered when auth is
// enabled
verify(0);
// Note: privileges required are currently only granted to old-style users for
// backwards compatibility, since we can't properly handle auth checking for the
// read from the source DB.
ActionSet actions;
actions.addAction(ActionType::copyDBTarget);
out->push_back(Privilege(dbname, actions)); // NOTE: dbname is always admin
}
bool run(const string& dbName, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool) {
string todb = cmdObj.getStringField("todb");
@@ -562,12 +568,9 @@ namespace mongo {
}
};
MONGO_INITIALIZER(RegisterCopyDBCommand)(InitializerContext* context) {
if (noauth) {
// Leaked intentionally: a Command registers itself when constructed.
new CopyDBCmd();
} else {
new NotWithAuthCmd("copydb");
}
// Leaked intentionally: a Command registers itself when constructed.
// NOTE: this initializer block cannot be removed due to SERVER-9167
new CopyDBCmd();
return Status::OK();
}

View File

@@ -163,6 +163,33 @@ namespace mongo {
::_exit(EXIT_ABRUPT);
}
#ifndef _WIN32
sigset_t asyncSignals;
void signalProcessingThread() {
while (true) {
int actualSignal = 0;
int status = sigwait( &asyncSignals, &actualSignal );
fassert(16779, status == 0);
switch (actualSignal) {
case SIGUSR1:
// log rotate signal
fassert(16780, rotateLogs());
break;
default:
// no one else should be here
fassertFailed(16778);
break;
}
}
}
void startSignalProcessingThread() {
verify( pthread_sigmask( SIG_SETMASK, &asyncSignals, 0 ) == 0 );
boost::thread it( signalProcessingThread );
}
#endif // not _WIN32
void setupSignalHandlers() {
setupSIGTRAPforGDB();
setupCoreSignals();
@@ -183,6 +210,12 @@ namespace mongo {
signal( SIGPIPE , SIG_IGN );
#endif
#ifndef _WIN32
sigemptyset( &asyncSignals );
sigaddset( &asyncSignals, SIGUSR1 );
startSignalProcessingThread();
#endif
setWindowsUnhandledExceptionFilter();
set_new_handler( my_new_handler );
}

View File

@@ -80,7 +80,7 @@ namespace mongo {
string key = toSTLString(name);
BSONHolder* holder = unwrapHolder(info.Holder());
if (holder->_removed.count(key))
if (!holder || holder->_removed.count(key))
return handle_scope.Close(v8::Handle<v8::Value>());
BSONObj obj = holder->_obj;
@@ -100,7 +100,7 @@ namespace mongo {
if (elmt.type() == mongo::Object || elmt.type() == mongo::Array) {
// if accessing a subobject, it may get modified and base obj would not know
// have to set base as modified, which means some optim is lost
unwrapHolder(info.Holder())->_modified = true;
holder->_modified = true;
}
}
catch (const DBException &dbEx) {
@@ -143,6 +143,7 @@ namespace mongo {
const v8::AccessorInfo& info) {
string key = toSTLString(name);
BSONHolder* holder = unwrapHolder(info.Holder());
if (!holder) return v8::Handle<v8::Value>();
holder->_removed.erase(key);
holder->_modified = true;
@@ -154,6 +155,7 @@ namespace mongo {
static v8::Handle<v8::Array> namedEnumerator(const v8::AccessorInfo &info) {
v8::HandleScope handle_scope;
BSONHolder* holder = unwrapHolder(info.Holder());
if (!holder) return v8::Handle<v8::Array>();
BSONObj obj = holder->_obj;
v8::Handle<v8::Array> out = v8::Array::New();
int outIndex = 0;
@@ -191,6 +193,7 @@ namespace mongo {
v8::HandleScope handle_scope;
string key = toSTLString(name);
BSONHolder* holder = unwrapHolder(info.Holder());
if (!holder) return v8::Handle<v8::Boolean>();
holder->_removed.insert(key);
holder->_modified = true;
@@ -213,6 +216,7 @@ namespace mongo {
V8Scope* scope = (V8Scope*)(scp->Value());
BSONHolder* holder = unwrapHolder(info.Holder());
if (!holder) return v8::Handle<v8::Value>();
if (holder->_removed.count(key))
return handle_scope.Close(v8::Handle<v8::Value>());
@@ -226,7 +230,7 @@ namespace mongo {
if (elmt.type() == mongo::Object || elmt.type() == mongo::Array) {
// if accessing a subobject, it may get modified and base obj would not know
// have to set base as modified, which means some optim is lost
unwrapHolder(info.Holder())->_modified = true;
holder->_modified = true;
}
}
catch (const DBException &dbEx) {
@@ -242,6 +246,7 @@ namespace mongo {
v8::Handle<v8::Boolean> indexedDelete(uint32_t index, const v8::AccessorInfo& info) {
string key = str::stream() << index;
BSONHolder* holder = unwrapHolder(info.Holder());
if (!holder) return v8::Handle<v8::Boolean>();
holder->_removed.insert(key);
holder->_modified = true;
@@ -285,6 +290,7 @@ namespace mongo {
const v8::AccessorInfo& info) {
string key = str::stream() << index;
BSONHolder* holder = unwrapHolder(info.Holder());
if (!holder) return v8::Handle<v8::Value>();
holder->_removed.erase(key);
holder->_modified = true;
@@ -1648,15 +1654,18 @@ namespace mongo {
if (o->Has(v8::String::New("_bson"))) {
originalBSON = unwrapBSONObj(o);
BSONHolder* holder = unwrapHolder(o);
if (!holder->_modified) {
if (holder && !holder->_modified) {
// object was not modified, use bson as is
return originalBSON;
}
}
BSONObjBuilder b;
// We special case the _id field in top-level objects and move it to the front.
// This matches other drivers behavior and makes finding the _id field quicker in BSON.
if (depth == 0) {
if (o->HasRealNamedProperty(v8::String::New("_id"))) {
if (o->HasOwnProperty(v8::String::New("_id"))) {
v8ToMongoElement(b, "_id", o->Get(v8::String::New("_id")), 0, &originalBSON);
}
}
@@ -1667,7 +1676,7 @@ namespace mongo {
v8::Local<v8::Value> value = o->Get(name);
const string sname = toSTLString(name);
if (depth == 0 && sname == "_id")
continue;
continue; // already handled above
v8ToMongoElement(b, sname, value, depth + 1, &originalBSON);
}

View File

@@ -141,7 +141,7 @@ namespace mongo {
bool rotate() {
if ( ! _enabled ) {
cout << "LoggingManager not enabled" << endl;
cout << "logRotate is not possible: loggingManager not enabled" << endl;
return true;
}
@@ -156,7 +156,7 @@ namespace mongo {
ss << _path << "." << terseCurrentTime( false );
string s = ss.str();
if (0 != rename(_path.c_str(), s.c_str())) {
error() << "Failed to rename '" << _path
error() << "failed to rename '" << _path
<< "' to '" << s
<< "': " << errnoWithDescription() << endl;
return false;
@@ -187,7 +187,7 @@ namespace mongo {
tmp = freopen(_path.c_str(), _append ? "a" : "w", stdout);
#endif
if ( !tmp ) {
cerr << "can't open: " << _path.c_str() << " for log file" << endl;
error() << "can't open: " << _path.c_str() << " for log file" << endl;
return false;
}

View File

@@ -150,6 +150,15 @@ namespace mongo {
// Note: this is for blocking sockets only.
SSL_CTX_set_mode(_context, SSL_MODE_AUTO_RETRY);
// Set context within which session can be reused
int status = SSL_CTX_set_session_id_context(
_context,
static_cast<unsigned char*>(static_cast<void*>(&_context)),
sizeof(_context));
if (!status) {
uasserted(16768,"ssl initialization problem");
}
SSLThreadInfo::init();
SSLThreadInfo::get();

View File

@@ -33,7 +33,7 @@ namespace mongo {
void joinStringDelim( const std::vector<std::string>& strs , std::string* res , char delim );
inline std::string tolowerString( const std::string& input ) {
inline std::string tolowerString( StringData input ) {
std::string::size_type sz = input.size();
boost::scoped_array<char> line(new char[sz+1]);

View File

@@ -47,7 +47,7 @@ namespace mongo {
* 1.2.3-rc4-pre-
* If you really need to do something else you'll need to fix _versionArray()
*/
const char versionString[] = "2.4.2";
const char versionString[] = "2.4.4-pre-";
// See unit test for example outputs
BSONArray toVersionArray(const char* version){