void CursorCache::gotKillCursors(Message& m ) { int *x = (int *) m.singleData()->_data; x++; // reserved int n = *x++; if ( n > 2000 ) { LOG( n < 30000 ? LL_WARNING : LL_ERROR ) << "receivedKillCursors, n=" << n << endl; } uassert( 13286 , "sent 0 cursors to kill" , n >= 1 ); uassert( 13287 , "too many cursors to kill" , n < 30000 ); long long * cursors = (long long *)x; AuthorizationManager* authManager = ClientBasic::getCurrent()->getAuthorizationManager(); for ( int i=0; i<n; i++ ) { long long id = cursors[i]; LOG(_myLogLevel) << "CursorCache::gotKillCursors id: " << id << endl; if ( ! id ) { LOG( LL_WARNING ) << " got cursor id of 0 to kill" << endl; continue; } string server; { scoped_lock lk( _mutex ); MapSharded::iterator i = _cursors.find( id ); if ( i != _cursors.end() ) { if (authManager->checkAuthorization(i->second->getNS(), ActionType::killCursors)) { _cursors.erase( i ); } continue; } MapNormal::iterator refsIt = _refs.find(id); MapNormal::iterator refsNSIt = _refsNS.find(id); if (refsIt == _refs.end()) { LOG( LL_WARNING ) << "can't find cursor: " << id << endl; continue; } verify(refsNSIt != _refsNS.end()); if (!authManager->checkAuthorization(refsNSIt->second, ActionType::killCursors)) { continue; } server = refsIt->second; _refs.erase(refsIt); _refsNS.erase(refsNSIt); } LOG(_myLogLevel) << "CursorCache::found gotKillCursors id: " << id << " server: " << server << endl; verify( server.size() ); scoped_ptr<ScopedDbConnection> conn( ScopedDbConnection::getScopedDbConnection( server ) ); conn->get()->killCursor( id ); conn->done(); } }
bool handleSpecialNamespaces( Request& r , QueryMessage& q ) { const char * ns = r.getns(); ns = strstr( r.getns() , ".$cmd.sys." ); if ( ! ns ) return false; ns += 10; BSONObjBuilder b; vector<Shard> shards; AuthorizationManager* authManager = ClientBasic::getCurrent()->getAuthorizationManager(); if ( strcmp( ns , "inprog" ) == 0 ) { uassert(16545, "not authorized to run inprog", authManager->checkAuthorization(AuthorizationManager::SERVER_RESOURCE_NAME, ActionType::inprog)); Shard::getAllShards( shards ); BSONArrayBuilder arr( b.subarrayStart( "inprog" ) ); for ( unsigned i=0; i<shards.size(); i++ ) { Shard shard = shards[i]; scoped_ptr<ScopedDbConnection> conn( ScopedDbConnection::getScopedDbConnection( shard.getConnString() ) ); BSONObj temp = conn->get()->findOne( r.getns() , q.query ); if ( temp["inprog"].isABSONObj() ) { BSONObjIterator i( temp["inprog"].Obj() ); while ( i.more() ) { BSONObjBuilder x; BSONObjIterator j( i.next().Obj() ); while( j.more() ) { BSONElement e = j.next(); if ( str::equals( e.fieldName() , "opid" ) ) { stringstream ss; ss << shard.getName() << ':' << e.numberInt(); x.append( "opid" , ss.str() ); } else if ( str::equals( e.fieldName() , "client" ) ) { x.appendAs( e , "client_s" ); } else { x.append( e ); } } arr.append( x.obj() ); } } conn->done(); } arr.done(); } else if ( strcmp( ns , "killop" ) == 0 ) { uassert(16546, "not authorized to run killop", authManager->checkAuthorization(AuthorizationManager::SERVER_RESOURCE_NAME, ActionType::killop)); BSONElement e = q.query["op"]; if ( e.type() != String ) { b.append( "err" , "bad op" ); b.append( e ); } else { b.append( e ); string s = e.String(); string::size_type i = s.find( ':' ); if ( i == string::npos ) { b.append( "err" , "bad opid" ); } else { string shard = s.substr( 0 , i ); int opid = atoi( s.substr( i + 1 ).c_str() ); b.append( "shard" , shard ); b.append( "shardid" , opid ); log() << "want to kill op: " << e << endl; Shard s(shard); scoped_ptr<ScopedDbConnection> conn( ScopedDbConnection::getScopedDbConnection( s.getConnString() ) ); conn->get()->findOne( r.getns() , BSON( "op" << opid ) ); conn->done(); } } } else if ( strcmp( ns , "unlock" ) == 0 ) { b.append( "err" , "can't do unlock through mongos" ); } else { LOG( LL_WARNING ) << "unknown sys command [" << ns << "]" << endl; return false; } BSONObj x = b.done(); replyToQuery(0, r.p(), r.m(), x); return true; }