shared_ptr<Shard> ShardRegistry::find(const string& ident) {
        string errmsg;
        ConnectionString connStr = ConnectionString::parse(ident, errmsg);
        uassert(18642,
                str::stream() << "Error parsing connection string: " << ident,
                errmsg.empty());

        if (connStr.type() == ConnectionString::SET) {
            boost::lock_guard<boost::mutex> lk(_rsMutex);
            ShardMap::iterator iter = _rsLookup.find(connStr.getSetName());

            if (iter == _rsLookup.end()) {
                return nullptr;
            }

            return iter->second;
        }
        else {
            boost::lock_guard<boost::mutex> lk(_mutex);
            ShardMap::iterator iter = _lookup.find(ident);

            if (iter == _lookup.end()) {
                return nullptr;
            }

            return iter->second;
        }
    }
示例#2
0
void ShardRegistry::_updateLookupMapsForShard_inlock(shared_ptr<Shard> shard,
                                                     const ConnectionString& newConnString) {
    auto oldConnString = shard->getConnString();
    for (const auto& host : oldConnString.getServers()) {
        _lookup.erase(host.toString());
    }

    _lookup[shard->getId()] = shard;

    if (newConnString.type() == ConnectionString::SET) {
        _rsLookup[newConnString.getSetName()] = shard;
    } else if (newConnString.type() == ConnectionString::CUSTOM) {
        // CUSTOM connection strings (ie "$dummy:10000) become DBDirectClient connections which
        // always return "localhost" as their resposne to getServerAddress().  This is just for
        // making dbtest work.
        _lookup["localhost"] = shard;
    }

    // TODO: The only reason to have the shard host names in the lookup table is for the
    // setShardVersion call, which resolves the shard id from the shard address. This is
    // error-prone and will go away eventually when we switch all communications to go through
    // the remote command runner and all nodes are sharding aware by default.
    _lookup[newConnString.toString()] = shard;

    for (const HostAndPort& hostAndPort : newConnString.getServers()) {
        _lookup[hostAndPort.toString()] = shard;
    }
}
示例#3
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;
}
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);
}
void ConfigServerFixture::setUp() {
    shardConnectionPool.clear();
    DBException::traceExceptions = true;

    // Make all connections redirect to the direct client
    _connectHook = new CustomConnectHook(&_txn);
    ConnectionString::setConnectionHook(_connectHook);

    // Create the default config database before querying, necessary for direct connections
    clearServer();
    _client.insert("config.test",
                   BSON("hello"
                        << "world"));
    _client.dropCollection("config.test");

    // Create an index over the chunks, to allow correct diffing
    ASSERT_OK(
        dbtests::createIndex(&_txn,
                             ChunkType::ConfigNS,
                             BSON(ChunkType::ns() << 1 << ChunkType::DEPRECATED_lastmod() << 1)));

    const ConnectionString connStr(uassertStatusOK(ConnectionString::parse("$dummy:10000")));

    ShardingState::get(&_txn)->initialize(&_txn, connStr.toString());
    ShardingState::get(&_txn)->setShardName(shardName());
}
示例#6
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"] ) );
            }
        }
示例#7
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() );

    }
示例#8
0
void ShardRegistry::remove(const ShardId& id) {
    stdx::lock_guard<stdx::mutex> lk(_mutex);

    set<string> entriesToRemove;
    for (const auto& i : _lookup) {
        shared_ptr<Shard> s = i.second;
        if (s->getId() == id) {
            entriesToRemove.insert(i.first);
            ConnectionString connStr = s->getConnString();
            for (const auto& host : connStr.getServers()) {
                entriesToRemove.insert(host.toString());
            }
        }
    }
    for (const auto& entry : entriesToRemove) {
        _lookup.erase(entry);
    }

    for (ShardMap::iterator i = _rsLookup.begin(); i != _rsLookup.end();) {
        shared_ptr<Shard> s = i->second;
        if (s->getId() == id) {
            _rsLookup.erase(i++);
        } else {
            ++i;
        }
    }

    shardConnectionPool.removeHost(id);
    ReplicaSetMonitor::remove(id);
}
    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;
    }
示例#10
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;
                 }
             }
         }
     }
 }
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;
}
void ShardingInitializationMongoD::updateShardIdentityConfigString(
    OperationContext* opCtx, const ConnectionString& newConnectionString) {
    BSONObj updateObj(
        ShardIdentityType::createConfigServerUpdateObject(newConnectionString.toString()));

    UpdateRequest updateReq(NamespaceString::kServerConfigurationNamespace);
    updateReq.setQuery(BSON("_id" << ShardIdentityType::IdName));
    updateReq.setUpdateModification(updateObj);

    try {
        AutoGetOrCreateDb autoDb(
            opCtx, NamespaceString::kServerConfigurationNamespace.db(), MODE_X);

        auto result = update(opCtx, autoDb.getDb(), updateReq);
        if (result.numMatched == 0) {
            warning() << "failed to update config string of shard identity document because "
                      << "it does not exist. This shard could have been removed from the cluster";
        } else {
            LOG(2) << "Updated config server connection string in shardIdentity document to"
                   << newConnectionString;
        }
    } catch (const DBException& exception) {
        auto status = exception.toStatus();
        if (!ErrorCodes::isNotMasterError(status.code())) {
            warning() << "Error encountered while trying to update config connection string to "
                      << newConnectionString.toString() << causedBy(redact(status));
        }
    }
}
示例#13
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;
	}
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;
}
示例#16
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;
}
示例#17
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;
}
示例#18
0
    Status DBClientShardResolver::findMaster( const std::string connString,
                                              ConnectionString* resolvedHost ) {
        std::string errMsg;

        ConnectionString rawHost = ConnectionString::parse( connString, errMsg );
        dassert( errMsg == "" );
        dassert( rawHost.type() == ConnectionString::SET
                 || rawHost.type() == ConnectionString::MASTER );

        if ( rawHost.type() == ConnectionString::MASTER ) {
            *resolvedHost = rawHost;
            return Status::OK();
        }

        //
        // If we need to, then get the particular node we're targeting in the replica set
        //

        // Don't create the monitor unless we need to - fast path
        ReplicaSetMonitorPtr replMonitor = ReplicaSetMonitor::get(rawHost.getSetName());

        if (!replMonitor) {
            // Slow path
            std::set<HostAndPort> seedServers(rawHost.getServers().begin(),
                                              rawHost.getServers().end());
            ReplicaSetMonitor::createIfNeeded(rawHost.getSetName(), seedServers);
            replMonitor = ReplicaSetMonitor::get(rawHost.getSetName());
        }

        if (!replMonitor) {
            return Status( ErrorCodes::ReplicaSetNotFound,
                           string("unknown replica set ") + rawHost.getSetName() );
        }

        try {
            // This can throw when we don't find a master!
            HostAndPort masterHostAndPort = replMonitor->getMasterOrUassert();
            *resolvedHost = ConnectionString::parse( masterHostAndPort.toString(), errMsg );
            dassert( errMsg == "" );
            return Status::OK();
        }
        catch ( const DBException& ) {
            return Status( ErrorCodes::HostNotFound,
                           string("could not contact primary for replica set ")
                           + replMonitor->getName() );
        }

        // Unreachable
        dassert( false );
        return Status( ErrorCodes::UnknownError, "" );
    }
示例#19
0
 shared_ptr<DBClientConnection> makeConnection(
     const char *masterHost,
     string& errmsg
     ) 
 {
     verify(!masterSameProcess(masterHost));
     ConnectionString cs = ConnectionString::parse(masterHost, errmsg);
     shared_ptr<DBClientConnection> conn(static_cast<DBClientConnection *>(cs.connect(errmsg)));
     if (!replAuthenticate(conn.get())) {
         errmsg = "can't authenticate replication";
         conn.reset();
     }
     return conn;
 }
/**
 * Returns the remote time as reported by the cluster or server.  The maximum difference between the
 * reported time and the actual time on the remote server (at the completion of the function) is the
 * maxNetSkew
 */
Date_t DistributedLock::remoteTime(const ConnectionString& cluster, unsigned long long maxNetSkew) {
    ConnectionString server(*cluster.getServers().begin());

    // Get result and delay if successful, errMsg if not
    bool success = false;
    BSONObj result;
    string errMsg;
    Milliseconds delay{0};

    unique_ptr<ScopedDbConnection> connPtr;
    try {
        connPtr.reset(new ScopedDbConnection(server.toString()));
        ScopedDbConnection& conn = *connPtr;

        Date_t then = jsTime();
        success = conn->runCommand(string("admin"), BSON("serverStatus" << 1), result);
        delay = jsTime() - then;

        if (!success)
            errMsg = result.toString();
        conn.done();
    } catch (const DBException& ex) {
        if (connPtr && connPtr->get()->isFailed()) {
            // Return to the pool so the pool knows about the failure
            connPtr->done();
        }

        success = false;
        errMsg = ex.toString();
    }

    if (!success) {
        throw TimeNotFoundException(str::stream() << "could not get status from server "
                                                  << server.toString() << " in cluster "
                                                  << cluster.toString() << " to check time"
                                                  << causedBy(errMsg),
                                    13647);
    }

    // Make sure that our delay is not more than 2x our maximum network skew, since this is the max
    // our remote time value can be off by if we assume a response in the middle of the delay.
    if (delay > Milliseconds(maxNetSkew * 2)) {
        throw TimeNotFoundException(
            str::stream() << "server " << server.toString() << " in cluster " << cluster.toString()
                          << " did not respond within max network delay of " << maxNetSkew << "ms",
            13648);
    }

    return result["localTime"].Date() - (delay / 2);
}
    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;
    }
示例#22
0
            bool run(const string& , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool) {
                errmsg.clear();

                // get replica set component hosts
                ConnectionString servers = ConnectionString::parse( cmdObj.firstElement().valuestrsafe() , errmsg );
                if ( ! errmsg.empty() ) {
                    log() << "addshard request " << cmdObj << " failed:" << errmsg << endl;
                    return false;
                }

                // using localhost in server names implies every other process must use localhost addresses too
                vector<HostAndPort> serverAddrs = servers.getServers();
                for ( size_t i = 0 ; i < serverAddrs.size() ; i++ ) {
                    if ( serverAddrs[i].isLocalHost() != grid.allowLocalHost() ) {
                        errmsg = str::stream() << 
                            "can't use localhost as a shard since all shards need to communicate. " <<
                            "either use all shards and configdbs in localhost or all in actual IPs " << 
                            " host: " << serverAddrs[i].toString() << " isLocalHost:" << serverAddrs[i].isLocalHost();
                        
                        log() << "addshard request " << cmdObj << " failed: attempt to mix localhosts and IPs" << endl;
                        return false;
                    }

                    // it's fine if mongods of a set all use default port
                    if ( ! serverAddrs[i].hasPort() ) {
                        serverAddrs[i].setPort( CmdLine::ShardServerPort );
                    }
                }

                // name is optional; addShard will provide one if needed
                string name = "";
                if ( cmdObj["name"].type() == String ) {
                    name = cmdObj["name"].valuestrsafe();
                }

                // maxSize is the space usage cap in a shard in MBs
                long long maxSize = 0;
                if ( cmdObj[ ShardFields::maxSize.name() ].isNumber() ) {
                    maxSize = cmdObj[ ShardFields::maxSize.name() ].numberLong();
                }

                if ( ! grid.addShard( &name , servers , maxSize , errmsg ) ) {
                    log() << "addshard request " << cmdObj << " failed: " << errmsg << endl;
                    return false;
                }

                result << "shardAdded" << name;
                return true;
            }
示例#23
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 );
 }
示例#24
0
void MoveChunkRequest::appendAsCommand(BSONObjBuilder* builder,
                                       const NamespaceString& nss,
                                       const ChunkVersion& shardVersion,
                                       const ConnectionString& configServerConnectionString,
                                       const ShardId& fromShardId,
                                       const ShardId& toShardId,
                                       const ChunkRange& range,
                                       int64_t maxChunkSizeBytes,
                                       const MigrationSecondaryThrottleOptions& secondaryThrottle,
                                       bool waitForDelete,
                                       bool takeDistLock) {
    invariant(builder->asTempObj().isEmpty());
    invariant(nss.isValid());

    builder->append(kMoveChunk, nss.ns());
    shardVersion.appendForCommands(builder);
    builder->append(kConfigServerConnectionString, configServerConnectionString.toString());
    builder->append(kFromShardId, fromShardId.toString());
    builder->append(kToShardId, toShardId.toString());
    range.append(builder);
    builder->append(kMaxChunkSizeBytes, static_cast<long long>(maxChunkSizeBytes));
    secondaryThrottle.append(builder);
    builder->append(kWaitForDelete, waitForDelete);
    builder->append(kTakeDistLock, takeDistLock);
}
    shared_ptr<ReplicaSetMonitor>
    ReplicaSetMonitorManager::getOrCreateMonitor(const ConnectionString& connStr) {
        invariant(connStr.type() == ConnectionString::SET);

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

        shared_ptr<ReplicaSetMonitor>& monitor = _monitors[connStr.getSetName()];
        if (!monitor) {
            const std::set<HostAndPort> servers(connStr.getServers().begin(),
                                                connStr.getServers().end());

            monitor = std::make_shared<ReplicaSetMonitor>(connStr.getSetName(), servers);
        }

        return monitor;
    }
示例#26
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 );
    }
void MoveChunkRequest::appendAsCommand(BSONObjBuilder* builder,
                                       const NamespaceString& nss,
                                       ChunkVersion chunkVersion,
                                       const ConnectionString& configServerConnectionString,
                                       const ShardId& fromShardId,
                                       const ShardId& toShardId,
                                       const ChunkRange& range,
                                       int64_t maxChunkSizeBytes,
                                       const MigrationSecondaryThrottleOptions& secondaryThrottle,
                                       bool waitForDelete) {
    invariant(builder->asTempObj().isEmpty());
    invariant(nss.isValid());

    builder->append(kMoveChunk, nss.ns());
    chunkVersion.appendToCommand(builder);  // 3.4 shard compatibility
    builder->append(kEpoch, chunkVersion.epoch());
    // config connection string is included for 3.4 shard compatibility
    builder->append(kConfigServerConnectionString, configServerConnectionString.toString());
    builder->append(kFromShardId, fromShardId.toString());
    builder->append(kToShardId, toShardId.toString());
    range.append(builder);
    builder->append(kMaxChunkSizeBytes, static_cast<long long>(maxChunkSizeBytes));
    secondaryThrottle.append(builder);
    builder->append(kWaitForDelete, waitForDelete);
    builder->append(kTakeDistLock, false);
}
示例#28
0
void ShardRegistry::updateConfigServerConnectionString(ConnectionString configServerCS) {
    log() << "Updating config server connection string to: " << configServerCS.toString();
    stdx::lock_guard<stdx::mutex> lk(_mutex);
    _configServerCS = std::move(configServerCS);

    _addConfigShard_inlock();
}
示例#29
0
void ShardRegistry::updateLookupMapsForShard(shared_ptr<Shard> shard,
                                             const ConnectionString& newConnString) {
    log() << "Updating ShardRegistry connection string for shard " << shard->getId()
          << " to: " << newConnString.toString();
    stdx::lock_guard<stdx::mutex> lk(_mutex);
    _updateLookupMapsForShard_inlock(std::move(shard), newConnString);
}
示例#30
0
文件: rs.cpp 项目: CoolCloud/mongo
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();
    }

}