try {
            serverGlobalParams.overrideShardIdentity = fromjson(docAsString);
        } catch (const DBException& exception) {
            return exception.toStatus(
                "Error encountered while parsing _overrideShardIdentity JSON document");
        }

/**
 *
 */

#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kControl

#include "mongo/db/mongod_options.h"

#include <boost/filesystem.hpp>
#include <iostream>
#include <string>
#include <vector>

#include "mongo/base/init.h"
#include "mongo/base/status.h"
#include "mongo/bson/json.h"
#include "mongo/bson/util/builder.h"
#include "mongo/config.h"
#include "mongo/db/auth/cluster_auth_mode.h"
#include "mongo/db/cluster_auth_mode_option_gen.h"
#include "mongo/db/global_settings.h"
#include "mongo/db/keyfile_option_gen.h"
#include "mongo/db/mongod_options_general_gen.h"
#include "mongo/db/mongod_options_legacy_gen.h"
#include "mongo/db/mongod_options_replication_gen.h"
#include "mongo/db/mongod_options_sharding_gen.h"
#include "mongo/db/mongod_options_storage_gen.h"
#include "mongo/db/repl/repl_settings.h"
#include "mongo/db/server_options.h"
#include "mongo/db/server_options_base.h"
#include "mongo/db/server_options_nongeneral_gen.h"
#include "mongo/db/server_options_server_helpers.h"
#include "mongo/db/storage/storage_parameters_gen.h"
#include "mongo/logv2/log.h"
#include "mongo/logv2/log_domain_global.h"
#include "mongo/logv2/log_manager.h"
#include "mongo/util/net/ssl_options.h"
#include "mongo/util/options_parser/startup_options.h"
#include "mongo/util/str.h"
#include "mongo/util/version.h"

namespace mongo {

using std::endl;

std::string storageDBPathDescription() {
    StringBuilder sb;

    sb << "Directory for datafiles - defaults to " << storageGlobalParams.kDefaultDbPath;

#ifdef _WIN32
    boost::filesystem::path currentPath = boost::filesystem::current_path();

    sb << " which is " << currentPath.root_name().string() << storageGlobalParams.kDefaultDbPath
       << " based on the current working drive";
#endif

    return sb.str();
}

Status addMongodOptions(moe::OptionSection* options) try {
    uassertStatusOK(addGeneralServerOptions(options));
    uassertStatusOK(addNonGeneralServerOptions(options));
    uassertStatusOK(addMongodGeneralOptions(options));
    uassertStatusOK(addMongodReplicationOptions(options));
    uassertStatusOK(addMongodShardingOptions(options));
    uassertStatusOK(addMongodStorageOptions(options));
    uassertStatusOK(addMongodLegacyOptions(options));
    uassertStatusOK(addKeyfileServerOption(options));
    uassertStatusOK(addClusterAuthModeServerOption(options));

    return Status::OK();
} catch (const AssertionException& ex) {
    return ex.toStatus();
}

void printMongodHelp(const moe::OptionSection& options) {
    std::cout << options.helpString() << std::endl;
};

namespace {

void appendSysInfo(BSONObjBuilder* obj) {
    auto o = BSONObjBuilder(obj->subobjStart("sysinfo"));
#if defined(_SC_PAGE_SIZE)
    o.append("_SC_PAGE_SIZE", (long long)sysconf(_SC_PAGE_SIZE));
#endif
#if defined(_SC_PHYS_PAGES)
    o.append("_SC_PHYS_PAGES", (long long)sysconf(_SC_PHYS_PAGES));
#endif
#if defined(_SC_AVPHYS_PAGES)
    o.append("_SC_AVPHYS_PAGES", (long long)sysconf(_SC_AVPHYS_PAGES));
#endif
}

}  // namespace

bool handlePreValidationMongodOptions(const moe::Environment& params,
                                      const std::vector<std::string>& args) {
    if (params.count("help") && params["help"].as<bool>() == true) {
        printMongodHelp(moe::startupOptions);
        return false;
    }
    if (params.count("version") && params["version"].as<bool>() == true) {
        auto&& vii = VersionInfoInterface::instance();
        std::cout << mongodVersion(vii) << std::endl;
        vii.logBuildInfo(&std::cout);
        return false;
    }
    if (params.count("sysinfo") && params["sysinfo"].as<bool>() == true) {
        BSONObjBuilder obj;
        appendSysInfo(&obj);
        std::cout << tojson(obj.done(), ExtendedRelaxedV2_0_0, true) << std::endl;
        return false;
    }

    if (params.count("master") || params.count("slave")) {
        LOGV2_FATAL_CONTINUE(20881, "Master/slave replication is no longer supported");
        return false;
    }

    if (params.count("replication.enableMajorityReadConcern") &&
        params["replication.enableMajorityReadConcern"].as<bool>() == false) {
        LOGV2_FATAL_CONTINUE(5324700, "enableMajorityReadConcern:false is no longer supported");
        return false;
    }

    return true;
}

Status validateMongodOptions(const moe::Environment& params) {
    Status ret = validateServerOptions(params);
    if (!ret.isOK()) {
        return ret;
    }

    if (params.count("nojournal") && params.count("storage.journal.enabled")) {
        return Status(ErrorCodes::BadValue,
                      "Can't specify both --journal and --nojournal options.");
    }

#ifdef _WIN32
    if (params.count("install") || params.count("reinstall")) {
        if (params.count("storage.dbPath") &&
            !boost::filesystem::path(params["storage.dbPath"].as<std::string>()).is_absolute()) {
            return Status(ErrorCodes::BadValue,
                          "dbPath requires an absolute file path with Windows services");
        }
    }
#endif

    if (params.count("storage.queryableBackupMode")) {
        // Command line options that are disallowed when --queryableBackupMode is specified.
        for (const auto& disallowedOption :
             {"replication.replSet", "configsvr", "upgrade", "repair", "profile"}) {
            if (params.count(disallowedOption)) {
                return Status(ErrorCodes::BadValue,
                              str::stream() << "Cannot specify both queryable backup mode and "
                                            << disallowedOption);
            }
        }

        bool isClusterRoleShard = params.count("shardsvr");
        if (params.count("sharding.clusterRole")) {
            auto clusterRole = params["sharding.clusterRole"].as<std::string>();
            isClusterRoleShard = isClusterRoleShard || (clusterRole == "shardsvr");
        }

        if (isClusterRoleShard && !params.count("sharding._overrideShardIdentity")) {
            return Status(
                ErrorCodes::BadValue,
                "shardsvr cluster role with queryableBackupMode requires _overrideShardIdentity");
        }
    }

    return Status::OK();
}

Status canonicalizeMongodOptions(moe::Environment* params) {

    Status ret = canonicalizeServerOptions(params);
    if (!ret.isOK()) {
        return ret;
    }

    if (params->count("nojournal")) {
        Status ret =
            params->set("storage.journal.enabled", moe::Value(!(*params)["nojournal"].as<bool>()));
        if (!ret.isOK()) {
            return ret;
        }
        ret = params->remove("nojournal");
        if (!ret.isOK()) {
            return ret;
        }
    }

    // "security.authorization" comes from the config file, so override it if "auth" is
    // set since those come from the command line.
    if (params->count("auth")) {
        Status ret =
            params->set("security.authorization",
                        (*params)["auth"].as<bool>() ? moe::Value(std::string("enabled"))
                                                     : moe::Value(std::string("disabled")));
        if (!ret.isOK()) {
            return ret;
        }
        ret = params->remove("auth");
        if (!ret.isOK()) {
            return ret;
        }
    }

    // "sharding.archiveMovedChunks" comes from the config file, so override it if
    // "noMoveParanoia" or "moveParanoia" are set since those come from the command line.
    if (params->count("noMoveParanoia")) {
        Status ret = params->set("sharding.archiveMovedChunks",
                                 moe::Value(!(*params)["noMoveParanoia"].as<bool>()));
        if (!ret.isOK()) {
            return ret;
        }
        ret = params->remove("noMoveParanoia");
        if (!ret.isOK()) {
            return ret;
        }
    }
    if (params->count("moveParanoia")) {
        Status ret = params->set("sharding.archiveMovedChunks",
                                 moe::Value((*params)["moveParanoia"].as<bool>()));
        if (!ret.isOK()) {
            return ret;
        }
        ret = params->remove("moveParanoia");
        if (!ret.isOK()) {
            return ret;
        }
    }

    // "sharding.clusterRole" comes from the config file, so override it if "configsvr" or
    // "shardsvr" are set since those come from the command line.
    if (params->count("configsvr")) {
        if ((*params)["configsvr"].as<bool>() == false) {
            // Handle the case where "configsvr" comes from the legacy config file and is set to
            // false.  This option is not allowed in the YAML config.
            return Status(ErrorCodes::BadValue,
                          "configsvr option cannot be set to false in config file");
        }
        Status ret = params->set("sharding.clusterRole", moe::Value(std::string("configsvr")));
        if (!ret.isOK()) {
            return ret;
        }
        ret = params->remove("configsvr");
        if (!ret.isOK()) {
            return ret;
        }
    }
    if (params->count("shardsvr")) {
        if ((*params)["shardsvr"].as<bool>() == false) {
            // Handle the case where "shardsvr" comes from the legacy config file and is set to
            // false.  This option is not allowed in the YAML config.
            return Status(ErrorCodes::BadValue,
                          "shardsvr option cannot be set to false in config file");
        }
        Status ret = params->set("sharding.clusterRole", moe::Value(std::string("shardsvr")));
        if (!ret.isOK()) {
            return ret;
        }
        ret = params->remove("shardsvr");
        if (!ret.isOK()) {
            return ret;
        }
    }

    if (params->count("profile")) {
        int profilingMode;
        Status ret = params->get("profile", &profilingMode);
        if (!ret.isOK()) {
            return ret;
        }
        std::string profilingModeString;
        if (profilingMode == 0) {
            profilingModeString = "off";
        } else if (profilingMode == 1) {
            profilingModeString = "slowOp";
        } else if (profilingMode == 2) {
            profilingModeString = "all";
        } else {
            StringBuilder sb;
            sb << "Bad value for profile: " << profilingMode
               << ".  Supported modes are: (0=off|1=slowOp|2=all)";
            return Status(ErrorCodes::BadValue, sb.str());
        }
        ret = params->set("operationProfiling.mode", moe::Value(profilingModeString));
        if (!ret.isOK()) {
            return ret;
        }
        ret = params->remove("profile");
        if (!ret.isOK()) {
            return ret;
        }
    }

    // Ensure that "replication.replSet" logically overrides "replication.replSetName".  We
    // can't canonicalize them as the same option, because they mean slightly different things.
    // "replication.replSet" can include a seed list, while "replication.replSetName" just has
    // the replica set name.
    if (params->count("replication.replSet") && params->count("replication.replSetName")) {
        ret = params->remove("replication.replSetName");
        if (!ret.isOK()) {
            return ret;
        }
    }

    // "security.javascriptEnabled" comes from the config file, so override it if "noscripting"
    // is set since that comes from the command line.
    if (params->count("noscripting")) {
        Status ret = params->set("security.javascriptEnabled",
                                 moe::Value(!(*params)["noscripting"].as<bool>()));
        if (!ret.isOK()) {
            return ret;
        }
        ret = params->remove("noscripting");
        if (!ret.isOK()) {
            return ret;
        }
    }

    return Status::OK();
}

Status storeMongodOptions(const moe::Environment& params) {
    Status ret = storeServerOptions(params);
    if (!ret.isOK()) {
        return ret;
    }

    // TODO: Integrate these options with their setParameter counterparts
    if (params.count("security.authSchemaVersion")) {
        return Status(ErrorCodes::BadValue,
                      "security.authSchemaVersion is currently not supported in config files");
    }

    if (params.count("security.enableLocalhostAuthBypass")) {
        return Status(ErrorCodes::BadValue,
                      "security.enableLocalhostAuthBypass is currently not supported in config "
                      "files");
    }

    if (params.count("storage.engine")) {
        storageGlobalParams.engine = params["storage.engine"].as<std::string>();
        storageGlobalParams.engineSetByUser = true;
    }

    if (params.count("storage.dbPath")) {
        storageGlobalParams.dbpath = params["storage.dbPath"].as<std::string>();
        if (params.count("processManagement.fork") && storageGlobalParams.dbpath[0] != '/') {
            // we need to change dbpath if we fork since we change
            // fork only exists on *nix
            storageGlobalParams.dbpath = serverGlobalParams.cwd + "/" + storageGlobalParams.dbpath;
        }
    }
#ifdef _WIN32
    if (storageGlobalParams.dbpath.size() > 1 &&
        storageGlobalParams.dbpath[storageGlobalParams.dbpath.size() - 1] == '/') {
        // size() check is for the unlikely possibility of --dbpath "/"
        storageGlobalParams.dbpath =
            storageGlobalParams.dbpath.erase(storageGlobalParams.dbpath.size() - 1);
    }

    StringData dbpath(storageGlobalParams.dbpath);
    if (dbpath.size() >= 2 && dbpath.startsWith("\\\\")) {
        // Check if the dbpath is on a Windows network share (eg. \\myserver\myshare)
        LOGV2_WARNING_OPTIONS(5808500,
                              {logv2::LogTag::kStartupWarnings},
                              "dbpath should not be used on a network share");
    }
#endif

    if (params.count("operationProfiling.mode")) {
        std::string profilingMode = params["operationProfiling.mode"].as<std::string>();
        if (profilingMode == "off") {
            serverGlobalParams.defaultProfile = 0;
        } else if (profilingMode == "slowOp") {
            serverGlobalParams.defaultProfile = 1;
        } else if (profilingMode == "all") {
            serverGlobalParams.defaultProfile = 2;
        } else {
            StringBuilder sb;
            sb << "Bad value for operationProfiling.mode: " << profilingMode
               << ".  Supported modes are: (off|slowOp|all)";
            return Status(ErrorCodes::BadValue, sb.str());
        }
    }

    if (params.count("storage.syncPeriodSecs")) {
        storageGlobalParams.syncdelay = params["storage.syncPeriodSecs"].as<double>();
        storageGlobalParams.checkpointDelaySecs =
            static_cast<size_t>(params["storage.syncPeriodSecs"].as<double>());

        if (storageGlobalParams.syncdelay < 0 ||
            storageGlobalParams.syncdelay > StorageGlobalParams::kMaxSyncdelaySecs) {
            return Status(ErrorCodes::BadValue,
                          str::stream() << "syncdelay out of allowed range (0-"
                                        << StorageGlobalParams::kMaxSyncdelaySecs << "s)");
        }
    }

    if (params.count("storage.directoryPerDB")) {
        storageGlobalParams.directoryperdb = params["storage.directoryPerDB"].as<bool>();
    }

    if (params.count("storage.queryableBackupMode") &&
        params["storage.queryableBackupMode"].as<bool>()) {
        storageGlobalParams.readOnly = true;
    }

    if (params.count("storage.groupCollections")) {
        storageGlobalParams.groupCollections = params["storage.groupCollections"].as<bool>();
    }

    if (params.count("cpu")) {
        serverGlobalParams.cpu = params["cpu"].as<bool>();
    }

    if (params.count("storage.journal.enabled")) {
        storageGlobalParams.dur = params["storage.journal.enabled"].as<bool>();
    }

    if (params.count("storage.journal.commitIntervalMs")) {
        // don't check if dur is false here as many will just use the default, and will default
        // to off on win32.  ie no point making life a little more complex by giving an error on
        // a dev environment.
        auto journalCommitIntervalMs = params["storage.journal.commitIntervalMs"].as<int>();
        storageGlobalParams.journalCommitIntervalMs.store(journalCommitIntervalMs);
        if (journalCommitIntervalMs < 1 ||
            journalCommitIntervalMs > StorageGlobalParams::kMaxJournalCommitIntervalMs) {
            return Status(ErrorCodes::BadValue,
                          str::stream()
                              << "--journalCommitInterval out of allowed range (1-"
                              << StorageGlobalParams::kMaxJournalCommitIntervalMs << "ms)");
        }
    }

    if (params.count("security.javascriptEnabled")) {
        mongodGlobalParams.scriptingEnabled = params["security.javascriptEnabled"].as<bool>();
    }

    if (params.count("security.clusterIpSourceAllowlist")) {
        auto allowlistedClusterNetwork = std::make_shared<std::vector<std::string>>();
        for (const std::string& allowlistEntry :
             params["security.clusterIpSourceAllowlist"].as<std::vector<std::string>>()) {
            std::vector<std::string> intermediates;
            str::splitStringDelim(allowlistEntry, &intermediates, ',');
            std::copy(intermediates.begin(),
                      intermediates.end(),
                      std::back_inserter(*allowlistedClusterNetwork));
        }
        mongodGlobalParams.allowlistedClusterNetwork = allowlistedClusterNetwork;
    }

    if (params.count("repair") && params["repair"].as<bool>() == true) {
        storageGlobalParams.upgrade = 1;  // --repair implies --upgrade
        storageGlobalParams.repair = 1;
    }
    if (params.count("upgrade") && params["upgrade"].as<bool>() == true) {
        storageGlobalParams.upgrade = 1;
    }
    if (params.count("notablescan")) {
        storageGlobalParams.noTableScan.store(params["notablescan"].as<bool>());
    }

    repl::ReplSettings replSettings;
    if (params.count("replication.replSet")) {
        /* seed list of hosts for the repl set */
        replSettings.setReplSetString(params["replication.replSet"].as<std::string>().c_str());
    } else if (params.count("replication.replSetName")) {
        // "replSetName" is previously removed if "replSet" and "replSetName" are both found to be
        // set by the user. Therefore, we only need to check for it if "replSet" in not found.
        replSettings.setReplSetString(params["replication.replSetName"].as<std::string>().c_str());
    } else {
        // If neither "replication.replSet" nor "replication.replSetName" is set, then we are in
        // standalone mode.
        // A standalone node does not use the oplog collection, so special truncation handling for
        // the capped collection is unnecessary.
        // A standalone node that will be reintroduced to its replica set must not allow oplog
        // truncation while in standalone mode because oplog history needed for startup recovery as
        // a replica set member could be deleted. Replication can need history older than the last
        // checkpoint to support transactions.
        // Note: we only use this to defer oplog collection truncation via OplogStones in WT. Non-WT
        // storage engines will continue to perform regular capped collection handling for the oplog
        // collection, regardless of this parameter setting.
        storageGlobalParams.allowOplogTruncation = false;
    }

    if (!replSettings.getReplSetString().empty() &&
        (params.count("security.authorization") &&
         params["security.authorization"].as<std::string>() == "enabled") &&
        !serverGlobalParams.startupClusterAuthMode.x509Only() &&
        serverGlobalParams.keyFile.empty()) {
        return Status(
            ErrorCodes::BadValue,
            str::stream()
                << "security.keyFile is required when authorization is enabled with replica sets");
    }

    serverGlobalParams.enableMajorityReadConcern = true;

    if (storageGlobalParams.engineSetByUser &&
        (storageGlobalParams.engine == "ephemeralForTest" ||
         storageGlobalParams.engine == "devnull")) {
        LOGV2(5324701,
              "Test storage engine does not support enableMajorityReadConcern=true, forcibly "
              "setting to false",
              "storageEngine"_attr = storageGlobalParams.engine);
        serverGlobalParams.enableMajorityReadConcern = false;
    }

    if (!serverGlobalParams.enableMajorityReadConcern) {
        // Lock-free reads is not supported with enableMajorityReadConcern=false, so we disable it.
        if (!storageGlobalParams.disableLockFreeReads) {
            LOGV2_WARNING(4788401,
                          "Lock-free reads is not compatible with "
                          "enableMajorityReadConcern=false: disabling lock-free reads.");
            storageGlobalParams.disableLockFreeReads = true;
        }
    }

    if (params.count("replication.oplogSizeMB")) {
        long long x = params["replication.oplogSizeMB"].as<int>();
        if (x <= 0) {
            return Status(ErrorCodes::BadValue,
                          str::stream() << "bad --oplogSize, arg must be greater than 0,"
                                           "found: "
                                        << x);
        }
        // note a small size such as x==1 is ok for an arbiter.
        if (x > 1000 && sizeof(void*) == 4) {
            StringBuilder sb;
            sb << "--oplogSize of " << x
               << "MB is too big for 32 bit version. Use 64 bit build instead.";
            return Status(ErrorCodes::BadValue, sb.str());
        }
        replSettings.setOplogSizeBytes(x * 1024 * 1024);
        invariant(replSettings.getOplogSizeBytes() > 0);
    }

    if (params.count("storage.oplogMinRetentionHours")) {
        storageGlobalParams.oplogMinRetentionHours.store(
            params["storage.oplogMinRetentionHours"].as<double>());
        if (storageGlobalParams.oplogMinRetentionHours.load() < 0) {
            return Status(ErrorCodes::BadValue,
                          "bad --oplogMinRetentionHours, argument must be greater or equal to 0");
        }
        invariant(storageGlobalParams.oplogMinRetentionHours.load() >= 0);
    }

    if (params.count("cacheSize")) {
        long x = params["cacheSize"].as<long>();
        if (x <= 0) {
            return Status(ErrorCodes::BadValue, "bad --cacheSize arg");
        }
        return Status(ErrorCodes::BadValue, "--cacheSize option not currently supported");
    }
    if (!params.count("net.port")) {
        if (params.count("sharding.clusterRole")) {
            std::string clusterRole = params["sharding.clusterRole"].as<std::string>();
            if (clusterRole == "configsvr") {
                serverGlobalParams.port = ServerGlobalParams::ConfigServerPort;
            } else if (clusterRole == "shardsvr") {
                serverGlobalParams.port = ServerGlobalParams::ShardServerPort;
            } else {
                StringBuilder sb;
                sb << "Bad value for sharding.clusterRole: " << clusterRole
                   << ".  Supported modes are: (configsvr|shardsvr)";
                return Status(ErrorCodes::BadValue, sb.str());
            }
        }
    } else {
        if (serverGlobalParams.port < 0 || serverGlobalParams.port > 65535) {
            return Status(ErrorCodes::BadValue, "bad --port number");
        }
    }
    if (params.count("sharding.clusterRole")) {
        auto clusterRoleParam = params["sharding.clusterRole"].as<std::string>();
        const bool replicationEnabled =
            params.count("replication.replSet") || params.count("replication.replSetName");
        // Force to set up the node as a replica set, unless we're a shard and we're using queryable
        // backup mode.
        if ((clusterRoleParam == "configsvr" || !params.count("storage.queryableBackupMode")) &&
            !replicationEnabled) {
            return Status(ErrorCodes::BadValue,
                          str::stream() << "Cannot start a " << clusterRoleParam
                                        << " as a standalone server. Please use the option "
                                           "--replset to start the node as a replica set.");
        }
        if (clusterRoleParam == "configsvr") {
            serverGlobalParams.clusterRole = ClusterRole::ConfigServer;
            // Config server requires majority read concern.
            uassert(5324702,
                    str::stream() << "Cannot initialize config server with "
                                  << "enableMajorityReadConcern=false",
                    serverGlobalParams.enableMajorityReadConcern);

            // If we haven't explicitly specified a journal option, default journaling to true for
            // the config server role
            if (!params.count("storage.journal.enabled")) {
                storageGlobalParams.dur = true;
            }

            if (!params.count("storage.dbPath")) {
                storageGlobalParams.dbpath = storageGlobalParams.kDefaultConfigDbPath;
            }
        } else if (clusterRoleParam == "shardsvr") {
            serverGlobalParams.clusterRole = ClusterRole::ShardServer;
        }
    }

    if (params.count("sharding.archiveMovedChunks")) {
        serverGlobalParams.moveParanoia = params["sharding.archiveMovedChunks"].as<bool>();
    }

    if (params.count("sharding._overrideShardIdentity")) {
        auto docAsString = params["sharding._overrideShardIdentity"].as<std::string>();

    }

    if (params.count("pairwith") || params.count("arbiter") || params.count("opIdMem")) {
        return Status(ErrorCodes::BadValue,
                      "****\n"
                      "Replica Pairs have been deprecated. Invalid options: "
                      "--pairwith, --arbiter, and/or --opIdMem\n"
                      "<http://example.com>\n"
                      "****");
    }

#ifdef _WIN32
    // If dbPath is a default value, prepend with drive name so log entries are explicit
    // We must resolve the dbpath before it stored in repairPath in the default case.
    if (storageGlobalParams.dbpath == storageGlobalParams.kDefaultDbPath ||
        storageGlobalParams.dbpath == storageGlobalParams.kDefaultConfigDbPath) {
        boost::filesystem::path currentPath = boost::filesystem::current_path();
        storageGlobalParams.dbpath = currentPath.root_name().string() + storageGlobalParams.dbpath;
    }
#endif

    // Check if we are 32 bit and have not explicitly specified any journaling options
    if (sizeof(void*) == 4 && !params.count("storage.journal.enabled")) {
        LOGV2_WARNING(20880,
                      "32-bit servers don't have journaling enabled by default. Please use "
                      "--journal if you want durability");
    }

    bool isClusterRoleShard = params.count("shardsvr");
    bool isClusterRoleConfig = params.count("configsvr");
    if (params.count("sharding.clusterRole")) {
        auto clusterRole = params["sharding.clusterRole"].as<std::string>();
        isClusterRoleShard = isClusterRoleShard || (clusterRole == "shardsvr");
        isClusterRoleConfig = isClusterRoleConfig || (clusterRole == "configsvr");
    }

    if ((isClusterRoleShard || isClusterRoleConfig) && skipShardingConfigurationChecks) {
        auto clusterRoleStr = isClusterRoleConfig ? "--configsvr" : "--shardsvr";
        return Status(ErrorCodes::BadValue,
                      str::stream() << "Can not specify " << clusterRoleStr
                                    << " and set skipShardingConfigurationChecks=true");
    }

    if ((isClusterRoleShard || isClusterRoleConfig) && params.count("setParameter")) {
        std::map<std::string, std::string> parameters =
            params["setParameter"].as<std::map<std::string, std::string>>();
        const bool requireApiVersionValue = ([&parameters] {
            const auto requireApiVersionParam = parameters.find("requireApiVersion");
            if (requireApiVersionParam == parameters.end()) {
                return false;
            }
            const auto& val = requireApiVersionParam->second;
            return (0 == val.compare("1")) || (0 == val.compare("true"));
        })();

        if (requireApiVersionValue) {
            auto clusterRoleStr = isClusterRoleConfig ? "--configsvr" : "--shardsvr";
            return Status(ErrorCodes::BadValue,
                          str::stream() << "Can not specify " << clusterRoleStr
                                        << " and set requireApiVersion=true");
        }
    }

    setGlobalReplSettings(replSettings);
    return Status::OK();
}

}  // namespace mongo


ComputePressureGrem::~ComputePressureGrem()
{
  delete [] fix_grem;
}

/* ----------------------------------------------------------------------
   LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
   http://lammps.sandia.gov, Sandia National Laboratories
   Steve Plimpton, example@nnthink.com

   DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains

   See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */

#include <mpi.h>
#include <string.h>
#include <stdlib.h>
#include "compute_pressure_grem.h"
#include "atom.h"
#include "update.h"
#include "domain.h"
#include "modify.h"
#include "fix.h"
#include "force.h"
#include "pair.h"
#include "kspace.h"
#include "error.h"

using namespace LAMMPS_NS;

/* ----------------------------------------------------------------------
   Last argument is the id of the gREM fix
------------------------------------------------------------------------- */

ComputePressureGrem::ComputePressureGrem(LAMMPS *lmp, int narg, char **arg) :
  ComputePressure(lmp, narg-1, arg)
{
  int len = strlen(arg[narg-1])+1;
  fix_grem = new char[len];
  strcpy(fix_grem,arg[narg-1]);
}

/* ---------------------------------------------------------------------- */

/* ---------------------------------------------------------------------- */

void ComputePressureGrem::init()
{
  ComputePressure::init();

  // Initialize hook to gREM fix
  int ifix = modify->find_fix(fix_grem);
  if (ifix < 0)
    error->all(FLERR,"Fix grem ID for compute PRESSURE/GREM does not exist");

  int dim;
  scale_grem = (double *)modify->fix[ifix]->extract("scale_grem",dim);

  if (scale_grem == NULL || dim != 0)
    error->all(FLERR,"Cannot extract gREM scale factor from fix grem");
}

/* ----------------------------------------------------------------------
   compute total pressure, averaged over Pxx, Pyy, Pzz
------------------------------------------------------------------------- */

double ComputePressureGrem::compute_scalar()
{
  invoked_scalar = update->ntimestep;
  if (update->vflag_global != invoked_scalar)
    error->all(FLERR,"Virial was not tallied on needed timestep");

  // invoke temperature if it hasn't been already

  double t;
  if (keflag) {
    if (temperature->invoked_scalar != update->ntimestep)
      t = temperature->compute_scalar() / (*scale_grem);
    else t = temperature->scalar / (*scale_grem);
  }

  if (dimension == 3) {
    inv_volume = 1.0 / (domain->xprd * domain->yprd * domain->zprd);
    virial_compute(3,3);
    if (keflag)
      scalar = (temperature->dof * boltz * t +
                virial[0] + virial[1] + virial[2]) / 3.0 * inv_volume * nktv2p;
    else
      scalar = (virial[0] + virial[1] + virial[2]) / 3.0 * inv_volume * nktv2p;
  } else {
    inv_volume = 1.0 / (domain->xprd * domain->yprd);
    virial_compute(2,2);
    if (keflag)
      scalar = (temperature->dof * boltz * t +
                virial[0] + virial[1]) / 2.0 * inv_volume * nktv2p;
    else
      scalar = (virial[0] + virial[1]) / 2.0 * inv_volume * nktv2p;
  }

  return scalar;
}

/* ----------------------------------------------------------------------
   compute pressure tensor
   assume KE tensor has already been computed
------------------------------------------------------------------------- */

void ComputePressureGrem::compute_vector()
{
  invoked_vector = update->ntimestep;
  if (update->vflag_global != invoked_vector)
    error->all(FLERR,"Virial was not tallied on needed timestep");

  if (force->kspace && kspace_virial && force->kspace->scalar_pressure_flag)
    error->all(FLERR,"Must use 'kspace_modify pressure/scalar no' for "
	       "tensor components with kspace_style msm");

  // invoke temperature if it hasn't been already

  double ke_tensor[6];
  if (keflag) {
    if (temperature->invoked_vector != update->ntimestep)
      temperature->compute_vector();
    for (int i = 0; i < 6; ++i)
      ke_tensor[i] = temperature->vector[i] / (*scale_grem);
  }

  if (dimension == 3) {
    inv_volume = 1.0 / (domain->xprd * domain->yprd * domain->zprd);
    virial_compute(6,3);
    if (keflag) {
      for (int i = 0; i < 6; i++)
        vector[i] = (ke_tensor[i] + virial[i]) * inv_volume * nktv2p;
    } else
      for (int i = 0; i < 6; i++)
        vector[i] = virial[i] * inv_volume * nktv2p;
  } else {
    inv_volume = 1.0 / (domain->xprd * domain->yprd);
    virial_compute(4,2);
    if (keflag) {
      vector[0] = (ke_tensor[0] + virial[0]) * inv_volume * nktv2p;
      vector[1] = (ke_tensor[1] + virial[1]) * inv_volume * nktv2p;
      vector[3] = (ke_tensor[3] + virial[3]) * inv_volume * nktv2p;
      vector[2] = vector[4] = vector[5] = 0.0;
    } else {
      vector[0] = virial[0] * inv_volume * nktv2p;
      vector[1] = virial[1] * inv_volume * nktv2p;
      vector[3] = virial[3] * inv_volume * nktv2p;
      vector[2] = vector[4] = vector[5] = 0.0;
    }
  }
}


switch (type) {
    case SignalType::Abort:
      return {SIGABRT};
    case SignalType::Error:
      return {SIGILL, SIGFPE, SIGSEGV};
    case SignalType::Quit:
      return {SIGINT, SIGTERM};
    case SignalType::Pipe:
      return {};
    case SignalType::HangUp:
      return {};
    case SignalType::User:
      return {};
    case SignalType::Other:
      return {};
    default:
      return {};
  }

/*
    This file is part of TON Blockchain Library.

*/
#include "td/utils/port/signals.h"

#include "td/utils/port/config.h"
#include "td/utils/port/stacktrace.h"
#include "td/utils/port/StdStreams.h"

#include "td/utils/common.h"
#include "td/utils/format.h"

#if TD_PORT_POSIX
#include <signal.h>
#include <sys/mman.h>
#include <unistd.h>
#endif
#if TD_PORT_WINDOWS
#include <csignal>
#endif

#include <cerrno>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <limits>

namespace td {

#if TD_PORT_POSIX && !TD_DARWIN_TV_OS && !TD_DARWIN_WATCH_OS
static Status protect_memory(void *addr, size_t len) {
  if (mprotect(addr, len, PROT_NONE) != 0) {
    return OS_ERROR("mprotect failed");
  }
  return Status::OK();
}
#endif

Status setup_signals_alt_stack() {
#if TD_PORT_POSIX && !TD_DARWIN_TV_OS && !TD_DARWIN_WATCH_OS
  auto page_size = getpagesize();
  auto stack_size = (MINSIGSTKSZ + 16 * page_size - 1) / page_size * page_size;

  void *stack = mmap(nullptr, stack_size + 2 * page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
  if (stack == MAP_FAILED) {
    return OS_ERROR("Mmap failed");
  }

  TRY_STATUS(protect_memory(stack, page_size));
  TRY_STATUS(protect_memory(static_cast<char *>(stack) + stack_size + page_size, page_size));

  stack_t signal_stack;
  signal_stack.ss_sp = static_cast<char *>(stack) + page_size;
  signal_stack.ss_size = stack_size;
  signal_stack.ss_flags = 0;

  if (sigaltstack(&signal_stack, nullptr) != 0) {
    return OS_ERROR("sigaltstack failed");
  }
#endif
  return Status::OK();
}

#if TD_PORT_POSIX
static void set_handler(struct sigaction &act, decltype(act.sa_handler) handler) {
  act.sa_handler = handler;
}
static void set_handler(struct sigaction &act, decltype(act.sa_sigaction) handler) {
  act.sa_sigaction = handler;
  act.sa_flags |= SA_SIGINFO;
}
template <class F>
static Status set_signal_handler_impl(vector<int> signals, F func) {
  struct sigaction act;
  std::memset(&act, '\0', sizeof(act));

  sigemptyset(&act.sa_mask);
  for (auto signal : signals) {
    sigaddset(&act.sa_mask, signal);
  }
  act.sa_flags = SA_RESTART | SA_ONSTACK;
  set_handler(act, func);

  for (auto signal : signals) {
    if (sigaction(signal, &act, nullptr) != 0) {
      return OS_ERROR("sigaction failed");
    }
  }
  return Status::OK();
}

static vector<int> get_native_signals(SignalType type) {
  switch (type) {
    case SignalType::Abort:
      return {SIGABRT, SIGXCPU, SIGXFSZ};
    case SignalType::Error:
      return {SIGILL, SIGFPE, SIGBUS, SIGSEGV, SIGSYS};
    case SignalType::Quit:
      return {SIGINT, SIGTERM, SIGQUIT};
    case SignalType::Pipe:
      return {SIGPIPE};
    case SignalType::HangUp:
      return {SIGHUP};
    case SignalType::User:
      return {SIGUSR1, SIGUSR2};
    case SignalType::Other:
      return {SIGTRAP, SIGALRM, SIGVTALRM, SIGPROF, SIGTSTP, SIGTTIN, SIGTTOU};
    default:
      return {};
  }
}
#endif
#if TD_PORT_WINDOWS
static Status set_signal_handler_impl(vector<int> signals, void (*func)(int sig)) {
  for (auto signal : signals) {
    if (std::signal(signal, func) == SIG_ERR) {
      return Status::Error("Failed to set signal handler");
    }
  }
  return Status::OK();
}

static vector<int> get_native_signals(SignalType type) {

}
#endif

Status set_signal_handler(SignalType type, void (*func)(int)) {
  return set_signal_handler_impl(get_native_signals(type), func == nullptr ? SIG_DFL : func);
}

using extended_signal_handler = void (*)(int sig, void *addr);
static extended_signal_handler extended_signal_handlers[NSIG] = {};

#if TD_PORT_POSIX
static void siginfo_handler(int signum, siginfo_t *info, void *data) {
  auto handler = extended_signal_handlers[signum];
  handler(signum, info->si_addr);
}
#elif TD_PORT_WINDOWS
static void siginfo_handler(int signum) {
  auto handler = extended_signal_handlers[signum];
  handler(signum, nullptr);
}
#endif

Status set_extended_signal_handler(SignalType type, extended_signal_handler func) {
  CHECK(func != nullptr);
  auto signals = get_native_signals(type);
  for (auto signal : signals) {
    if (0 <= signal && signal < NSIG) {
      extended_signal_handlers[signal] = func;
    } else {
      UNREACHABLE();
    }
  }
  return set_signal_handler_impl(std::move(signals), siginfo_handler);
}

Status set_runtime_signal_handler(int runtime_signal_number, void (*func)(int)) {
#ifdef SIGRTMIN
  CHECK(SIGRTMIN + runtime_signal_number <= SIGRTMAX);
  return set_signal_handler_impl({SIGRTMIN + runtime_signal_number}, func == nullptr ? SIG_DFL : func);
#else
  return Status::OK();
#endif
}

Status ignore_signal(SignalType type) {
  return set_signal_handler_impl(get_native_signals(type), SIG_IGN);
}

static void signal_safe_append_int(char **s, Slice name, int number) {
  if (number < 0) {
    number = std::numeric_limits<int>::max();
  }

  *--*s = ' ';
  *--*s = ']';

  do {
    *--*s = static_cast<char>(number % 10 + '0');
    number /= 10;
  } while (number > 0);

  *--*s = ' ';

  for (auto pos = static_cast<int>(name.size()) - 1; pos >= 0; pos--) {
    *--*s = name[pos];
  }

  *--*s = '[';
}

static void signal_safe_write_data(Slice data) {
#if TD_PORT_POSIX
  while (!data.empty()) {
    auto res = write(2, data.begin(), data.size());
    if (res < 0 && errno == EINTR) {
      continue;
    }
    if (res <= 0) {
      break;
    }

    if (res > 0) {
      data.remove_prefix(res);
    }
  }
#elif TD_PORT_WINDOWS
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM)
  HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
  DWORD bytes_written;
  WriteFile(stderr_handle, data.data(), static_cast<DWORD>(data.size()), &bytes_written, nullptr);
#else
// there is no stderr
#endif
#endif
}

static int get_process_id() {
#if TD_PORT_POSIX
  return getpid();
#elif TD_PORT_WINDOWS
  return GetCurrentProcessId();
#endif
}

void signal_safe_write(Slice data, bool add_header) {
  auto old_errno = errno;

  if (add_header) {
    constexpr size_t HEADER_BUF_SIZE = 100;
    char header[HEADER_BUF_SIZE];
    char *header_end = header + HEADER_BUF_SIZE;
    char *header_begin = header_end;

    signal_safe_append_int(&header_begin, "time", static_cast<int>(std::time(nullptr)));
    signal_safe_append_int(&header_begin, "pid", get_process_id());

    signal_safe_write_data(Slice(header_begin, header_end));
  }

  signal_safe_write_data(data);

  errno = old_errno;
}

void signal_safe_write_signal_number(int sig, bool add_header) {
  char buf[100];
  char *end = buf + sizeof(buf);
  char *ptr = end;
  *--ptr = '\n';
  do {
    *--ptr = static_cast<char>(sig % 10 + '0');
    sig /= 10;
  } while (sig != 0);

  ptr -= 8;
  std::memcpy(ptr, "Signal: ", 8);
  signal_safe_write(Slice(ptr, end), add_header);
}

void signal_safe_write_pointer(void *p, bool add_header) {
  std::uintptr_t addr = reinterpret_cast<std::uintptr_t>(p);
  char buf[100];
  char *end = buf + sizeof(buf);
  char *ptr = end;
  *--ptr = '\n';
  do {
    *--ptr = format::hex_digit(addr % 16);
    addr /= 16;
  } while (addr != 0);
  *--ptr = 'x';
  *--ptr = '0';
  ptr -= 9;
  std::memcpy(ptr, "Address: ", 9);
  signal_safe_write(Slice(ptr, end), add_header);
}

static void block_stdin() {
#if TD_PORT_POSIX
  Stdin().get_native_fd().set_is_blocking(true).ignore();
#endif
}

static void default_failure_signal_handler(int sig) {
  Stacktrace::init();
  signal_safe_write_signal_number(sig);

  Stacktrace::PrintOptions options;
  options.use_gdb = true;
  Stacktrace::print_to_stderr(options);

  block_stdin();
  _Exit(EXIT_FAILURE);
}

Status set_default_failure_signal_handler() {
#if TD_PORT_POSIX
  Stdin();  // init static variables before atexit
#endif
  std::atexit(block_stdin);
  TRY_STATUS(setup_signals_alt_stack());
  TRY_STATUS(set_signal_handler(SignalType::Abort, default_failure_signal_handler));
  TRY_STATUS(set_signal_handler(SignalType::Error, default_failure_signal_handler));
  return Status::OK();
}

}  // namespace td


void HadoopFileSystemTest::SetUp() {
	HadoopFileSystemBaseTest::init();
	nativeHdfs.connectFromSystemEnvironment();
}

#include "HadoopFileSystemTest.h"

#include "FileSystem/HadoopFileSystem.h"

#include "SystemEnvironment.h"
#include "TestResources.h"

// BEGIN HadoopFileSystemBaseTest

void HadoopFileSystemBaseTest::init() {
	this->hadoopFileSystem = std::unique_ptr<HadoopFileSystem>(new HadoopFileSystem());

	const FileSystemConnection fileSystemConnection = SystemEnvironment::getLocalHadoopFileSystemConnection();

	// TODO check this
	this->hadoopFileSystem->connect(fileSystemConnection);

	TestResources::createTestResources();
}

void HadoopFileSystemBaseTest::shutdown() {
	// TODO percy check this

	TestResources::removeTestResources();
}

Uri HadoopFileSystemBaseTest::uri(const std::string path) const {
	return Uri(Uri::fileSystemTypeToScheme(FileSystemType::HDFS), "test_hdfs_disk1", Path(path));
}

// END HadoopFileSystemBaseTest

// BEGIN HadoopFileSystemTest

void HadoopFileSystemTest::TearDown() {
	HadoopFileSystemBaseTest::shutdown();
	nativeHdfs.disconnect();
}

// END HadoopFileSystemTest