From 0532b35568497fc4159764f8858007656965cb38 Mon Sep 17 00:00:00 2001 From: Aaron Date: Tue, 26 May 2009 17:18:34 -0400 Subject: [PATCH] add client ip / port to current op, add unlocked version of current op to http interface --- db/curop.h | 146 ++++++++++++++++++++++++--------------------- db/db.cpp | 2 +- db/dbwebserver.cpp | 1 + db/instance.cpp | 8 +-- db/instance.h | 4 +- db/query.cpp | 2 +- 6 files changed, 87 insertions(+), 76 deletions(-) diff --git a/db/curop.h b/db/curop.h index 52853d119b8..2ba4f90d057 100644 --- a/db/curop.h +++ b/db/curop.h @@ -1,69 +1,77 @@ -// curop.h - -#pragma once - -#include "namespace.h" -#include "security.h" - -namespace mongo { - - extern struct CurOp { - void reset(time_t now) { - active = true; - opNum++; - startTime = now; - ns[0] = '?'; // just in case not set later - *query = 0; - killCurrentOp = 0; - } - - bool active; - unsigned opNum; - time_t startTime; - int op; - char ns[Namespace::MaxNsLen+1]; - char query[128]; - char zero; - - CurOp() { - opNum = 0; - ns[sizeof(ns)-1] = 0; - query[sizeof(query)-1] = 0; - } - - BSONObj info() { - AuthenticationInfo *ai = authInfo.get(); - if( ai == 0 || !ai->isAuthorized("admin") ) { - BSONObjBuilder b; - b.append("err", "unauthorized"); - return b.obj(); - } - return infoNoauth(); - } - - BSONObj infoNoauth() { - BSONObjBuilder b; - b.append("opid", opNum); - b.append("active", active); - if( active ) - b.append("secs_running", (int) (time(0)-startTime)); - if( op == 2004 ) - b.append("op", "query"); - else if( op == 2005 ) - b.append("op", "getMore"); - else if( op == 2001 ) - b.append("op", "update"); - else if( op == 2002 ) - b.append("op", "insert"); - else if( op == 2006 ) - b.append("op", "delete"); - else - b.append("op", op); - b.append("ns", ns); - b.append("query", query); - b.append("inLock", dbMutexInfo.isLocked()); - return b.obj(); - } - } currentOp; - -} +// curop.h + +#pragma once + +#include "namespace.h" +#include "security.h" + +namespace mongo { + + extern struct CurOp { + void reset(time_t now, const sockaddr_in &_client) { + active = true; + opNum++; + startTime = now; + ns[0] = '?'; // just in case not set later + *query = 0; + killCurrentOp = 0; + client = _client; + } + + bool active; + unsigned opNum; + time_t startTime; + int op; + char ns[Namespace::MaxNsLen+2]; + char query[128]; + char zero; + struct sockaddr_in client; + + CurOp() { + opNum = 0; + // These addresses should never be written to again. The zeroes are + // placed here as a precaution because currentOp may be accessed + // without the db mutex. + ns[sizeof(ns)-1] = 0; + query[sizeof(query)-1] = 0; + } + + BSONObj info() { + AuthenticationInfo *ai = authInfo.get(); + if( ai == 0 || !ai->isAuthorized("admin") ) { + BSONObjBuilder b; + b.append("err", "unauthorized"); + return b.obj(); + } + return infoNoauth(); + } + + BSONObj infoNoauth() { + BSONObjBuilder b; + b.append("opid", opNum); + b.append("active", active); + if( active ) + b.append("secs_running", (int) (time(0)-startTime)); + if( op == 2004 ) + b.append("op", "query"); + else if( op == 2005 ) + b.append("op", "getMore"); + else if( op == 2001 ) + b.append("op", "update"); + else if( op == 2002 ) + b.append("op", "insert"); + else if( op == 2006 ) + b.append("op", "delete"); + else + b.append("op", op); + b.append("ns", ns); + b.append("query", query); + b.append("inLock", dbMutexInfo.isLocked()); + stringstream clientStr; + clientStr << inet_ntoa( client.sin_addr ) << ":" << ntohs( client.sin_port ); + b.append("client", clientStr.str()); + return b.obj(); + } + } currentOp; + +} diff --git a/db/db.cpp b/db/db.cpp index 58c7896afa5..aacee569e36 100644 --- a/db/db.cpp +++ b/db/db.cpp @@ -201,7 +201,7 @@ namespace mongo { le->nPrev++; DbResponse dbresponse; - if ( !assembleResponse( m, dbresponse ) ) { + if ( !assembleResponse( m, dbresponse, dbMsgPort.farEnd.sa ) ) { out() << curTimeMillis() % 10000 << " end msg " << dbMsgPort.farEnd.toString() << endl; /* todo: we may not wish to allow this, even on localhost: very low priv accounts could stop us. */ if ( dbMsgPort.farEnd.isLocalHost() ) { diff --git a/db/dbwebserver.cpp b/db/dbwebserver.cpp index bc659f17b84..ec29ebcc578 100644 --- a/db/dbwebserver.cpp +++ b/db/dbwebserver.cpp @@ -173,6 +173,7 @@ namespace mongo { } ss << "\nreplInfo: " << replInfo << '\n'; + ss << "currentOp (unlocked): " << currentOp.infoNoauth() << "\n"; } bool allowed( const char * rq , vector& headers, const SockAddr &from ){ diff --git a/db/instance.cpp b/db/instance.cpp index b3ac8e06150..01829697ef3 100644 --- a/db/instance.cpp +++ b/db/instance.cpp @@ -113,7 +113,7 @@ namespace mongo { } // Returns false when request includes 'end' - bool assembleResponse( Message &m, DbResponse &dbresponse ) { + 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; @@ -141,7 +141,7 @@ namespace mongo { stringstream ss; char buf[64]; time_t now = time(0); - currentOp.reset(now); + currentOp.reset(now, client); time_t_to_String(now, buf); buf[20] = 0; // don't want the year @@ -331,7 +331,7 @@ namespace mongo { { string s = query.toString(); ss << " query: " << s; - strncpy(currentOp.query, s.c_str(), sizeof(currentOp.query)-1); + strncpy(currentOp.query, s.c_str(), sizeof(currentOp.query)-2); } bool updatedExisting = updateObjects(ns, toupdate, query, flags & 1, ss); recordUpdate( updatedExisting, ( upsert || updatedExisting ) ? 1 : 0 ); @@ -351,7 +351,7 @@ namespace mongo { { string s = pattern.toString(); ss << " query: " << s; - strncpy(currentOp.query, s.c_str(), sizeof(currentOp.query)-1); + strncpy(currentOp.query, s.c_str(), sizeof(currentOp.query)-2); } int n = deleteObjects(ns, pattern, justOne, true); recordDelete( n ); diff --git a/db/instance.h b/db/instance.h index 75211dfb90f..efa2085ca8a 100644 --- a/db/instance.h +++ b/db/instance.h @@ -87,7 +87,9 @@ namespace mongo { } }; - bool assembleResponse( Message &m, DbResponse &dbresponse ); + static SockAddr unknownAddress( "0.0.0.0", 0 ); + + bool assembleResponse( Message &m, DbResponse &dbresponse, const sockaddr_in &client = unknownAddress.sa ); void receivedKillCursors(Message& m); void receivedUpdate(Message& m, stringstream& ss); diff --git a/db/query.cpp b/db/query.cpp index 3677b477585..ae61980f18f 100644 --- a/db/query.cpp +++ b/db/query.cpp @@ -1192,7 +1192,7 @@ namespace mongo { ss << "query " << ns << " ntoreturn:" << ntoreturn; { string s = jsobj.toString(); - strncpy(currentOp.query, s.c_str(), sizeof(currentOp.query)-1); + strncpy(currentOp.query, s.c_str(), sizeof(currentOp.query)-2); } BufBuilder bb;