bool waitForTick(const std::shared_ptr<PermissionsRunnable>& runnable) { size_t now = runnable->ticks; size_t timeout = 1000; size_t delay = 0; while (delay < timeout) { sleepFor(20); if (runnable->ticks > now) { return true; } sleepFor(200); delay += 220; } return false; }
MONGO_FAIL_POINT_BLOCK(setYieldAllLocksWait, customWait) { const BSONObj& data = customWait.getData(); BSONElement customWaitNS = data["namespace"]; if (!customWaitNS || planExecNS.ns() == customWaitNS.str()) { sleepFor(Milliseconds(data["waitForMillis"].numberInt())); } }
void ShardingUptimeReporter::startPeriodicThread() { invariant(!_thread.joinable()); _thread = stdx::thread([] { Client::initThread("Uptime reporter"); const std::string hostName(getHostNameCached()); const std::string instanceId(constructInstanceIdString(hostName)); const Timer upTimeTimer; while (!globalInShutdownDeprecated()) { { auto opCtx = cc().makeOperationContext(); reportStatus(opCtx.get(), instanceId, hostName, upTimeTimer); auto status = Grid::get(opCtx.get()) ->getBalancerConfiguration() ->refreshAndCheck(opCtx.get()); if (!status.isOK()) { warning() << "failed to refresh mongos settings" << causedBy(status); } } MONGO_IDLE_THREAD_BLOCK; sleepFor(kUptimeReportInterval); } }); }
void ShardingUptimeReporter::startPeriodicThread() { invariant(!_thread.joinable()); _thread = stdx::thread([this] { Client::initThread("Uptime reporter"); const std::string instanceId(constructInstanceIdString()); const Timer upTimeTimer; while (!inShutdown()) { { auto txn = cc().makeOperationContext(); reportStatus(txn.get(), instanceId, upTimeTimer); auto status = Grid::get(txn.get())->getBalancerConfiguration()->refreshAndCheck(txn.get()); if (!status.isOK()) { warning() << "failed to refresh mongos settings" << causedBy(status); } } sleepFor(kUptimeReportInterval); } }); }
void showLoad(){ printf("|"); sleepFor(100); printf("\b"); fflush(stdout); printf("/"); sleepFor(100); printf("\b"); fflush(stdout); printf("-"); sleepFor(100); printf("\b"); fflush(stdout); printf("|"); sleepFor(100); printf("\b"); fflush(stdout); printf("/"); sleepFor(100); printf("\b"); fflush(stdout); printf("-"); sleepFor(100); printf("\b"); fflush(stdout); printf("|"); sleepFor(100); printf("\b"); fflush(stdout); }
void waitForConfig(std::shared_ptr<TestConfigPlugin>& plugin, size_t count) { // Max wait of 3 seconds. size_t delay = 3000; while (delay > 0) { if (plugin->genConfigCount > count) { break; } delay -= 20; sleepFor(20); } }
bool socketExistsLocal(const std::string& check_path) { // Wait until the runnable/thread created the socket. int delay = 0; while (delay < kTimeout) { if (osquery::socketExists(check_path).ok()) { return true; } sleepFor(kDelay); delay += kDelay; } return false; }
bool socketExists(const std::string& socket_path) { // Wait until the runnable/thread created the socket. int delay = 0; while (delay < kTimeoutUS) { if (pathExists(socket_path).ok() && isReadable(socket_path).ok()) { return true; } sleepFor(kDelayUS / 1000); delay += kDelayUS; } return false; }
QueryData query(const std::string& sql, int attempts = 3) { // Calling open will except if the socket does not exist. QueryData qd; for (int i = 0; i < attempts; ++i) { try { ExtensionManagerClient client(socket_path); client.query(sql, qd); } catch (const std::exception& /* e */) { sleepFor(kDelay); } } return qd; }
bool ping(int attempts = 3) { // Calling open will except if the socket does not exist. for (int i = 0; i < attempts; ++i) { try { ExtensionManagerClient client(socket_path); auto status = client.ping(); return (status.getCode() == (int)ExtensionCode::EXT_SUCCESS); } catch (const std::exception& /* e */) { sleepFor(kDelay); } } return false; }
void WriteUnitOfWork::commit() { invariant(!_committed); invariant(!_released); invariant(_opCtx->_ruState == RecoveryUnitState::kActiveUnitOfWork); if (_toplevel) { if (MONGO_FAIL_POINT(sleepBeforeCommit)) { sleepFor(Milliseconds(100)); } _opCtx->recoveryUnit()->commitUnitOfWork(); _opCtx->_ruState = RecoveryUnitState::kNotInUnitOfWork; } _opCtx->lockState()->endWriteUnitOfWork(); _committed = true; }
bool ping(int attempts = 3) { // Calling open will except if the socket does not exist. ExtensionStatus status; for (int i = 0; i < attempts; ++i) { try { EXManagerClient client(socket_path); client.get()->ping(status); return (status.code == ExtensionCode::EXT_SUCCESS); } catch (const std::exception& e) { sleepFor(kDelayUS / 1000); } } return false; }
Status checkStalePid(const std::string& content) { int pid; try { pid = boost::lexical_cast<int>(content); } catch (const boost::bad_lexical_cast& e) { if (FLAGS_force) { return Status(0, "Force loading and not parsing pidfile"); } else { return Status(1, "Could not parse pidfile"); } } PlatformProcess target(pid); int status = 0; // The pid is running, check if it is an osqueryd process by name. std::stringstream query_text; query_text << "SELECT name FROM processes WHERE pid = " << pid << " AND name LIKE 'osqueryd%';"; auto q = SQL(query_text.str()); if (!q.ok()) { return Status(1, "Error querying processes: " + q.getMessageString()); } if (q.rows().size() > 0) { // If the process really is osqueryd, return an "error" status. if (FLAGS_force) { // The caller may choose to abort the existing daemon with --force. // Do not use SIGQUIT as it will cause a crash on OS X. status = target.kill() ? 0 : -1; sleepFor(1000); return Status(status, "Tried to force remove the existing osqueryd"); } return Status(1, "osqueryd (" + content + ") is already running"); } else { LOG(INFO) << "Found stale process for osqueryd (" << content << ") removing pidfile"; } return Status(0, "OK"); }
// static void QueryYield::yieldAllLocks(OperationContext* txn, RecordFetcher* fetcher, const std::string& planExecNS) { // Things have to happen here in a specific order: // 1) Tell the RecordFetcher to do any setup which needs to happen inside locks // 2) Release lock mgr locks // 3) Go to sleep // 4) Touch the record we're yielding on, if there is one (RecordFetcher::fetch) // 5) Reacquire lock mgr locks Locker* locker = txn->lockState(); Locker::LockSnapshot snapshot; if (fetcher) { fetcher->setup(); } // Nothing was unlocked, just return, yielding is pointless. if (!locker->saveLockStateAndUnlock(&snapshot)) { return; } // Top-level locks are freed, release any potential low-level (storage engine-specific // locks). If we are yielding, we are at a safe place to do so. txn->recoveryUnit()->abandonSnapshot(); MONGO_FAIL_POINT_BLOCK(setYieldAllLocksWait, customWait) { const BSONObj& data = customWait.getData(); BSONElement customWaitNS = data["namespace"]; if (!customWaitNS || planExecNS == customWaitNS.str()) { sleepFor(stdx::chrono::milliseconds(data["waitForMillis"].numberInt())); } } // Track the number of yields in CurOp. CurOp::get(txn)->yielded(); if (fetcher) { fetcher->fetch(); } locker->restoreLockState(snapshot); }
QueryData query(const std::string& sql, int attempts = 3) { // Calling open will except if the socket does not exist. ExtensionResponse response; for (int i = 0; i < attempts; ++i) { try { EXManagerClient client(socket_path); client.get()->query(response, sql); } catch (const std::exception& e) { sleepFor(kDelayUS / 1000); } } QueryData qd; for (const auto& row : response.response) { qd.push_back(row); } return qd; }
SignedLogicalTime LogicalTimeValidator::signLogicalTime(OperationContext* opCtx, const LogicalTime& newTime) { auto keyManager = _getKeyManagerCopy(); auto keyStatusWith = keyManager->getKeyForSigning(nullptr, newTime); auto keyStatus = keyStatusWith.getStatus(); while (keyStatus == ErrorCodes::KeyNotFound && LogicalClock::get(opCtx)->isEnabled()) { keyManager->refreshNow(opCtx); keyStatusWith = keyManager->getKeyForSigning(nullptr, newTime); keyStatus = keyStatusWith.getStatus(); if (keyStatus == ErrorCodes::KeyNotFound) { sleepFor(kRefreshIntervalIfErrored); } } uassertStatusOK(keyStatus); return _getProof(keyStatusWith.getValue(), newTime); }
AutoGetCollection::AutoGetCollection(OperationContext* opCtx, const NamespaceString& nss, LockMode modeDB, LockMode modeColl, ViewMode viewMode) : _viewMode(viewMode), _autoDb(opCtx, nss.db(), modeDB), _collLock(opCtx->lockState(), nss.ns(), modeColl), _coll(_autoDb.getDb() ? _autoDb.getDb()->getCollection(opCtx, nss) : nullptr) { Database* db = _autoDb.getDb(); // If the database exists, but not the collection, check for views. if (_viewMode == ViewMode::kViewsForbidden && db && !_coll && db->getViewCatalog()->lookup(opCtx, nss.ns())) uasserted(ErrorCodes::CommandNotSupportedOnView, str::stream() << "Namespace " << nss.ns() << " is a view, not a collection"); // Wait for a configured amount of time after acquiring locks if the failpoint is enabled. MONGO_FAIL_POINT_BLOCK(setAutoGetCollectionWait, customWait) { const BSONObj& data = customWait.getData(); sleepFor(Milliseconds(data["waitForMillis"].numberInt())); } }
void Balancer::run() { Client::initThread("Balancer"); // This is the body of a BackgroundJob so if we throw here we're basically ending the balancer // thread prematurely. while (!inShutdown()) { auto txn = cc().makeOperationContext(); if (!_init(txn.get())) { log() << "will retry to initialize balancer in one minute"; sleepsecs(60); continue; } break; } Seconds balanceRoundInterval(kBalanceRoundDefaultInterval); while (!inShutdown()) { auto txn = cc().makeOperationContext(); BalanceRoundDetails roundDetails; try { // ping has to be first so we keep things in the config server in sync _ping(txn.get(), false); MONGO_FAIL_POINT_BLOCK(balancerRoundIntervalSetting, scopedBalancerRoundInterval) { const BSONObj& data = scopedBalancerRoundInterval.getData(); balanceRoundInterval = Seconds(data["sleepSecs"].numberInt()); } // Use fresh shard state and balancer settings Grid::get(txn.get())->shardRegistry()->reload(txn.get()); auto balancerConfig = Grid::get(txn.get())->getBalancerConfiguration(); Status refreshStatus = balancerConfig->refreshAndCheck(txn.get()); if (!refreshStatus.isOK()) { warning() << "Skipping balancing round" << causedBy(refreshStatus); sleepFor(balanceRoundInterval); continue; } // now make sure we should even be running if (!balancerConfig->isBalancerActive() || MONGO_FAIL_POINT(skipBalanceRound)) { LOG(1) << "skipping balancing round because balancing is disabled"; // Ping again so scripts can determine if we're active without waiting _ping(txn.get(), true); sleepFor(balanceRoundInterval); continue; } uassert(13258, "oids broken after resetting!", _checkOIDs(txn.get())); { auto scopedDistLock = grid.catalogManager(txn.get()) ->distLock(txn.get(), "balancer", "doing balance round", DistLockManager::kSingleLockAttemptTimeout); if (!scopedDistLock.isOK()) { LOG(1) << "skipping balancing round" << causedBy(scopedDistLock.getStatus()); // Ping again so scripts can determine if we're active without waiting _ping(txn.get(), true); sleepFor(balanceRoundInterval); // no need to wake up soon continue; } LOG(1) << "*** start balancing round. " << "waitForDelete: " << balancerConfig->waitForDelete() << ", secondaryThrottle: " << balancerConfig->getSecondaryThrottle().toBSON(); OCCASIONALLY warnOnMultiVersion( uassertStatusOK(_clusterStats->getStats(txn.get()))); Status status = _enforceTagRanges(txn.get()); if (!status.isOK()) { warning() << "Failed to enforce tag ranges" << causedBy(status); } else { LOG(1) << "Done enforcing tag range boundaries."; } const auto candidateChunks = uassertStatusOK( _chunkSelectionPolicy->selectChunksToMove(txn.get(), _balancedLastTime)); if (candidateChunks.empty()) { LOG(1) << "no need to move any chunk"; _balancedLastTime = 0; } else { _balancedLastTime = _moveChunks(txn.get(), candidateChunks, balancerConfig->getSecondaryThrottle(), balancerConfig->waitForDelete()); roundDetails.setSucceeded(static_cast<int>(candidateChunks.size()), _balancedLastTime); grid.catalogManager(txn.get()) ->logAction(txn.get(), "balancer.round", "", roundDetails.toBSON()); } LOG(1) << "*** End of balancing round"; } // Ping again so scripts can determine if we're active without waiting _ping(txn.get(), true); sleepFor(_balancedLastTime ? kShortBalanceRoundInterval : balanceRoundInterval); } catch (const std::exception& e) { log() << "caught exception while doing balance: " << e.what(); // Just to match the opening statement if in log level 1 LOG(1) << "*** End of balancing round"; // This round failed, tell the world! roundDetails.setFailed(e.what()); grid.catalogManager(txn.get()) ->logAction(txn.get(), "balancer.round", "", roundDetails.toBSON()); // Sleep a fair amount before retrying because of the error sleepFor(balanceRoundInterval); } } }
/** * Outline: * * 1. Get oplog with session info from the source shard. * 2. For each oplog entry, convert to type 'n' if not yet type 'n' while preserving all info * needed for retryable writes. * 3. Also update the sessionCatalog for every oplog entry. * 4. Once the source shard returned an empty oplog buffer, it means that this should enter * ReadyToCommit state and wait for the commit signal (by calling finish()). * 5. Once finish() is called, keep on trying to get more oplog from the source shard until it * returns an empty result again. * 6. Wait for writes to be committed to majority of the replica set. */ void SessionCatalogMigrationDestination::_retrieveSessionStateFromSource(ServiceContext* service) { Client::initThread( "sessionCatalogMigration-" + _migrationSessionId.toString(), service, nullptr); auto uniqueCtx = cc().makeOperationContext(); auto opCtx = uniqueCtx.get(); bool oplogDrainedAfterCommiting = false; ProcessOplogResult lastResult; repl::OpTime lastOpTimeWaited; while (true) { { stdx::lock_guard<stdx::mutex> lk(_mutex); if (_state == State::ErrorOccurred) { return; } } try { auto nextBatch = getNextSessionOplogBatch(opCtx, _fromShard, _migrationSessionId); BSONArray oplogArray(nextBatch[kOplogField].Obj()); BSONArrayIteratorSorted oplogIter(oplogArray); if (!oplogIter.more()) { { stdx::lock_guard<stdx::mutex> lk(_mutex); if (_state == State::Committing) { // The migration is considered done only when it gets an empty result from // the source shard while this is in state committing. This is to make sure // that it doesn't miss any new oplog created between the time window where // this depleted the buffer from the source shard and receiving the commit // command. if (oplogDrainedAfterCommiting) { break; } oplogDrainedAfterCommiting = true; } } WriteConcernResult wcResult; auto wcStatus = waitForWriteConcern(opCtx, lastResult.oplogTime, kMajorityWC, &wcResult); if (!wcStatus.isOK()) { _errorOccurred(wcStatus.toString()); return; } // We depleted the buffer at least once, transition to ready for commit. { stdx::lock_guard<stdx::mutex> lk(_mutex); // Note: only transition to "ready to commit" if state is not error/force stop. if (_state == State::Migrating) { _state = State::ReadyToCommit; _isStateChanged.notify_all(); } } if (lastOpTimeWaited == lastResult.oplogTime) { // We got an empty result at least twice in a row from the source shard so // space it out a little bit so we don't hammer the shard. opCtx->sleepFor(Milliseconds(200)); } lastOpTimeWaited = lastResult.oplogTime; } while (oplogIter.more()) { lastResult = processSessionOplog(opCtx, oplogIter.next().Obj(), lastResult); } } catch (const DBException& excep) { if (excep.code() == ErrorCodes::ConflictingOperationInProgress || excep.code() == ErrorCodes::TransactionTooOld) { // This means that the server has a newer txnNumber than the oplog being migrated, // so just skip it. continue; } if (excep.code() == ErrorCodes::CommandNotFound) { // TODO: remove this after v3.7 // // This means that the donor shard is running at an older version so it is safe to // just end this because there is no session information to transfer. break; } _errorOccurred(excep.toString()); return; } } WriteConcernResult wcResult; auto wcStatus = waitForWriteConcern(opCtx, lastResult.oplogTime, kMajorityWC, &wcResult); if (!wcStatus.isOK()) { _errorOccurred(wcStatus.toString()); return; } { stdx::lock_guard<stdx::mutex> lk(_mutex); _state = State::Done; _isStateChanged.notify_all(); } }
StatusWith<DistLockManager::ScopedDistLock> ReplSetDistLockManager::lock( StringData name, StringData whyMessage, milliseconds waitFor, milliseconds lockTryInterval) { Timer timer(_serviceContext->getTickSource()); Timer msgTimer(_serviceContext->getTickSource()); while (waitFor <= milliseconds::zero() || milliseconds(timer.millis()) < waitFor) { OID lockSessionID = OID::gen(); string who = str::stream() << _processID << ":" << getThreadName(); auto lockExpiration = _lockExpiration; MONGO_FAIL_POINT_BLOCK(setDistLockTimeout, customTimeout) { const BSONObj& data = customTimeout.getData(); lockExpiration = stdx::chrono::milliseconds(data["timeoutMs"].numberInt()); } LOG(1) << "trying to acquire new distributed lock for " << name << " ( lock timeout : " << durationCount<Milliseconds>(lockExpiration) << " ms, ping interval : " << durationCount<Milliseconds>(_pingInterval) << " ms, process : " << _processID << " )" << " with lockSessionID: " << lockSessionID << ", why: " << whyMessage; auto lockResult = _catalog->grabLock(name, lockSessionID, who, _processID, Date_t::now(), whyMessage); auto status = lockResult.getStatus(); if (status.isOK()) { // Lock is acquired since findAndModify was able to successfully modify // the lock document. LOG(0) << "distributed lock '" << name << "' acquired, ts : " << lockSessionID; return ScopedDistLock(lockSessionID, this); } if (status != ErrorCodes::LockStateChangeFailed) { // An error occurred but the write might have actually been applied on the // other side. Schedule an unlock to clean it up just in case. queueUnlock(lockSessionID); return status; } // Get info from current lock and check if we can overtake it. auto getLockStatusResult = _catalog->getLockByName(name); const auto& getLockStatus = getLockStatusResult.getStatus(); if (!getLockStatusResult.isOK() && getLockStatus != ErrorCodes::LockNotFound) { return getLockStatus; } // Note: Only attempt to overtake locks that actually exists. If lock was not // found, use the normal grab lock path to acquire it. if (getLockStatusResult.isOK()) { auto currentLock = getLockStatusResult.getValue(); auto canOvertakeResult = canOvertakeLock(currentLock, lockExpiration); if (!canOvertakeResult.isOK()) { return canOvertakeResult.getStatus(); } if (canOvertakeResult.getValue()) { auto overtakeResult = _catalog->overtakeLock(name, lockSessionID, currentLock.getLockID(), who, _processID, Date_t::now(), whyMessage); const auto& overtakeStatus = overtakeResult.getStatus(); if (overtakeResult.isOK()) { // Lock is acquired since findAndModify was able to successfully modify // the lock document. LOG(0) << "lock '" << name << "' successfully forced"; LOG(0) << "distributed lock '" << name << "' acquired, ts : " << lockSessionID; return ScopedDistLock(lockSessionID, this); } if (overtakeStatus != ErrorCodes::LockStateChangeFailed) { // An error occurred but the write might have actually been applied on the // other side. Schedule an unlock to clean it up just in case. queueUnlock(lockSessionID); return overtakeStatus; } } } LOG(1) << "distributed lock '" << name << "' was not acquired."; if (waitFor == milliseconds::zero()) { break; } // Periodically message for debugging reasons if (msgTimer.seconds() > 10) { LOG(0) << "waited " << timer.seconds() << "s for distributed lock " << name << " for " << whyMessage; msgTimer.reset(); } milliseconds timeRemaining = std::max(milliseconds::zero(), waitFor - milliseconds(timer.millis())); sleepFor(std::min(lockTryInterval, timeRemaining)); } return {ErrorCodes::LockBusy, str::stream() << "timed out waiting for " << name}; }
int main(int argc, char* argv[]) { signal(SIGINT, sig_int); unsigned int unslept = sleepFor(1); printf("sleepFor returned: %u\n", unslept); return 0; }
StatusWith<DistLockManager::ScopedDistLock> LegacyDistLockManager::lock( OperationContext* txn, StringData name, StringData whyMessage, milliseconds waitFor, milliseconds lockTryInterval) { auto distLock = stdx::make_unique<DistributedLock>(_configServer, name.toString()); { stdx::lock_guard<stdx::mutex> sl(_mutex); if (_isStopped) { return Status(ErrorCodes::LockBusy, "legacy distlock manager is stopped"); } if (_pingerEnabled) { auto pingStatus = _pinger->startPing(*(distLock.get()), kDefaultPingInterval); if (!pingStatus.isOK()) { return pingStatus; } } } auto lastStatus = Status(ErrorCodes::LockBusy, str::stream() << "timed out waiting for " << name); Timer timer; Timer msgTimer; while (waitFor <= milliseconds::zero() || milliseconds(timer.millis()) < waitFor) { bool acquired = false; BSONObj lockDoc; try { acquired = distLock->lock_try( whyMessage.toString(), &lockDoc, durationCount<Seconds>(kDefaultSocketTimeout)); if (!acquired) { lastStatus = Status(ErrorCodes::LockBusy, str::stream() << "Lock for " << whyMessage << " is taken."); } } catch (const LockException& lockExcep) { OID needUnlockID(lockExcep.getMustUnlockID()); if (needUnlockID.isSet()) { _pinger->addUnlockOID(needUnlockID); } lastStatus = lockExcep.toStatus(); } catch (...) { lastStatus = exceptionToStatus(); } if (acquired) { verify(!lockDoc.isEmpty()); auto locksTypeResult = LocksType::fromBSON(lockDoc); if (!locksTypeResult.isOK()) { return StatusWith<ScopedDistLock>( ErrorCodes::UnsupportedFormat, str::stream() << "error while parsing lock document: " << lockDoc << " : " << locksTypeResult.getStatus().toString()); } const LocksType& lock = locksTypeResult.getValue(); dassert(lock.isLockIDSet()); { stdx::lock_guard<stdx::mutex> sl(_mutex); _lockMap.insert(std::make_pair(lock.getLockID(), std::move(distLock))); } return ScopedDistLock(txn, lock.getLockID(), this); } if (waitFor == milliseconds::zero()) break; if (lastStatus != ErrorCodes::LockBusy) { return lastStatus; } // Periodically message for debugging reasons if (msgTimer.seconds() > 10) { log() << "waited " << timer.seconds() << "s for distributed lock " << name << " for " << whyMessage << ": " << lastStatus.toString(); msgTimer.reset(); } milliseconds timeRemaining = std::max(milliseconds::zero(), waitFor - milliseconds(timer.millis())); sleepFor(std::min(lockTryInterval, timeRemaining)); } return lastStatus; }
void Balancer::run() { Client::initThread("Balancer"); // This is the body of a BackgroundJob so if we throw here we're basically ending the balancer // thread prematurely. while (!inShutdown()) { auto txn = cc().makeOperationContext(); if (!_init(txn.get())) { log() << "will retry to initialize balancer in one minute"; sleepsecs(60); continue; } break; } Seconds balanceRoundInterval(kBalanceRoundDefaultInterval); while (!inShutdown()) { auto txn = cc().makeOperationContext(); BalanceRoundDetails roundDetails; try { // ping has to be first so we keep things in the config server in sync _ping(txn.get()); MONGO_FAIL_POINT_BLOCK(balancerRoundIntervalSetting, scopedBalancerRoundInterval) { const BSONObj& data = scopedBalancerRoundInterval.getData(); balanceRoundInterval = Seconds(data["sleepSecs"].numberInt()); } BSONObj balancerResult; // use fresh shard state grid.shardRegistry()->reload(txn.get()); // refresh chunk size (even though another balancer might be active) Chunk::refreshChunkSize(txn.get()); auto balSettingsResult = grid.catalogManager(txn.get())->getGlobalSettings( txn.get(), SettingsType::BalancerDocKey); const bool isBalSettingsAbsent = balSettingsResult.getStatus() == ErrorCodes::NoMatchingDocument; if (!balSettingsResult.isOK() && !isBalSettingsAbsent) { warning() << balSettingsResult.getStatus(); return; } const SettingsType& balancerConfig = isBalSettingsAbsent ? SettingsType{} : balSettingsResult.getValue(); // now make sure we should even be running if ((!isBalSettingsAbsent && !Chunk::shouldBalance(balancerConfig)) || MONGO_FAIL_POINT(skipBalanceRound)) { LOG(1) << "skipping balancing round because balancing is disabled"; // Ping again so scripts can determine if we're active without waiting _ping(txn.get(), true); sleepFor(balanceRoundInterval); continue; } uassert(13258, "oids broken after resetting!", _checkOIDs(txn.get())); { auto scopedDistLock = grid.catalogManager(txn.get()) ->distLock(txn.get(), "balancer", "doing balance round", DistLockManager::kSingleLockAttemptTimeout); if (!scopedDistLock.isOK()) { LOG(1) << "skipping balancing round" << causedBy(scopedDistLock.getStatus()); // Ping again so scripts can determine if we're active without waiting _ping(txn.get(), true); sleepFor(balanceRoundInterval); // no need to wake up soon continue; } const bool waitForDelete = (balancerConfig.isWaitForDeleteSet() ? balancerConfig.getWaitForDelete() : false); MigrationSecondaryThrottleOptions secondaryThrottle( MigrationSecondaryThrottleOptions::create( MigrationSecondaryThrottleOptions::kDefault)); if (balancerConfig.isKeySet()) { secondaryThrottle = uassertStatusOK(MigrationSecondaryThrottleOptions::createFromBalancerConfig( balancerConfig.toBSON())); } LOG(1) << "*** start balancing round. " << "waitForDelete: " << waitForDelete << ", secondaryThrottle: " << secondaryThrottle.toBSON(); const auto candidateChunks = uassertStatusOK(_getCandidateChunks(txn.get())); if (candidateChunks.empty()) { LOG(1) << "no need to move any chunk"; _balancedLastTime = 0; } else { _balancedLastTime = _moveChunks(txn.get(), candidateChunks, secondaryThrottle, waitForDelete); roundDetails.setSucceeded(static_cast<int>(candidateChunks.size()), _balancedLastTime); grid.catalogManager(txn.get()) ->logAction(txn.get(), "balancer.round", "", roundDetails.toBSON()); } LOG(1) << "*** End of balancing round"; } // Ping again so scripts can determine if we're active without waiting _ping(txn.get(), true); sleepFor(_balancedLastTime ? kShortBalanceRoundInterval : balanceRoundInterval); } catch (const std::exception& e) { log() << "caught exception while doing balance: " << e.what(); // Just to match the opening statement if in log level 1 LOG(1) << "*** End of balancing round"; // This round failed, tell the world! roundDetails.setFailed(e.what()); grid.catalogManager(txn.get()) ->logAction(txn.get(), "balancer.round", "", roundDetails.toBSON()); // Sleep a fair amount before retrying because of the error sleepFor(balanceRoundInterval); } } }
int main() { char loading = 0; char wrongCommand = 0; char win = 0; bool inGame = true; char AttsServers = 20; char VerizonServers = 20; int VerizonAttack = 0; int DeadServers = 0; int ServerLose = 0; char password[] = "atts"; char givenPassword[10]; char ID[50]; char IDAdmin[] = "root"; char Continue[] = "CONTINUE"; char Manual[] = "MANUAL"; char Restart[] = "RESTART"; char Ranking[] = "RANKING"; char Mitm[] = "MITM"; char OverCPU[] = "OVERCPU"; char Fix[] = "FIX"; char givenCommand[20]; char Exit[] = "EXIT"; char Name[50]; char lineManual[TAILLE_MAX] = ""; srand(time(NULL)); FILE* manual = NULL; FILE* ranking = NULL; printf("Connection to ATTS' servers"); sleepFor(1000); loading = 0; while (loading < 10) { showLoad(); loading ++; } printf("\nConnection established\n"); sleepFor(500); printf("Please enter your ID\n"); printf("ID : "); scanf("%s", ID); sleepFor(500); if (strcmp(ID, IDAdmin) == 0) { printf("Hi Admin, please enter your password"); } else { printf("\nWrong ID. You will be rejected by the server in 5 seconds"); sleepFor(5000); return 0; } printf("\nPassword : "******"%s", givenPassword); loading = 0; while (loading < 5) { showLoad(); loading ++; } printf("\b"); if (strcmp(givenPassword, password) == 0) { printf("Access Granted\n"); loading = 0; while (loading < 5) { showLoad(); loading ++; } printf("\b"); } else { printf("Wrong password. You will be rejected by the server in 5 seconds"); sleepFor(5000); return 0; } while (wrongCommand != 1) { printf("You are now connected, to see the manual type MANUAL, to see the ranking type\nRANKING else type CONTINUE\n"); printf("command : "); scanf("%s", givenCommand); loading = 0; while (loading < 5) { showLoad(); loading ++; } printf("\b"); if (strcmp(givenCommand, Manual) == 0) { manual = fopen("manual.txt", "r"); if (manual != NULL) { while (fgets(lineManual, TAILLE_MAX, manual) != NULL) { printf("%s", lineManual); sleepFor(500); } printf("\ncommand :"); scanf("%s", givenCommand); if (strcmp(givenCommand, Restart) == 0) { wrongCommand = 0; } else if (strcmp(givenCommand, Exit) == 0) { printf("The program will stop in few seconds"); sleepFor(5000); return 0; } else { printf("Wrong command"); } } else { printf("Unknown error detected during the manual opening, the program will restart automatically in few seconds\n"); sleepFor(5000); } } else if (strcmp(givenCommand, Ranking) == 0) { ranking = fopen("ranking.txt", "r"); if (ranking != NULL) { while (fgets(lineManual, TAILLE_MAX, ranking) != NULL) { printf("%s", lineManual); sleepFor(500); } printf("\nWhen you have read everything you can type RESTART or EXIT"); printf("\ncommand :"); scanf("%s", givenCommand); if (strcmp(givenCommand, Restart) == 0) { wrongCommand = 0; } else if (strcmp(givenCommand, Exit) == 0) { printf("The program will stop in few seconds"); sleepFor(5000); return 0; } else { printf("Wrong command"); } } else { printf("Unknown error detected during the ranking file opening, the program will restart automatically in few seconds\n"); sleepFor(5000); } } else if (strcmp(givenCommand, Continue) == 0) { printf("Welcome in the Servers Administration Center SAC\nComponents are loading"); loading = 0; while (loading < 10) { showLoad(); loading ++; } printf("\b"); printf("\nComponents are ready to use\nVerizon is trying to hack your servers but you knew that was planned today!\nIt is your turn!"); while (inGame != false) { printf("\ncommand : "); scanf("%s", givenCommand); loading = 0; while (loading < 2) { showLoad(); loading ++; } printf("\b"); if (strcmp(givenCommand, Mitm) == 0) { printf("\nVerizon's servers hacked, they lost one server!"); VerizonServers --; loading = 0; while (loading < 2) { showLoad(); loading ++; } printf("\b"); VerizonAttack = rand() % 3; if (VerizonAttack == 0) { printf("\nVerizon uses the MITM method, you lose 1 server"); AttsServers --; } else if (VerizonAttack == 1) { printf("\nVerizon allocates a server to overheat your CPU"); DeadServers = rand() % 5; sleepFor(500); if (DeadServers == 0) { printf("\nVerizon wastes his attack, you keep all of your servers"); } else if (DeadServers == 1) { printf("\nVerizon kills 1 of your servers"); AttsServers --; } else if (DeadServers == 2) { printf("\nVerizon kills 2 of your servers"); AttsServers -= 2; } else if (DeadServers == 3) { printf("\nVerizon kills 3 of your servers"); AttsServers -= 3; } else { printf("\nVerizon kills 4 of your servers"); AttsServers -= 4; } sleepFor(500); ServerLose = rand() % 2; if (ServerLose == 0) { printf("\nBy using one of his servers, Verizon lose one of his servers"); VerizonServers --; } else { printf("\nVerizon hacks you with his server but don't broke it"); } } else { printf("\nVerizon fixes a server"); VerizonServers ++; } printf("\nYou have %d servers and Verizon has %d servers...", AttsServers, VerizonServers); } else if (strcmp(givenCommand, OverCPU) == 0) { printf("\nYou allocate a server to overheat their CPU"); DeadServers = rand() % 5; sleepFor(500); if (DeadServers == 0) { printf("\nYou waste your attack, they keep all of their servers"); } else if (DeadServers == 1) { printf("\nYou kill 1 of their servers"); VerizonServers --; } else if (DeadServers == 2) { printf("\nYou kill 2 of their servers"); VerizonServers -= 2; } else if (DeadServers == 3) { printf("\nYou kill 3 of their servers"); VerizonServers -= 3; } else { printf("\nYou kill 4 of their servers"); VerizonServers -= 4; } sleepFor(500); ServerLose = rand() % 2; if (ServerLose == 0) { printf("\nBy using one of his servers, you lose one of your servers"); AttsServers --; } else { printf("\nYou hack Verizon with your server but don't broke it"); } VerizonAttack = rand() % 3; if (VerizonAttack == 0) { printf("\nVerizon uses the MITM method, you lose 1 server"); AttsServers --; } else if (VerizonAttack == 1) { printf("\nVerizon allocates a server to overheat your CPU"); DeadServers = rand() % 5; sleepFor(500); if (DeadServers == 0) { printf("\nVerizon wastes his attack, you keep all of your servers"); } else if (DeadServers == 1) { printf("\nVerizon kills 1 of your servers"); AttsServers --; } else if (DeadServers == 2) { printf("\nVerizon kills 2 of your servers"); AttsServers -=2; } else if (DeadServers == 3) { printf("\nVerizon kills 3 of your servers"); AttsServers -=3; } else { printf("\nVerizon kills 4 of your servers"); AttsServers -=4; } sleepFor(500); ServerLose = rand() % 2; if (ServerLose == 0) { printf("\nBy using one of his servers, Verizon lose one of his servers"); VerizonServers --; } else { printf("\nVerizon hacks you with his server but don't broke it"); } } else { printf("\nVerizon fixes a server"); VerizonServers ++; } printf("\nYou have %d servers and Verizon has %d servers...", AttsServers, VerizonServers); } else if (strcmp(givenCommand, Fix) == 0) { printf("\nYou fix 1 of your servers"); AttsServers ++; VerizonAttack = rand() % 3; if (VerizonAttack == 0) { printf("\nVerizon uses the MITM method, you lose 1 server"); AttsServers --; } else if (VerizonAttack == 1) { printf("\nVerizon allocates a server to overheat your CPU"); DeadServers = rand() % 5; sleepFor(500); if (DeadServers == 0) { printf("\nVerizon wastes his attack, you keep all of your servers"); } else if (DeadServers == 1) { printf("\nVerizon kills 1 of your servers"); AttsServers --; } else if (DeadServers == 2) { printf("\nVerizon kills 2 of your servers"); AttsServers --; AttsServers --; } else if (DeadServers == 3) { printf("\nVerizon kills 3 of your servers"); AttsServers --; AttsServers --; AttsServers --; } else { printf("\nVerizon kills 4 of your servers"); AttsServers --; AttsServers --; AttsServers --; AttsServers --; } sleepFor(500); ServerLose = rand() % 2; if (ServerLose == 0) { printf("\nBy using one of his servers, Verizon lose one of his servers"); VerizonServers --; } else { printf("\nVerizon hacks you with his server but don't broke it"); } } else { printf("\nVerizon fixes a server"); VerizonServers ++; } printf("\nYou have %d servers and Verizon has %d servers...", AttsServers, VerizonServers); } else { printf("Wrong command! Retry"); } if (AttsServers <= 0) { printf("\nYou lose"); printf("\nVerizon hits you and kept %d servers", VerizonServers); AttsServers = 20; VerizonServers = 20; inGame = false; } else if (VerizonServers <= 0) { printf("\nYou win!"); printf("\nYou hit Verizon, you kept %d servers and ATTS became\nthe biggest company because of you!\n", AttsServers); printf("\nPlease enter your name : "); scanf("%s", Name); printf("%s's Bank Account : 2450$", Name); sleepFor(250); printf("\b\b"); sleepFor(250); printf("\b"); sleepFor(250); printf("\b"); sleepFor(250); printf("\b"); sleepFor(250); loading = 0; while(loading <= 15){ printf("9"); sleepFor(250); loading++; } printf("$"); sleepFor(500); printf("\nDear %s,\nTo thank you, we send you a bit of money\nand we promote you Security Team CHIEF!\nCongratulations,\nATTS Inc CEO, Hugues KADI", Name); ranking = fopen("ranking.txt", "a"); fprintf(ranking, "\n%s hit Verizon and kept %d servers!", Name, AttsServers); AttsServers = 20; VerizonServers = 20; inGame = false; } } printf("\ncommand RESTART or EXIT : "); scanf("%s", givenCommand); if (strcmp(givenCommand, Restart) == 0) { wrongCommand = 0; } else if (strcmp(givenCommand, Exit) == 0) { printf("The program will stop in few seconds"); sleepFor(5000); return 0; } else { printf("Wrong command"); } } else if (strcmp(givenCommand, Exit) == 0) { printf("The program will stop in few seconds"); sleepFor(5000); return 0; } else { printf("Wrong command\n"); } } return 0; }
void sleepUntil(const SteadyClockTimePoint& t) { sleepFor(t - SteadyClock::now()); }
StatusWith<DistLockManager::ScopedDistLock> ReplSetDistLockManager::lock( OperationContext* txn, StringData name, StringData whyMessage, milliseconds waitFor, milliseconds lockTryInterval) { Timer timer(_serviceContext->getTickSource()); Timer msgTimer(_serviceContext->getTickSource()); // Counts how many attempts have been made to grab the lock, which have failed with network // error. This value is reset for each lock acquisition attempt because these are // independent write operations. int networkErrorRetries = 0; // Distributed lock acquisition works by tring to update the state of the lock to 'taken'. If // the lock is currently taken, we will back off and try the acquisition again, repeating this // until the lockTryInterval has been reached. If a network error occurs at each lock // acquisition attempt, the lock acquisition will be retried immediately. while (waitFor <= milliseconds::zero() || milliseconds(timer.millis()) < waitFor) { const OID lockSessionID = OID::gen(); const string who = str::stream() << _processID << ":" << getThreadName(); auto lockExpiration = _lockExpiration; MONGO_FAIL_POINT_BLOCK(setDistLockTimeout, customTimeout) { const BSONObj& data = customTimeout.getData(); lockExpiration = stdx::chrono::milliseconds(data["timeoutMs"].numberInt()); } LOG(1) << "trying to acquire new distributed lock for " << name << " ( lock timeout : " << durationCount<Milliseconds>(lockExpiration) << " ms, ping interval : " << durationCount<Milliseconds>(_pingInterval) << " ms, process : " << _processID << " )" << " with lockSessionID: " << lockSessionID << ", why: " << whyMessage; auto lockResult = _catalog->grabLock( txn, name, lockSessionID, who, _processID, Date_t::now(), whyMessage); auto status = lockResult.getStatus(); if (status.isOK()) { // Lock is acquired since findAndModify was able to successfully modify // the lock document. log() << "distributed lock '" << name << "' acquired for '" << whyMessage << "', ts : " << lockSessionID; return ScopedDistLock(txn, lockSessionID, this); } // If a network error occurred, unlock the lock synchronously and try again if (ShardRegistry::kAllRetriableErrors.count(status.code()) && networkErrorRetries < kMaxNumLockAcquireRetries) { LOG(1) << "Failed to acquire distributed lock because of retriable error. Retrying " "acquisition by first unlocking the stale entry, which possibly exists now" << causedBy(status); networkErrorRetries++; status = _catalog->unlock(txn, lockSessionID); if (status.isOK()) { // We certainly do not own the lock, so we can retry continue; } // Fall-through to the error checking logic below invariant(status != ErrorCodes::LockStateChangeFailed); LOG(1) << "Failed to retry acqusition of distributed lock. No more attempts will be made" << causedBy(status); } if (status != ErrorCodes::LockStateChangeFailed) { // An error occurred but the write might have actually been applied on the // other side. Schedule an unlock to clean it up just in case. queueUnlock(lockSessionID); return status; } // Get info from current lock and check if we can overtake it. auto getLockStatusResult = _catalog->getLockByName(txn, name); const auto& getLockStatus = getLockStatusResult.getStatus(); if (!getLockStatusResult.isOK() && getLockStatus != ErrorCodes::LockNotFound) { return getLockStatus; } // Note: Only attempt to overtake locks that actually exists. If lock was not // found, use the normal grab lock path to acquire it. if (getLockStatusResult.isOK()) { auto currentLock = getLockStatusResult.getValue(); auto canOvertakeResult = canOvertakeLock(txn, currentLock, lockExpiration); if (!canOvertakeResult.isOK()) { return canOvertakeResult.getStatus(); } if (canOvertakeResult.getValue()) { auto overtakeResult = _catalog->overtakeLock(txn, name, lockSessionID, currentLock.getLockID(), who, _processID, Date_t::now(), whyMessage); const auto& overtakeStatus = overtakeResult.getStatus(); if (overtakeResult.isOK()) { // Lock is acquired since findAndModify was able to successfully modify // the lock document. LOG(0) << "lock '" << name << "' successfully forced"; LOG(0) << "distributed lock '" << name << "' acquired, ts : " << lockSessionID; return ScopedDistLock(txn, lockSessionID, this); } if (overtakeStatus != ErrorCodes::LockStateChangeFailed) { // An error occurred but the write might have actually been applied on the // other side. Schedule an unlock to clean it up just in case. queueUnlock(lockSessionID); return overtakeStatus; } } } LOG(1) << "distributed lock '" << name << "' was not acquired."; if (waitFor == milliseconds::zero()) { break; } // Periodically message for debugging reasons if (msgTimer.seconds() > 10) { LOG(0) << "waited " << timer.seconds() << "s for distributed lock " << name << " for " << whyMessage; msgTimer.reset(); } // A new lock acquisition attempt will begin now (because the previous found the lock to be // busy, so reset the retries counter) networkErrorRetries = 0; const milliseconds timeRemaining = std::max(milliseconds::zero(), waitFor - milliseconds(timer.millis())); sleepFor(std::min(lockTryInterval, timeRemaining)); } return {ErrorCodes::LockBusy, str::stream() << "timed out waiting for " << name}; }