summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Studer <greg@10gen.com>2013-02-20 19:28:39 -0500
committerGreg Studer <greg@10gen.com>2013-02-20 19:29:20 -0500
commit46436d5fd83099aec712ba513a3a8677924939ed (patch)
tree9faff7d4776921c3a17c5ee9128f870d7a5f090d
parent897627666be933bbfe2c396cd5ca4d08d03b70ee (diff)
downloadmongo-46436d5fd83099aec712ba513a3a8677924939ed.tar.gz
SERVER-8574 contact all config servers before waiting for distributed lock on config upgrade
-rw-r--r--src/mongo/s/config_upgrade.cpp45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/mongo/s/config_upgrade.cpp b/src/mongo/s/config_upgrade.cpp
index 8954c892ff1..4ba54462e09 100644
--- a/src/mongo/s/config_upgrade.cpp
+++ b/src/mongo/s/config_upgrade.cpp
@@ -277,6 +277,41 @@ namespace mongo {
return VersionStatus_NeedUpgrade;
}
+ // Checks that all config servers are online
+ bool _checkConfigServersAlive(const ConnectionString& configLoc, string* errMsg) {
+
+ scoped_ptr<ScopedDbConnection> connPtr;
+
+ bool resultOk;
+ BSONObj result;
+ try {
+ connPtr.reset(ScopedDbConnection::getInternalScopedDbConnection(configLoc, 30));
+ ScopedDbConnection& conn = *connPtr;
+
+ if (conn->type() == ConnectionString::SYNC) {
+ // TODO: Dynamic cast is bad, we need a better way of managing this op
+ // via the heirarchy (or not)
+ return (dynamic_cast<SyncClusterConnection*>(conn.get()))->prepare(*errMsg);
+ }
+ else {
+ resultOk = conn->runCommand("admin", BSON( "fsync" << 1 ), result);
+ }
+ }
+ catch (const DBException& e) {
+ *errMsg = e.toString();
+ return false;
+ }
+
+ connPtr->done();
+
+ if (!resultOk) {
+ *errMsg = DBClientWithCommands::getLastErrorString(result);
+ return false;
+ }
+
+ return true;
+ }
+
// Dispatches upgrades based on version to the upgrades registered in the upgrade registry
bool _nextUpgrade(const ConnectionString& configLoc,
const ConfigUpgradeRegistry& registry,
@@ -403,6 +438,16 @@ namespace mongo {
return false;
}
+ // Contact the config servers to make sure all are online - otherwise we wait a long time
+ // for locks.
+ if (!_checkConfigServersAlive(configLoc, errMsg)) {
+
+ *errMsg = stream() << "all config servers must be reachable for config upgrade"
+ << causedBy(errMsg);
+
+ return false;
+ }
+
//
// Acquire a lock for the upgrade process.
//