示例#1
0
Status ActionSet::parseActionSetFromString(const std::string& actionsString, ActionSet* result) {
    std::vector<std::string> actionsList;
    splitStringDelim(actionsString, &actionsList, ',');
    std::vector<std::string> unrecognizedActions;
    Status status = parseActionSetFromStringVector(actionsList, result, &unrecognizedActions);
    invariantOK(status);
    if (unrecognizedActions.empty()) {
        return Status::OK();
    }
    std::string unrecognizedActionsString;
    joinStringDelim(unrecognizedActions, &unrecognizedActionsString, ',');
    return Status(
        ErrorCodes::FailedToParse,
        str::stream() << "Unrecognized action privilege strings: " << unrecognizedActionsString);
}
Status V2UserDocumentParser::initializeUserPrivilegesFromUserDocument(const BSONObj& doc,
                                                                      User* user) const {
    BSONElement privilegesElement = doc[PRIVILEGES_FIELD_NAME];
    if (privilegesElement.eoo())
        return Status::OK();
    if (privilegesElement.type() != Array) {
        return Status(ErrorCodes::UnsupportedFormat,
                      "User document 'inheritedPrivileges' element must be Array if present.");
    }
    PrivilegeVector privileges;
    std::string errmsg;
    for (BSONObjIterator it(privilegesElement.Obj()); it.more(); it.next()) {
        if ((*it).type() != Object) {
            warning() << "Wrong type of element in inheritedPrivileges array for "
                      << user->getName() << ": " << *it;
            continue;
        }
        Privilege privilege;
        ParsedPrivilege pp;
        if (!pp.parseBSON((*it).Obj(), &errmsg)) {
            warning() << "Could not parse privilege element in user document for "
                      << user->getName() << ": " << errmsg;
            continue;
        }
        std::vector<std::string> unrecognizedActions;
        Status status =
            ParsedPrivilege::parsedPrivilegeToPrivilege(pp, &privilege, &unrecognizedActions);
        if (!status.isOK()) {
            warning() << "Could not parse privilege element in user document for "
                      << user->getName() << causedBy(status);
            continue;
        }
        if (unrecognizedActions.size()) {
            std::string unrecognizedActionsString;
            joinStringDelim(unrecognizedActions, &unrecognizedActionsString, ',');
            warning() << "Encountered unrecognized actions \" " << unrecognizedActionsString
                      << "\" while parsing user document for " << user->getName();
        }
        privileges.push_back(privilege);
    }
    user->setPrivileges(privileges);
    return Status::OK();
}
示例#3
0
    bool ConfigServer::init( vector<string> configHosts ) {
        uassert( 10187 ,  "need configdbs" , configHosts.size() );

        string hn = getHostName();
        if ( hn.empty() ) {
            sleepsecs(5);
            dbexit( EXIT_BADOPTIONS );
        }

        set<string> hosts;
        for ( size_t i=0; i<configHosts.size(); i++ ) {
            string host = configHosts[i];
            hosts.insert( getHost( host , false ) );
            configHosts[i] = getHost( host , true );
        }

        for ( set<string>::iterator i=hosts.begin(); i!=hosts.end(); i++ ) {
            string host = *i;
            bool ok = false;
            for ( int x=10; x>0; x-- ) {
                if ( ! hostbyname( host.c_str() ).empty() ) {
                    ok = true;
                    break;
                }
                log() << "can't resolve DNS for [" << host << "]  sleeping and trying " << x << " more times" << endl;
                sleepsecs( 10 );
            }
            if ( ! ok )
                return false;
        }

        _config = configHosts;

        string fullString;
        joinStringDelim( configHosts, &fullString, ',' );
        _primary.setAddress( fullString , true );
        log(1) << " config string : " << fullString << endl;

        return true;
    }
示例#4
0
    BalancerPolicy::ChunkInfo* BalancerPolicy::balance( const string& ns,
            const ShardToLimitsMap& shardToLimitsMap,
            const ShardToChunksMap& shardToChunksMap,
            int balancedLastTime ) {
        pair<string,unsigned> min("",numeric_limits<unsigned>::max());
        pair<string,unsigned> max("",0);
        vector<string> drainingShards;

        bool maxOpsQueued = false;

        for (ShardToChunksIter i = shardToChunksMap.begin(); i!=shardToChunksMap.end(); ++i ) {

            // Find whether this shard's capacity or availability are exhausted
            const string& shard = i->first;
            BSONObj shardLimits;
            ShardToLimitsIter it = shardToLimitsMap.find( shard );
            if ( it != shardToLimitsMap.end() ) shardLimits = it->second;
            const bool maxedOut = isSizeMaxed( shardLimits );
            const bool draining = isDraining( shardLimits );
            const bool opsQueued = hasOpsQueued( shardLimits );

            
            // Is this shard a better chunk receiver then the current one?
            // Shards that would be bad receiver candidates:
            // + maxed out shards
            // + draining shards
            // + shards with operations queued for writeback
            const unsigned size = i->second.size();
            if ( ! maxedOut && ! draining && ! opsQueued ) {
                if ( size < min.second ) {
                    min = make_pair( shard , size );
                }
            }
            else if ( opsQueued ) {
                MONGO_LOG(1) << "won't send a chunk to: " << shard << " because it has ops queued" << endl;
            }
            else if ( maxedOut ) {
                MONGO_LOG(1) << "won't send a chunk to: " << shard << " because it is maxedOut" << endl;
            }


            // Check whether this shard is a better chunk donor then the current one.
            // Draining shards take a lower priority than overloaded shards.
            if ( size > max.second ) {
                max = make_pair( shard , size );
                maxOpsQueued = opsQueued;
            }
            if ( draining && (size > 0)) {
                drainingShards.push_back( shard );
            }
        }

        // If there is no candidate chunk receiver -- they may have all been maxed out,
        // draining, ... -- there's not much that the policy can do.
        if ( min.second == numeric_limits<unsigned>::max() ) {
            log() << "no available shards to take chunks" << endl;
            return NULL;
        }

        if ( maxOpsQueued ) {
            log() << "biggest shard " << max.first << " has unprocessed writebacks, waiting for completion of migrate" << endl;
            return NULL;
        }

        MONGO_LOG(1) << "collection : " << ns << endl;
        MONGO_LOG(1) << "donor      : " << max.second << " chunks on " << max.first << endl;
        MONGO_LOG(1) << "receiver   : " << min.second << " chunks on " << min.first << endl;
        if ( ! drainingShards.empty() ) {
            string drainingStr;
            joinStringDelim( drainingShards, &drainingStr, ',' );
            MONGO_LOG(1) << "draining           : " << ! drainingShards.empty() << "(" << drainingShards.size() << ")" << endl;
        }

        // Solving imbalances takes a higher priority than draining shards. Many shards can
        // be draining at once but we choose only one of them to cater to per round.
        // Important to start balanced, so when there are few chunks any imbalance must be fixed.
        const int imbalance = max.second - min.second;
        int threshold = 8;
        if (balancedLastTime || max.second < 20) threshold = 2;
        else if (max.second < 80) threshold = 4;
        string from, to;
        if ( imbalance >= threshold ) {
            from = max.first;
            to = min.first;

        }
        else if ( ! drainingShards.empty() ) {
            from = drainingShards[ rand() % drainingShards.size() ];
            to = min.first;

        }
        else {
            // Everything is balanced here!
            return NULL;
        }

        const vector<BSONObj>& chunksFrom = shardToChunksMap.find( from )->second;
        const vector<BSONObj>& chunksTo = shardToChunksMap.find( to )->second;
        BSONObj chunkToMove = pickChunk( chunksFrom , chunksTo );
        log() << "chose [" << from << "] to [" << to << "] " << chunkToMove << endl;

        return new ChunkInfo( ns, to, from, chunkToMove );
    }
示例#5
0
    BalancerPolicy::ChunkInfo* BalancerPolicy::balance( const string& ns, 
                                                        const ShardToLimitsMap& shardToLimitsMap,  
                                                        const ShardToChunksMap& shardToChunksMap, 
                                                        int balancedLastTime ){
        pair<string,unsigned> min("",numeric_limits<unsigned>::max());
        pair<string,unsigned> max("",0);
        vector<string> drainingShards;
	        
        for (ShardToChunksIter i = shardToChunksMap.begin(); i!=shardToChunksMap.end(); ++i ){

            // Find whether this shard has reached its size cap or whether it is being removed.
            const string& shard = i->first;
            BSONObj shardLimits;
            ShardToLimitsIter it = shardToLimitsMap.find( shard );
            if ( it != shardToLimitsMap.end() ) shardLimits = it->second;
            const bool maxedOut = isSizeMaxed( shardLimits );
            const bool draining = isDraining( shardLimits );

            // Check whether this shard is a better chunk receiver then the current one. 
            // Maxed out shards or draining shards cannot be considered receivers.
            const unsigned size = i->second.size();
            if ( ! maxedOut && ! draining ){
                if ( size < min.second ){
                    min = make_pair( shard , size );
                }
            }

            // Check whether this shard is a better chunk donor then the current one.
            // Draining shards take a lower priority than overloaded shards.
            if ( size > max.second ){
                max = make_pair( shard , size ); 
            }
            if ( draining && (size > 0)){
                drainingShards.push_back( shard );
            }
        }

        // If there is no candidate chunk receiver -- they may have all been maxed out, 
        // draining, ... -- there's not much that the policy can do.  
        if ( min.second == numeric_limits<unsigned>::max() ){
            log() << "no availalable shards to take chunks" << endl;
            return NULL;
        }
        
        log(1) << "collection : " << ns << endl;
        log(1) << "donor      : " << max.second << " chunks on " << max.first << endl;
        log(1) << "receiver   : " << min.second << " chunks on " << min.first << endl;
        if ( ! drainingShards.empty() ){
            string drainingStr;
            joinStringDelim( drainingShards, &drainingStr, ',' );
            log(1) << "draining           : " << ! drainingShards.empty() << "(" << drainingShards.size() << ")" << endl;
        }

        // Solving imbalances takes a higher priority than draining shards. Many shards can
        // be draining at once but we choose only one of them to cater to per round.
        const int imbalance = max.second - min.second;
        const int threshold = balancedLastTime ? 2 : 8;
        string from, to;
        if ( imbalance >= threshold ){
            from = max.first;
            to = min.first;

        } else if ( ! drainingShards.empty() ){
            from = drainingShards[ rand() % drainingShards.size() ];
            to = min.first;

        } else {
            // Everything is balanced here! 
            return NULL;
        }

        const vector<BSONObj>& chunksFrom = shardToChunksMap.find( from )->second;
        const vector<BSONObj>& chunksTo = shardToChunksMap.find( to )->second;
        BSONObj chunkToMove = pickChunk( chunksFrom , chunksTo );
        log() << "chose [" << from << "] to [" << to << "] " << chunkToMove << endl;        

        return new ChunkInfo( ns, to, from, chunkToMove );
    }