Status ReplSetRequestVotesArgs::initialize(const BSONObj& argsObj) {
    Status status = bsonCheckOnlyHasFields("ReplSetRequestVotes", argsObj, kLegalArgsFieldNames);
    if (!status.isOK())
        return status;

    status = bsonExtractIntegerField(argsObj, kTermFieldName, &_term);
    if (!status.isOK())
        return status;

    status = bsonExtractIntegerField(argsObj, kCandidateIdFieldName, &_candidateId);
    if (!status.isOK())
        return status;

    status = bsonExtractIntegerField(argsObj, kConfigVersionFieldName, &_cfgver);
    if (!status.isOK())
        return status;

    status = bsonExtractStringField(argsObj, kSetNameFieldName, &_setName);
    if (!status.isOK())
        return status;

    status = bsonExtractBooleanField(argsObj, kDryRunFieldName, &_dryRun);
    if (!status.isOK())
        return status;

    status = bsonExtractOpTimeField(argsObj, kLastCommittedOpFieldName, &_lastCommittedOp);
    if (!status.isOK())
        return status;

    return Status::OK();
}
예제 #2
0
StatusWith<MongosType> MongosType::fromBSON(const BSONObj& source) {
    MongosType mt;

    {
        std::string mtName;
        Status status = bsonExtractStringField(source, name.name(), &mtName);
        if (!status.isOK())
            return status;
        mt._name = mtName;
    }

    {
        BSONElement mtPingElem;
        Status status = bsonExtractTypedField(source, ping.name(), BSONType::Date, &mtPingElem);
        if (!status.isOK())
            return status;
        mt._ping = mtPingElem.date();
    }

    {
        long long mtUptime;
        Status status = bsonExtractIntegerField(source, uptime.name(), &mtUptime);
        if (!status.isOK())
            return status;
        mt._uptime = mtUptime;
    }

    {
        bool mtWaiting;
        Status status = bsonExtractBooleanField(source, waiting.name(), &mtWaiting);
        if (!status.isOK())
            return status;
        mt._waiting = mtWaiting;
    }

    if (source.hasField(mongoVersion.name())) {
        std::string mtMongoVersion;
        Status status = bsonExtractStringField(source, mongoVersion.name(), &mtMongoVersion);
        if (!status.isOK())
            return status;
        mt._mongoVersion = mtMongoVersion;
    }

    if (source.hasField(configVersion.name())) {
        long long mtConfigVersion;
        Status status = bsonExtractIntegerField(source, configVersion.name(), &mtConfigVersion);
        if (!status.isOK())
            return status;
        mt._configVersion = mtConfigVersion;
    }

    return mt;
}
예제 #3
0
파일: bgsync.cpp 프로젝트: mpobrien/mongo
OpTimeWithHash BackgroundSync::_readLastAppliedOpTimeWithHash(OperationContext* opCtx) {
    BSONObj oplogEntry;
    try {
        bool success = writeConflictRetry(
            opCtx, "readLastAppliedHash", NamespaceString::kRsOplogNamespace.ns(), [&] {
                Lock::DBLock lk(opCtx, "local", MODE_X);
                return Helpers::getLast(
                    opCtx, NamespaceString::kRsOplogNamespace.ns().c_str(), oplogEntry);
            });

        if (!success) {
            // This can happen when we are to do an initial sync.  lastHash will be set
            // after the initial sync is complete.
            return OpTimeWithHash(0);
        }
    } catch (const DBException& ex) {
        severe() << "Problem reading " << NamespaceString::kRsOplogNamespace.ns() << ": "
                 << redact(ex);
        fassertFailed(18904);
    }
    long long hash;
    auto status = bsonExtractIntegerField(oplogEntry, kHashFieldName, &hash);
    if (!status.isOK()) {
        severe() << "Most recent entry in " << NamespaceString::kRsOplogNamespace.ns()
                 << " is missing or has invalid \"" << kHashFieldName
                 << "\" field. Oplog entry: " << redact(oplogEntry) << ": " << redact(status);
        fassertFailed(18902);
    }
    OplogEntry parsedEntry(oplogEntry);
    return OpTimeWithHash(hash, parsedEntry.getOpTime());
}
StatusWith<long long> ShardingCatalogManager::_runCountCommandOnConfig(OperationContext* opCtx,
                                                                       const NamespaceString& nss,
                                                                       BSONObj query) {
    BSONObjBuilder countBuilder;
    countBuilder.append("count", nss.coll());
    countBuilder.append("query", query);

    auto configShard = Grid::get(opCtx)->shardRegistry()->getConfigShard();
    auto resultStatus =
        configShard->runCommandWithFixedRetryAttempts(opCtx,
                                                      kConfigReadSelector,
                                                      nss.db().toString(),
                                                      countBuilder.done(),
                                                      Shard::kDefaultConfigCommandTimeout,
                                                      Shard::RetryPolicy::kIdempotent);
    if (!resultStatus.isOK()) {
        return resultStatus.getStatus();
    }
    if (!resultStatus.getValue().commandStatus.isOK()) {
        return resultStatus.getValue().commandStatus;
    }

    auto responseObj = std::move(resultStatus.getValue().response);

    long long result;
    auto status = bsonExtractIntegerField(responseObj, "n", &result);
    if (!status.isOK()) {
        return status;
    }

    return result;
}
예제 #5
0
파일: bgsync.cpp 프로젝트: gormanb/mongo
long long BackgroundSync::_readLastAppliedHash(OperationContext* txn) {
    BSONObj oplogEntry;
    try {
        MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
            ScopedTransaction transaction(txn, MODE_IX);
            Lock::DBLock lk(txn->lockState(), "local", MODE_X);
            bool success = Helpers::getLast(txn, rsOplogName.c_str(), oplogEntry);
            if (!success) {
                // This can happen when we are to do an initial sync.  lastHash will be set
                // after the initial sync is complete.
                return 0;
            }
        }
        MONGO_WRITE_CONFLICT_RETRY_LOOP_END(txn, "readLastAppliedHash", rsOplogName);
    } catch (const DBException& ex) {
        severe() << "Problem reading " << rsOplogName << ": " << redact(ex);
        fassertFailed(18904);
    }
    long long hash;
    auto status = bsonExtractIntegerField(oplogEntry, kHashFieldName, &hash);
    if (!status.isOK()) {
        severe() << "Most recent entry in " << rsOplogName << " is missing or has invalid \""
                 << kHashFieldName << "\" field. Oplog entry: " << redact(oplogEntry) << ": "
                 << redact(status);
        fassertFailed(18902);
    }
    return hash;
}
예제 #6
0
    bool run(OperationContext* txn,
             const std::string& db,
             BSONObj& cmdObj,
             int options,
             std::string& errmsg,
             BSONObjBuilder& result) final {
        long long op;
        uassertStatusOK(bsonExtractIntegerField(cmdObj, "op", &op));

        log() << "going to kill op: " << op;
        result.append("info", "attempting to kill op");

        // Internally opid is an unsigned 32-bit int, but as BSON only has signed integer types,
        // we wrap values exceeding 2,147,483,647 to negative numbers. The following undoes this
        // transformation, so users can use killOp on the (negative) opid they received.
        if (op >= std::numeric_limits<int>::min() && op < 0)
            op += 1ull << 32;

        uassert(26823,
                str::stream() << "invalid op : " << op,
                (op >= 0) && (op <= std::numeric_limits<unsigned int>::max()));

        getGlobalServiceContext()->killOperation(static_cast<unsigned int>(op));
        return true;
    }
StatusWith<long long> CatalogManagerReplicaSet::_runCountCommandOnConfig(const HostAndPort& target,
                                                                         const NamespaceString& ns,
                                                                         BSONObj query) {
    BSONObjBuilder countBuilder;
    countBuilder.append("count", ns.coll());
    countBuilder.append("query", query);
    _appendReadConcern(&countBuilder);

    auto responseStatus =
        grid.shardRegistry()->runCommandOnConfig(target, ns.db().toString(), countBuilder.done());

    if (!responseStatus.isOK()) {
        return responseStatus.getStatus();
    }

    auto responseObj = responseStatus.getValue();
    Status status = Command::getStatusFromCommandResult(responseObj);
    if (!status.isOK()) {
        return status;
    }

    long long result;
    status = bsonExtractIntegerField(responseObj, "n", &result);
    if (!status.isOK()) {
        return status;
    }

    return result;
}
예제 #8
0
Status HandshakeArgs::initialize(const BSONObj& argsObj) {
    Status status = bsonCheckOnlyHasFields("HandshakeArgs", argsObj, kLegalHandshakeFieldNames);
    if (!status.isOK())
        return status;

    BSONElement oid;
    status = bsonExtractTypedField(argsObj, kRIDFieldName, jstOID, &oid);
    if (!status.isOK())
        return status;
    _rid = oid.OID();
    _hasRid = true;

    status = bsonExtractIntegerField(argsObj, kMemberIdFieldName, &_memberId);
    if (!status.isOK()) {
        // field not necessary for master slave, do not return NoSuchKey Error
        if (status != ErrorCodes::NoSuchKey) {
            return status;
        }
        _memberId = -1;
    } else {
        _hasMemberId = true;
    }

    return Status::OK();
}
    Status ReplSetRequestVotesResponse::initialize(const BSONObj& argsObj) {
        Status status = bsonCheckOnlyHasFields("ReplSetRequestVotes",
                                               argsObj,
                                               kLegalResponseFieldNames);
        if (!status.isOK())
            return status;

        status = bsonExtractIntegerField(argsObj, kTermFieldName, &_term);
        if (!status.isOK())
            return status;

        status = bsonExtractBooleanField(argsObj, kVoteGrantedFieldName, &_voteGranted);
        if (!status.isOK())
            return status;

        status = bsonExtractStringField(argsObj, kReasonFieldName, &_reason);
        if (!status.isOK())
            return status;

        status = bsonExtractBooleanField(argsObj, kOkFieldName, &_ok);
        if (!status.isOK())
            return status;

        return Status::OK();
    }
Status ReplSetHeartbeatArgs::initialize(const BSONObj& argsObj) {
    Status status =
        bsonCheckOnlyHasFields("ReplSetHeartbeatArgs", argsObj, kLegalHeartbeatFieldNames);
    if (!status.isOK())
        return status;

    status = bsonExtractBooleanFieldWithDefault(argsObj, kCheckEmptyFieldName, false, &_checkEmpty);
    if (!status.isOK())
        return status;
    _hasCheckEmpty = true;

    status = bsonExtractIntegerField(argsObj, kProtocolVersionFieldName, &_protocolVersion);
    if (!status.isOK())
        return status;
    _hasProtocolVersion = true;

    status = bsonExtractIntegerField(argsObj, kConfigVersionFieldName, &_configVersion);
    if (!status.isOK())
        return status;
    _hasConfigVersion = true;

    status = bsonExtractIntegerFieldWithDefault(argsObj, kSenderIdFieldName, -1, &_senderId);
    if (!status.isOK())
        return status;
    _hasSenderId = true;

    status = bsonExtractStringField(argsObj, kSetNameFieldName, &_setName);
    if (!status.isOK())
        return status;
    _hasSetName = true;

    std::string hostAndPortString;
    status =
        bsonExtractStringFieldWithDefault(argsObj, kSenderHostFieldName, "", &hostAndPortString);
    if (!status.isOK())
        return status;

    if (!hostAndPortString.empty()) {
        status = _senderHost.initialize(hostAndPortString);
        if (!status.isOK())
            return status;
        _hasSenderHost = true;
    }

    return Status::OK();
}
예제 #11
0
    Status LastVote::initialize(const BSONObj& argsObj) {
        Status status = bsonCheckOnlyHasFields("VotedFar",
                                               argsObj,
                                               kLegalFieldNames);
        if (!status.isOK())
            return status;

        status = bsonExtractIntegerField(argsObj, kTermFieldName, &_term);
        if (!status.isOK())
            return status;

        status = bsonExtractIntegerField(argsObj, kCandidateIdFieldName, &_candidateId);
        if (!status.isOK())
            return status;

        return Status::OK();
    }
Status ShardingNetworkConnectionHook::validateHostImpl(
    const HostAndPort& remoteHost, const executor::RemoteCommandResponse& isMasterReply) {
    auto shard = grid.shardRegistry()->getShardNoReload(remoteHost.toString());
    if (!shard) {
        return {ErrorCodes::ShardNotFound,
                str::stream() << "No shard found for host: " << remoteHost.toString()};
    }

    long long configServerModeNumber;
    auto status = bsonExtractIntegerField(isMasterReply.data, "configsvr", &configServerModeNumber);

    switch (status.code()) {
        case ErrorCodes::OK: {
            // The ismaster response indicates remoteHost is a config server.
            if (!shard->isConfig()) {
                return {ErrorCodes::InvalidOptions,
                        str::stream() << "Surprised to discover that " << remoteHost.toString()
                                      << " believes it is a config server"};
            }
            using ConfigServerMode = CatalogManager::ConfigServerMode;
            const BSONElement setName = isMasterReply.data["setName"];
            return grid.forwardingCatalogManager()->scheduleReplaceCatalogManagerIfNeeded(
                (configServerModeNumber == 0 ? ConfigServerMode::SCCC : ConfigServerMode::CSRS),
                (setName.type() == String ? setName.valueStringData() : StringData()),
                remoteHost);
        }
        case ErrorCodes::NoSuchKey: {
            // The ismaster response indicates that remoteHost is not a config server, or that
            // the config server is running a version prior to the 3.1 development series.
            if (!shard->isConfig()) {
                return Status::OK();
            }
            long long remoteMaxWireVersion;
            status = bsonExtractIntegerFieldWithDefault(isMasterReply.data,
                                                        "maxWireVersion",
                                                        RELEASE_2_4_AND_BEFORE,
                                                        &remoteMaxWireVersion);
            if (!status.isOK()) {
                return status;
            }
            if (remoteMaxWireVersion < FIND_COMMAND) {
                // Prior to the introduction of the find command and the 3.1 release series, it was
                // not possible to distinguish a config server from a shard server from its ismaster
                // response. As such, we must assume that the system is properly configured.
                return Status::OK();
            }
            return {ErrorCodes::InvalidOptions,
                    str::stream() << "Surprised to discover that " << remoteHost.toString()
                                  << " does not believe it is a config server"};
        }
        default:
            // The ismaster response was malformed.
            return status;
    }
}
예제 #13
0
void ChunkManager::calcInitSplitsAndShards(OperationContext* txn,
                                           const ShardId& primaryShardId,
                                           const vector<BSONObj>* initPoints,
                                           const set<ShardId>* initShardIds,
                                           vector<BSONObj>* splitPoints,
                                           vector<ShardId>* shardIds) const {
    verify(_chunkMap.size() == 0);

    Chunk c(this,
            _keyPattern.getKeyPattern().globalMin(),
            _keyPattern.getKeyPattern().globalMax(),
            primaryShardId);

    if (!initPoints || !initPoints->size()) {
        // discover split points
        const auto primaryShard = grid.shardRegistry()->getShard(txn, primaryShardId);
        auto targetStatus =
            primaryShard->getTargeter()->findHost({ReadPreference::PrimaryPreferred, TagSet{}});
        uassertStatusOK(targetStatus);

        NamespaceString nss(getns());
        auto result = grid.shardRegistry()->runCommand(
            txn, targetStatus.getValue(), nss.db().toString(), BSON("count" << nss.coll()));

        long long numObjects = 0;
        uassertStatusOK(result.getStatus());
        uassertStatusOK(Command::getStatusFromCommandResult(result.getValue()));
        uassertStatusOK(bsonExtractIntegerField(result.getValue(), "n", &numObjects));

        if (numObjects > 0)
            c.pickSplitVector(txn, *splitPoints, Chunk::MaxChunkSize);

        // since docs already exists, must use primary shard
        shardIds->push_back(primaryShardId);
    } else {
        // make sure points are unique and ordered
        set<BSONObj> orderedPts;
        for (unsigned i = 0; i < initPoints->size(); ++i) {
            BSONObj pt = (*initPoints)[i];
            orderedPts.insert(pt);
        }
        for (set<BSONObj>::iterator it = orderedPts.begin(); it != orderedPts.end(); ++it) {
            splitPoints->push_back(*it);
        }

        if (!initShardIds || !initShardIds->size()) {
            // If not specified, only use the primary shard (note that it's not safe for mongos
            // to put initial chunks on other shards without the primary mongod knowing).
            shardIds->push_back(primaryShardId);
        } else {
            std::copy(initShardIds->begin(), initShardIds->end(), std::back_inserter(*shardIds));
        }
    }
}
예제 #14
0
Status checkAdminDatabase(OperationContext* txn, Database* adminDb) {
    // Assumes txn holds MODE_X or MODE_S lock on "admin" database.
    if (!adminDb) {
        return Status::OK();
    }
    Collection* const usersCollection =
        adminDb->getCollection(AuthorizationManager::usersCollectionNamespace);
    const bool hasUsers =
        usersCollection && !Helpers::findOne(txn, usersCollection, BSONObj(), false).isNull();
    Collection* const adminVersionCollection =
        adminDb->getCollection(AuthorizationManager::versionCollectionNamespace);
    BSONObj authSchemaVersionDocument;
    if (!adminVersionCollection ||
        !Helpers::findOne(txn,
                          adminVersionCollection,
                          AuthorizationManager::versionDocumentQuery,
                          authSchemaVersionDocument)) {
        if (!hasUsers) {
            // It's OK to have no auth version document if there are no user documents.
            return Status::OK();
        }
        std::string msg = str::stream()
            << "During initial sync, found documents in "
            << AuthorizationManager::usersCollectionNamespace.ns()
            << " but could not find an auth schema version document in "
            << AuthorizationManager::versionCollectionNamespace.ns() << ".  "
            << "This indicates that the primary of this replica set was not successfully "
               "upgraded to schema version "
            << AuthorizationManager::schemaVersion26Final
            << ", which is the minimum supported schema version in this version of MongoDB";
        return {ErrorCodes::AuthSchemaIncompatible, msg};
    }
    long long foundSchemaVersion;
    Status status = bsonExtractIntegerField(authSchemaVersionDocument,
                                            AuthorizationManager::schemaVersionFieldName,
                                            &foundSchemaVersion);
    if (!status.isOK()) {
        std::string msg = str::stream()
            << "During initial sync, found malformed auth schema version document: "
            << status.toString() << "; document: " << authSchemaVersionDocument;
        return {ErrorCodes::AuthSchemaIncompatible, msg};
    }
    if ((foundSchemaVersion != AuthorizationManager::schemaVersion26Final) &&
        (foundSchemaVersion != AuthorizationManager::schemaVersion28SCRAM)) {
        std::string msg = str::stream()
            << "During initial sync, found auth schema version " << foundSchemaVersion
            << ", but this version of MongoDB only supports schema versions "
            << AuthorizationManager::schemaVersion26Final << " and "
            << AuthorizationManager::schemaVersion28SCRAM;
        return {ErrorCodes::AuthSchemaIncompatible, msg};
    }

    return Status::OK();
}
예제 #15
0
 Status bsonExtractIntegerFieldWithDefault(const BSONObj& object,
                                           const StringData& fieldName,
                                           long long defaultValue,
                                           long long* out) {
     Status status = bsonExtractIntegerField(object, fieldName, out);
     if (status == ErrorCodes::NoSuchKey) {
         *out = defaultValue;
         status = Status::OK();
     }
     return status;
 }
예제 #16
0
StatusWith<LocksType> LocksType::fromBSON(const BSONObj& source) {
    LocksType lock;

    {
        std::string lockName;
        Status status = bsonExtractStringField(source, name.name(), &lockName);
        if (!status.isOK())
            return status;
        lock._name = lockName;
    }

    {
        long long lockStateInt;
        Status status = bsonExtractIntegerField(source, state.name(), &lockStateInt);
        if (!status.isOK())
            return status;
        lock._state = static_cast<State>(lockStateInt);
    }

    if (source.hasField(process.name())) {
        std::string lockProcess;
        Status status = bsonExtractStringField(source, process.name(), &lockProcess);
        if (!status.isOK())
            return status;
        lock._process = lockProcess;
    }

    if (source.hasField(lockID.name())) {
        BSONElement lockIDElem;
        Status status = bsonExtractTypedField(source, lockID.name(), BSONType::jstOID, &lockIDElem);
        if (!status.isOK())
            return status;
        lock._lockID = lockIDElem.OID();
    }

    if (source.hasField(who.name())) {
        std::string lockWho;
        Status status = bsonExtractStringField(source, who.name(), &lockWho);
        if (!status.isOK())
            return status;
        lock._who = lockWho;
    }

    if (source.hasField(why.name())) {
        std::string lockWhy;
        Status status = bsonExtractStringField(source, why.name(), &lockWhy);
        if (!status.isOK())
            return status;
        lock._why = lockWhy;
    }

    return lock;
}
예제 #17
0
        virtual bool run(OperationContext* txn, const string& , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
            Status status = getGlobalReplicationCoordinator()->checkReplEnabledForCommand(&result);
            if (!status.isOK())
                return appendCommandStatus(result, status);

            const bool force = cmdObj["force"].trueValue();

            long long stepDownForSecs = cmdObj.firstElement().numberLong();
            if (stepDownForSecs == 0) {
                stepDownForSecs = 60;
            }
            else if (stepDownForSecs < 0) {
                status = Status(ErrorCodes::BadValue,
                                "stepdown period must be a positive integer");
                return appendCommandStatus(result, status);
            }

            long long secondaryCatchUpPeriodSecs;
            status = bsonExtractIntegerField(cmdObj,
                                             "secondaryCatchUpPeriodSecs",
                                             &secondaryCatchUpPeriodSecs);
            if (status.code() == ErrorCodes::NoSuchKey) {
                // if field is absent, default values
                if (force) {
                    secondaryCatchUpPeriodSecs = 0;
                }
                else {
                    secondaryCatchUpPeriodSecs = 10;
                }
            }
            else if (!status.isOK()) {
                return appendCommandStatus(result, status);
            }

            if (secondaryCatchUpPeriodSecs < 0) {
                status = Status(ErrorCodes::BadValue,
                                "secondaryCatchUpPeriodSecs period must be a positive or absent");
                return appendCommandStatus(result, status);
            }

            if (stepDownForSecs < secondaryCatchUpPeriodSecs) {
                status = Status(ErrorCodes::BadValue,
                                "stepdown period must be longer than secondaryCatchUpPeriodSecs");
                return appendCommandStatus(result, status);
            }

            status = getGlobalReplicationCoordinator()->stepDown(
                    txn,
                    force,
                    ReplicationCoordinator::Milliseconds(secondaryCatchUpPeriodSecs * 1000),
                    ReplicationCoordinator::Milliseconds(stepDownForSecs * 1000));
            return appendCommandStatus(result, status);
        }
Status ShardingNetworkConnectionHook::validateHostImpl(
    const HostAndPort& remoteHost, const executor::RemoteCommandResponse& isMasterReply) {
    auto shard = grid.shardRegistry()->getShardForHostNoReload(remoteHost);
    if (!shard) {
        return {ErrorCodes::ShardNotFound,
                str::stream() << "No shard found for host: " << remoteHost.toString()};
    }

    long long configServerModeNumber;
    auto status = bsonExtractIntegerField(isMasterReply.data, "configsvr", &configServerModeNumber);
    // TODO SERVER-22320 fix should collapse the switch to only NoSuchKey handling

    switch (status.code()) {
        case ErrorCodes::OK: {
            // The ismaster response indicates remoteHost is a config server.
            if (!shard->isConfig()) {
                return {ErrorCodes::InvalidOptions,
                        str::stream() << "Surprised to discover that " << remoteHost.toString()
                                      << " believes it is a config server"};
            }
            return Status::OK();
        }
        case ErrorCodes::NoSuchKey: {
            // The ismaster response indicates that remoteHost is not a config server, or that
            // the config server is running a version prior to the 3.1 development series.
            if (!shard->isConfig()) {
                return Status::OK();
            }
            long long remoteMaxWireVersion;
            status = bsonExtractIntegerFieldWithDefault(isMasterReply.data,
                                                        "maxWireVersion",
                                                        RELEASE_2_4_AND_BEFORE,
                                                        &remoteMaxWireVersion);
            if (!status.isOK()) {
                return status;
            }
            if (remoteMaxWireVersion < FIND_COMMAND) {
                // Prior to the introduction of the find command and the 3.1 release series, it was
                // not possible to distinguish a config server from a shard server from its ismaster
                // response. As such, we must assume that the system is properly configured.
                return Status::OK();
            }
            return {ErrorCodes::InvalidOptions,
                    str::stream() << "Surprised to discover that " << remoteHost.toString()
                                  << " does not believe it is a config server"};
        }
        default:
            // The ismaster response was malformed.
            return status;
    }
}
예제 #19
0
    Status ReplSetRequestVotesArgs::initialize(const BSONObj& argsObj) {
        Status status = bsonCheckOnlyHasFields("ReplSetRequestVotes",
                                               argsObj,
                                               kLegalArgsFieldNames);
        if (!status.isOK())
            return status;

        status = bsonExtractIntegerField(argsObj, kTermFieldName, &_term);
        if (!status.isOK())
            return status;

        status = bsonExtractIntegerField(argsObj, kCandidateIdFieldName, &_candidateId);
        if (!status.isOK())
            return status;

        status = bsonExtractIntegerField(argsObj, kConfigVersionFieldName, &_cfgver);
        if (!status.isOK())
            return status;

        status = bsonExtractStringField(argsObj, kSetNameFieldName, &_setName);
        if (!status.isOK())
            return status;

        // extracting the lastCommittedOp is a bit of a process
        BSONObj lastCommittedOp = argsObj[kLastCommittedOpFieldName].Obj();
        Timestamp ts;
        status = bsonExtractTimestampField(lastCommittedOp, kOpTimeFieldName, &ts);
        if (!status.isOK())
            return status;
        long long term;
        status = bsonExtractIntegerField(lastCommittedOp, kTermFieldName, &term);
        if (!status.isOK())
            return status;
        _lastCommittedOp = OpTime(lastCommittedOp[kOpTimeFieldName].timestamp(),
                                  lastCommittedOp[kTermFieldName].Long());

        return Status::OK();
    }
/**
 * Returns true if config version in replSetUpdatePosition response is higher than config version in
 * locally generated update command request object.
 * Returns false if config version is missing in either document.
 */
bool _isTargetConfigNewerThanRequest(const BSONObj& commandResult, const BSONObj& commandRequest) {
    long long targetConfigVersion;
    if (!bsonExtractIntegerField(commandResult, kConfigVersionFieldName, &targetConfigVersion)
             .isOK()) {
        return false;
    }

    const long long localConfigVersion =
        _parseCommandRequestConfigVersion<UpdatePositionArgs>(commandRequest);
    if (localConfigVersion == -1) {
        return false;
    }

    return targetConfigVersion > localConfigVersion;
}
예제 #21
0
StatusWith<LogicalTimeMetadata> LogicalTimeMetadata::readFromMetadata(
    const BSONElement& metadataElem) {
    if (metadataElem.eoo()) {
        return LogicalTimeMetadata();
    }

    const auto& obj = metadataElem.Obj();

    Timestamp ts;
    Status status = bsonExtractTimestampField(obj, kClusterTimeFieldName, &ts);
    if (!status.isOK()) {
        return status;
    }

    BSONElement signatureElem;
    status = bsonExtractTypedField(obj, kSignatureFieldName, Object, &signatureElem);
    if (!status.isOK()) {
        return status;
    }

    const auto& signatureObj = signatureElem.Obj();

    // Extract BinData type signature hash and construct a SHA1Block instance from it.
    BSONElement hashElem;
    status = bsonExtractTypedField(signatureObj, kSignatureHashFieldName, BinData, &hashElem);
    if (!status.isOK()) {
        return status;
    }

    int hashLength = 0;
    auto rawBinSignature = hashElem.binData(hashLength);
    BSONBinData proofBinData(rawBinSignature, hashLength, hashElem.binDataType());
    auto proofStatus = SHA1Block::fromBinData(proofBinData);

    if (!proofStatus.isOK()) {
        return proofStatus.getStatus();
    }

    long long keyId;
    status = bsonExtractIntegerField(signatureObj, kSignatureKeyIdFieldName, &keyId);
    if (!status.isOK()) {
        return status;
    }

    return LogicalTimeMetadata(
        SignedLogicalTime(LogicalTime(ts), std::move(proofStatus.getValue()), keyId));
}
예제 #22
0
파일: kill_op.cpp 프로젝트: ChineseDr/mongo
    static long long parseOpId(const BSONObj& cmdObj) {
        long long op;
        uassertStatusOK(bsonExtractIntegerField(cmdObj, "op", &op));

        // Internally opid is an unsigned 32-bit int, but as BSON only has signed integer types,
        // we wrap values exceeding 2,147,483,647 to negative numbers. The following undoes this
        // transformation, so users can use killOp on the (negative) opid they received.
        if (op >= std::numeric_limits<int>::min() && op < 0)
            op += 1ull << 32;

        uassert(26823,
                str::stream() << "invalid op : " << op,
                (op >= 0) && (op <= std::numeric_limits<unsigned int>::max()));


        return op;
    }
예제 #23
0
StatusWith<ChunkSizeSettingsType> ChunkSizeSettingsType::fromBSON(const BSONObj& obj) {
    long long maxChunkSizeMB;
    Status status = bsonExtractIntegerField(obj, kValue, &maxChunkSizeMB);
    if (!status.isOK())
        return status;

    const uint64_t maxChunkSizeBytes = maxChunkSizeMB * 1024 * 1024;

    if (!checkMaxChunkSizeValid(maxChunkSizeBytes)) {
        return {ErrorCodes::BadValue,
                str::stream() << maxChunkSizeMB << " is not a valid value for " << kKey};
    }

    ChunkSizeSettingsType settings;
    settings._maxChunkSizeBytes = maxChunkSizeBytes;

    return settings;
}
예제 #24
0
Status bsonExtractOpTimeField(const BSONObj& object, StringData fieldName, repl::OpTime* out) {
    BSONElement element;
    Status status = bsonExtractTypedField(object, fieldName, Object, &element);
    if (!status.isOK())
        return status;

    BSONObj opTimeObj = element.Obj();
    Timestamp ts;
    status = bsonExtractTimestampField(opTimeObj, kTimestampFieldName, &ts);
    if (!status.isOK())
        return status;
    long long term;
    status = bsonExtractIntegerField(opTimeObj, kTermFieldName, &term);
    if (!status.isOK())
        return status;
    *out = repl::OpTime(ts, term);
    return Status::OK();
}
예제 #25
0
Status ReadAfterOpTimeArgs::initialize(const BSONObj& cmdObj) {
    auto afterElem = cmdObj[ReadAfterOpTimeArgs::kRootFieldName];

    if (afterElem.eoo()) {
        return Status::OK();
    }

    if (!afterElem.isABSONObj()) {
        return Status(ErrorCodes::FailedToParse, "'after' field should be an object");
    }

    BSONObj readAfterObj = afterElem.Obj();
    BSONElement opTimeElem;
    auto opTimeStatus = bsonExtractTypedField(
        readAfterObj, ReadAfterOpTimeArgs::kOpTimeFieldName, Object, &opTimeElem);

    if (!opTimeStatus.isOK()) {
        return opTimeStatus;
    }

    BSONObj opTimeObj = opTimeElem.Obj();
    BSONElement timestampElem;

    Timestamp timestamp;
    auto timestampStatus = bsonExtractTimestampField(
        opTimeObj, ReadAfterOpTimeArgs::kOpTimestampFieldName, &timestamp);

    if (!timestampStatus.isOK()) {
        return timestampStatus;
    }

    long long termNumber;
    auto termStatus =
        bsonExtractIntegerField(opTimeObj, ReadAfterOpTimeArgs::kOpTermFieldName, &termNumber);

    if (!termStatus.isOK()) {
        return termStatus;
    }

    _opTime = OpTime(timestamp, termNumber);

    return Status::OK();
}
예제 #26
0
파일: util.cpp 프로젝트: AshishSanju/mongo
StatusWith<FTDCType> getBSONDocumentType(const BSONObj& obj) {
    long long value;

    Status status = bsonExtractIntegerField(obj, kFTDCTypeField, &value);
    if (!status.isOK()) {
        return {status};
    }

    if (static_cast<FTDCType>(value) != FTDCType::kMetricChunk &&
        static_cast<FTDCType>(value) != FTDCType::kMetadata) {
        return {ErrorCodes::BadValue,
                str::stream() << "Field '" << std::string(kFTDCTypeField)
                              << "' is not an expected value, found '"
                              << value
                              << "'"};
    }

    return {static_cast<FTDCType>(value)};
}
예제 #27
0
파일: kill_op.cpp 프로젝트: lalford/mongo
        bool run(OperationContext* txn,
                 const std::string& db,
                 BSONObj& cmdObj,
                 int options,
                 std::string& errmsg,
                 BSONObjBuilder& result,
                 bool fromRepl) final {

            long long op;
            uassertStatusOK(bsonExtractIntegerField(cmdObj, "op", &op));

            log() << "going to kill op: " << op;
            result.append("info", "attempting to kill op");

            uassert(26823, str::stream() << "invalid op : " << op,
                    (op >= 0) && (op <= std::numeric_limits<unsigned int>::max()));

            getGlobalServiceContext()->killOperation(static_cast<unsigned int>(op));
            return true;
        }
예제 #28
0
/**
 * Returns true if config version in replSetUpdatePosition response is higher than config version in
 * locally generated update command request object.
 * Returns false if config version is missing in either document.
 */
bool _isTargetConfigNewerThanRequest(
    const BSONObj& commandResult,
    const BSONObj& commandRequest,
    ReplicationCoordinator::ReplSetUpdatePositionCommandStyle commandStyle) {
    long long targetConfigVersion;
    if (!bsonExtractIntegerField(commandResult, kConfigVersionFieldName, &targetConfigVersion)
             .isOK()) {
        return false;
    }

    const long long localConfigVersion =
        commandStyle == ReplicationCoordinator::ReplSetUpdatePositionCommandStyle::kNewStyle
        ? _parseCommandRequestConfigVersion<UpdatePositionArgs>(commandRequest)
        : _parseCommandRequestConfigVersion<OldUpdatePositionArgs>(commandRequest);
    if (localConfigVersion == -1) {
        return false;
    }

    return targetConfigVersion > localConfigVersion;
}
Status ShardingNetworkConnectionHook::validateHostImpl(
    const HostAndPort& remoteHost, const executor::RemoteCommandResponse& isMasterReply) {
    auto shard = grid.shardRegistry()->getShardForHostNoReload(remoteHost);
    if (!shard) {
        return {ErrorCodes::ShardNotFound,
                str::stream() << "No shard found for host: " << remoteHost.toString()};
    }

    long long configServerModeNumber;
    auto status = bsonExtractIntegerField(isMasterReply.data, "configsvr", &configServerModeNumber);
    // TODO SERVER-22320 fix should collapse the switch to only NoSuchKey handling

    switch (status.code()) {
        case ErrorCodes::OK: {
            // The ismaster response indicates remoteHost is a config server.
            if (!shard->isConfig()) {
                return {ErrorCodes::InvalidOptions,
                        str::stream() << "Surprised to discover that " << remoteHost.toString()
                                      << " believes it is a config server"};
            }
            return Status::OK();
        }
        case ErrorCodes::NoSuchKey: {
            // The ismaster response indicates that remoteHost is not a config server, or that
            // the config server is running a version prior to the 3.1 development series.
            if (!shard->isConfig()) {
                return Status::OK();
            }

            return {ErrorCodes::InvalidOptions,
                    str::stream() << "Surprised to discover that " << remoteHost.toString()
                                  << " does not believe it is a config server"};
        }
        default:
            // The ismaster response was malformed.
            return status;
    }
}
예제 #30
0
StatusWith<long long> CatalogManagerReplicaSet::_runCountCommand(const HostAndPort& target,
                                                                 const NamespaceString& ns,
                                                                 BSONObj query) {
    BSONObj countCmd = BSON("count" << ns.coll() << "query" << query);
    auto responseStatus = grid.shardRegistry()->runCommand(target, ns.db().toString(), countCmd);
    if (!responseStatus.isOK()) {
        return responseStatus.getStatus();
    }

    auto responseObj = responseStatus.getValue();
    Status status = Command::getStatusFromCommandResult(responseObj);
    if (!status.isOK()) {
        return status;
    }

    long long result;
    status = bsonExtractIntegerField(responseObj, "n", &result);
    if (!status.isOK()) {
        return status;
    }

    return result;
}