void LegacyReplicationCoordinator::prepareReplSetUpdatePositionCommand(
         OperationContext* txn,
         BSONObjBuilder* cmdBuilder) {
     invariant(getReplicationMode() == modeReplSet);
     boost::lock_guard<boost::mutex> lock(_mutex);
     cmdBuilder->append("replSetUpdatePosition", 1);
     // create an array containing objects each member connected to us and for ourself
     BSONArrayBuilder arrayBuilder(cmdBuilder->subarrayStart("optimes"));
     OID myID = getMyRID(txn);
     {
         for (SlaveOpTimeMap::const_iterator itr = _slaveOpTimeMap.begin();
                 itr != _slaveOpTimeMap.end(); ++itr) {
             const OID& rid = itr->first;
             const BSONObj& config = mapFindWithDefault(_ridConfigMap, rid, BSONObj());
             BSONObjBuilder entry(arrayBuilder.subobjStart());
             entry.append("_id", rid);
             entry.append("optime", itr->second);
             // SERVER-14550 Even though the "config" field isn't used on the other end in 2.8,
             // we need to keep sending it for 2.6 compatibility.
             // TODO(spencer): Remove this after 2.8 is released.
             if (rid == myID) {
                 entry.append("config", theReplSet->myConfig().asBson());
             }
             else {
                 entry.append("config", config);
             }
         }
     }
 }
示例#2
0
文件: mmap.cpp 项目: C2Devel/mongo
 MongoFile* MongoFileFinder::findByPath(const std::string& path) const {
     return mapFindWithDefault(pathToFile,
     #if BOOST_VERSION >= 104400
         boost::filesystem::absolute(path).generic_string(),
     #else
         boost::filesystem::system_complete(path).string(),
     #endif
         static_cast<MongoFile*>(NULL));
 }
void ConnectionPoolStats::updateStatsForHost(HostAndPort host, ConnectionStatsPerHost newStats) {
    // Update stats for this host.
    auto hostStats = mapFindWithDefault(statsByHost, host);
    hostStats += newStats;
    statsByHost.insert(std::make_pair(host, hostStats));

    // Update total connection stats.
    totalInUse += newStats.inUse;
    totalAvailable += newStats.available;
    totalCreated += newStats.created;
}
    Status LegacyReplicationCoordinator::setLastOptime(OperationContext* txn,
                                                       const OID& rid,
                                                       const OpTime& ts) {
        {
            boost::lock_guard<boost::mutex> lock(_mutex);
            if (ts <= mapFindWithDefault(_slaveOpTimeMap, rid, OpTime())) {
                // Only update if ts is newer than what we have already
                return Status::OK();
            }
            BSONObj config = mapFindWithDefault(_ridConfigMap, rid, BSONObj());
            LOG(2) << "received notification that node with RID " << rid << " and config " << config
                    << " has reached optime: " << ts.toStringPretty();

            if (rid != getMyRID(txn)) {
                // TODO(spencer): Remove this invariant for backwards compatibility
                invariant(!config.isEmpty());
                // This is what updates the progress information used for satisfying write concern
                // and wakes up threads waiting for replication.
                if (!updateSlaveTracking(BSON("_id" << rid), config, ts)) {
                    return Status(ErrorCodes::NodeNotFound,
                                  str::stream() << "could not update node with _id: "
                                          << config["_id"].Int()
                                          << " because it cannot be found in current ReplSetConfig");
                }
            }

            // This updates the _slaveOpTimeMap which is used for forwarding slave progress
            // upstream in chained replication.
            LOG(2) << "Updating our knowledge of the replication progress for node with RID " <<
                    rid << " to be at optime " << ts;
            _slaveOpTimeMap[rid] = ts;
        }

        if (getReplicationMode() == modeReplSet && !getCurrentMemberState().primary()) {
            // pass along if we are not primary
            theReplSet->syncSourceFeedback.forwardSlaveProgress();
        }
        return Status::OK();
    }
示例#5
0
    void PrivilegeSet::_rebuildEntry(const StringData& resource,
                                     ResourcePrivilegeCacheEntry* entry) {
        const ActionSet emptyActionSet;
        entry->actions.removeAllActions();

        for (PrincipalPrivilegeMap::const_iterator iter = _byPrincipal.begin(),
                 end = _byPrincipal.end();
             iter != end; ++iter) {

            entry->actions.addAllActionsFromSet(
                    mapFindWithDefault(iter->second, resource, emptyActionSet));
        }

        entry->dirty = false;
    }
 ResponseStatus NetworkInterfaceMockWithMap::_getResponseFromMap(
                             const ReplicationExecutor::RemoteCommandRequest& request) {
     boost::unique_lock<boost::mutex> lk(_mutex);
     while (1) {
         BlockableResponseStatus result = mapFindWithDefault(
                                     _responses,
                                     request,
                                     BlockableResponseStatus(
                                         ResponseStatus(
                                              ErrorCodes::NoSuchKey,
                                              str::stream() << "Could not find response for " <<
                                              "Request(" << request.target.toString() << ", " <<
                                              request.dbname << ", " << request.cmdObj << ')'),
                                         false));
         if (!result.isBlocked) {
             return result.response;
         }
         _someResponseUnblocked.wait(lk);
     }
 }
RotatableFileWriter* RotatableFileManager::getFile(const std::string& name) {
    return mapFindWithDefault(_writers, name, static_cast<RotatableFileWriter*>(NULL));
}
BsonTemplateEvaluator::OperatorFn BsonTemplateEvaluator::operatorEvaluator(
    const std::string& op) const {
    return mapFindWithDefault(_operatorFunctions, op, OperatorFn());
}
示例#9
0
 FailPoint* FailPointRegistry::getFailPoint(const string& name) const {
     return mapFindWithDefault(_fpMap, name, static_cast<FailPoint*>(NULL));
 }
    virtual bool run(OperationContext* opCtx,
                     const string&,
                     const BSONObj& cmdObj,
                     BSONObjBuilder& result) {
        /* currently request to arbiter is (somewhat arbitrarily) an ismaster request that is not
           authenticated.
        */
        if (cmdObj["forShell"].trueValue()) {
            LastError::get(opCtx->getClient()).disable();
        }

        transport::Session::TagMask sessionTagsToSet = 0;
        transport::Session::TagMask sessionTagsToUnset = 0;

        // Tag connections to avoid closing them on stepdown.
        auto hangUpElement = cmdObj["hangUpOnStepDown"];
        if (!hangUpElement.eoo() && !hangUpElement.trueValue()) {
            sessionTagsToSet |= transport::Session::kKeepOpen;
        }

        auto& clientMetadataIsMasterState = ClientMetadataIsMasterState::get(opCtx->getClient());
        bool seenIsMaster = clientMetadataIsMasterState.hasSeenIsMaster();
        if (!seenIsMaster) {
            clientMetadataIsMasterState.setSeenIsMaster();
        }

        BSONElement element = cmdObj[kMetadataDocumentName];
        if (!element.eoo()) {
            if (seenIsMaster) {
                uasserted(ErrorCodes::ClientMetadataCannotBeMutated,
                          "The client metadata document may only be sent in the first isMaster");
            }

            auto swParseClientMetadata = ClientMetadata::parse(element);

            uassertStatusOK(swParseClientMetadata.getStatus());

            invariant(swParseClientMetadata.getValue());

            swParseClientMetadata.getValue().get().logClientMetadata(opCtx->getClient());

            clientMetadataIsMasterState.setClientMetadata(
                opCtx->getClient(), std::move(swParseClientMetadata.getValue()));
        }

        // Parse the optional 'internalClient' field. This is provided by incoming connections from
        // mongod and mongos.
        auto internalClientElement = cmdObj["internalClient"];
        if (internalClientElement) {
            sessionTagsToSet |= transport::Session::kInternalClient;

            uassert(ErrorCodes::TypeMismatch,
                    str::stream() << "'internalClient' must be of type Object, but was of type "
                                  << typeName(internalClientElement.type()),
                    internalClientElement.type() == BSONType::Object);

            bool foundMaxWireVersion = false;
            for (auto&& elem : internalClientElement.Obj()) {
                auto fieldName = elem.fieldNameStringData();
                if (fieldName == "minWireVersion") {
                    // We do not currently use 'internalClient.minWireVersion'.
                    continue;
                } else if (fieldName == "maxWireVersion") {
                    foundMaxWireVersion = true;

                    uassert(ErrorCodes::TypeMismatch,
                            str::stream() << "'maxWireVersion' field of 'internalClient' must be "
                                             "of type int, but was of type "
                                          << typeName(elem.type()),
                            elem.type() == BSONType::NumberInt);

                    // All incoming connections from mongod/mongos of earlier versions should be
                    // closed if the featureCompatibilityVersion is bumped to 3.6.
                    if (elem.numberInt() >=
                        WireSpec::instance().incomingInternalClient.maxWireVersion) {
                        sessionTagsToSet |=
                            transport::Session::kLatestVersionInternalClientKeepOpen;
                    } else {
                        sessionTagsToUnset |=
                            transport::Session::kLatestVersionInternalClientKeepOpen;
                    }
                } else {
                    uasserted(ErrorCodes::BadValue,
                              str::stream() << "Unrecognized field of 'internalClient': '"
                                            << fieldName
                                            << "'");
                }
            }

            uassert(ErrorCodes::BadValue,
                    "Missing required field 'maxWireVersion' of 'internalClient'",
                    foundMaxWireVersion);
        } else {
            sessionTagsToUnset |= (transport::Session::kInternalClient |
                                   transport::Session::kLatestVersionInternalClientKeepOpen);
            sessionTagsToSet |= transport::Session::kExternalClientKeepOpen;
        }

        auto session = opCtx->getClient()->session();
        if (session) {
            session->mutateTags(
                [sessionTagsToSet, sessionTagsToUnset](transport::Session::TagMask originalTags) {
                    // After a mongos sends the initial "isMaster" command with its mongos client
                    // information, it sometimes sends another "isMaster" command that is forwarded
                    // from its client. Once kInternalClient has been set, we assume that any future
                    // "isMaster" commands are forwarded in this manner, and we do not update the
                    // session tags.
                    if ((originalTags & transport::Session::kInternalClient) == 0) {
                        return (originalTags | sessionTagsToSet) & ~sessionTagsToUnset;
                    } else {
                        return originalTags;
                    }
                });
        }

        appendReplicationInfo(opCtx, result, 0);

        if (serverGlobalParams.clusterRole == ClusterRole::ConfigServer) {
            const int configServerModeNumber = 2;
            result.append("configsvr", configServerModeNumber);
        }

        result.appendNumber("maxBsonObjectSize", BSONObjMaxUserSize);
        result.appendNumber("maxMessageSizeBytes", MaxMessageSizeBytes);
        result.appendNumber("maxWriteBatchSize", write_ops::kMaxWriteBatchSize);
        result.appendDate("localTime", jsTime());
        result.append("logicalSessionTimeoutMinutes", localLogicalSessionTimeoutMinutes);
        result.appendNumber("connectionId", opCtx->getClient()->getConnectionId());

        if (internalClientElement) {
            result.append("minWireVersion",
                          WireSpec::instance().incomingInternalClient.minWireVersion);
            result.append("maxWireVersion",
                          WireSpec::instance().incomingInternalClient.maxWireVersion);
        } else {
            result.append("minWireVersion",
                          WireSpec::instance().incomingExternalClient.minWireVersion);
            result.append("maxWireVersion",
                          WireSpec::instance().incomingExternalClient.maxWireVersion);
        }

        result.append("readOnly", storageGlobalParams.readOnly);

        const auto parameter = mapFindWithDefault(ServerParameterSet::getGlobal()->getMap(),
                                                  "automationServiceDescriptor",
                                                  static_cast<ServerParameter*>(nullptr));
        if (parameter)
            parameter->append(opCtx, result, "automationServiceDescriptor");

        if (opCtx->getClient()->session()) {
            MessageCompressorManager::forSession(opCtx->getClient()->session())
                .serverNegotiate(cmdObj, &result);
        }

        auto& saslMechanismRegistry = SASLServerMechanismRegistry::get(opCtx->getServiceContext());
        saslMechanismRegistry.advertiseMechanismNamesForUser(opCtx, cmdObj, &result);

        return true;
    }
示例#11
0
    bool CmdLine::store( const std::vector<std::string>& argv,
                         boost::program_options::options_description& visible,
                         boost::program_options::options_description& hidden,
                         boost::program_options::positional_options_description& positional,
                         boost::program_options::variables_map &params ) {


        if (argv.empty())
            return false;

        {
            // setup binary name
            cmdLine.binaryName = argv[0];
            size_t i = cmdLine.binaryName.rfind( '/' );
            if ( i != string::npos )
                cmdLine.binaryName = cmdLine.binaryName.substr( i + 1 );
            
            // setup cwd
            char buffer[1024];
#ifdef _WIN32
            verify( _getcwd( buffer , 1000 ) );
#else
            verify( getcwd( buffer , 1000 ) );
#endif
            cmdLine.cwd = buffer;
        }
        

        /* don't allow guessing - creates ambiguities when some options are
         * prefixes of others. allow long disguises and don't allow guessing
         * to get away with our vvvvvvv trick. */
        int style = (((po::command_line_style::unix_style ^
                       po::command_line_style::allow_guessing) |
                      po::command_line_style::allow_long_disguise) ^
                     po::command_line_style::allow_sticky);


        try {

            po::options_description all;
            all.add( visible );
            all.add( hidden );

            po::store( po::command_line_parser(std::vector<std::string>(argv.begin() + 1,
                                                                        argv.end()))
                       .options( all )
                       .positional( positional )
                       .style( style )
                       .run(),
                       params );

            if ( params.count("config") ) {
                ifstream f( params["config"].as<string>().c_str() );
                if ( ! f.is_open() ) {
                    cout << "ERROR: could not read from config file" << endl << endl;
                    cout << visible << endl;
                    return false;
                }

                stringstream ss;
                CmdLine::parseConfigFile( f, ss );
                po::store( po::parse_config_file( ss , all ) , params );
                f.close();
            }

            po::notify(params);
        }
        catch (po::error &e) {
            cout << "error command line: " << e.what() << endl;
            cout << "use --help for help" << endl;
            //cout << visible << endl;
            return false;
        }

        {
            BSONArrayBuilder b;
            std::vector<std::string> censoredArgv = argv;
            censor(&censoredArgv);
            for (size_t i=0; i < censoredArgv.size(); i++) {
                b << censoredArgv[i];
            }
            argvArray = b.arr();
        }

        {
            BSONObjBuilder b;
            for (po::variables_map::const_iterator it(params.begin()), end(params.end()); it != end; it++){
                if (!it->second.defaulted()){
                    const string& key = it->first;
                    const po::variable_value& value = it->second;
                    const type_info& type = value.value().type();

                    if (type == typeid(string)){
                        if (value.as<string>().empty())
                            b.appendBool(key, true); // boost po uses empty string for flags like --quiet
                        else {
                            if ( _isPasswordArgument(key.c_str()) ) {
                                b.append( key, "<password>" );
                            }
                            else {
                                b.append( key, value.as<string>() );
                            }
                        }
                    }
                    else if (type == typeid(int))
                        b.append(key, value.as<int>());
                    else if (type == typeid(double))
                        b.append(key, value.as<double>());
                    else if (type == typeid(bool))
                        b.appendBool(key, value.as<bool>());
                    else if (type == typeid(long))
                        b.appendNumber(key, (long long)value.as<long>());
                    else if (type == typeid(unsigned))
                        b.appendNumber(key, (long long)value.as<unsigned>());
                    else if (type == typeid(unsigned long long))
                        b.appendNumber(key, (long long)value.as<unsigned long long>());
                    else if (type == typeid(vector<string>))
                        b.append(key, value.as<vector<string> >());
                    else
                        b.append(key, "UNKNOWN TYPE: " + demangleName(type));
                }
            }
            parsedOpts = b.obj();
        }

        if (params.count("verbose")) {
            logLevel = 1;
        }

        for (string s = "vv"; s.length() <= 12; s.append("v")) {
            if (params.count(s)) {
                logLevel = s.length();
            }
        }

        if (params.count("quiet")) {
            cmdLine.quiet = true;
        }

        if (params.count("traceExceptions")) {
            DBException::traceExceptions = true;
        }

        if (params.count("maxConns")) {
            cmdLine.maxConns = params["maxConns"].as<int>();

            if ( cmdLine.maxConns < 5 ) {
                out() << "maxConns has to be at least 5" << endl;
                return false;
            }
            else if ( cmdLine.maxConns > MAX_MAX_CONN ) {
                out() << "maxConns can't be greater than " << MAX_MAX_CONN << endl;
                return false;
            }
        }

        if (params.count("objcheck")) {
            cmdLine.objcheck = true;
        }
        if (params.count("noobjcheck")) {
            if (params.count("objcheck")) {
                out() << "can't have both --objcheck and --noobjcheck" << endl;
                return false;
            }
            cmdLine.objcheck = false;
        }

        if (params.count("bind_ip")) {
            // passing in wildcard is the same as default behavior; remove and warn
            if ( cmdLine.bind_ip ==  "0.0.0.0" ) {
                cout << "warning: bind_ip of 0.0.0.0 is unnecessary; listens on all ips by default" << endl;
                cmdLine.bind_ip = "";
            }
        }

#ifndef _WIN32
        if (params.count("unixSocketPrefix")) {
            cmdLine.socket = params["unixSocketPrefix"].as<string>();
        }

        if (params.count("nounixsocket")) {
            cmdLine.noUnixSocket = true;
        }

        if (params.count("fork") && !params.count("shutdown")) {
            cmdLine.doFork = true;
        }
#endif  // _WIN32

        if (params.count("logpath")) {
            cmdLine.logpath = params["logpath"].as<string>();
            if (cmdLine.logpath.empty()) {
                cout << "logpath cannot be empty if supplied" << endl;
                return false;
            }
        }

        cmdLine.logWithSyslog = params.count("syslog");
        cmdLine.logAppend = params.count("logappend");
        if (!cmdLine.logpath.empty() && cmdLine.logWithSyslog) {
            cout << "Cant use both a logpath and syslog " << endl;
            return false;
        }

        if (cmdLine.doFork && cmdLine.logpath.empty() && !cmdLine.logWithSyslog) {
            cout << "--fork has to be used with --logpath or --syslog" << endl;
            return false;
        }

        if (params.count("keyFile")) {
            cmdLine.keyFile = params["keyFile"].as<string>();
        }

        if ( params.count("pidfilepath")) {
            cmdLine.pidFile = params["pidfilepath"].as<string>();
        }

        if (params.count("setParameter")) {
            std::vector<std::string> parameters =
                params["setParameter"].as<std::vector<std::string> >();
            for (size_t i = 0, length = parameters.size(); i < length; ++i) {
                std::string name;
                std::string value;
                if (!mongoutils::str::splitOn(parameters[i], '=', name, value)) {
                    cout << "Illegal option assignment: \"" << parameters[i] << "\"" << endl;
                    return false;
                }
                ServerParameter* parameter = mapFindWithDefault(
                        ServerParameterSet::getGlobal()->getMap(),
                        name,
                        static_cast<ServerParameter*>(NULL));
                if (NULL == parameter) {
                    cout << "Illegal --option parameter: \"" << name << "\"" << endl;
                    return false;
                }
                Status status = parameter->setFromString(value);
                if (!status.isOK()) {
                    cout << "Bad value for parameter \"" << name << "\": " << status.reason()
                         << endl;
                    return false;
                }
            }
        }

#ifdef MONGO_SSL
        if (params.count("sslWeakCertificateValidation")) {
            cmdLine.sslWeakCertificateValidation = true;
        }
        if (params.count("sslOnNormalPorts")) {
            cmdLine.sslOnNormalPorts = true;
            if ( cmdLine.sslPEMKeyFile.size() == 0 ) {
                log() << "need sslPEMKeyFile" << endl;
                return false;
            }
            if (cmdLine.sslWeakCertificateValidation &&
                cmdLine.sslCAFile.empty()) {
                log() << "need sslCAFile with sslWeakCertificateValidation" << endl;
                return false;
            }
        }
        else if (cmdLine.sslPEMKeyFile.size() || 
                 cmdLine.sslPEMKeyPassword.size() ||
                 cmdLine.sslCAFile.size() ||
                 cmdLine.sslCRLFile.size() ||
                 cmdLine.sslWeakCertificateValidation) {
            log() << "need to enable sslOnNormalPorts" << endl;
            return false;
        }
#endif

        return true;
    }
示例#12
0
文件: cmdline.cpp 项目: neiz/mongo
ParameterValidator* ParameterValidator::get( const string& name ) {
    return mapFindWithDefault(*pv_all, name, static_cast<ParameterValidator*>(NULL));
}
示例#13
0
void ServiceContextMongoD::initializeGlobalStorageEngine() {
    // This should be set once.
    invariant(!_storageEngine);

    const std::string dbpath = storageGlobalParams.dbpath;
    if (auto existingStorageEngine = StorageEngineMetadata::getStorageEngineForPath(dbpath)) {
        if (storageGlobalParams.engineSetByUser) {
            // Verify that the name of the user-supplied storage engine matches the contents of
            // the metadata file.
            const StorageEngine::Factory* factory =
                mapFindWithDefault(_storageFactories,
                                   storageGlobalParams.engine,
                                   static_cast<const StorageEngine::Factory*>(nullptr));

            if (factory) {
                uassert(28662,
                        str::stream()
                            << "Cannot start server. Detected data files in " << dbpath
                            << " created by"
                            << " the '" << *existingStorageEngine << "' storage engine, but the"
                            << " specified storage engine was '" << factory->getCanonicalName()
                            << "'.",
                        factory->getCanonicalName() == *existingStorageEngine);
            }
        } else {
            // Otherwise set the active storage engine as the contents of the metadata file.
            log() << "Detected data files in " << dbpath << " created by the '"
                  << *existingStorageEngine << "' storage engine, so setting the active"
                  << " storage engine to '" << *existingStorageEngine << "'.";
            storageGlobalParams.engine = *existingStorageEngine;
        }
    } else if (!storageGlobalParams.engineSetByUser) {
        // Ensure the default storage engine is available with this build of mongod.
        uassert(28663,
                str::stream()
                    << "Cannot start server. The default storage engine '"
                    << storageGlobalParams.engine
                    << "' is not available with this build of mongod. Please specify a different"
                    << " storage engine explicitly, e.g. --storageEngine=mmapv1.",
                isRegisteredStorageEngine(storageGlobalParams.engine));
    }

    const StorageEngine::Factory* factory = _storageFactories[storageGlobalParams.engine];

    uassert(18656,
            str::stream() << "Cannot start server with an unknown storage engine: "
                          << storageGlobalParams.engine,
            factory);

    std::unique_ptr<StorageEngineMetadata> metadata = StorageEngineMetadata::forPath(dbpath);

    // Validate options in metadata against current startup options.
    if (metadata.get()) {
        uassertStatusOK(factory->validateMetadata(*metadata, storageGlobalParams));
    }

    try {
        _lockFile.reset(new StorageEngineLockFile(storageGlobalParams.dbpath));
    } catch (const std::exception& ex) {
        uassert(28596,
                str::stream() << "Unable to determine status of lock file in the data directory "
                              << storageGlobalParams.dbpath << ": " << ex.what(),
                false);
    }
    if (_lockFile->createdByUncleanShutdown()) {
        warning() << "Detected unclean shutdown - " << _lockFile->getFilespec() << " is not empty.";
    }
    uassertStatusOK(_lockFile->open());

    ScopeGuard guard = MakeGuard(&StorageEngineLockFile::close, _lockFile.get());
    _storageEngine = factory->create(storageGlobalParams, *_lockFile);
    _storageEngine->finishInit();
    uassertStatusOK(_lockFile->writePid());

    // Write a new metadata file if it is not present.
    if (!metadata.get()) {
        metadata.reset(new StorageEngineMetadata(storageGlobalParams.dbpath));
        metadata->setStorageEngine(factory->getCanonicalName().toString());
        metadata->setStorageEngineOptions(factory->createMetadataOptions(storageGlobalParams));
        uassertStatusOK(metadata->write());
    }

    guard.Dismiss();

    _supportsDocLocking = _storageEngine->supportsDocLocking();
}
示例#14
0
 Auth AuthenticationTable::getAuthForDb( const std::string& dbname ) const {
     return mapFindWithDefault( _dbs, dbname, Auth() );
 }
 MockRemoteDBServer* MockReplicaSet::getNode(const string& hostAndPort) {
     return mapFindWithDefault(_nodeMap, hostAndPort, static_cast<MockRemoteDBServer*>(NULL));
 }
示例#16
0
void ServiceContextMongoD::initializeGlobalStorageEngine() {
    // This should be set once.
    invariant(!_storageEngine);

    // We should have a _lockFile or be in read-only mode. Confusingly, we can still have a lockFile
    // if we are in read-only mode. This can happen if the server is started in read-only mode on a
    // writable dbpath.
    invariant(_lockFile || storageGlobalParams.readOnly);

    const std::string dbpath = storageGlobalParams.dbpath;
    if (auto existingStorageEngine = StorageEngineMetadata::getStorageEngineForPath(dbpath)) {
        if (storageGlobalParams.engineSetByUser) {
            // Verify that the name of the user-supplied storage engine matches the contents of
            // the metadata file.
            const StorageEngine::Factory* factory =
                mapFindWithDefault(_storageFactories,
                                   storageGlobalParams.engine,
                                   static_cast<const StorageEngine::Factory*>(nullptr));

            if (factory) {
                uassert(28662,
                        str::stream()
                            << "Cannot start server. Detected data files in " << dbpath
                            << " created by"
                            << " the '" << *existingStorageEngine << "' storage engine, but the"
                            << " specified storage engine was '" << factory->getCanonicalName()
                            << "'.",
                        factory->getCanonicalName() == *existingStorageEngine);
            }
        } else {
            // Otherwise set the active storage engine as the contents of the metadata file.
            log() << "Detected data files in " << dbpath << " created by the '"
                  << *existingStorageEngine << "' storage engine, so setting the active"
                  << " storage engine to '" << *existingStorageEngine << "'.";
            storageGlobalParams.engine = *existingStorageEngine;
        }
    } else if (!storageGlobalParams.engineSetByUser) {
        // Ensure the default storage engine is available with this build of mongod.
        uassert(28663,
                str::stream()
                    << "Cannot start server. The default storage engine '"
                    << storageGlobalParams.engine
                    << "' is not available with this build of mongod. Please specify a different"
                    << " storage engine explicitly, e.g. --storageEngine=mmapv1.",
                isRegisteredStorageEngine(storageGlobalParams.engine));
    }

    const StorageEngine::Factory* factory = _storageFactories[storageGlobalParams.engine];

    uassert(18656,
            str::stream() << "Cannot start server with an unknown storage engine: "
                          << storageGlobalParams.engine,
            factory);

    if (storageGlobalParams.readOnly) {
        uassert(34368,
                str::stream()
                    << "Server was started in read-only mode, but the configured storage engine, "
                    << storageGlobalParams.engine << ", does not support read-only operation",
                factory->supportsReadOnly());
    }

    std::unique_ptr<StorageEngineMetadata> metadata = StorageEngineMetadata::forPath(dbpath);

    if (storageGlobalParams.readOnly) {
        uassert(34415,
                "Server was started in read-only mode, but the storage metadata file was not"
                " found.",
                metadata.get());
    }

    // Validate options in metadata against current startup options.
    if (metadata.get()) {
        uassertStatusOK(factory->validateMetadata(*metadata, storageGlobalParams));
    }

    ScopeGuard guard = MakeGuard([&] {
        if (_lockFile) {
            _lockFile->close();
        }
    });

    _storageEngine = factory->create(storageGlobalParams, _lockFile.get());
    _storageEngine->finishInit();

    if (_lockFile) {
        uassertStatusOK(_lockFile->writePid());
    }

    // Write a new metadata file if it is not present.
    if (!metadata.get()) {
        invariant(!storageGlobalParams.readOnly);
        metadata.reset(new StorageEngineMetadata(storageGlobalParams.dbpath));
        metadata->setStorageEngine(factory->getCanonicalName().toString());
        metadata->setStorageEngineOptions(factory->createMetadataOptions(storageGlobalParams));
        uassertStatusOK(metadata->write());
    }

    guard.Dismiss();

    _supportsDocLocking = _storageEngine->supportsDocLocking();
}
std::vector<BSONObj> AuthzManagerExternalStateMock::getCollectionContents(
    const NamespaceString& collectionName) {
    return mapFindWithDefault(_documents, collectionName, std::vector<BSONObj>());
}
示例#18
0
 MongoFile* MongoFileFinder::findByPath(const std::string& path) const {
     return mapFindWithDefault(pathToFile,
                               boost::filesystem::absolute(path).generic_string(),
                               static_cast<MongoFile*>(NULL));
 }