int killDb( int port, pid_t _pid, int signal ) { pid_t pid; int exitCode = 0; if ( port > 0 ) { if( dbs.count( port ) != 1 ) { cout << "No db started on port: " << port << endl; return 0; } pid = dbs[ port ].first; } else { pid = _pid; } kill_wrapper( pid, signal, port ); int i = 0; for( ; i < 130; ++i ) { if ( i == 30 ) { char now[64]; time_t_to_String(time(0), now); now[ 20 ] = 0; cout << now << " process on port " << port << ", with pid " << pid << " not terminated, sending sigkill" << endl; kill_wrapper( pid, SIGKILL, port ); } if(wait_for_pid(pid, false, &exitCode)) break; sleepmillis( 1000 ); } if ( i == 130 ) { char now[64]; time_t_to_String(time(0), now); now[ 20 ] = 0; cout << now << " failed to terminate process on port " << port << ", with pid " << pid << endl; assert( "Failed to terminate process" == 0 ); } if ( port > 0 ) { close( dbs[ port ].second ); dbs.erase( port ); } else { close( shells[ pid ] ); shells.erase( pid ); } // FIXME I think the intention here is to do an extra sleep only when SIGKILL is sent to the child process. // We may want to change the 4 below to 29, since values of i greater than that indicate we sent a SIGKILL. if ( i > 4 || signal == SIGKILL ) { sleepmillis( 4000 ); // allow operating system to reclaim resources } return exitCode; }
int killDb( int port, pid_t _pid, int signal, const BSONObj& opt ) { pid_t pid; int exitCode = 0; if ( port > 0 ) { if( !registry.isPortRegistered( port ) ) { log() << "No db started on port: " << port << endl; return 0; } pid = registry.pidForPort( port ); } else { pid = _pid; } kill_wrapper( pid, signal, port, opt ); int i = 0; for( ; i < 130; ++i ) { if ( i == 60 ) { char now[64]; time_t_to_String(time(0), now); now[ 20 ] = 0; log() << now << " process on port " << port << ", with pid " << pid << " not terminated, sending sigkill" << endl; kill_wrapper( pid, SIGKILL, port, opt ); } if(wait_for_pid(pid, false, &exitCode)) break; sleepmillis( 1000 ); } if ( i == 130 ) { char now[64]; time_t_to_String(time(0), now); now[ 20 ] = 0; log() << now << " failed to terminate process on port " << port << ", with pid " << pid << endl; verify( "Failed to terminate process" == 0 ); } if ( port > 0 ) { registry.deletePort( port ); } else { registry.deletePid( pid ); } // FIXME I think the intention here is to do an extra sleep only when SIGKILL is sent to the child process. // We may want to change the 4 below to 29, since values of i greater than that indicate we sent a SIGKILL. if ( i > 4 || signal == SIGKILL ) { sleepmillis( 4000 ); // allow operating system to reclaim resources } return exitCode; }
int killDb( int port, pid_t _pid, int signal ) { pid_t pid; int exitCode = 0; if ( port > 0 ) { if( dbs.count( port ) != 1 ) { cout << "No db started on port: " << port << endl; return 0; } pid = dbs[ port ].first; } else { pid = _pid; } kill_wrapper( pid, signal, port ); int i = 0; for( ; i < 130; ++i ) { if ( i == 30 ) { char now[64]; time_t_to_String(time(0), now); now[ 20 ] = 0; cout << now << " process on port " << port << ", with pid " << pid << " not terminated, sending sigkill" << endl; kill_wrapper( pid, SIGKILL, port ); } if(wait_for_pid(pid, false, &exitCode)) break; sleepmillis( 1000 ); } if ( i == 65 ) { char now[64]; time_t_to_String(time(0), now); now[ 20 ] = 0; cout << now << " failed to terminate process on port " << port << ", with pid " << pid << endl; assert( "Failed to terminate process" == 0 ); } if ( port > 0 ) { close( dbs[ port ].second ); dbs.erase( port ); } else { close( shells[ pid ] ); shells.erase( pid ); } if ( i > 4 || signal == SIGKILL ) { sleepmillis( 4000 ); // allow operating system to reclaim resources } return exitCode; }
void killDb( int port, pid_t _pid, int signal ) { pid_t pid; if ( port > 0 ) { if( dbs.count( port ) != 1 ) { cout << "No db started on port: " << port << endl; return; } pid = dbs[ port ].first; } else { pid = _pid; } assert( 0 == kill( pid, signal ) ); int i = 0; for( ; i < 65; ++i ) { if ( i == 5 ) { char now[64]; time_t_to_String(time(0), now); now[ 20 ] = 0; cout << now << " process on port " << port << ", with pid " << pid << " not terminated, sending sigkill" << endl; assert( 0 == kill( pid, SIGKILL ) ); } int temp; int ret = waitpid( pid, &temp, WNOHANG ); if ( ret == pid ) break; sleepms( 1000 ); } if ( i == 65 ) { char now[64]; time_t_to_String(time(0), now); now[ 20 ] = 0; cout << now << " failed to terminate process on port " << port << ", with pid " << pid << endl; assert( "Failed to terminate process" == 0 ); } if ( port > 0 ) { close( dbs[ port ].second ); dbs.erase( port ); } else { close( shells[ pid ] ); shells.erase( pid ); } if ( i > 4 || signal == SIGKILL ) { sleepms( 4000 ); // allow operating system to reclaim resources } }
std::string toStringLong() const { char buf[64]; time_t_to_String(secs, buf); std::stringstream ss; ss << time_t_to_String_short(secs) << ' '; ss << std::hex << secs << ':' << i; return ss.str(); }
/* note: can't use malloc herein - may be in signal handler. logLockless() likely does not comply and should still be fixed todo likewise class string? */ void rawOut( const string &s ) { if( s.empty() ) return; char buf[64]; time_t_to_String( time(0) , buf ); /* truncate / don't show the year: */ buf[19] = ' '; buf[20] = 0; Logstream::logLockless(buf); Logstream::logLockless(s); Logstream::logLockless("\n"); }
void rawOut( const string &s ) { if( s.empty() ) return; char now[64]; time_t_to_String(time(0), now); now[20] = 0; #if defined(_WIN32) (std::cout << now << " " << s).flush(); #else write( STDOUT_FILENO, now, 20 ); write( STDOUT_FILENO, " ", 1 ); write( STDOUT_FILENO, s.c_str(), s.length() ); fsync( STDOUT_FILENO ); #endif }
// Returns false when request includes 'end' bool assembleResponse( Message &m, DbResponse &dbresponse, const sockaddr_in &client ) { // before we lock... if ( m.data->operation() == dbQuery ) { const char *ns = m.data->_data + 4; if( strstr(ns, "$cmd.sys.") ) { if( strstr(ns, "$cmd.sys.inprog") ) { inProgCmd(m, dbresponse); return true; } if( strstr(ns, "$cmd.sys.killop") ) { killOp(m, dbresponse); return true; } } } if ( handlePossibleShardedMessage( m , dbresponse ) ){ /* important to do this before we lock so if a message has to be forwarded, doesn't block for that */ return true; } dblock lk; stringstream ss; char buf[64]; time_t now = time(0); CurOp& currentOp = *cc().curop(); currentOp.reset(now, client); time_t_to_String(now, buf); buf[20] = 0; // don't want the year ss << buf; Timer t; Client& c = cc(); c.clearns(); int logThreshold = 100; int ms; bool log = logLevel >= 1; c.curop()->op = m.data->operation(); #if 0 /* use this if you only want to process operations for a particular namespace. maybe add to cmd line parms or something fancier. */ DbMessage ddd(m); if ( strncmp(ddd.getns(), "clusterstock", 12) != 0 ) { static int q; if ( ++q < 20 ) out() << "TEMP skip " << ddd.getns() << endl; goto skip; } #endif if ( m.data->operation() == dbQuery ) { // receivedQuery() does its own authorization processing. receivedQuery(dbresponse, m, ss, true); } else if ( m.data->operation() == dbGetMore ) { // receivedQuery() does its own authorization processing. OPREAD; DEV log = true; ss << "getmore "; receivedGetMore(dbresponse, m, ss); } else if ( m.data->operation() == dbMsg ) { /* deprecated / rarely used. intended for connection diagnostics. */ ss << "msg "; char *p = m.data->_data; int len = strlen(p); if ( len > 400 ) out() << curTimeMillis() % 10000 << " long msg received, len:" << len << " ends with: " << p + len - 10 << endl; bool end = false; //strcmp("end", p) == 0; Message *resp = new Message(); resp->setData(opReply, "i am fine"); dbresponse.response = resp; dbresponse.responseTo = m.data->id; //dbMsgPort.reply(m, resp); if ( end ) return false; } else { const char *ns = m.data->_data + 4; char cl[256]; nsToClient(ns, cl); strncpy(currentOp.ns, ns, Namespace::MaxNsLen); AuthenticationInfo *ai = currentClient.get()->ai; if( !ai->isAuthorized(cl) ) { uassert_nothrow("unauthorized"); } else if ( m.data->operation() == dbInsert ) { OPWRITE; try { ss << "insert "; receivedInsert(m, ss); } catch ( AssertionException& e ) { LOGSOME problem() << " Caught Assertion insert, continuing\n"; ss << " exception " + e.toString(); } } else if ( m.data->operation() == dbUpdate ) { OPWRITE; try { ss << "update "; receivedUpdate(m, ss); } catch ( AssertionException& e ) { LOGSOME problem() << " Caught Assertion update, continuing" << endl; ss << " exception " + e.toString(); } } else if ( m.data->operation() == dbDelete ) { OPWRITE; try { ss << "remove "; receivedDelete(m, ss); } catch ( AssertionException& e ) { LOGSOME problem() << " Caught Assertion receivedDelete, continuing" << endl; ss << " exception " + e.toString(); } } else if ( m.data->operation() == dbKillCursors ) { OPREAD; try { logThreshold = 10; ss << "killcursors "; receivedKillCursors(m); } catch ( AssertionException& e ) { problem() << " Caught Assertion in kill cursors, continuing" << endl; ss << " exception " + e.toString(); } } else { out() << " operation isn't supported: " << m.data->operation() << endl; currentOp.active = false; assert(false); } } ms = t.millis(); log = log || (logLevel >= 2 && ++ctr % 512 == 0); DEV log = true; if ( log || ms > logThreshold ) { ss << ' ' << t.millis() << "ms"; out() << ss.str().c_str() << endl; } Database *database = cc().database(); if ( database && database->profile >= 1 ) { if ( database->profile >= 2 || ms >= 100 ) { // profile it profile(ss.str().c_str()+20/*skip ts*/, ms); } } currentOp.active = false; return true; }
void Logstream::flush(Tee *t) { const size_t MAX_LOG_LINE = 1024 * 10; // this ensures things are sane if ( doneSetup == 1717 ) { string msg = ss.str(); string threadName = getThreadName(); const char * type = logLevelToString(logLevel); size_t msgLen = msg.size(); if ( msgLen > MAX_LOG_LINE ) msgLen = MAX_LOG_LINE; const int spaceNeeded = (int)( msgLen + 64 /* for extra info */ + threadName.size()); int bufSize = 128; while ( bufSize < spaceNeeded ) bufSize += 128; BufBuilder b(bufSize); time_t_to_String( time(0) , b.grow(20) ); if (!threadName.empty()) { b.appendChar( '[' ); b.appendStr( threadName , false ); b.appendChar( ']' ); b.appendChar( ' ' ); } for ( int i=0; i<indent; i++ ) b.appendChar( '\t' ); if ( type[0] ) { b.appendStr( type , false ); b.appendStr( ": " , false ); } if ( msg.size() > MAX_LOG_LINE ) { stringstream sss; sss << "warning: log line attempted (" << msg.size() / 1024 << "k) over max size(" << MAX_LOG_LINE / 1024 << "k)"; sss << ", printing beginning and end ... "; b.appendStr( sss.str() ); const char * xx = msg.c_str(); b.appendBuf( xx , MAX_LOG_LINE / 3 ); b.appendStr( " .......... " ); b.appendStr( xx + msg.size() - ( MAX_LOG_LINE / 3 ) ); } else { b.appendStr( msg ); } string out( b.buf() , b.len() - 1); assert( b.len() < spaceNeeded ); scoped_lock lk(mutex); if( t ) t->write(logLevel,out); if ( globalTees ) { for ( unsigned i=0; i<globalTees->size(); i++ ) (*globalTees)[i]->write(logLevel,out); } #ifndef _WIN32 if ( isSyslog ) { syslog( logLevelToSysLogLevel(logLevel) , "%s" , out.data() ); } else #endif if(fwrite(out.data(), out.size(), 1, logfile)) { fflush(logfile); } else { int x = errno; cout << "Failed to write to logfile: " << errnoWithDescription(x) << ": " << out << endl; } #ifdef POSIX_FADV_DONTNEED // This only applies to pages that have already been flushed RARELY posix_fadvise(fileno(logfile), 0, 0, POSIX_FADV_DONTNEED); #endif } _init(); }