/** * Does a sanity-check validation of the registry ensuring three things: * 1. All upgrade paths lead to the same minCompatible/currentVersion * 2. Our constants match this final version pair * 3. There is a zero-version upgrade path */ void validateRegistry(const ConfigUpgradeRegistry& registry) { VersionRange maxCompatibleConfigVersionRange(-1, -1); bool hasZeroVersionUpgrade = false; for (ConfigUpgradeRegistry::const_iterator it = registry.begin(); it != registry.end(); ++it) { const Upgrade& upgrade = it->second; if (upgrade.fromVersion == 0) hasZeroVersionUpgrade = true; if (maxCompatibleConfigVersionRange.currentVersion < upgrade.toVersionRange.currentVersion) { maxCompatibleConfigVersionRange = upgrade.toVersionRange; } else if (maxCompatibleConfigVersionRange.currentVersion == upgrade.toVersionRange.currentVersion) { // Make sure all max upgrade paths end up with same version and compatibility fassert(16621, maxCompatibleConfigVersionRange == upgrade.toVersionRange); } } // Make sure we have a zero-version upgrade fassert(16622, hasZeroVersionUpgrade); // Make sure our max registered range is the same as our constants fassert(16623, maxCompatibleConfigVersionRange == VersionRange(MIN_COMPATIBLE_CONFIG_VERSION, CURRENT_CONFIG_VERSION)); }
// Dispatches upgrades based on version to the upgrades registered in the upgrade registry bool _nextUpgrade(const ConnectionString& configLoc, const ConfigUpgradeRegistry& registry, const VersionType& lastVersionInfo, VersionType* upgradedVersionInfo, string* errMsg) { int fromVersion = lastVersionInfo.getCurrentVersion(); ConfigUpgradeRegistry::const_iterator foundIt = registry.find(fromVersion); if (foundIt == registry.end()) { *errMsg = stream() << "newer version " << CURRENT_CONFIG_VERSION << " of mongo config metadata is required, " << "current version is " << fromVersion << ", " << "don't know how to upgrade from this version"; return false; } const Upgrade& upgrade = foundIt->second; int toVersion = upgrade.toVersionRange.currentVersion; log() << "starting next upgrade step from v" << fromVersion << " to v" << toVersion << endl; // Log begin to config.changelog grid.catalogManager()->logChange(NULL, "starting upgrade of config database", VersionType::ConfigNS, BSON("from" << fromVersion << "to" << toVersion)); if (!upgrade.upgradeCallback(configLoc, lastVersionInfo, errMsg)) { *errMsg = stream() << "error upgrading config database from v" << fromVersion << " to v" << toVersion << causedBy(errMsg); return false; } // Get the config version we've upgraded to and make sure it's sane Status verifyConfigStatus = getConfigVersion(configLoc, upgradedVersionInfo); if (!verifyConfigStatus.isOK()) { *errMsg = stream() << "failed to validate v" << fromVersion << " config version upgrade" << causedBy(verifyConfigStatus); return false; } grid.catalogManager()->logChange(NULL, "finished upgrade of config database", VersionType::ConfigNS, BSON("from" << fromVersion << "to" << toVersion)); return true; }