diff options
author | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2015-06-20 00:22:50 -0400 |
---|---|---|
committer | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2015-06-20 10:56:02 -0400 |
commit | 9c2ed42daa8fbbef4a919c21ec564e2db55e8d60 (patch) | |
tree | 3814f79c10d7b490948d8cb7b112ac1dd41ceff1 /src/mongo/db/repl/replica_set_config_checks.cpp | |
parent | 01965cf52bce6976637ecb8f4a622aeb05ab256a (diff) | |
download | mongo-9c2ed42daa8fbbef4a919c21ec564e2db55e8d60.tar.gz |
SERVER-18579: Clang-Format - reformat code, no comment reflow
Diffstat (limited to 'src/mongo/db/repl/replica_set_config_checks.cpp')
-rw-r--r-- | src/mongo/db/repl/replica_set_config_checks.cpp | 409 |
1 files changed, 198 insertions, 211 deletions
diff --git a/src/mongo/db/repl/replica_set_config_checks.cpp b/src/mongo/db/repl/replica_set_config_checks.cpp index 7b97d3679a3..6b972063c6a 100644 --- a/src/mongo/db/repl/replica_set_config_checks.cpp +++ b/src/mongo/db/repl/replica_set_config_checks.cpp @@ -40,247 +40,234 @@ namespace mongo { namespace repl { namespace { - /** - * Finds the index of the one member configuration in "newConfig" that corresponds - * to the current node (as identified by "externalState"). - * - * Returns an error if the current node does not appear or appears multiple times in - * "newConfig". - */ - StatusWith<int> findSelfInConfig( - ReplicationCoordinatorExternalState* externalState, - const ReplicaSetConfig& newConfig) { - - std::vector<ReplicaSetConfig::MemberIterator> meConfigs; - for (ReplicaSetConfig::MemberIterator iter = newConfig.membersBegin(); - iter != newConfig.membersEnd(); - ++iter) { - if (externalState->isSelf(iter->getHostAndPort())) { - meConfigs.push_back(iter); - } - } - if (meConfigs.empty()) { - return StatusWith<int>(ErrorCodes::NodeNotFound, str::stream() << - "No host described in new configuration " << - newConfig.getConfigVersion() << " for replica set " << - newConfig.getReplSetName() << " maps to this node"); - } - if (meConfigs.size() > 1) { - str::stream message; - message << "The hosts " << meConfigs.front()->getHostAndPort().toString(); - for (size_t i = 1; i < meConfigs.size() - 1; ++i) { - message << ", " << meConfigs[i]->getHostAndPort().toString(); - } - message << " and " << meConfigs.back()->getHostAndPort().toString() << - " all map to this node in new configuration version " << - newConfig.getConfigVersion() << " for replica set " << newConfig.getReplSetName(); - return StatusWith<int>(ErrorCodes::DuplicateKey, message); +/** + * Finds the index of the one member configuration in "newConfig" that corresponds + * to the current node (as identified by "externalState"). + * + * Returns an error if the current node does not appear or appears multiple times in + * "newConfig". + */ +StatusWith<int> findSelfInConfig(ReplicationCoordinatorExternalState* externalState, + const ReplicaSetConfig& newConfig) { + std::vector<ReplicaSetConfig::MemberIterator> meConfigs; + for (ReplicaSetConfig::MemberIterator iter = newConfig.membersBegin(); + iter != newConfig.membersEnd(); + ++iter) { + if (externalState->isSelf(iter->getHostAndPort())) { + meConfigs.push_back(iter); } - - int myIndex = std::distance(newConfig.membersBegin(), meConfigs.front()); - invariant(myIndex >= 0 && myIndex < newConfig.getNumMembers()); - return StatusWith<int>(myIndex); } - - /** - * Checks if the node with the given config index is electable, returning a useful - * status message if not. - */ - Status checkElectable(const ReplicaSetConfig& newConfig, int configIndex) { - const MemberConfig& myConfig = newConfig.getMemberAt(configIndex); - if (!myConfig.isElectable()) { - return Status( - ErrorCodes::NodeNotElectable, str::stream() << - "This node, " << myConfig.getHostAndPort().toString() << ", with _id " << - myConfig.getId() << " is not electable under the new configuration version " << - newConfig.getConfigVersion() << " for replica set " << - newConfig.getReplSetName()); - } - return Status::OK(); + if (meConfigs.empty()) { + return StatusWith<int>(ErrorCodes::NodeNotFound, + str::stream() << "No host described in new configuration " + << newConfig.getConfigVersion() << " for replica set " + << newConfig.getReplSetName() << " maps to this node"); } - - /** - * Like findSelfInConfig, above, but also returns an error if the member configuration - * for this node is not electable, as this is a requirement for nodes accepting - * reconfig or initiate commands. - */ - StatusWith<int> findSelfInConfigIfElectable( - ReplicationCoordinatorExternalState* externalState, - const ReplicaSetConfig& newConfig) { - StatusWith<int> result = findSelfInConfig(externalState, newConfig); - if (result.isOK()) { - Status status = checkElectable(newConfig, result.getValue()); - if (!status.isOK()) { - return StatusWith<int>(status); - } + if (meConfigs.size() > 1) { + str::stream message; + message << "The hosts " << meConfigs.front()->getHostAndPort().toString(); + for (size_t i = 1; i < meConfigs.size() - 1; ++i) { + message << ", " << meConfigs[i]->getHostAndPort().toString(); } - return result; + message << " and " << meConfigs.back()->getHostAndPort().toString() + << " all map to this node in new configuration version " + << newConfig.getConfigVersion() << " for replica set " + << newConfig.getReplSetName(); + return StatusWith<int>(ErrorCodes::DuplicateKey, message); } - /** - * Compares two initialized and validated replica set configurations, and checks to - * see if "newConfig" is a legal successor configuration to "oldConfig". - * - * Returns Status::OK() if "newConfig" may replace "oldConfig", or an indicative error - * otherwise. - * - * The checks performed by this test are necessary, but may not be sufficient for - * ensuring that "newConfig" is a legal successor to "oldConfig". For example, - * a legal reconfiguration must typically be executed on a node that is currently - * primary under "oldConfig" and is electable under "newConfig". Such checks that - * require knowledge of which node is executing the configuration are out of scope - * for this function. - */ - Status validateOldAndNewConfigsCompatible( - const ReplicaSetConfig& oldConfig, - const ReplicaSetConfig& newConfig) { - invariant(newConfig.isInitialized()); - invariant(oldConfig.isInitialized()); - - if (oldConfig.getConfigVersion() >= newConfig.getConfigVersion()) { - return Status(ErrorCodes::NewReplicaSetConfigurationIncompatible, - str::stream() << - "New replica set configuration version must be greater than old, but " << - newConfig.getConfigVersion() << " is not greater than " << - oldConfig.getConfigVersion() << " for replica set " << - newConfig.getReplSetName()); - } + int myIndex = std::distance(newConfig.membersBegin(), meConfigs.front()); + invariant(myIndex >= 0 && myIndex < newConfig.getNumMembers()); + return StatusWith<int>(myIndex); +} - if (oldConfig.getReplSetName() != newConfig.getReplSetName()) { - return Status(ErrorCodes::NewReplicaSetConfigurationIncompatible, - str::stream() << - "New and old configurations differ in replica set name; " - "old was " << oldConfig.getReplSetName() << ", and new is " << - newConfig.getReplSetName()); - } - - // - // For every member config mNew in newConfig, if there exists member config mOld - // in oldConfig such that mNew.getHostAndPort() == mOld.getHostAndPort(), it is required - // that mNew.getId() == mOld.getId(). - // - // Also, one may not use reconfig to change the value of the buildIndexes or - // arbiterOnly flags. - // - for (ReplicaSetConfig::MemberIterator mNew = newConfig.membersBegin(); - mNew != newConfig.membersEnd(); - ++mNew) { - for (ReplicaSetConfig::MemberIterator mOld = oldConfig.membersBegin(); - mOld != oldConfig.membersEnd(); - ++mOld) { - - const bool idsEqual = mOld->getId() == mNew->getId(); - const bool hostsEqual = mOld->getHostAndPort() == mNew->getHostAndPort(); - if (!idsEqual && !hostsEqual) { - continue; - } - if (hostsEqual && !idsEqual) { - return Status(ErrorCodes::NewReplicaSetConfigurationIncompatible, - str::stream() << - "New and old configurations both have members with " << - MemberConfig::kHostFieldName << " of " << - mOld->getHostAndPort().toString() << - " but in the new configuration the " << - MemberConfig::kIdFieldName << " field is " << - mNew->getId() << " and in the old configuration it is " << - mOld->getId() << - " for replica set " << newConfig.getReplSetName()); - } - // At this point, the _id and host fields are equal, so we're looking at the old and - // new configurations for the same member node. - const bool buildIndexesFlagsEqual = - mOld->shouldBuildIndexes() == mNew->shouldBuildIndexes(); - if (!buildIndexesFlagsEqual) { - return Status(ErrorCodes::NewReplicaSetConfigurationIncompatible, - str::stream() << - "New and old configurations differ in the setting of the " - "buildIndexes field for member " << - mOld->getHostAndPort().toString() << - "; to make this change, remove then re-add the member"); - } - const bool arbiterFlagsEqual = mOld->isArbiter() == mNew->isArbiter(); - if (!arbiterFlagsEqual) { - return Status(ErrorCodes::NewReplicaSetConfigurationIncompatible, - str::stream() << - "New and old configurations differ in the setting of the " - "arbiterOnly field for member " << - mOld->getHostAndPort().toString() << - "; to make this change, remove then re-add the member"); - - } - } - } - return Status::OK(); +/** + * Checks if the node with the given config index is electable, returning a useful + * status message if not. + */ +Status checkElectable(const ReplicaSetConfig& newConfig, int configIndex) { + const MemberConfig& myConfig = newConfig.getMemberAt(configIndex); + if (!myConfig.isElectable()) { + return Status(ErrorCodes::NodeNotElectable, + str::stream() << "This node, " << myConfig.getHostAndPort().toString() + << ", with _id " << myConfig.getId() + << " is not electable under the new configuration version " + << newConfig.getConfigVersion() << " for replica set " + << newConfig.getReplSetName()); } -} // namespace + return Status::OK(); +} - StatusWith<int> validateConfigForStartUp( - ReplicationCoordinatorExternalState* externalState, - const ReplicaSetConfig& oldConfig, - const ReplicaSetConfig& newConfig) { - Status status = newConfig.validate(); +/** + * Like findSelfInConfig, above, but also returns an error if the member configuration + * for this node is not electable, as this is a requirement for nodes accepting + * reconfig or initiate commands. + */ +StatusWith<int> findSelfInConfigIfElectable(ReplicationCoordinatorExternalState* externalState, + const ReplicaSetConfig& newConfig) { + StatusWith<int> result = findSelfInConfig(externalState, newConfig); + if (result.isOK()) { + Status status = checkElectable(newConfig, result.getValue()); if (!status.isOK()) { return StatusWith<int>(status); } - if (oldConfig.isInitialized()) { - status = validateOldAndNewConfigsCompatible(oldConfig, newConfig); - if (!status.isOK()) { - return StatusWith<int>(status); - } - } - return findSelfInConfig(externalState, newConfig); } + return result; +} - StatusWith<int> validateConfigForInitiate( - ReplicationCoordinatorExternalState* externalState, - const ReplicaSetConfig& newConfig) { - Status status = newConfig.validate(); - if (!status.isOK()) { - return StatusWith<int>(status); - } - if (newConfig.getConfigVersion() != 1) { - return StatusWith<int>( - ErrorCodes::NewReplicaSetConfigurationIncompatible, - str::stream() << "Configuration used to initiate a replica set must " << - " have version 1, but found " << newConfig.getConfigVersion()); - } - return findSelfInConfigIfElectable(externalState, newConfig); +/** + * Compares two initialized and validated replica set configurations, and checks to + * see if "newConfig" is a legal successor configuration to "oldConfig". + * + * Returns Status::OK() if "newConfig" may replace "oldConfig", or an indicative error + * otherwise. + * + * The checks performed by this test are necessary, but may not be sufficient for + * ensuring that "newConfig" is a legal successor to "oldConfig". For example, + * a legal reconfiguration must typically be executed on a node that is currently + * primary under "oldConfig" and is electable under "newConfig". Such checks that + * require knowledge of which node is executing the configuration are out of scope + * for this function. + */ +Status validateOldAndNewConfigsCompatible(const ReplicaSetConfig& oldConfig, + const ReplicaSetConfig& newConfig) { + invariant(newConfig.isInitialized()); + invariant(oldConfig.isInitialized()); + + if (oldConfig.getConfigVersion() >= newConfig.getConfigVersion()) { + return Status(ErrorCodes::NewReplicaSetConfigurationIncompatible, + str::stream() + << "New replica set configuration version must be greater than old, but " + << newConfig.getConfigVersion() << " is not greater than " + << oldConfig.getConfigVersion() << " for replica set " + << newConfig.getReplSetName()); } - StatusWith<int> validateConfigForReconfig( - ReplicationCoordinatorExternalState* externalState, - const ReplicaSetConfig& oldConfig, - const ReplicaSetConfig& newConfig, - bool force) { + if (oldConfig.getReplSetName() != newConfig.getReplSetName()) { + return Status(ErrorCodes::NewReplicaSetConfigurationIncompatible, + str::stream() << "New and old configurations differ in replica set name; " + "old was " << oldConfig.getReplSetName() << ", and new is " + << newConfig.getReplSetName()); + } - Status status = newConfig.validate(); - if (!status.isOK()) { - return StatusWith<int>(status); + // + // For every member config mNew in newConfig, if there exists member config mOld + // in oldConfig such that mNew.getHostAndPort() == mOld.getHostAndPort(), it is required + // that mNew.getId() == mOld.getId(). + // + // Also, one may not use reconfig to change the value of the buildIndexes or + // arbiterOnly flags. + // + for (ReplicaSetConfig::MemberIterator mNew = newConfig.membersBegin(); + mNew != newConfig.membersEnd(); + ++mNew) { + for (ReplicaSetConfig::MemberIterator mOld = oldConfig.membersBegin(); + mOld != oldConfig.membersEnd(); + ++mOld) { + const bool idsEqual = mOld->getId() == mNew->getId(); + const bool hostsEqual = mOld->getHostAndPort() == mNew->getHostAndPort(); + if (!idsEqual && !hostsEqual) { + continue; + } + if (hostsEqual && !idsEqual) { + return Status(ErrorCodes::NewReplicaSetConfigurationIncompatible, + str::stream() + << "New and old configurations both have members with " + << MemberConfig::kHostFieldName << " of " + << mOld->getHostAndPort().toString() + << " but in the new configuration the " + << MemberConfig::kIdFieldName << " field is " << mNew->getId() + << " and in the old configuration it is " << mOld->getId() + << " for replica set " << newConfig.getReplSetName()); + } + // At this point, the _id and host fields are equal, so we're looking at the old and + // new configurations for the same member node. + const bool buildIndexesFlagsEqual = + mOld->shouldBuildIndexes() == mNew->shouldBuildIndexes(); + if (!buildIndexesFlagsEqual) { + return Status(ErrorCodes::NewReplicaSetConfigurationIncompatible, + str::stream() + << "New and old configurations differ in the setting of the " + "buildIndexes field for member " + << mOld->getHostAndPort().toString() + << "; to make this change, remove then re-add the member"); + } + const bool arbiterFlagsEqual = mOld->isArbiter() == mNew->isArbiter(); + if (!arbiterFlagsEqual) { + return Status(ErrorCodes::NewReplicaSetConfigurationIncompatible, + str::stream() + << "New and old configurations differ in the setting of the " + "arbiterOnly field for member " + << mOld->getHostAndPort().toString() + << "; to make this change, remove then re-add the member"); + } } + } + return Status::OK(); +} +} // namespace +StatusWith<int> validateConfigForStartUp(ReplicationCoordinatorExternalState* externalState, + const ReplicaSetConfig& oldConfig, + const ReplicaSetConfig& newConfig) { + Status status = newConfig.validate(); + if (!status.isOK()) { + return StatusWith<int>(status); + } + if (oldConfig.isInitialized()) { status = validateOldAndNewConfigsCompatible(oldConfig, newConfig); if (!status.isOK()) { return StatusWith<int>(status); } + } + return findSelfInConfig(externalState, newConfig); +} - if (force) { - return findSelfInConfig(externalState, newConfig); - } - - return findSelfInConfigIfElectable(externalState, newConfig); +StatusWith<int> validateConfigForInitiate(ReplicationCoordinatorExternalState* externalState, + const ReplicaSetConfig& newConfig) { + Status status = newConfig.validate(); + if (!status.isOK()) { + return StatusWith<int>(status); + } + if (newConfig.getConfigVersion() != 1) { + return StatusWith<int>(ErrorCodes::NewReplicaSetConfigurationIncompatible, + str::stream() << "Configuration used to initiate a replica set must " + << " have version 1, but found " + << newConfig.getConfigVersion()); } + return findSelfInConfigIfElectable(externalState, newConfig); +} - StatusWith<int> validateConfigForHeartbeatReconfig( - ReplicationCoordinatorExternalState* externalState, - const ReplicaSetConfig& newConfig) { +StatusWith<int> validateConfigForReconfig(ReplicationCoordinatorExternalState* externalState, + const ReplicaSetConfig& oldConfig, + const ReplicaSetConfig& newConfig, + bool force) { + Status status = newConfig.validate(); + if (!status.isOK()) { + return StatusWith<int>(status); + } - Status status = newConfig.validate(); - if (!status.isOK()) { - return StatusWith<int>(status); - } + status = validateOldAndNewConfigsCompatible(oldConfig, newConfig); + if (!status.isOK()) { + return StatusWith<int>(status); + } + if (force) { return findSelfInConfig(externalState, newConfig); } + return findSelfInConfigIfElectable(externalState, newConfig); +} + +StatusWith<int> validateConfigForHeartbeatReconfig( + ReplicationCoordinatorExternalState* externalState, const ReplicaSetConfig& newConfig) { + Status status = newConfig.validate(); + if (!status.isOK()) { + return StatusWith<int>(status); + } + + return findSelfInConfig(externalState, newConfig); +} + } // namespace repl } // namespace mongo |