diff options
Diffstat (limited to 'db/cmdline.cpp')
-rw-r--r-- | db/cmdline.cpp | 191 |
1 files changed, 139 insertions, 52 deletions
diff --git a/db/cmdline.cpp b/db/cmdline.cpp index 65ee179..900a782 100644 --- a/db/cmdline.cpp +++ b/db/cmdline.cpp @@ -20,47 +20,92 @@ #include "cmdline.h" #include "commands.h" #include "../util/processinfo.h" +#include "security_key.h" + +#ifdef _WIN32 +#include <direct.h> +#endif namespace po = boost::program_options; +namespace fs = boost::filesystem; namespace mongo { - void setupSignals(); + void setupSignals( bool inFork ); + string getHostNameCached(); BSONArray argvArray; - void CmdLine::addGlobalOptions( boost::program_options::options_description& general , - boost::program_options::options_description& hidden ){ + void CmdLine::addGlobalOptions( boost::program_options::options_description& general , + boost::program_options::options_description& hidden ) { /* support for -vv -vvvv etc. */ for (string s = "vv"; s.length() <= 12; s.append("v")) { hidden.add_options()(s.c_str(), "verbose"); } - + general.add_options() - ("help,h", "show this usage information") - ("version", "show version information") - ("config,f", po::value<string>(), "configuration file specifying additional options") - ("verbose,v", "be more verbose (include multiple times for more verbosity e.g. -vvvvv)") - ("quiet", "quieter output") - ("port", po::value<int>(&cmdLine.port), "specify port number") - ("bind_ip", po::value<string>(&cmdLine.bind_ip), "comma separated list of ip addresses to listen on - all local ips by default") - ("logpath", po::value<string>() , "file to send all output to instead of stdout" ) - ("logappend" , "append to logpath instead of over-writing" ) - ("pidfilepath", po::value<string>(), "full path to pidfile (if not set, no pidfile is created)") + ("help,h", "show this usage information") + ("version", "show version information") + ("config,f", po::value<string>(), "configuration file specifying additional options") + ("verbose,v", "be more verbose (include multiple times for more verbosity e.g. -vvvvv)") + ("quiet", "quieter output") + ("port", po::value<int>(&cmdLine.port), "specify port number") + ("bind_ip", po::value<string>(&cmdLine.bind_ip), "comma separated list of ip addresses to listen on - all local ips by default") + ("logpath", po::value<string>() , "log file to send write to instead of stdout - has to be a file, not directory" ) + ("logappend" , "append to logpath instead of over-writing" ) + ("pidfilepath", po::value<string>(), "full path to pidfile (if not set, no pidfile is created)") + ("keyFile", po::value<string>(), "private key for cluster authentication (only for replica sets)") #ifndef _WIN32 - ("fork" , "fork server process" ) + ("unixSocketPrefix", po::value<string>(), "alternative directory for UNIX domain sockets (defaults to /tmp)") + ("fork" , "fork server process" ) #endif - ; - + ; + } - bool CmdLine::store( int argc , char ** argv , +#if defined(_WIN32) + void CmdLine::addWindowsOptions( boost::program_options::options_description& windows , + boost::program_options::options_description& hidden ) { + windows.add_options() + ("install", "install mongodb service") + ("remove", "remove mongodb service") + ("reinstall", "reinstall mongodb service (equivilant of mongod --remove followed by mongod --install)") + ("serviceName", po::value<string>(), "windows service name") + ("serviceDisplayName", po::value<string>(), "windows service display name") + ("serviceDescription", po::value<string>(), "windows service description") + ("serviceUser", po::value<string>(), "user name service executes as") + ("servicePassword", po::value<string>(), "password used to authenticate serviceUser") + ; + hidden.add_options()("service", "start mongodb service"); + } +#endif + + + bool CmdLine::store( int argc , char ** argv , boost::program_options::options_description& visible, boost::program_options::options_description& hidden, boost::program_options::positional_options_description& positional, - boost::program_options::variables_map ¶ms ){ - + boost::program_options::variables_map ¶ms ) { + + + { + // setup binary name + cmdLine.binaryName = argv[0]; + size_t i = cmdLine.binaryName.rfind( '/' ); + if ( i != string::npos ) + cmdLine.binaryName = cmdLine.binaryName.substr( i + 1 ); + + // setup cwd + char buffer[1024]; +#ifdef _WIN32 + assert( _getcwd( buffer , 1000 ) ); +#else + assert( getcwd( buffer , 1000 ) ); +#endif + cmdLine.cwd = buffer; + } + /* don't allow guessing - creates ambiguities when some options are * prefixes of others. allow long disguises and don't allow guessing * to get away with our vvvvvvv trick. */ @@ -69,7 +114,7 @@ namespace mongo { po::command_line_style::allow_long_disguise) ^ po::command_line_style::allow_sticky); - + try { po::options_description all; @@ -80,26 +125,27 @@ namespace mongo { .options( all ) .positional( positional ) .style( style ) - .run(), + .run(), params ); - if ( params.count("config") ){ + if ( params.count("config") ) { ifstream f( params["config"].as<string>().c_str() ); - if ( ! f.is_open() ){ + if ( ! f.is_open() ) { cout << "ERROR: could not read from config file" << endl << endl; cout << visible << endl; return false; } - + po::store( po::parse_config_file( f , all ) , params ); f.close(); } - + po::notify(params); - } + } catch (po::error &e) { - cout << "ERROR: " << e.what() << endl << endl; - cout << visible << endl; + cout << "error command line: " << e.what() << endl; + cout << "use --help for help" << endl; + //cout << visible << endl; return false; } @@ -120,44 +166,51 @@ namespace mongo { string logpath; #ifndef _WIN32 + if (params.count("unixSocketPrefix")) { + cmdLine.socket = params["unixSocketPrefix"].as<string>(); + if (!fs::is_directory(cmdLine.socket)) { + cout << cmdLine.socket << " must be a directory" << endl; + ::exit(-1); + } + } + if (params.count("fork")) { - if ( ! params.count( "logpath" ) ){ + if ( ! params.count( "logpath" ) ) { cout << "--fork has to be used with --logpath" << endl; ::exit(-1); } - - { // test logpath + + { + // test logpath logpath = params["logpath"].as<string>(); assert( logpath.size() ); - if ( logpath[0] != '/' ){ - char temp[256]; - assert( getcwd( temp , 256 ) ); - logpath = (string)temp + "/" + logpath; + if ( logpath[0] != '/' ) { + logpath = cmdLine.cwd + "/" + logpath; } FILE * test = fopen( logpath.c_str() , "a" ); - if ( ! test ){ + if ( ! test ) { cout << "can't open [" << logpath << "] for log file: " << errnoWithDescription() << endl; ::exit(-1); } fclose( test ); } - + cout.flush(); cerr.flush(); pid_t c = fork(); - if ( c ){ + if ( c ) { _exit(0); } - if ( chdir("/") < 0 ){ + if ( chdir("/") < 0 ) { cout << "Cant chdir() while forking server process: " << strerror(errno) << endl; ::exit(-1); } setsid(); - + pid_t c2 = fork(); - if ( c2 ){ + if ( c2 ) { cout << "forked process: " << c2 << endl; _exit(0); } @@ -170,19 +223,19 @@ namespace mongo { fclose(stdin); FILE* f = freopen("/dev/null", "w", stderr); - if ( f == NULL ){ + if ( f == NULL ) { cout << "Cant reassign stderr while forking server process: " << strerror(errno) << endl; ::exit(-1); } f = freopen("/dev/null", "r", stdin); - if ( f == NULL ){ + if ( f == NULL ) { cout << "Cant reassign stdin while forking server process: " << strerror(errno) << endl; ::exit(-1); } setupCoreSignals(); - setupSignals(); + setupSignals( true ); } #endif if (params.count("logpath")) { @@ -196,6 +249,18 @@ namespace mongo { writePidFile( params["pidfilepath"].as<string>() ); } + if (params.count("keyFile")) { + const string f = params["keyFile"].as<string>(); + + if (!setUpSecurityKey(f)) { + // error message printed in setUpPrivateKey + dbexit(EXIT_BADOPTIONS); + } + + noauth = false; + } + + { BSONArrayBuilder b; for (int i=0; i < argc; i++) @@ -205,29 +270,51 @@ namespace mongo { return true; } - - void ignoreSignal( int signal ){ - } - void setupCoreSignals(){ + void ignoreSignal( int sig ) {} + + void setupCoreSignals() { #if !defined(_WIN32) assert( signal(SIGUSR1 , rotateLogs ) != SIG_ERR ); assert( signal(SIGHUP , ignoreSignal ) != SIG_ERR ); #endif } - class CmdGetCmdLineOpts : Command{ - public: + class CmdGetCmdLineOpts : Command { + public: CmdGetCmdLineOpts(): Command("getCmdLineOpts") {} void help(stringstream& h) const { h << "get argv"; } virtual LockType locktype() const { return NONE; } virtual bool adminOnly() const { return true; } virtual bool slaveOk() const { return true; } - virtual bool run(const string&, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl){ + virtual bool run(const string&, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) { result.append("argv", argvArray); return true; } } cmdGetCmdLineOpts; + + string prettyHostName() { + StringBuilder s(128); + s << getHostNameCached(); + if( cmdLine.port != CmdLine::DefaultDBPort ) + s << ':' << mongo::cmdLine.port; + return s.str(); + } + + ParameterValidator::ParameterValidator( const string& name ) : _name( name ) { + if ( ! _all ) + _all = new map<string,ParameterValidator*>(); + (*_all)[_name] = this; + } + + ParameterValidator * ParameterValidator::get( const string& name ) { + map<string,ParameterValidator*>::iterator i = _all->find( name ); + if ( i == _all->end() ) + return NULL; + return i->second; + } + map<string,ParameterValidator*> * ParameterValidator::_all = 0; + } |