Beispiel #1
0
void killOps() {
    if ( mongo::shellUtils::_nokillop || mongo::shellUtils::_allMyUris.size() == 0 )
        return;

    if ( atPrompt )
        return;

    sleepmillis(10); // give current op a chance to finish

    for( map< string, set<string> >::const_iterator i = shellUtils::_allMyUris.begin(); i != shellUtils::_allMyUris.end(); ++i ) {
        string errmsg;
        ConnectionString cs = ConnectionString::parse( i->first, errmsg );
        if (!cs.isValid()) continue;
        boost::scoped_ptr<DBClientWithCommands> conn( cs.connect( errmsg ) );
        if (!conn) continue;

        const set<string>& uris = i->second;

        BSONObj inprog =  conn->findOne( "admin.$cmd.sys.inprog", Query() )["inprog"].embeddedObject().getOwned();
        BSONForEach( op, inprog ) {
            if ( uris.count( op["client"].String() ) ) {
                ONCE if ( !autoKillOp ) {
                    cout << endl << "do you want to kill the current op(s) on the server? (y/n): ";
                    cout.flush();

                    char yn;
                    cin >> yn;

                    if ( yn != 'y' && yn != 'Y' )
                        return;
                }

                conn->findOne( "admin.$cmd.sys.killop", QUERY( "op"<< op["opid"] ) );
            }
        }
Beispiel #2
0
	inline boost::shared_ptr<DBClientBase> mongo_init(){
		mongo::client::GlobalInstance instance;
		if (!instance.initialized()) {
			std::cout << "failed to initialize the client driver: " << instance.status() << std::endl;
			return NULL;
		}

		std::string uri = "mongodb://localhost:27017";
		std::string errmsg;

		ConnectionString cs = ConnectionString::parse(uri, errmsg);

		if (!cs.isValid()) {
			std::cout << "Error parsing connection string " << uri << ": " << errmsg << std::endl;
			return NULL;
		}

		boost::shared_ptr<DBClientBase> conn(cs.connect(errmsg));
		if (!conn) {
			std::cout << "couldn't connect : " << errmsg << std::endl;
			return NULL;
		}


		{
			// clean up old data from any previous tests
			BSONObjBuilder query;
			conn->remove("test.people", query.obj());
		}

		//insert(conn.get(), "eliot", 15);
		//insert(conn.get(), "sara", 23);

		return conn;
	}
void StartChunkCloneRequest::appendAsCommand(
    BSONObjBuilder* builder,
    const NamespaceString& nss,
    const MigrationSessionId& sessionId,
    const ConnectionString& configServerConnectionString,
    const ConnectionString& fromShardConnectionString,
    const ShardId& fromShardId,
    const ShardId& toShardId,
    const BSONObj& chunkMinKey,
    const BSONObj& chunkMaxKey,
    const BSONObj& shardKeyPattern,
    const MigrationSecondaryThrottleOptions& secondaryThrottle) {
    invariant(builder->asTempObj().isEmpty());
    invariant(nss.isValid());
    invariant(fromShardConnectionString.isValid());

    builder->append(kRecvChunkStart, nss.ns());
    sessionId.append(builder);
    builder->append(kConfigServerConnectionString, configServerConnectionString.toString());
    builder->append(kFromShardConnectionString, fromShardConnectionString.toString());
    builder->append(kFromShardId, fromShardId.toString());
    builder->append(kToShardId, toShardId.toString());
    builder->append(kChunkMinKey, chunkMinKey);
    builder->append(kChunkMaxKey, chunkMaxKey);
    builder->append(kShardKeyPattern, shardKeyPattern);
    secondaryThrottle.append(builder);
}
Beispiel #4
0
 void ConnectionRegistry::killOperationsOnAllConnections( bool withPrompt ) const {
     Prompter prompter( "do you want to kill the current op(s) on the server?" );
     mongo::mutex::scoped_lock lk( _mutex );
     for( map<string,set<string> >::const_iterator i = _connectionUris.begin();
         i != _connectionUris.end(); ++i ) {
         string errmsg;
         ConnectionString cs = ConnectionString::parse( i->first, errmsg );
         if ( !cs.isValid() ) {
             continue;   
         }
         boost::scoped_ptr<DBClientWithCommands> conn( cs.connect( errmsg ) );
         if ( !conn ) {
             continue;
         }
         
         const set<string>& uris = i->second;
         
         BSONObj inprog = conn->findOne( "admin.$cmd.sys.inprog", Query() )[ "inprog" ]
                 .embeddedObject().getOwned();
         BSONForEach( op, inprog ) {
             if ( uris.count( op[ "client" ].String() ) ) {
                 if ( !withPrompt || prompter.confirm() ) {
                     conn->findOne( "admin.$cmd.sys.killop", QUERY( "op"<< op[ "opid" ] ) );                        
                 }
                 else {
                     return;
                 }
             }
         }
     }
 }
Beispiel #5
0
switch_status_t mongo_connection_create(DBClientBase **connection, const char *conn_str)
{
  DBClientBase *conn = NULL;
  string conn_string(conn_str), err_msg;
  ConnectionString cs = ConnectionString::parse(conn_string, err_msg);
  switch_status_t status = SWITCH_STATUS_FALSE;
 
  if (!cs.isValid()) {
    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't parse url: %s\n", err_msg.c_str());
    return status;
  }

  try {
    conn = cs.connect(err_msg);
  } catch (DBException &e) {
    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't connect to mongo [%s]: %s\n", conn_str, err_msg.c_str());
    return status;
  }

  if (conn) {
    *connection = conn;
    status = SWITCH_STATUS_SUCCESS;
    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected to mongo [%s]\n", conn_str);
  }

  return status;
}
    virtual bool run(OperationContext* txn,
                     const string&,
                     BSONObj& cmdObj,
                     int,
                     string& errmsg,
                     BSONObjBuilder& result,
                     bool fromRepl) {
        string fromhost = cmdObj.getStringField("fromhost");
        if (fromhost.empty()) {
            /* copy from self */
            stringstream ss;
            ss << "localhost:" << serverGlobalParams.port;
            fromhost = ss.str();
        }

        BSONObj ret;

        ConnectionString cs = ConnectionString::parse(fromhost, errmsg);
        if (!cs.isValid()) {
            return false;
        }

        authConn_.reset(cs.connect(errmsg));
        if (!authConn_.get()) {
            return false;
        }

        if (!authConn_->runCommand("admin", BSON("getnonce" << 1), ret)) {
            errmsg = "couldn't get nonce " + ret.toString();
            return false;
        }

        result.appendElements(ret);
        return true;
    }
int main(int argc, char* argv[]) {
    if (argc > 2) {
        std::cout << "usage: " << argv[0] << " [MONGODB_URI]" << std::endl;
        return EXIT_FAILURE;
    }

    mongo::client::GlobalInstance instance;
    if (!instance.initialized()) {
        std::cout << "failed to initialize the client driver: " << instance.status() << std::endl;
        return EXIT_FAILURE;
    }

    std::string uri = argc == 2 ? argv[1] : "mongodb://localhost:27017";
    std::string errmsg;

    ConnectionString cs = ConnectionString::parse(uri, errmsg);

    if (!cs.isValid()) {
        std::cout << "Error parsing connection string " << uri << ": " << errmsg << std::endl;
        return EXIT_FAILURE;
    }

    boost::scoped_ptr<DBClientBase> conn(cs.connect(errmsg));
    if (!conn) {
        cout << "couldn't connect : " << errmsg << endl;
        return EXIT_FAILURE;
    }

    try {
        unsigned long long count = conn->count("test.foo");
        cout << "count of exiting documents in collection test.foo : " << count << endl;

        conn->remove("test.foo", BSONObj());

        BSONObj o = BSON("hello"
                         << "world");
        conn->insert("test.foo", o);

        string e = conn->getLastError();
        if (!e.empty()) {
            cout << "insert #1 failed: " << e << endl;
        }

        // make an index with a unique key constraint
        conn->createIndex("test.foo", IndexSpec().addKeys(BSON("hello" << 1)).unique());

        try {
            conn->insert("test.foo", o);  // will cause a dup key error on "hello" field
        } catch (const OperationException&) {
            // duplicate key error
        }
        cout << "we expect a dup key error here:" << endl;
        cout << "  " << conn->getLastErrorDetailed().toString() << endl;
    } catch (DBException& e) {
        cout << "caught DBException " << e.toString() << endl;
        return 1;
    }

    return 0;
}
DBClientBase* MongoConnectionPool::get(const std::string& host) {
	std::string errMsg;
	ConnectionString cs = ConnectionString::parse(host, errMsg);
	if(cs.isValid()) {
		return get(cs);
	}
	return 0;
}
int main(int argc, char* argv[]) {

    if ( argc > 2 ) {
        std::cout << "usage: " << argv[0] << " [MONGODB_URI]"  << std::endl;
        return EXIT_FAILURE;
    }

    mongo::client::GlobalInstance instance;
    if (!instance.initialized()) {
        std::cout << "failed to initialize the client driver: " << instance.status() << std::endl;
        return EXIT_FAILURE;
    }

    std::string uri = argc == 2 ? argv[1] : "mongodb://localhost:27017";
    std::string errmsg;

    ConnectionString cs = ConnectionString::parse(uri, errmsg);

    if (!cs.isValid()) {
        std::cout << "Error parsing connection string " << uri << ": " << errmsg << std::endl;
        return EXIT_FAILURE;
    }

    boost::scoped_ptr<DBClientBase> conn(cs.connect(errmsg));
    if ( !conn ) {
        std::cout << "couldn't connect : " << errmsg << std::endl;
        return EXIT_FAILURE;
    }
    conn->dropCollection("test.test");

    // Don't run on MongoDB < 2.2
    BSONObj cmdResult;
    conn->runCommand("admin", BSON("buildinfo" << true), cmdResult);
    std::vector<BSONElement> versionArray = cmdResult["versionArray"].Array();
    if (versionArray[0].Int() < 2 || versionArray[1].Int() < 2)
        return EXIT_SUCCESS;

    conn->insert("test.test", BSON("x" << 0));
    conn->insert("test.test", BSON("x" << 1));
    conn->insert("test.test", BSON("x" << 1));
    conn->insert("test.test", BSON("x" << 2));
    conn->insert("test.test", BSON("x" << 2));
    conn->insert("test.test", BSON("x" << 2));

    std::auto_ptr<DBClientCursor> cursor = conn->aggregate("test.test",
                                           BSON_ARRAY(
                                                   BSON("$match" << BSON("x" << GT << 0)) <<
                                                   BSON("$group" << BSON("_id" << "$x" << "count" << BSON("$sum" << 1)))
                                           )
                                                          );

    std::cout << "------- AGGREGATION -------" << std::endl;
    while (cursor->more()) {
        std::cout << cursor->next() << std::endl;
    }

    return EXIT_SUCCESS;
}
Beispiel #10
0
int main(int argc, char* argv[]) {

    if ( argc > 2 ) {
        std::cout << "usage: " << argv[0] << " [MONGODB_URI]"  << std::endl;
        return EXIT_FAILURE;
    }

    mongo::client::GlobalInstance instance;
    if (!instance.initialized()) {
        std::cout << "failed to initialize the client driver: " << instance.status() << std::endl;
        return EXIT_FAILURE;
    }

    std::string uri = argc == 2 ? argv[1] : "mongodb://localhost:27017";
    std::string errmsg;

    ConnectionString cs = ConnectionString::parse(uri, errmsg);

    if (!cs.isValid()) {
        std::cout << "Error parsing connection string " << uri << ": " << errmsg << std::endl;
        return EXIT_FAILURE;
    }

    boost::scoped_ptr<DBClientBase> conn(cs.connect(errmsg));
    if ( !conn ) {
        cout << "couldn't connect : " << errmsg << endl;
        return EXIT_FAILURE;
    }

    try {
        BSONObj o = BSON( "hello" << "world" );

        cout << "dropping collection..." << endl;
        conn->dropCollection("test.foo");

        cout << "inserting..." << endl;

        time_t start = time(0);
        for( unsigned i = 0; i < 100000; i++ ) {
            conn->insert("test.foo", o);
        }

        // wait until all operations applied
        cout << "getlasterror returns: \"" << conn->getLastError() << '"' << endl;

        time_t done = time(0);
        time_t dt = done-start;
        cout << dt << " seconds " << 100000/dt << " per second" << endl;
    }
    catch(DBException& e) {
        cout << "caught DBException " << e.toString() << endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}
Beispiel #11
0
int main( int argc, const char **argv ) {

    const char *port = "27017";
    if ( argc != 1 ) {
        if ( argc != 3 ) {
            std::cout << "need to pass port as second param" << endl;
            return EXIT_FAILURE;
        }
        port = argv[ 2 ];
    }

    std::string errmsg;
    ConnectionString cs = ConnectionString::parse(string("127.0.0.1:") + port, errmsg);
    if (!cs.isValid()) {
        cout << "error parsing url: " << errmsg << endl;
        return EXIT_FAILURE;
    }

    boost::scoped_ptr<DBClientBase> conn(cs.connect(errmsg));
    if (!conn) {
        cout << "couldn't connect: " << errmsg << endl;
        return EXIT_FAILURE;
    }

    BSONObj ret;
    // clean up old data from any previous tests
    conn->runCommand( "test", BSON("removeUsersFromDatabase" << 1), ret );

    conn->runCommand( "test",
                      BSON( "createUser" << "eliot" <<
                            "pwd" << "bar" <<
                            "roles" << BSON_ARRAY("readWrite")),
                      ret);

    errmsg.clear();
    conn->auth(BSON("user" << "eliot" <<
                    "db" << "test" <<
                    "pwd" << "bar" <<
                    "mechanism" << "MONGODB-CR"));

    try {
        conn->auth(BSON("user" << "eliot" <<
                        "db" << "test" <<
                        "pwd" << "bars" << // incorrect password
                        "mechanism" << "MONGODB-CR"));
        // Shouldn't get here.
        cout << "Authentication with invalid password should have failed but didn't" << endl;
        return EXIT_FAILURE;
    } catch (const DBException& e) {
        // expected
    }
    return EXIT_SUCCESS;
}
    virtual bool run(OperationContext* txn,
                     const string&,
                     BSONObj& cmdObj,
                     int,
                     string& errmsg,
                     BSONObjBuilder& result,
                     bool fromRepl) {
        string fromDb = cmdObj.getStringField("fromdb");
        string fromHost = cmdObj.getStringField("fromhost");
        if (fromHost.empty()) {
            /* copy from self */
            stringstream ss;
            ss << "localhost:" << serverGlobalParams.port;
            fromHost = ss.str();
        }

        ConnectionString cs = ConnectionString::parse(fromHost, errmsg);
        if (!cs.isValid()) {
            appendCommandStatus(result, false, errmsg);
            return false;
        }

        BSONElement mechanismElement;
        Status status = bsonExtractField(cmdObj, saslCommandMechanismFieldName, &mechanismElement);
        if (!status.isOK()) {
            return appendCommandStatus(result, status);
        }

        BSONElement payloadElement;
        status = bsonExtractField(cmdObj, saslCommandPayloadFieldName, &payloadElement);
        if (!status.isOK()) {
            log() << "Failed to extract payload: " << status;
            return false;
        }

        authConn_.reset(cs.connect(errmsg));
        if (!authConn_.get()) {
            return false;
        }

        BSONObj ret;
        if (!authConn_->runCommand(
                fromDb, BSON("saslStart" << 1 << mechanismElement << payloadElement), ret)) {
            return appendCommandStatus(result, Command::getStatusFromCommandResult(ret));
        }

        result.appendElements(ret);
        return true;
    }
Beispiel #13
0
 DBClientBase* DBConnectionPool::get(const string& host) {
     DBClientBase * c = _get( host );
     if ( c ){
         onHandedOut( c );
         return c;
     }
     
     string errmsg;
     ConnectionString cs = ConnectionString::parse( host , errmsg );
     uassert( 13071 , (string)"invalid hostname [" + host + "]" + errmsg , cs.isValid() );
     
     c = cs.connect( errmsg );
     uassert( 11002 ,  _name + ": connect failed " + host + " : " + errmsg , c );
     return _finishCreate( host , c );
 }
Beispiel #14
0
    DBClientBase* DBConnectionPool::get(const string& host) {
        DBClientBase * c = _get( host );
        if ( c ) {
            onHandedOut( c );
            return c;
        }

        string errmsg;
        ConnectionString cs = ConnectionString::parse( host , errmsg );
        uassert( 13071 , (string)"invalid hostname [" + host + "]" + errmsg , cs.isValid() );

        c = cs.connect( errmsg );
        if ( ! c )
            throw SocketException( SocketException::CONNECT_ERROR , host , 11002 , str::stream() << _name << " error: " << errmsg );
        return _finishCreate( host , c );
    }
Beispiel #15
0
int main( int argc , const char ** argv ) {
    
    unsigned nThreads = 1;
    bool print = false;

    for ( int i=1; i<argc; i++ ) {
        if ( mongoutils::str::equals( "--threads" , argv[i] ) ) {
            nThreads = atoi( argv[++i] );
        }
        else if ( mongoutils::str::equals( "--print" , argv[1] ) ) {
            print = true;
        }
        else {
            cerr << "unknown option: " << argv[i] << endl;
            return 1;
        }
            
    }

    string errmsg;
    ConnectionString cs = ConnectionString::parse( "foo/127.0.0.1" , errmsg );
    if ( ! cs.isValid() ) {
        cout << "error parsing url: " << errmsg << endl;
        return 1;
    }

    DBClientReplicaSet * conn = (DBClientReplicaSet*)cs.connect( errmsg );
    if ( ! conn ) {
        cout << "error connecting: " << errmsg << endl;
        return 2;
    }

    string collName = "test.rs1";

    conn->dropCollection( collName );
    
    vector<boost::shared_ptr<boost::thread> > threads;
    for ( unsigned i=0; i<nThreads; i++ ) {
        string errmsg;
        threads.push_back( boost::shared_ptr<boost::thread>( new boost::thread( boost::bind( workerThread , collName , print , (DBClientReplicaSet*)cs.connect(errmsg) ) ) ) );
    }
    
    for ( unsigned i=0; i<threads.size(); i++ ) {
        threads[i]->join();
    }

}
int main( int argc, const char **argv ) {

    if ( argc > 2 ) {
        std::cout << "usage: " << argv[0] << " [MONGODB_URI]"  << std::endl;
        return EXIT_FAILURE;
    }

    client::GlobalInstance instance;
    if (!instance.initialized()) {
        std::cout << "failed to initialize the client driver: " << instance.status() << std::endl;
        return EXIT_FAILURE;
    }

    std::string uri = argc == 2 ? argv[1] : "mongodb://localhost:27017";
    std::string errmsg;

    ConnectionString cs = ConnectionString::parse(uri, errmsg);

    if (!cs.isValid()) {
        std::cout << "Error parsing connection string " << uri << ": " << errmsg << std::endl;
        return EXIT_FAILURE;
    }

    boost::scoped_ptr<DBClientBase> conn(cs.connect(errmsg));
    if ( !conn ) {
        cout << "couldn't connect : " << errmsg << endl;
        return EXIT_FAILURE;
    }

    try {
        BSONObj cmdResult;
        conn->runCommand("admin", BSON("buildinfo" << true), cmdResult);
        if (cmdResult["versionArray"].Array()[1].Int() < 6)
            return EXIT_SUCCESS;

        insertGeoData(conn.get());
        queryGeoData(conn.get());
        conn->dropCollection(kDbCollectionName);
    }
    catch(const DBException& dbe) {
        cout << "caught DBException " << dbe.toString() << endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}
Beispiel #17
0
int main() {
    try {
        DBClientBase *conn = NULL;
        string err_msg;
        ConnectionString cs = ConnectionString::parse("localhost", err_msg);
        
        if (!cs.isValid()) {
            throw "bad: " + err_msg;
        }
        
        try {
            conn = cs.connect(err_msg);
        } catch (DBException &e) {
            cout << "caught " << err_msg << endl;
            return 1;
        }
        
        if (!conn){
            cout<<"Unable to connect to DB"<<endl;
            return 1;
        }
        
//        BSONObjBuilder b;
//        b.append("name", "Joe");
//        b.append("age", 33);
//        BSONObj p = b.obj();
//        
//        conn->insert("db.coll",p,0);
        
        
        GridFS * fs;
       
        fs = new GridFS(*conn,"test");
        BSONObj p = fs->storeFile("pic.JPG");
        conn->insert("db.coll",p,0);
    }
    catch( DBException &e ) {
        cout << "caught " << e.what() << endl;
    }
    return 0;
}
Beispiel #18
0
        void ConnectionRegistry::killOperationsOnAllConnections( bool withPrompt ) const {
            Prompter prompter( "do you want to kill the current op(s) on the server?" );
            boost::lock_guard<boost::mutex> lk( _mutex );
            for( map<string,set<string> >::const_iterator i = _connectionUris.begin();
                i != _connectionUris.end(); ++i ) {
                string errmsg;
                ConnectionString cs = ConnectionString::parse( i->first, errmsg );
                if ( !cs.isValid() ) {
                    continue;   
                }
                boost::scoped_ptr<DBClientWithCommands> conn( cs.connect( errmsg ) );
                if ( !conn ) {
                    continue;
                }
                
                const set<string>& uris = i->second;

                BSONObj currentOpRes;
                conn->runPseudoCommand("admin",
                                       "currentOp",
                                       "$cmd.sys.inprog", {}, currentOpRes);
                auto inprog = currentOpRes["inprog"].embeddedObject();
                BSONForEach( op, inprog ) {
                    if ( uris.count( op[ "client" ].String() ) ) {
                        if ( !withPrompt || prompter.confirm() ) {
                            BSONObjBuilder cmdBob;
                            BSONObj info;
                            cmdBob.append("op", op["opid"]);
                            auto cmdArgs = cmdBob.done();
                            conn->runPseudoCommand("admin", "killOp", "$cmd.sys.killop",
                                                   cmdArgs, info);
                        }
                        else {
                            return;
                        }
                    }
                }
            }
        }
Beispiel #19
0
int main(int argc, char* argv[]) {

    if ( argc > 2 ) {
        std::cout << "usage: " << argv[0] << " [MONGODB_URI]"  << std::endl;
        return EXIT_FAILURE;
    }

    mongo::client::GlobalInstance instance;
    if (!instance.initialized()) {
        std::cout << "failed to initialize the client driver: " << instance.status() << std::endl;
        return EXIT_FAILURE;
    }

    std::string uri = argc == 2 ? argv[1] : "mongodb://localhost:27017";
    std::string errmsg;

    ConnectionString cs = ConnectionString::parse(uri, errmsg);

    if (!cs.isValid()) {
        std::cout << "Error parsing connection string " << uri << ": " << errmsg << std::endl;
        return EXIT_FAILURE;
    }

    boost::scoped_ptr<DBClientBase> conn(cs.connect(errmsg));
    if ( !conn ) {
        cout << "couldn't connect : " << errmsg << endl;
        return EXIT_FAILURE;
    }

    int ret = EXIT_SUCCESS;
    try {
        ret = run(conn.get());
    }
    catch( DBException &e ) {
        cout << "caught " << e.what() << endl;
        ret = EXIT_FAILURE;
    }
    return ret;
}
Beispiel #20
0
void ShardingState::initialize(const string& server) {
    uassert(18509,
            "Unable to obtain host name during sharding initialization.",
            !getHostName().empty());

    stdx::lock_guard<stdx::mutex> lk(_mutex);

    if (_enabled) {
        // TODO: Do we need to throw exception if the config servers have changed from what we
        // already have in place? How do we test for that?
        return;
    }

    ShardedConnectionInfo::addHook();

    std::string errmsg;
    ConnectionString configServerCS = ConnectionString::parse(server, errmsg);
    uassert(28633,
            str::stream() << "Invalid config server connection string: " << errmsg,
            configServerCS.isValid());

    auto catalogManager = stdx::make_unique<CatalogManagerLegacy>();
    uassertStatusOK(catalogManager->init(configServerCS));

    auto shardRegistry(stdx::make_unique<ShardRegistry>(
        stdx::make_unique<RemoteCommandTargeterFactoryImpl>(),
        stdx::make_unique<repl::ReplicationExecutor>(
            executor::makeNetworkInterface().release(), nullptr, 0),
        nullptr,
        catalogManager.get()));
    shardRegistry->startup();

    grid.init(std::move(catalogManager), std::move(shardRegistry));

    _enabled = true;
}
Beispiel #21
0
static bool runMongosServer( bool doUpgrade ) {
    setThreadName( "mongosMain" );
    printShardingVersionInfo( false );

    // set some global state

    // Add sharding hooks to both connection pools - ShardingConnectionHook includes auth hooks
    pool.addHook( new ShardingConnectionHook( false ) );
    shardConnectionPool.addHook( new ShardingConnectionHook( true ) );

    // Mongos shouldn't lazily kill cursors, otherwise we can end up with extras from migration
    DBClientConnection::setLazyKillCursor( false );

    ReplicaSetMonitor::setConfigChangeHook(
        stdx::bind(&ConfigServer::replicaSetChange, &configServer, stdx::placeholders::_1 , stdx::placeholders::_2));

    if (!configServer.init(mongosGlobalParams.configdbs)) {
        log() << "couldn't resolve config db address" << endl;
        return false;
    }

    if ( ! configServer.ok( true ) ) {
        log() << "configServer connection startup check failed" << endl;
        return false;
    }

    startConfigServerChecker();

    VersionType initVersionInfo;
    VersionType versionInfo;
    string errMsg;
    string configServerURL = configServer.getPrimary().getConnString();
    ConnectionString configServerConnString = ConnectionString::parse(configServerURL, errMsg);
    if (!configServerConnString.isValid()) {
        error() << "Invalid connection string for config servers: " << configServerURL << endl;
        return false;
    }
    bool upgraded = checkAndUpgradeConfigVersion(configServerConnString,
                                                 doUpgrade,
                                                 &initVersionInfo,
                                                 &versionInfo,
                                                 &errMsg);

    if (!upgraded) {
        error() << "error upgrading config database to v" << CURRENT_CONFIG_VERSION
                << causedBy(errMsg) << endl;
        return false;
    }

    if ( doUpgrade ) {
        log() << "Config database is at version v" << CURRENT_CONFIG_VERSION;
        return true;
    }

    configServer.reloadSettings();

    init();

#if !defined(_WIN32)
    mongo::signalForkSuccess();
#endif

    if (serverGlobalParams.isHttpInterfaceEnabled)
        boost::thread web( stdx::bind(&webServerThread,
                                       new NoAdminAccess())); // takes ownership

    Status status = getGlobalAuthorizationManager()->initialize();
    if (!status.isOK()) {
        log() << "Initializing authorization data failed: " << status;
        return false;
    }

    MessageServer::Options opts;
    opts.port = serverGlobalParams.port;
    opts.ipList = serverGlobalParams.bind_ip;
    start(opts);

    // listen() will return when exit code closes its socket.
    dbexit( EXIT_NET_ERROR );
    return true;
}
Beispiel #22
0
    int Tool::main( int argc , char ** argv, char ** envp ) {
        setupSignalHandlers(true);

        static StaticObserver staticObserver;

        mongo::runGlobalInitializersOrDie(argc, argv, envp);

        // hide password from ps output
        for (int i=0; i < (argc-1); ++i) {
            if (!strcmp(argv[i], "-p") || !strcmp(argv[i], "--password")) {
                char* arg = argv[i+1];
                while (*arg) {
                    *arg++ = 'x';
                }
            }
        }

        if (!toolGlobalParams.useDirectClient) {
            if (toolGlobalParams.noconnection) {
                // do nothing
            }
            else {
                string errmsg;

                ConnectionString cs = ConnectionString::parse(toolGlobalParams.connectionString,
                                                              errmsg);
                if ( ! cs.isValid() ) {
                    toolError() << "invalid hostname [" << toolGlobalParams.connectionString << "] "
                              << errmsg << std::endl;
                    ::_exit(-1);
                }

                _conn = cs.connect( errmsg );
                if ( ! _conn ) {
                    toolError() << "couldn't connect to [" << toolGlobalParams.connectionString
                              << "] " << errmsg << std::endl;
                    ::_exit(-1);
                }

                toolInfoOutput() << "connected to: " << toolGlobalParams.connectionString
                                 << std::endl;
            }

        }
        else {
            verify( lastError.get( true ) );

            Client::initThread("tools");
            _conn = new DBDirectClient();
            storageGlobalParams.dbpath = toolGlobalParams.dbpath;
            try {
                acquirePathLock();
            }
            catch ( DBException& ) {
                toolError() << std::endl << "If you are running a mongod on the same "
                             "path you should connect to that instead of direct data "
                              "file access" << std::endl << std::endl;
                dbexit( EXIT_FS );
                ::_exit(EXIT_FAILURE);
            }

            FileAllocator::get()->start();

            dur::startup();
        }

        int ret = -1;
        try {
            if (!toolGlobalParams.useDirectClient && !toolGlobalParams.noconnection)
                auth();
            ret = run();
        }
        catch ( DBException& e ) {
            toolError() << "assertion: " << e.toString() << std::endl;
            ret = -1;
        }
        catch(const boost::filesystem::filesystem_error &fse) {
            /*
              https://jira.mongodb.org/browse/SERVER-2904

              Simple tools that don't access the database, such as
              bsondump, aren't throwing DBExceptions, but are throwing
              boost exceptions.

              The currently available set of error codes don't seem to match
              boost documentation.  boost::filesystem::not_found_error
              (from http://www.boost.org/doc/libs/1_31_0/libs/filesystem/doc/exception.htm)
              doesn't seem to exist in our headers.  Also, fse.code() isn't
              boost::system::errc::no_such_file_or_directory when this
              happens, as you would expect.  And, determined from
              experimentation that the command-line argument gets turned into
              "\\?" instead of "/?" !!!
             */
#if defined(_WIN32)
            if (/*(fse.code() == boost::system::errc::no_such_file_or_directory) &&*/
                (fse.path1() == "\\?"))
                printHelp(cerr);
            else
#endif // _WIN32
                toolError() << "error: " << fse.what() << std::endl;

            ret = -1;
        }

        if ( currentClient.get() )
            currentClient.get()->shutdown();

        if (toolGlobalParams.useDirectClient)
            dbexit( EXIT_CLEAN );

        fflush(stdout);
        fflush(stderr);
        ::_exit(ret);
    }
Beispiel #23
0
        virtual bool run(OperationContext* txn,
                         const string& dbname,
                         BSONObj& cmdObj,
                         int,
                         string& errmsg,
                         BSONObjBuilder& result,
                         bool fromRepl) {

            string fromhost = cmdObj.getStringField("fromhost");
            bool fromSelf = fromhost.empty();
            if ( fromSelf ) {
                /* copy from self */
                stringstream ss;
                ss << "localhost:" << serverGlobalParams.port;
                fromhost = ss.str();
            }

            CloneOptions cloneOptions;
            cloneOptions.fromDB = cmdObj.getStringField("fromdb");
            cloneOptions.logForRepl = !fromRepl;
            cloneOptions.slaveOk = cmdObj["slaveOk"].trueValue();
            cloneOptions.useReplAuth = false;
            cloneOptions.snapshot = true;
            cloneOptions.mayYield = true;
            cloneOptions.mayBeInterrupted = false;

            string todb = cmdObj.getStringField("todb");
            if ( fromhost.empty() || todb.empty() || cloneOptions.fromDB.empty() ) {
                errmsg = "params missing - {copydb: 1, fromhost: <connection string>, "
                         "fromdb: <db>, todb: <db>}";
                return false;
            }

            if ( !NamespaceString::validDBName( todb ) ) {
                errmsg = "invalid todb name: " + todb;
                return false;
            }

            Cloner cloner;

            // Get MONGODB-CR parameters
            string username = cmdObj.getStringField( "username" );
            string nonce = cmdObj.getStringField( "nonce" );
            string key = cmdObj.getStringField( "key" );

            if ( !username.empty() && !nonce.empty() && !key.empty() ) {
                uassert( 13008, "must call copydbgetnonce first", authConn_.get() );
                BSONObj ret;
                {
                    if ( !authConn_->runCommand( cloneOptions.fromDB,
                                                 BSON( "authenticate" << 1 << "user" << username
                                                       << "nonce" << nonce << "key" << key ), ret ) ) {
                        errmsg = "unable to login " + ret.toString();
                        return false;
                    }
                }
                cloner.setConnection( authConn_.release() );
            }
            else if (cmdObj.hasField(saslCommandConversationIdFieldName) &&
                     cmdObj.hasField(saslCommandPayloadFieldName)) {
                uassert( 25487, "must call copydbsaslstart first", authConn_.get() );
                BSONObj ret;
                if ( !authConn_->runCommand( cloneOptions.fromDB,
                                             BSON( "saslContinue" << 1 <<
                                                   cmdObj[saslCommandConversationIdFieldName] <<
                                                   cmdObj[saslCommandPayloadFieldName] ),
                                             ret ) ) {
                    errmsg = "unable to login " + ret.toString();
                    return false;
                }

                if (!ret["done"].Bool()) {
                    result.appendElements( ret );
                    return true;
                }

                result.append("done", true);
                cloner.setConnection( authConn_.release() );
            }
            else if (!fromSelf) {
                // If fromSelf leave the cloner's conn empty, it will use a DBDirectClient instead.

                ConnectionString cs = ConnectionString::parse(fromhost, errmsg);
                if (!cs.isValid()) {
                    return false;
                }

                DBClientBase* conn = cs.connect(errmsg);
                if (!conn) {
                    return false;
                }
                cloner.setConnection(conn);
            }

            if (fromSelf) {
                // SERVER-4328 todo lock just the two db's not everything for the fromself case
                Lock::GlobalWrite lk(txn->lockState());
                return cloner.go(txn, todb, fromhost, cloneOptions, NULL, errmsg);
            }

            Lock::DBLock lk (txn->lockState(), todb, MODE_X);
            return cloner.go(txn, todb, fromhost, cloneOptions, NULL, errmsg);
        }
Beispiel #24
0
    bool mergeChunks( OperationContext* txn,
                      const NamespaceString& nss,
                      const BSONObj& minKey,
                      const BSONObj& maxKey,
                      const OID& epoch,
                      string* errMsg ) {

        //
        // Get sharding state up-to-date
        //

        ConnectionString configLoc = ConnectionString::parse( shardingState.getConfigServer(),
                                                              *errMsg );
        if ( !configLoc.isValid() ){
            warning() << *errMsg << endl;
            return false;
        }

        //
        // Get the distributed lock
        //

        ScopedDistributedLock collLock( configLoc, nss.ns() );
        collLock.setLockMessage( stream() << "merging chunks in " << nss.ns() << " from "
                                          << minKey << " to " << maxKey );

        Status acquisitionStatus = collLock.tryAcquire();
        if (!acquisitionStatus.isOK()) {
            *errMsg = stream() << "could not acquire collection lock for " << nss.ns()
                               << " to merge chunks in [" << minKey << "," << maxKey << ")"
                               << causedBy(acquisitionStatus);

            warning() << *errMsg << endl;
            return false;
        }

        //
        // We now have the collection lock, refresh metadata to latest version and sanity check
        //

        ChunkVersion shardVersion;
        Status status = shardingState.refreshMetadataNow(txn, nss.ns(), &shardVersion);

        if ( !status.isOK() ) {

            *errMsg = str::stream() << "could not merge chunks, failed to refresh metadata for "
                                    << nss.ns() << causedBy( status.reason() );

            warning() << *errMsg << endl;
            return false;
        }

        if ( epoch.isSet() && shardVersion.epoch() != epoch ) {

            *errMsg = stream() << "could not merge chunks, collection " << nss.ns()
                               << " has changed" << " since merge was sent" << "(sent epoch : "
                               << epoch.toString()
                               << ", current epoch : " << shardVersion.epoch().toString() << ")";

            warning() << *errMsg << endl;
            return false;
        }

        CollectionMetadataPtr metadata = shardingState.getCollectionMetadata( nss.ns() );

        if ( !metadata || metadata->getKeyPattern().isEmpty() ) {

            *errMsg = stream() << "could not merge chunks, collection " << nss.ns()
                               << " is not sharded";

            warning() << *errMsg << endl;
            return false;
        }

        dassert( metadata->getShardVersion().equals( shardVersion ) );

        if ( !metadata->isValidKey( minKey ) || !metadata->isValidKey( maxKey ) ) {

            *errMsg = stream() << "could not merge chunks, the range "
                               << rangeToString( minKey, maxKey ) << " is not valid"
                               << " for collection " << nss.ns() << " with key pattern "
                               << metadata->getKeyPattern();

            warning() << *errMsg << endl;
            return false;
        }

        //
        // Get merged chunk information
        //

        ChunkVersion mergeVersion = metadata->getCollVersion();
        mergeVersion.incMinor();

        OwnedPointerVector<ChunkType> chunksToMerge;

        ChunkType itChunk;
        itChunk.setMin( minKey );
        itChunk.setMax( minKey );
        itChunk.setNS( nss.ns() );
        itChunk.setShard( shardingState.getShardName() );

        while ( itChunk.getMax().woCompare( maxKey ) < 0 &&
                metadata->getNextChunk( itChunk.getMax(), &itChunk ) ) {
            auto_ptr<ChunkType> saved( new ChunkType );
            itChunk.cloneTo( saved.get() );
            chunksToMerge.mutableVector().push_back( saved.release() );
        }

        if ( chunksToMerge.empty() ) {

            *errMsg = stream() << "could not merge chunks, collection " << nss.ns()
                               << " range starting at " << minKey
                               << " and ending at " << maxKey
                               << " does not belong to shard " << shardingState.getShardName();

            warning() << *errMsg << endl;
            return false;
        }

        //
        // Validate the range starts and ends at chunks and has no holes, error if not valid
        //

        BSONObj firstDocMin = ( *chunksToMerge.begin() )->getMin();
        BSONObj firstDocMax = ( *chunksToMerge.begin() )->getMax();
        // minKey is inclusive
        bool minKeyInRange = rangeContains( firstDocMin, firstDocMax, minKey );

        if ( !minKeyInRange ) {

            *errMsg = stream() << "could not merge chunks, collection " << nss.ns()
                               << " range starting at " << minKey
                               << " does not belong to shard " << shardingState.getShardName();

            warning() << *errMsg << endl;
            return false;
        }

        BSONObj lastDocMin = ( *chunksToMerge.rbegin() )->getMin();
        BSONObj lastDocMax = ( *chunksToMerge.rbegin() )->getMax();
        // maxKey is exclusive
        bool maxKeyInRange = lastDocMin.woCompare( maxKey ) < 0 &&
                lastDocMax.woCompare( maxKey ) >= 0;

        if ( !maxKeyInRange ) {
            *errMsg = stream() << "could not merge chunks, collection " << nss.ns()
                               << " range ending at " << maxKey
                               << " does not belong to shard " << shardingState.getShardName();

            warning() << *errMsg << endl;
            return false;
        }

        bool validRangeStartKey = firstDocMin.woCompare( minKey ) == 0;
        bool validRangeEndKey = lastDocMax.woCompare( maxKey ) == 0;

        if ( !validRangeStartKey || !validRangeEndKey ) {

            *errMsg = stream() << "could not merge chunks, collection " << nss.ns()
                               << " does not contain a chunk "
                               << ( !validRangeStartKey ? "starting at " + minKey.toString() : "" )
                               << ( !validRangeStartKey && !validRangeEndKey ? " or " : "" )
                               << ( !validRangeEndKey ? "ending at " + maxKey.toString() : "" );

            warning() << *errMsg << endl;
            return false;
        }

        if ( chunksToMerge.size() == 1 ) {

            *errMsg = stream() << "could not merge chunks, collection " << nss.ns()
                               << " already contains chunk for " << rangeToString( minKey, maxKey );

            warning() << *errMsg << endl;
            return false;
        }

        bool holeInRange = false;

        // Look for hole in range
        ChunkType* prevChunk = *chunksToMerge.begin();
        ChunkType* nextChunk = NULL;
        for ( OwnedPointerVector<ChunkType>::const_iterator it = chunksToMerge.begin();
                it != chunksToMerge.end(); ++it ) {
            if ( it == chunksToMerge.begin() ) continue;

            nextChunk = *it;
            if ( prevChunk->getMax().woCompare( nextChunk->getMin() ) != 0 ) {
                holeInRange = true;
                break;
            }
            prevChunk = nextChunk;
        }

        if ( holeInRange ) {

            dassert( NULL != nextChunk );
            *errMsg = stream() << "could not merge chunks, collection " << nss.ns()
                               << " has a hole in the range " << rangeToString( minKey, maxKey )
                               << " at " << rangeToString( prevChunk->getMax(),
                                                           nextChunk->getMin() );

            warning() << *errMsg << endl;
            return false;
        }

        //
        // Run apply ops command
        //

        BSONObj applyOpsCmd = buildApplyOpsCmd( chunksToMerge,
                                                shardVersion,
                                                mergeVersion );

        bool ok;
        BSONObj result;
        try {
            ScopedDbConnection conn( configLoc, 30.0 );
            ok = conn->runCommand( "config", applyOpsCmd, result );
            if ( !ok ) *errMsg = result.toString();
            conn.done();
        }
        catch( const DBException& ex ) {
            ok = false;
            *errMsg = ex.toString();
        }

        if ( !ok ) {
            *errMsg = stream() << "could not merge chunks for " << nss.ns()
                               << ", writing to config failed" << causedBy( errMsg );

            warning() << *errMsg << endl;
            return false;
        }

        //
        // Install merged chunk metadata
        //

        {
            Lock::DBLock writeLk(txn->lockState(), nss.db(), newlm::MODE_X);
            shardingState.mergeChunks(txn, nss.ns(), minKey, maxKey, mergeVersion);
        }

        //
        // Log change
        //

        BSONObj mergeLogEntry = buildMergeLogEntry( chunksToMerge,
                                                    shardVersion,
                                                    mergeVersion );

        configServer.logChange( "merge", nss.ns(), mergeLogEntry );

        return true;
    }
Beispiel #25
0
static switch_status_t config(switch_memory_pool_t *pool)
{
	const char *cf = "mongo.conf";
	switch_xml_t cfg, xml, settings, param;
	switch_status_t status = SWITCH_STATUS_SUCCESS;

	/* set defaults */
	globals.map = "";
	globals.reduce = "";
	globals.finalize = "";
	globals.conn_str = "";
	globals.socket_timeout = 0.0;

	if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
		return SWITCH_STATUS_GENERR;
	}

	if ((settings = switch_xml_child(cfg, "settings"))) {
		for (param = switch_xml_child(settings, "param"); param; param = param->next) {
			char *var = (char *) switch_xml_attr_soft(param, "name");
			char *val = (char *) switch_xml_attr_soft(param, "value");

			if (!strcmp(var, "connection-string")) {
				if (zstr(val)) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "missing connection-string value\n");
					status = SWITCH_STATUS_GENERR;
				} else {
					try {
						string errmsg;
						ConnectionString cs = ConnectionString::parse(string(val), errmsg);
						if (!cs.isValid()) {
							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "connection-string \"%s\" is not valid: %s\n", val, errmsg.c_str());
							status = SWITCH_STATUS_GENERR;
						} else {
							globals.conn_str = switch_core_strdup(pool, val);
						}
					} catch (DBException &e) {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "connection-string \"%s\" is not valid: %s\n", val, e.toString().c_str());
						status = SWITCH_STATUS_GENERR;
					} catch (...) {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "connection-string \"%s\" is not valid\n", val);
						status = SWITCH_STATUS_GENERR;
					}
				}
			} else if (!strcmp(var, "map")) {
				if (!zstr(val)) {
					globals.map = switch_core_strdup(pool, val);
				}
			} else if (!strcmp(var, "reduce")) {
				if (!zstr(val)) {
					globals.reduce = switch_core_strdup(pool, val);
				}
			} else if (!strcmp(var, "finalize")) {
				if (!zstr(val)) {
					globals.finalize = switch_core_strdup(pool, val);
				}
			} else if (!strcmp(var, "socket-timeout")) {
				if (!zstr(val)) {
					if (switch_is_number(val)) {
						double timeout = atof(val);
						if (timeout >= 0.0) {
							globals.socket_timeout = timeout;
						} else {
							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "socket-timeout \"%s\" is not valid\n", val);
						}
					} else {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "socket-timeout \"%s\" is not valid\n", val);
					}
				}
			} else if (!strcmp(var, "max-connections")) {
				if (!zstr(val)) {
					if (switch_is_number(val)) {
						int max_connections = atoi(val);
						if (max_connections > 0) {
							PoolForHost::setMaxPerHost(max_connections);
						} else {
							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "max-connections \"%s\" is not valid\n", val);
						}
					} else {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "max-connections \"%s\" is not valid\n", val);
					}
				}
			}
		}
	}

	switch_xml_free(xml);

	return status;
}
Beispiel #26
0
static bool runMongosServer( bool doUpgrade ) {

    setThreadName( "mongosMain" );
    printShardingVersionInfo( false );

    // set some global state

    pool.addHook( new ShardingConnectionHook( false ) );
    pool.setName( "mongos connectionpool" );

    shardConnectionPool.addHook( new ShardingConnectionHook( true ) );
    shardConnectionPool.setName( "mongos shardconnection connectionpool" );

    // Mongos shouldn't lazily kill cursors, otherwise we can end up with extras from migration
    DBClientConnection::setLazyKillCursor( false );

    ReplicaSetMonitor::setConfigChangeHook( boost::bind( &ConfigServer::replicaSetChange , &configServer , _1 ) );

    if ( ! configServer.init( configdbs ) ) {
        log() << "couldn't resolve config db address" << endl;
        return false;
    }

    if ( ! configServer.ok( true ) ) {
        log() << "configServer connection startup check failed" << endl;
        return false;
    }

    {
        class CheckConfigServers : public task::Task {
            virtual string name() const {
                return "CheckConfigServers";
            }
            virtual void doWork() {
                configServer.ok(true);
            }
        };

        task::repeat(new CheckConfigServers, 60*1000);
    }

    VersionType initVersionInfo;
    VersionType versionInfo;
    string errMsg;
    string configServerURL = configServer.getPrimary().getConnString();
    ConnectionString configServerConnString = ConnectionString::parse(configServerURL, errMsg);
    if (!configServerConnString.isValid()) {
        error() << "Invalid connection string for config servers: " << configServerURL << endl;
        return false;
    }
    bool upgraded = checkAndUpgradeConfigVersion(configServerConnString,
                    doUpgrade,
                    &initVersionInfo,
                    &versionInfo,
                    &errMsg);

    if (!upgraded) {
        error() << "error upgrading config database to v" << CURRENT_CONFIG_VERSION
                << causedBy(errMsg) << endl;
        return false;
    }

    configServer.reloadSettings();

    init();

#if !defined(_WIN32)
    CmdLine::launchOk();
#endif

    if ( !noHttpInterface )
        boost::thread web( boost::bind(&webServerThread, new NoAdminAccess() /* takes ownership */) );

    MessageServer::Options opts;
    opts.port = cmdLine.port;
    opts.ipList = cmdLine.bind_ip;
    start(opts);

    // listen() will return when exit code closes its socket.
    dbexit( EXIT_NET_ERROR );
    return true;
}
Beispiel #27
0
    /* static */
    void WriteBackListener::init( DBClientBase& conn ) {
        
        if ( conn.type() == ConnectionString::SYNC ) {
            // don't want write back listeners for config servers
            return;
        }

        if ( conn.type() != ConnectionString::SET ) {
            init( conn.getServerAddress() );
            return;
        }
        

        {
            scoped_lock lk( _cacheLock );
            if ( _seenSets.count( conn.getServerAddress() ) )
                return;
        }

        // we want to do writebacks on all rs nodes
        string errmsg;
        ConnectionString cs = ConnectionString::parse( conn.getServerAddress() , errmsg );
        uassert( 13641 , str::stream() << "can't parse host [" << conn.getServerAddress() << "]" , cs.isValid() );

        vector<HostAndPort> hosts = cs.getServers();
        
        for ( unsigned i=0; i<hosts.size(); i++ )
            init( hosts[i].toString() );

    }
Beispiel #28
0
static ExitCode runMongosServer( bool doUpgrade ) {
    setThreadName( "mongosMain" );
    printShardingVersionInfo( false );

    // set some global state

    // Add sharding hooks to both connection pools - ShardingConnectionHook includes auth hooks
    pool.addHook( new ShardingConnectionHook( false ) );
    shardConnectionPool.addHook( new ShardingConnectionHook( true ) );

    // Mongos shouldn't lazily kill cursors, otherwise we can end up with extras from migration
    DBClientConnection::setLazyKillCursor( false );

    ReplicaSetMonitor::setConfigChangeHook(
        stdx::bind(&ConfigServer::replicaSetChange, &configServer, stdx::placeholders::_1 , stdx::placeholders::_2));

    // Mongos connection pools already takes care of authenticating new connections so the
    // replica set connection shouldn't need to.
    DBClientReplicaSet::setAuthPooledSecondaryConn(false);

    if (getHostName().empty()) {
        dbexit(EXIT_BADOPTIONS);
    }

    if (!grid.initCatalogManager(mongosGlobalParams.configdbs)) {
        mongo::log(LogComponent::kSharding) << "couldn't initialize catalog manager";
        return EXIT_SHARDING_ERROR;
    }

    if (!configServer.init(mongosGlobalParams.configdbs)) {
        mongo::log(LogComponent::kSharding) << "couldn't resolve config db address" << endl;
        return EXIT_SHARDING_ERROR;
    }

    if (!configServer.ok(true)) {
        mongo::log(LogComponent::kSharding) << "configServer connection startup check failed" << endl;
        return EXIT_SHARDING_ERROR;
    }

    startConfigServerChecker();

    VersionType initVersionInfo;
    VersionType versionInfo;
    string errMsg;
    string configServerURL = configServer.getPrimary().getConnString();
    ConnectionString configServerConnString = ConnectionString::parse(configServerURL, errMsg);
    if (!configServerConnString.isValid()) {
        error(LogComponent::kDefault) << "Invalid connection string for config servers: " << configServerURL << endl;
        return EXIT_SHARDING_ERROR;
    }
    bool upgraded = checkAndUpgradeConfigVersion(configServerConnString,
                                                 doUpgrade,
                                                 &initVersionInfo,
                                                 &versionInfo,
                                                 &errMsg);

    if (!upgraded) {
        error(LogComponent::kDefault) << "error upgrading config database to v"
                << CURRENT_CONFIG_VERSION
                << causedBy(errMsg) << endl;
        return EXIT_SHARDING_ERROR;
    }

    if ( doUpgrade ) {
        mongo::log(LogComponent::kDefault) << "Config database is at version v"
                << CURRENT_CONFIG_VERSION;
        return EXIT_CLEAN;
    }

    configServer.reloadSettings();

#if !defined(_WIN32)
    mongo::signalForkSuccess();
#endif

    if (serverGlobalParams.isHttpInterfaceEnabled) {
        boost::shared_ptr<DbWebServer> dbWebServer(
                                new DbWebServer(serverGlobalParams.bind_ip,
                                                serverGlobalParams.port + 1000,
                                                new NoAdminAccess()));
        dbWebServer->setupSockets();

        boost::thread web(stdx::bind(&webServerListenThread, dbWebServer));
        web.detach();
    }

    Status status = getGlobalAuthorizationManager()->initialize(NULL);
    if (!status.isOK()) {
        mongo::log(LogComponent::kDefault) << "Initializing authorization data failed: " << status;
        return EXIT_SHARDING_ERROR;
    }

    MessageServer::Options opts;
    opts.port = serverGlobalParams.port;
    opts.ipList = serverGlobalParams.bind_ip;
    start(opts);

    // listen() will return when exit code closes its socket.
    return EXIT_NET_ERROR;
}
Beispiel #29
0
static bool runMongosServer( bool doUpgrade ) {
    setupSignalHandlers();
    setThreadName( "mongosMain" );
    printShardingVersionInfo( false );

    // set some global state

    pool.addHook( new ShardingConnectionHook( false ) );
    pool.setName( "mongos connectionpool" );

    shardConnectionPool.addHook( new ShardingConnectionHook( true ) );
    shardConnectionPool.setName( "mongos shardconnection connectionpool" );

    // Mongos shouldn't lazily kill cursors, otherwise we can end up with extras from migration
    DBClientConnection::setLazyKillCursor( false );

    ReplicaSetMonitor::setConfigChangeHook( boost::bind( &ConfigServer::replicaSetChange , &configServer , _1 ) );

    if ( ! configServer.init( configdbs ) ) {
        log() << "couldn't resolve config db address" << endl;
        return false;
    }

    if ( ! configServer.ok( true ) ) {
        log() << "configServer connection startup check failed" << endl;
        return false;
    }

    startConfigServerChecker();

    VersionType initVersionInfo;
    VersionType versionInfo;
    string errMsg;
    string configServerURL = configServer.getPrimary().getConnString();
    ConnectionString configServerConnString = ConnectionString::parse(configServerURL, errMsg);
    if (!configServerConnString.isValid()) {
        error() << "Invalid connection string for config servers: " << configServerURL << endl;
        return false;
    }
    bool upgraded = checkAndUpgradeConfigVersion(configServerConnString,
                                                 doUpgrade,
                                                 &initVersionInfo,
                                                 &versionInfo,
                                                 &errMsg);

    if (!upgraded) {
        error() << "error upgrading config database to v" << CURRENT_CONFIG_VERSION
                << causedBy(errMsg) << endl;
        return false;
    }

    configServer.reloadSettings();

    init();

#if !defined(_WIN32)
    CmdLine::launchOk();
#endif

    if ( cmdLine.isHttpInterfaceEnabled )
        boost::thread web( boost::bind(&webServerThread, new NoAdminAccess() /* takes ownership */) );

    if (getGlobalAuthorizationManager()->isAuthEnabled()) {
        // TODO(spencer): This should only be done if we haven't yet upgraded to the new V2 user
        // data format.  Fix this as part of SERVER-9516.
        Status status = getGlobalAuthorizationManager()->initializeAllV1UserData();
        if (!status.isOK()) {
            log() << "Initializing user data failed: " << status.toString() << endl;
            return false;
        }
    }

    MessageServer::Options opts;
    opts.port = cmdLine.port;
    opts.ipList = cmdLine.bind_ip;
    start(opts);

    // listen() will return when exit code closes its socket.
    dbexit( EXIT_NET_ERROR );
    return true;
}
Beispiel #30
0
        virtual bool run(OperationContext* txn,
                         const string& dbname,
                         BSONObj& cmdObj,
                         int,
                         string& errmsg,
                         BSONObjBuilder& result,
                         bool fromRepl) {

            string fromhost = cmdObj.getStringField("fromhost");
            bool fromSelf = fromhost.empty();
            if ( fromSelf ) {
                /* copy from self */
                stringstream ss;
                ss << "localhost:" << serverGlobalParams.port;
                fromhost = ss.str();
            }

            CloneOptions cloneOptions;
            cloneOptions.fromDB = cmdObj.getStringField("fromdb");
            cloneOptions.logForRepl = !fromRepl;
            cloneOptions.slaveOk = cmdObj["slaveOk"].trueValue();
            cloneOptions.useReplAuth = false;
            cloneOptions.snapshot = true;
            cloneOptions.mayYield = true;
            cloneOptions.mayBeInterrupted = false;

            string todb = cmdObj.getStringField("todb");
            if ( fromhost.empty() || todb.empty() || cloneOptions.fromDB.empty() ) {
                errmsg = "parms missing - {copydb: 1, fromhost: <connection string>, "
                         "fromdb: <db>, todb: <db>}";
                return false;
            }

            Cloner cloner;
            string username = cmdObj.getStringField( "username" );
            string nonce = cmdObj.getStringField( "nonce" );
            string key = cmdObj.getStringField( "key" );
            if ( !username.empty() && !nonce.empty() && !key.empty() ) {
                uassert( 13008, "must call copydbgetnonce first", authConn_.get() );
                BSONObj ret;
                {
                    if ( !authConn_->runCommand( cloneOptions.fromDB,
                                                 BSON( "authenticate" << 1 << "user" << username
                                                       << "nonce" << nonce << "key" << key ), ret ) ) {
                        errmsg = "unable to login " + ret.toString();
                        return false;
                    }
                }
                cloner.setConnection( authConn_.release() );
            }
            else if (!fromSelf) {
                // If fromSelf leave the cloner's conn empty, it will use a DBDirectClient instead.

                ConnectionString cs = ConnectionString::parse(fromhost, errmsg);
                if (!cs.isValid()) {
                    return false;
                }

                DBClientBase* conn = cs.connect(errmsg);
                if (!conn) {
                    return false;
                }
                cloner.setConnection(conn);
            }


            // SERVER-4328 todo lock just the two db's not everything for the fromself case
            scoped_ptr<Lock::ScopedLock> lk( fromSelf ?
                                             static_cast<Lock::ScopedLock*>(new Lock::GlobalWrite(txn->lockState())) :
                                             static_cast<Lock::ScopedLock*>(new Lock::DBWrite(txn->lockState(), todb)));
            WriteUnitOfWork wunit(txn);
            if (!cloner.go(txn, todb, fromhost, cloneOptions, NULL, errmsg )) {
                return false;
            }
            wunit.commit();
            return true;
        }