virtual bool run(const string& ns, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { fassert(16175, rotateLogs()); return 1; }
static void rotateLogsOrDie(int sig) { fassert(16176, rotateLogs()); }
void *sys_allocPage() { void *ret = HeapAlloc( s_heapHandle, 0, s_pageSize ); fassert( ret != 0 ); return ret; }
Lock::ScopedLock::~ScopedLock() { LockState& ls = lockState(); int prevCount = ls.recursiveCount(); Lock::ScopedLock* what = ls.leaveScopedLock(); fassert( 16171 , prevCount != 1 || what == this ); }
Status DurableViewCatalogImpl::iterate(OperationContext* opCtx, Callback callback) { dassert(opCtx->lockState()->isDbLockedForMode(_db->name(), MODE_IS) || opCtx->lockState()->isDbLockedForMode(_db->name(), MODE_IX)); Collection* systemViews = _db->getCollection(opCtx, _db->getSystemViewsName()); if (!systemViews) return Status::OK(); Lock::CollectionLock lk(opCtx->lockState(), _db->getSystemViewsName(), MODE_IS); auto cursor = systemViews->getCursor(opCtx); while (auto record = cursor->next()) { RecordData& data = record->data; // Check the document is valid BSON, with only the expected fields. // Use the latest BSON validation version. Existing view definitions are allowed to contain // decimal data even if decimal is disabled. fassert(40224, validateBSON(data.data(), data.size(), BSONVersion::kLatest)); BSONObj viewDef = data.toBson(); // Check read definitions for correct structure, and refuse reading past invalid // definitions. Ignore any further view definitions. bool valid = true; for (const BSONElement& e : viewDef) { std::string name(e.fieldName()); valid &= name == "_id" || name == "viewOn" || name == "pipeline" || name == "collation"; } const auto viewName = viewDef["_id"].str(); const auto viewNameIsValid = NamespaceString::validCollectionComponent(viewName) && NamespaceString::validDBName(nsToDatabaseSubstring(viewName)); valid &= viewNameIsValid; // Only perform validation via NamespaceString if the collection name has been determined to // be valid. If not valid then the NamespaceString constructor will uassert. if (viewNameIsValid) { NamespaceString viewNss(viewName); valid &= viewNss.isValid() && viewNss.db() == _db->name(); } valid &= NamespaceString::validCollectionName(viewDef["viewOn"].str()); const bool hasPipeline = viewDef.hasField("pipeline"); valid &= hasPipeline; if (hasPipeline) { valid &= viewDef["pipeline"].type() == mongo::Array; } valid &= (!viewDef.hasField("collation") || viewDef["collation"].type() == BSONType::Object); if (!valid) { return {ErrorCodes::InvalidViewDefinition, str::stream() << "found invalid view definition " << viewDef["_id"] << " while reading '" << _db->getSystemViewsName() << "'"}; } Status callbackStatus = callback(viewDef); if (!callbackStatus.isOK()) { return callbackStatus; } } return Status::OK(); }
bool copyRuntime( const Path& binpath, const Path& tgtpath ) { message( "Searching VSx CRT in " + binpath.getFullLocation() ); // open the binary path in search of "Microsoft.*.CRT" VFSProvider* provider = Engine::getVFS( "file" ); fassert( provider != 0 ); DirEntry* dir = provider->openDir( binpath.getFullLocation() ); if( dir == 0 ) { warning( "Can't search CRT in " + binpath.getFullLocation() ); return false; } String fname; while( dir->read(fname) ) { if( fname.wildcardMatch("Microsoft.*.CRT") ) { // we're done with dir. delete dir; Path source( binpath.getFullLocation() + "/" + fname + "/"); Path target( tgtpath.getFullLocation() + "/" + fname + "/"); // first, create the target path int32 fsStatus; if( ! Sys::fal_mkdir( target.getFullLocation(), fsStatus, true ) ) { warning( "Can't create CRT directory in " + target.getFullLocation() ); return false; } // then copy everything inside it. DirEntry* crtdir = provider->openDir( source.getFullLocation() ); if( crtdir == 0 ) { warning( "Can't read source CRT directory " + source.getFullLocation() ); return false; } //loop copying everything that's not a dir. String sFile; while( crtdir->read( sFile ) ) { if( sFile.startsWith(".") ) continue; source.setFilename( sFile ); target.setFilename( sFile ); if ( ! copyFile( source.get(), target.get() ) ) { delete crtdir; warning( "Can't copy CRT file " + source.get() + " into " + target.get() ); return false; } } return true; } } delete dir; return false; }
void UpdateStage::doInsert() { _specificStats.inserted = true; const UpdateRequest* request = _params.request; UpdateDriver* driver = _params.driver; CanonicalQuery* cq = _params.canonicalQuery; UpdateLifecycle* lifecycle = request->getLifecycle(); // Since this is an insert (no docs found and upsert:true), we will be logging it // as an insert in the oplog. We don't need the driver's help to build the // oplog record, then. We also set the context of the update driver to the INSERT_CONTEXT. // Some mods may only work in that context (e.g. $setOnInsert). driver->setLogOp(false); driver->setContext(ModifierInterface::ExecInfo::INSERT_CONTEXT); // Reset the document we will be writing to _doc.reset(); // The original document we compare changes to - immutable paths must not change BSONObj original; bool isInternalRequest = request->isFromReplication() || request->isFromMigration(); const vector<FieldRef*>* immutablePaths = NULL; if (!isInternalRequest && lifecycle) immutablePaths = lifecycle->getImmutableFields(); // Calling populateDocumentWithQueryFields will populate the '_doc' with fields from the // query which creates the base of the update for the inserted doc (because upsert // was true). if (cq) { uassertStatusOK(driver->populateDocumentWithQueryFields(cq, immutablePaths, _doc)); if (driver->isDocReplacement()) _specificStats.fastmodinsert = true; original = _doc.getObject(); } else { fassert(17354, CanonicalQuery::isSimpleIdQuery(request->getQuery())); BSONElement idElt = request->getQuery()[idFieldName]; original = idElt.wrap(); fassert(17352, _doc.root().appendElement(idElt)); } // Apply the update modifications and then log the update as an insert manually. Status status = driver->update(StringData(), &_doc); if (!status.isOK()) { uasserted(16836, status.reason()); } // Ensure _id exists and is first uassertStatusOK(ensureIdAndFirst(_doc)); // Validate that the object replacement or modifiers resulted in a document // that contains all the immutable keys and can be stored if it isn't coming // from a migration or via replication. if (!isInternalRequest){ FieldRefSet noFields; // This will only validate the modified fields if not a replacement. uassertStatusOK(validate(original, noFields, _doc, immutablePaths, driver->modOptions()) ); } // Insert the doc BSONObj newObj = _doc.getObject(); uassert(17420, str::stream() << "Document to upsert is larger than " << BSONObjMaxUserSize, newObj.objsize() <= BSONObjMaxUserSize); _specificStats.objInserted = newObj; // If this is an explain, bail out now without doing the insert. if (request->isExplain()) { return; } WriteUnitOfWork wunit(request->getOpCtx()); invariant(_collection); StatusWith<DiskLoc> newLoc = _collection->insertDocument(request->getOpCtx(), newObj, !request->isGod()/*enforceQuota*/); uassertStatusOK(newLoc.getStatus()); if (request->shouldCallLogOp()) { repl::logOp(request->getOpCtx(), "i", request->getNamespaceString().ns().c_str(), newObj, NULL, NULL, request->isFromMigration()); } wunit.commit(); }
void Suite::registerSuite( const std::string& name , Suite* s ) { Suite*& m = _allSuites()[name]; fassert( 10162, ! m ); m = s; }
void *sys_allocPage() { void *ret = mmap(((void *)0), s_pageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); fassert( ret != MAP_FAILED ); return ret; }
OpTime ReplicationCoordinatorExternalStateMock::onTransitionToPrimary(OperationContext* opCtx, bool isV1ElectionProtocol) { _lastOpTime = _firstOpTimeOfMyTerm; _firstOpTimeOfMyTerm = OpTime(); return fassert(40297, _lastOpTime); }
int Suite::run( const std::vector<std::string>& suites , const std::string& filter , int runsPerTest ) { if (_allSuites().empty()) { log() << "error: no suites registered."; return EXIT_FAILURE; } for ( unsigned int i = 0; i < suites.size(); i++ ) { if ( _allSuites().count( suites[i] ) == 0 ) { log() << "invalid test suite [" << suites[i] << "], use --list to see valid names" << std::endl; return EXIT_FAILURE; } } std::vector<std::string> torun(suites); if ( torun.empty() ) { for ( SuiteMap::const_iterator i = _allSuites().begin(); i !=_allSuites().end(); ++i ) { torun.push_back( i->first ); } } std::vector<Result*> results; for ( std::vector<std::string>::iterator i=torun.begin(); i!=torun.end(); i++ ) { std::string name = *i; Suite* s = _allSuites()[name]; fassert( 16145, s ); log() << "going to run suite: " << name << std::endl; results.push_back( s->run( filter, runsPerTest ) ); } log() << "**************************************************" << std::endl; int rc = 0; int tests = 0; int fails = 0; int asserts = 0; for ( std::vector<Result*>::iterator i=results.begin(); i!=results.end(); i++ ) { Result* r = *i; log() << r->toString(); if ( abs( r->rc() ) > abs( rc ) ) rc = r->rc(); tests += r->_tests; fails += r->_fails; asserts += r->_asserts; } Result totals ("TOTALS"); totals._tests = tests; totals._fails = fails; totals._asserts = asserts; log() << totals.toString(); // includes endl return rc; }
StatusWith<DiskLoc> Collection::insertDocument( const BSONObj& docToInsert, bool enforceQuota ) { if ( _indexCatalog.findIdIndex() ) { if ( docToInsert["_id"].eoo() ) { return StatusWith<DiskLoc>( ErrorCodes::InternalError, "Collection::insertDocument got document without _id" ); } } int lenWHdr = _details->getRecordAllocationSize( docToInsert.objsize() + Record::HeaderSize ); fassert( 17208, lenWHdr >= ( docToInsert.objsize() + Record::HeaderSize ) ); if ( _details->isCapped() ) { // TOOD: old god not done Status ret = _indexCatalog.checkNoIndexConflicts( docToInsert ); if ( !ret.isOK() ) return StatusWith<DiskLoc>( ret ); } // TODO: for now, capped logic lives inside NamespaceDetails, which is hidden // under the RecordStore, this feels broken since that should be a // collection access method probably StatusWith<DiskLoc> loc = _recordStore.allocRecord( lenWHdr, enforceQuota ? largestFileNumberInQuota() : 0 ); if ( !loc.isOK() ) return loc; Record *r = loc.getValue().rec(); fassert( 17210, r->lengthWithHeaders() >= lenWHdr ); // copy the data r = reinterpret_cast<Record*>( getDur().writingPtr(r, lenWHdr) ); memcpy( r->data(), docToInsert.objdata(), docToInsert.objsize() ); addRecordToRecListInExtent(r, loc.getValue()); // XXX move down into record store _details->incrementStats( r->netLength(), 1 ); // TOOD: old god not done _infoCache.notifyOfWriteOp(); try { _indexCatalog.indexRecord( docToInsert, loc.getValue() ); } catch( AssertionException& e ) { if ( _details->isCapped() ) { return StatusWith<DiskLoc>( ErrorCodes::InternalError, str::stream() << "unexpected index insertion failure on" << " capped collection" << e.toString() << " - collection and its index will not match" ); } // normal case -- we can roll back deleteDocument( loc.getValue(), false, true, NULL ); return StatusWith<DiskLoc>( e.toStatus( "insertDocument" ) ); } // TODO: this is what the old code did, but is it correct? _details->paddingFits(); return loc; }
void OplogBufferCollection::_dropCollection(OperationContext* txn) { fassert(40155, _storageInterface->dropCollection(txn, _nss)); }
void OplogBufferCollection::_createCollection(OperationContext* txn) { CollectionOptions options; options.temp = true; fassert(40154, _storageInterface->createCollection(txn, _nss, options)); }
long long Helpers::removeRange( const string& ns , const BSONObj& min , const BSONObj& max , const BSONObj& keyPattern , bool yield , bool maxInclusive , RemoveCallback * callback, bool fromMigrate ) { fassert( 16251, Lock::isWriteLocked( ns ) ); BSONObj keya , keyb; BSONObj minClean = toKeyFormat( min , keya ); BSONObj maxClean = toKeyFormat( max , keyb ); verify( keya == keyb ); Client::Context ctx(ns); shared_ptr<Cursor> cursor; auto_ptr<ClientCursor> clientCursor; { NamespaceDetails* nsd = nsdetails( ns.c_str() ); if ( ! nsd ) return 0; int ii = nsd->findIndexByKeyPattern( keya ); verify( ii >= 0 ); IndexDetails& i = nsd->idx( ii ); cursor.reset( BtreeCursor::make( nsd , ii , i , minClean , maxClean , maxInclusive, 1 ) ); clientCursor.reset( new ClientCursor( QueryOption_NoCursorTimeout , cursor , ns ) ); clientCursor->setDoingDeletes( true ); } long long num = 0; while ( clientCursor->ok() ) { if ( yield && ! clientCursor->yieldSometimes( ClientCursor::WillNeed) ) { // cursor got finished by someone else, so we're done clientCursor.release(); // if the collection/db is dropped, cc may be deleted break; } if ( ! clientCursor->ok() ) break; DiskLoc rloc = clientCursor->currLoc(); if ( callback ) callback->goingToDelete( clientCursor->current() ); clientCursor->advance(); // SERVER-5198 Additional advancement is unnecessary for a single btree cursor, and see // SERVER-5725. cursor->prepareToTouchEarlierIterate(); logOp( "d" , ns.c_str() , rloc.obj()["_id"].wrap() , 0 , 0 , fromMigrate ); theDataFileMgr.deleteRecord(ns.c_str() , rloc.rec(), rloc); num++; cursor->recoverFromTouchingEarlierIterate(); getDur().commitIfNeeded(); } return num; }
ServiceContext* getGlobalServiceContext() { fassert(17508, globalServiceContext); return globalServiceContext; }
void minOSPageSizeBytesTest(size_t minOSPageSizeBytes) { fassert( 16325, minOSPageSizeBytes > 0 ); fassert( 16326, minOSPageSizeBytes < 1000000 ); // check to see if the page size is a power of 2 fassert( 16327, (minOSPageSizeBytes & (minOSPageSizeBytes - 1)) == 0); }
void flush() { if (!_view || !_fd) return; { LockMongoFilesShared mmfilesLock; std::set<MongoFile*> mmfs = MongoFile::getAllFiles(); std::set<MongoFile*>::const_iterator it = mmfs.find(_theFile); if ( it == mmfs.end() || (*it)->getUniqueId() != _id ) { // this was deleted while we were unlocked return; } // Hold the flush mutex to ensure the file is not closed during flush _flushMutex.lock(); } stdx::lock_guard<stdx::mutex> lk(_flushMutex, stdx::adopt_lock); int loopCount = 0; bool success = false; bool timeout = false; int dosError = ERROR_SUCCESS; const int maximumTimeInSeconds = 60 * 15; Timer t; while ( !success && !timeout ) { ++loopCount; success = FALSE != FlushViewOfFile( _view, 0 ); if ( !success ) { dosError = GetLastError(); if ( dosError != ERROR_LOCK_VIOLATION ) { break; } timeout = t.seconds() > maximumTimeInSeconds; } } if ( success && loopCount > 1 ) { log() << "FlushViewOfFile for " << _filename << " succeeded after " << loopCount << " attempts taking " << t.millis() << "ms" << endl; } else if ( !success ) { log() << "FlushViewOfFile for " << _filename << " failed with error " << dosError << " after " << loopCount << " attempts taking " << t.millis() << "ms" << endl; // Abort here to avoid data corruption fassert(16387, false); } success = FALSE != FlushFileBuffers(_fd); if (!success) { int err = GetLastError(); log() << "FlushFileBuffers failed: " << errnoWithDescription( err ) << " file: " << _filename << endl; dataSyncFailedHandler(); } }
bool initializeServerGlobalState(bool isMongodShutdownSpecialCase) { Listener::globalTicketHolder.resize( cmdLine.maxConns ); #ifndef _WIN32 if (!fs::is_directory(cmdLine.socket)) { cout << cmdLine.socket << " must be a directory" << endl; return false; } if (cmdLine.doFork) { fassert(16447, !cmdLine.logpath.empty() || cmdLine.logWithSyslog); cout.flush(); cerr.flush(); cmdLine.parentProc = getpid(); // facilitate clean exit when child starts successfully setupLaunchSignals(); pid_t c = fork(); if ( c ) { int pstat; waitpid(c, &pstat, 0); if ( WIFEXITED(pstat) ) { if ( ! WEXITSTATUS(pstat) ) { cout << "child process started successfully, parent exiting" << endl; } _exit( WEXITSTATUS(pstat) ); } _exit(50); } if ( chdir("/") < 0 ) { cout << "Cant chdir() while forking server process: " << strerror(errno) << endl; ::_exit(-1); } setsid(); cmdLine.leaderProc = getpid(); pid_t c2 = fork(); if ( c2 ) { int pstat; cout << "forked process: " << c2 << endl; waitpid(c2, &pstat, 0); if ( WIFEXITED(pstat) ) { _exit( WEXITSTATUS(pstat) ); } _exit(51); } // stdout handled in initLogging //fclose(stdout); //freopen("/dev/null", "w", stdout); fclose(stderr); fclose(stdin); FILE* f = freopen("/dev/null", "w", stderr); if ( f == NULL ) { cout << "Cant reassign stderr while forking server process: " << strerror(errno) << endl; return false; } f = freopen("/dev/null", "r", stdin); if ( f == NULL ) { cout << "Cant reassign stdin while forking server process: " << strerror(errno) << endl; return false; } setupCoreSignals(); setupSignals( true ); } if (cmdLine.logWithSyslog) { StringBuilder sb; sb << cmdLine.binaryName << "." << cmdLine.port; Logstream::useSyslog( sb.str().c_str() ); } #endif if (!cmdLine.logpath.empty() && !isMongodShutdownSpecialCase) { fassert(16448, !cmdLine.logWithSyslog); string absoluteLogpath = boost::filesystem::absolute( cmdLine.logpath, cmdLine.cwd).string(); if (!initLogging(absoluteLogpath, cmdLine.logAppend)) { cout << "Bad logpath value: \"" << absoluteLogpath << "\"; terminating." << endl; return false; } } if (!cmdLine.pidFile.empty()) { writePidFile(cmdLine.pidFile); } if (!cmdLine.keyFile.empty()) { if (!setUpSecurityKey(cmdLine.keyFile)) { // error message printed in setUpPrivateKey return false; } noauth = false; } #ifdef MONGO_SSL if (cmdLine.sslOnNormalPorts) { if ( cmdLine.sslPEMKeyPassword.size() == 0 ) { log() << "need sslPEMKeyPassword" << endl; return false; } if ( cmdLine.sslPEMKeyFile.size() == 0 ) { log() << "need sslPEMKeyFile" << endl; return false; } cmdLine.sslServerManager = new SSLManager( false ); if ( ! cmdLine.sslServerManager->setupPEM( cmdLine.sslPEMKeyFile , cmdLine.sslPEMKeyPassword ) ) { return false; } } else if ( cmdLine.sslPEMKeyFile.size() || cmdLine.sslPEMKeyPassword.size() ) { log() << "need to enable sslOnNormalPorts" << endl; return false; } #endif return true; }
bool initializeServerGlobalState(bool isMongodShutdownSpecialCase) { Listener::globalTicketHolder.resize( cmdLine.maxConns ); #ifndef _WIN32 if (!fs::is_directory(cmdLine.socket)) { cout << cmdLine.socket << " must be a directory" << endl; return false; } if (cmdLine.doFork) { fassert(16447, !cmdLine.logpath.empty() || cmdLine.logWithSyslog); cout.flush(); cerr.flush(); cmdLine.parentProc = getpid(); // facilitate clean exit when child starts successfully setupLaunchSignals(); cout << "about to fork child process, waiting until server is ready for connections." << endl; pid_t child1 = fork(); if (child1 == -1) { cout << "ERROR: stage 1 fork() failed: " << errnoWithDescription(); _exit(EXIT_ABRUPT); } else if (child1) { // this is run in the original parent process int pstat; waitpid(child1, &pstat, 0); if (WIFEXITED(pstat)) { if (WEXITSTATUS(pstat)) { cout << "ERROR: child process failed, exited with error number " << WEXITSTATUS(pstat) << endl; } else { cout << "child process started successfully, parent exiting" << endl; } _exit(WEXITSTATUS(pstat)); } _exit(50); } if ( chdir("/") < 0 ) { cout << "Cant chdir() while forking server process: " << strerror(errno) << endl; ::_exit(-1); } setsid(); cmdLine.leaderProc = getpid(); pid_t child2 = fork(); if (child2 == -1) { cout << "ERROR: stage 2 fork() failed: " << errnoWithDescription(); _exit(EXIT_ABRUPT); } else if (child2) { // this is run in the middle process int pstat; cout << "forked process: " << child2 << endl; waitpid(child2, &pstat, 0); if ( WIFEXITED(pstat) ) { _exit( WEXITSTATUS(pstat) ); } _exit(51); } // this is run in the final child process (the server) // stdout handled in initLogging //fclose(stdout); //freopen("/dev/null", "w", stdout); fclose(stderr); fclose(stdin); FILE* f = freopen("/dev/null", "w", stderr); if ( f == NULL ) { cout << "Cant reassign stderr while forking server process: " << strerror(errno) << endl; return false; } f = freopen("/dev/null", "r", stdin); if ( f == NULL ) { cout << "Cant reassign stdin while forking server process: " << strerror(errno) << endl; return false; } setupCoreSignals(); setupSignals( true ); } if (cmdLine.logWithSyslog) { StringBuilder sb; sb << cmdLine.binaryName << "." << cmdLine.port; Logstream::useSyslog( sb.str().c_str() ); } #endif if (!cmdLine.logpath.empty() && !isMongodShutdownSpecialCase) { fassert(16448, !cmdLine.logWithSyslog); string absoluteLogpath = boost::filesystem::absolute( cmdLine.logpath, cmdLine.cwd).string(); if (!initLogging(absoluteLogpath, cmdLine.logAppend)) { cout << "Bad logpath value: \"" << absoluteLogpath << "\"; terminating." << endl; return false; } } if (!cmdLine.pidFile.empty()) { writePidFile(cmdLine.pidFile); } if (!cmdLine.keyFile.empty()) { if (!setUpSecurityKey(cmdLine.keyFile)) { // error message printed in setUpPrivateKey return false; } noauth = false; } return true; }
void Strategy::clientCommandOp(OperationContext* txn, Request& request) { QueryMessage q(request.d()); LOG(3) << "command: " << q.ns << " " << q.query << " ntoreturn: " << q.ntoreturn << " options: " << q.queryOptions; if (q.queryOptions & QueryOption_Exhaust) { uasserted(18527, string("the 'exhaust' query option is invalid for mongos commands: ") + q.ns + " " + q.query.toString()); } NamespaceString nss(request.getns()); // Regular queries are handled in strategy_shard.cpp verify(nss.isCommand() || nss.isSpecialCommand()); if (handleSpecialNamespaces(txn, request, q)) return; int loops = 5; bool cmChangeAttempted = false; while (true) { BSONObjBuilder builder; try { BSONObj cmdObj = q.query; { BSONElement e = cmdObj.firstElement(); if (e.type() == Object && (e.fieldName()[0] == '$' ? str::equals("query", e.fieldName() + 1) : str::equals("query", e.fieldName()))) { // Extract the embedded query object. if (cmdObj.hasField(Query::ReadPrefField.name())) { // The command has a read preference setting. We don't want // to lose this information so we copy this to a new field // called $queryOptions.$readPreference BSONObjBuilder finalCmdObjBuilder; finalCmdObjBuilder.appendElements(e.embeddedObject()); BSONObjBuilder queryOptionsBuilder( finalCmdObjBuilder.subobjStart("$queryOptions")); queryOptionsBuilder.append(cmdObj[Query::ReadPrefField.name()]); queryOptionsBuilder.done(); cmdObj = finalCmdObjBuilder.obj(); } else { cmdObj = e.embeddedObject(); } } } Command::runAgainstRegistered(txn, q.ns, cmdObj, builder, q.queryOptions); BSONObj x = builder.done(); replyToQuery(0, request.p(), request.m(), x); return; } catch (const StaleConfigException& e) { if (loops <= 0) throw e; loops--; log() << "retrying command: " << q.query; // For legacy reasons, ns may not actually be set in the exception :-( string staleNS = e.getns(); if (staleNS.size() == 0) staleNS = q.ns; ShardConnection::checkMyConnectionVersions(txn, staleNS); if (loops < 4) versionManager.forceRemoteCheckShardVersionCB(txn, staleNS); } catch (const DBException& e) { if (e.getCode() == ErrorCodes::IncompatibleCatalogManager) { fassert(28791, !cmChangeAttempted); cmChangeAttempted = true; grid.forwardingCatalogManager()->waitForCatalogManagerChange(txn); } else { Command::appendCommandStatus(builder, e.toStatus()); BSONObj x = builder.done(); replyToQuery(0, request.p(), request.m(), x); return; } } } }
void Lock::GlobalRead::_tempRelease() { fassert(16127, !noop); char ts = threadState(); fassert(16128, ts == 'R'); qlk.unlock_R(); }
Status LegacyReplicationCoordinator::processHeartbeat(const ReplSetHeartbeatArgs& args, ReplSetHeartbeatResponse* response) { if (args.getProtocolVersion() != 1) { return Status(ErrorCodes::BadValue, "incompatible replset protocol version"); } { if (_settings.ourSetName() != args.getSetName()) { log() << "replSet set names do not match, our cmdline: " << _settings.replSet << rsLog; log() << "replSet s: " << args.getSetName() << rsLog; response->noteMismatched(); return Status(ErrorCodes::BadValue, "repl set names do not match"); } } response->noteReplSet(); if( (theReplSet == 0) || (theReplSet->startupStatus == ReplSetImpl::LOADINGCONFIG) ) { if (!args.getSenderHost().empty()) { scoped_lock lck( _settings.discoveredSeeds_mx ); _settings.discoveredSeeds.insert(args.getSenderHost().toString()); } response->setHbMsg("still initializing"); return Status::OK(); } if (theReplSet->name() != args.getSetName()) { response->noteMismatched(); return Status(ErrorCodes::BadValue, "repl set names do not match (2)"); } response->setSetName(theReplSet->name()); MemberState currentState = theReplSet->state(); response->setState(currentState.s); if (currentState == MemberState::RS_PRIMARY) { response->setElectionTime(theReplSet->getElectionTime().asDate()); } response->setElectable(theReplSet->iAmElectable()); response->setHbMsg(theReplSet->hbmsg()); response->setTime((long long) time(0)); response->setOpTime(theReplSet->lastOpTimeWritten.asDate()); const Member *syncTarget = BackgroundSync::get()->getSyncTarget(); if (syncTarget) { response->setSyncingTo(syncTarget->fullName()); } int v = theReplSet->config().version; response->setVersion(v); if (v > args.getConfigVersion()) { ReplicaSetConfig config; fassert(18635, config.initialize(theReplSet->config().asBson())); response->setConfig(config); } Member* from = NULL; if (v == args.getConfigVersion() && args.getSenderId() != -1) { from = theReplSet->getMutableMember(args.getSenderId()); } if (!from) { from = theReplSet->findByName(args.getSenderHost().toString()); if (!from) { return Status::OK(); } } // if we thought that this node is down, let it know if (!from->hbinfo().up()) { response->noteStateDisagreement(); } // note that we got a heartbeat from this node theReplSet->mgr->send(stdx::bind(&ReplSet::msgUpdateHBRecv, theReplSet, from->hbinfo().id(), time(0))); return Status::OK(); }
int socketPoll( pollfd* fdarray, unsigned long nfds, int timeout ) { fassert(17185, isPollSupported()); return wsaPollFunction(fdarray, nfds, timeout); }
void WiredTigerRecoveryUnit::assertInActiveTxn() const { fassert( 28575, _active ); }
DiskLoc DataFileMgr::insert(const char* ns, const void* obuf, int32_t len, bool mayInterrupt, bool god, bool mayAddIndex, bool* addedID) { Database* database = cc().database(); bool wouldAddIndex = false; massert( 10093 , "cannot insert into reserved $ collection", god || NamespaceString::normal( ns ) ); uassert( 10094 , str::stream() << "invalid ns: " << ns , isValidNS( ns ) ); { const char *sys = strstr(ns, "system."); if ( sys ) { if ( !insert_checkSys(sys, ns, wouldAddIndex, obuf, god) ) return DiskLoc(); if ( mayAddIndex && wouldAddIndex ) { // TODO: this should be handled above this function BSONObj spec( static_cast<const char*>( obuf ) ); string collectionToIndex = spec.getStringField( "ns" ); uassert(10096, "invalid ns to index", collectionToIndex.find( '.' ) != string::npos); massert(10097, str::stream() << "trying to create index on wrong db " << " db: " << database->name() << " collection: " << collectionToIndex, database->ownsNS( collectionToIndex ) ); Collection* collection = database->getCollection( collectionToIndex ); if ( !collection ) { collection = database->createCollection( collectionToIndex, false, NULL, true ); verify( collection ); if ( !god ) ensureIdIndexForNewNs( collection ); } Status status = collection->getIndexCatalog()->createIndex( spec, mayInterrupt ); if ( status.code() == ErrorCodes::IndexAlreadyExists ) return DiskLoc(); uassertStatusOK( status ); return DiskLoc(); } } } Collection* collection = database->getCollection( ns ); if ( collection == NULL ) { collection = database->createCollection( ns, false, NULL, false ); int ies = Extent::initialSize(len); if( str::contains(ns, '$') && len + Record::HeaderSize >= BtreeData_V1::BucketSize - 256 && len + Record::HeaderSize <= BtreeData_V1::BucketSize + 256 ) { // probably an index. so we pick a value here for the first extent instead of using // initialExtentSize() which is more for user collections. // TODO: we could look at the # of records in the parent collection to be smarter here. ies = (32+4) * 1024; } collection->increaseStorageSize( ies, false); if ( !god ) ensureIdIndexForNewNs( collection ); } NamespaceDetails* d = collection->details(); IDToInsert idToInsert; // only initialized if needed if( !god ) { /* Check if we have an _id field. If we don't, we'll add it. Note that btree buckets which we insert aren't BSONObj's, but in that case god==true. */ BSONObj io((const char *) obuf); BSONElement idField = io.getField( "_id" ); uassert( 10099 , "_id cannot be an array", idField.type() != Array ); // we don't add _id for capped collections in local as they don't have an _id index if( idField.eoo() && !wouldAddIndex && nsToDatabase( ns ) != "local" && d->haveIdIndex() ) { if( addedID ) *addedID = true; idToInsert.init(); len += idToInsert.size(); } BSONElementManipulator::lookForTimestamps( io ); } int lenWHdr = d->getRecordAllocationSize( len + Record::HeaderSize ); fassert( 16440, lenWHdr >= ( len + Record::HeaderSize ) ); // If the collection is capped, check if the new object will violate a unique index // constraint before allocating space. if ( d->isCapped() && !god) { BSONObj temp = BSONObj( reinterpret_cast<const char *>( obuf ) ); Status ret = collection->getIndexCatalog()->checkNoIndexConflicts( temp ); uassert(12582, "duplicate key insert for unique index of capped collection", ret.isOK() ); } DiskLoc loc = allocateSpaceForANewRecord(ns, d, lenWHdr, god); if ( loc.isNull() ) { string errmsg = str::stream() << "insert: couldn't alloc space for object ns:" << ns << " capped:" << d->isCapped(); log() << errmsg; uasserted( 17248, errmsg ); } Record *r = loc.rec(); { verify( r->lengthWithHeaders() >= lenWHdr ); r = (Record*) getDur().writingPtr(r, lenWHdr); if( idToInsert.needed() ) { /* a little effort was made here to avoid a double copy when we add an ID */ int originalSize = *((int*) obuf); ((int&)*r->data()) = originalSize + idToInsert.size(); memcpy(r->data()+4, idToInsert.rawdata(), idToInsert.size()); memcpy(r->data()+4+idToInsert.size(), ((char*)obuf)+4, originalSize-4); } else { if( obuf ) // obuf can be null from internal callers memcpy(r->data(), obuf, len); } } addRecordToRecListInExtent(r, loc); d->incrementStats( r->netLength(), 1 ); // we don't bother resetting query optimizer stats for the god tables - also god is true when adding a btree bucket if ( !god ) collection->infoCache()->notifyOfWriteOp(); /* add this record to our indexes */ if ( d->getTotalIndexCount() > 0 ) { try { BSONObj obj(r->data()); collection->getIndexCatalog()->indexRecord(obj, loc); } catch( AssertionException& e ) { // should be a dup key error on _id index if( d->isCapped() ) { massert( 12583, "unexpected index insertion failure on capped collection", !d->isCapped() ); string s = e.toString(); s += " : on addIndex/capped - collection and its index will not match"; setLastError(0, s.c_str()); error() << s << endl; } else { // normal case -- we can roll back _deleteRecord(d, ns, r, loc); throw; } } } d->paddingFits(); return loc; }
Status IndexBuilder::_build(OperationContext* txn, Database* db, bool allowBackgroundBuilding, Lock::DBLock* dbLock) const { const NamespaceString ns(_index["ns"].String()); Collection* c = db->getCollection( txn, ns.ns() ); if ( !c ) { WriteUnitOfWork wunit(txn); c = db->getOrCreateCollection( txn, ns.ns() ); verify(c); wunit.commit(); } // Show which index we're building in the curop display. txn->getCurOp()->setQuery(_index); MultiIndexBlock indexer(txn, c); indexer.allowInterruption(); if (allowBackgroundBuilding) indexer.allowBackgroundBuilding(); Status status = Status::OK(); IndexDescriptor* descriptor(NULL); try { status = indexer.init(_index); if ( status.code() == ErrorCodes::IndexAlreadyExists ) return Status::OK(); if (status.isOK()) { if (allowBackgroundBuilding) { descriptor = indexer.registerIndexBuild(); invariant(dbLock); dbLock->relockWithMode(MODE_IX); } Lock::CollectionLock colLock(txn->lockState(), ns.ns(), MODE_IX); status = indexer.insertAllDocumentsInCollection(); } if (status.isOK()) { if (allowBackgroundBuilding) { dbLock->relockWithMode(MODE_X); } WriteUnitOfWork wunit(txn); indexer.commit(); wunit.commit(); } } catch (const DBException& e) { status = e.toStatus(); } if (allowBackgroundBuilding) { dbLock->relockWithMode(MODE_X); Database* db = dbHolder().get(txn, ns.db()); fassert(28553, db); fassert(28554, db->getCollection(txn, ns.ns())); indexer.unregisterIndexBuild(descriptor); } if (status.code() == ErrorCodes::InterruptedAtShutdown) { // leave it as-if kill -9 happened. This will be handled on restart. indexer.abortWithoutCleanup(); } return status; }
void ReplicationCoordinatorImpl::_startElectSelfV1() { invariant(!_voteRequester); invariant(!_freshnessChecker); stdx::unique_lock<stdx::mutex> lk(_mutex); switch (_rsConfigState) { case kConfigSteady: break; case kConfigInitiating: case kConfigReconfiguring: case kConfigHBReconfiguring: LOG(2) << "Not standing for election; processing a configuration change"; // Transition out of candidate role. _topCoord->processLoseElection(); return; default: severe() << "Entered replica set election code while in illegal config state " << int(_rsConfigState); fassertFailed(28641); } auto finishedEvent = _makeEvent(); if (!finishedEvent) { return; } _electionFinishedEvent = finishedEvent; auto dryRunFinishedEvent = _makeEvent(); if (!dryRunFinishedEvent) { return; } _electionDryRunFinishedEvent = dryRunFinishedEvent; LoseElectionDryRunGuardV1 lossGuard(this); invariant(_rsConfig.getMemberAt(_selfIndex).isElectable()); // Note: If we aren't durable, send last applied. const auto lastOpTime = _isDurableStorageEngine() ? _getMyLastDurableOpTime_inlock() : _getMyLastAppliedOpTime_inlock(); if (lastOpTime == OpTime()) { log() << "not trying to elect self, " "do not yet have a complete set of data from any point in time"; return; } log() << "conducting a dry run election to see if we could be elected"; _voteRequester.reset(new VoteRequester); // This is necessary because the voteRequester may call directly into winning an // election, if there are no other MaybeUp nodes. Winning an election attempts to lock // _mutex again. lk.unlock(); long long term = _topCoord->getTerm(); StatusWith<ReplicationExecutor::EventHandle> nextPhaseEvh = _voteRequester->start(&_replExecutor, _rsConfig, _selfIndex, _topCoord->getTerm(), true, // dry run lastOpTime); if (nextPhaseEvh.getStatus() == ErrorCodes::ShutdownInProgress) { return; } fassert(28685, nextPhaseEvh.getStatus()); _replExecutor.onEvent(nextPhaseEvh.getValue(), stdx::bind(&ReplicationCoordinatorImpl::_onDryRunComplete, this, term)); lossGuard.dismiss(); }
void SimpleRecordStoreV1::_compactExtent(OperationContext* txn, const DiskLoc diskloc, int extentNumber, RecordStoreCompactAdaptor* adaptor, const CompactOptions* compactOptions, CompactStats* stats ) { log() << "compact begin extent #" << extentNumber << " for namespace " << _ns << " " << diskloc; unsigned oldObjSize = 0; // we'll report what the old padding was unsigned oldObjSizeWithPadding = 0; Extent *e = _extentManager->getExtent( diskloc ); e->assertOk(); fassert( 17437, e->validates(diskloc) ); { // the next/prev pointers within the extent might not be in order so we first // page the whole thing in sequentially log() << "compact paging in len=" << e->length/1000000.0 << "MB" << endl; Timer t; size_t length = e->length; touch_pages( reinterpret_cast<const char*>(e), length ); int ms = t.millis(); if( ms > 1000 ) log() << "compact end paging in " << ms << "ms " << e->length/1000000.0/t.seconds() << "MB/sec" << endl; } { log() << "compact copying records" << endl; long long datasize = 0; long long nrecords = 0; DiskLoc L = e->firstRecord; if( !L.isNull() ) { while( 1 ) { Record *recOld = recordFor(L); L = getNextRecordInExtent(L); if ( compactOptions->validateDocuments && !adaptor->isDataValid(recOld) ) { // object is corrupt! log() << "compact skipping corrupt document!"; stats->corruptDocuments++; } else { unsigned dataSize = adaptor->dataSize( recOld ); unsigned docSize = dataSize; nrecords++; oldObjSize += docSize; oldObjSizeWithPadding += recOld->netLength(); unsigned lenWHdr = docSize + Record::HeaderSize; unsigned lenWPadding = lenWHdr; switch( compactOptions->paddingMode ) { case CompactOptions::NONE: if ( _details->isUserFlagSet(Flag_UsePowerOf2Sizes) ) lenWPadding = quantizePowerOf2AllocationSpace(lenWPadding); break; case CompactOptions::PRESERVE: // if we are preserving the padding, the record should not change size lenWPadding = recOld->lengthWithHeaders(); break; case CompactOptions::MANUAL: lenWPadding = compactOptions->computeRecordSize(lenWPadding); if (lenWPadding < lenWHdr || lenWPadding > BSONObjMaxUserSize / 2 ) { lenWPadding = lenWHdr; } break; } CompactDocWriter writer( recOld, dataSize, lenWPadding ); StatusWith<DiskLoc> status = insertRecord( txn, &writer, 0 ); uassertStatusOK( status.getStatus() ); datasize += recordFor( status.getValue() )->netLength(); adaptor->inserted( recordFor( status.getValue() ), status.getValue() ); } if( L.isNull() ) { // we just did the very last record from the old extent. it's still pointed to // by the old extent ext, but that will be fixed below after this loop break; } // remove the old records (orphan them) periodically so our commit block doesn't get too large bool stopping = false; RARELY stopping = !txn->checkForInterruptNoAssert().isOK(); if( stopping || txn->recoveryUnit()->isCommitNeeded() ) { *txn->recoveryUnit()->writing(&e->firstRecord) = L; Record *r = recordFor(L); txn->recoveryUnit()->writingInt(r->prevOfs()) = DiskLoc::NullOfs; txn->recoveryUnit()->commitIfNeeded(); txn->checkForInterrupt(); } } } // if !L.isNull() invariant( _details->firstExtent() == diskloc ); invariant( _details->lastExtent() != diskloc ); DiskLoc newFirst = e->xnext; _details->setFirstExtent( txn, newFirst ); *txn->recoveryUnit()->writing(&_extentManager->getExtent( newFirst )->xprev) = DiskLoc(); _extentManager->freeExtent( txn, diskloc ); txn->recoveryUnit()->commitIfNeeded(); { double op = 1.0; if( oldObjSize ) op = static_cast<double>(oldObjSizeWithPadding)/oldObjSize; log() << "compact finished extent #" << extentNumber << " containing " << nrecords << " documents (" << datasize/1000000.0 << "MB)" << " oldPadding: " << op << ' ' << static_cast<unsigned>(op*100.0)/100; } } }
static const char * rdv_onion_name(enum onion_type onion_type) { fassert(onion_type < lengthof(onion_names)); return (onion_names[onion_type]); }