diff options
author | Matt Kneiser <matt.kneiser@mongodb.com> | 2022-07-05 17:09:20 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-07-07 18:26:31 +0000 |
commit | c44db4ac9d0c4c368835dac9f2fbd5869d885f17 (patch) | |
tree | c07de8fbd279573725d877619f263a684ec420f4 /src/mongo | |
parent | 2f2dc04da0c7fd853a2ff68c245c5f6e28f50fa1 (diff) | |
download | mongo-c44db4ac9d0c4c368835dac9f2fbd5869d885f17.tar.gz |
SERVER-9434 Audit and Normalize Process Exit Codes
- Put all references to ExitCode enumerators under an enum class to namespace
all the enumerators and avoid polluting the mongo namespace with possible
naming collisions.
- Added magic-number exit codes to exit_code.h like 50 & 51
(LauncherMiddleError & LauncherError respectively).
- Reserved a range of exit codes to account for FreeBSD's usage of 64-78.
- Renamed all enums with removal of EXIT_ which could conflict or get confused
with built-in macros.
- camelCased all ExitCode enum values.
- Added the generic - ExitCode::fail - for returning 1 as failure.
- Added explicit dependency on the exit_code.h header for all files using
ExitCode's.
- Removed all references to implementation-defined exit codes like EXIT_FAILURE
and EXIT_SUCCESS.
- Narrowed return values of the shell's undocumented quit() argument to portable
values within 0-255, 0/ExitCode::clean otherwise.
- Deprecated 8 unused ExitCode's
- java
- oomMalloc
- oomRealloc
- fs
- clockSkew
- windowsServiceStop
- possibleCorruption
- test
- Wrapped the 2 Windows-only ExitCode's in #ifdef's
- ntServiceError
- windowsServiceStop
Diffstat (limited to 'src/mongo')
55 files changed, 290 insertions, 238 deletions
diff --git a/src/mongo/base/initializer.cpp b/src/mongo/base/initializer.cpp index 0002295b1f4..6e0d90b7e39 100644 --- a/src/mongo/base/initializer.cpp +++ b/src/mongo/base/initializer.cpp @@ -41,6 +41,7 @@ #include "mongo/base/status.h" #include "mongo/logv2/log.h" #include "mongo/util/assert_util.h" +#include "mongo/util/exit_code.h" #include "mongo/util/quick_exit.h" #include "mongo/util/str.h" @@ -220,7 +221,7 @@ Status runGlobalDeinitializers() { void runGlobalInitializersOrDie(const std::vector<std::string>& argv) { if (Status status = runGlobalInitializers(argv); !status.isOK()) { std::cerr << "Failed global initialization: " << status << std::endl; - quickExit(1); + quickExit(ExitCode::fail); } } diff --git a/src/mongo/db/auth/sasl_mechanism_registry.cpp b/src/mongo/db/auth/sasl_mechanism_registry.cpp index e72e9afa30e..4ba33279435 100644 --- a/src/mongo/db/auth/sasl_mechanism_registry.cpp +++ b/src/mongo/db/auth/sasl_mechanism_registry.cpp @@ -203,7 +203,7 @@ ServiceContext::ConstructorActionRegisterer SASLServerMechanismRegistryValidatio "mechanism"_attr = mech); // Quick Exit since we are in the middle of setting up ServiceContext - quickExit(EXIT_BADOPTIONS); + quickExit(ExitCode::badOptions); } } }}; diff --git a/src/mongo/db/commands/drop_indexes.cpp b/src/mongo/db/commands/drop_indexes.cpp index 9313915c9d3..ef91b031514 100644 --- a/src/mongo/db/commands/drop_indexes.cpp +++ b/src/mongo/db/commands/drop_indexes.cpp @@ -251,7 +251,7 @@ public: if (MONGO_unlikely(reIndexCrashAfterDrop.shouldFail())) { LOGV2(20458, "Exiting because 'reIndexCrashAfterDrop' fail point was set"); - quickExit(EXIT_ABRUPT); + quickExit(ExitCode::abrupt); } // The following function performs its own WriteConflict handling, so don't wrap it in a diff --git a/src/mongo/db/commands/shutdown.cpp b/src/mongo/db/commands/shutdown.cpp index 0fa728a7c59..d0a42833deb 100644 --- a/src/mongo/db/commands/shutdown.cpp +++ b/src/mongo/db/commands/shutdown.cpp @@ -34,6 +34,7 @@ #include "mongo/db/commands/shutdown.h" #include "mongo/stdx/thread.h" #include "mongo/util/assert_util.h" +#include "mongo/util/exit_code.h" #include "mongo/util/fail_point.h" #define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kCommand @@ -79,7 +80,7 @@ void finishShutdown(OperationContext* opCtx, return; } #endif - shutdown(EXIT_CLEAN, shutdownArgs); // this never returns + shutdown(ExitCode::clean, shutdownArgs); // this never returns }) .detach(); } diff --git a/src/mongo/db/initialize_server_global_state.cpp b/src/mongo/db/initialize_server_global_state.cpp index 18c2cf45555..240c2830fcb 100644 --- a/src/mongo/db/initialize_server_global_state.cpp +++ b/src/mongo/db/initialize_server_global_state.cpp @@ -69,7 +69,7 @@ namespace mongo::initialize_server_global_state { #ifndef _WIN32 static void croak(StringData prefix, int savedErr = errno) { std::cout << prefix << ": " << errorMessage(posixError(savedErr)) << std::endl; - quickExit(EXIT_ABRUPT); + quickExit(ExitCode::abrupt); } void signalForkSuccess() { @@ -92,7 +92,7 @@ void signalForkSuccess() { "Write to child pipe failed", "errno"_attr = ec.value(), "errnoDesc"_attr = errorMessage(ec)); - quickExit(1); + quickExit(ExitCode::fail); } } else if (nw == 0) { continue; @@ -190,22 +190,22 @@ static bool forkServer() { std::cout << "about to fork child process, waiting until server is ready for connections." << std::endl; - auto waitAndPropagate = [&](pid_t pid, int signalCode, bool verbose) { + auto waitAndPropagate = [&](pid_t pid, ExitCode signalCode, bool verbose) { int pstat; if (waitpid(pid, &pstat, 0) == -1) croak("waitpid"); if (!WIFEXITED(pstat)) - quickExit(signalCode); // child died from a signal + quickExit(signalCode); if (int ec = WEXITSTATUS(pstat)) { if (verbose) std::cout << "ERROR: child process failed, exited with " << ec << std::endl << "To see additional information in this output, start without " << "the \"--fork\" option." << std::endl; - quickExit(ec); + quickExit(ExitCode::fail); } if (verbose) std::cout << "child process started successfully, parent exiting" << std::endl; - quickExit(0); + quickExit(ExitCode::clean); }; // Start in the <launcher> process. @@ -215,7 +215,7 @@ static bool forkServer() { break; default: // In the <launcher> process - waitAndPropagate(middle, 50, true); + waitAndPropagate(middle, ExitCode::launcherMiddleError, true); break; case 0: break; @@ -250,8 +250,8 @@ static bool forkServer() { if (nr == 0) // pipe reached eof without the daemon signalling readiness. // Wait for <daemon> to exit, and exit with its exit code. - waitAndPropagate(daemon, 51, false); - quickExit(0); + waitAndPropagate(daemon, ExitCode::launcherError, false); + quickExit(ExitCode::clean); } break; case 0: break; @@ -287,7 +287,7 @@ static bool forkServer() { void forkServerOrDie() { if (!forkServer()) - quickExit(EXIT_FAILURE); + quickExit(ExitCode::fail); } namespace { @@ -398,12 +398,12 @@ MONGO_INITIALIZER_GENERAL(ServerLogRedirection, * Mongo server processes cannot safely call ::exit() or std::exit(), but * some third-party libraries may call one of those functions. In that * case, to avoid static-destructor problems in the server, this exits the - * process immediately with code EXIT_FAILURE. + * process immediately with code ExitCode::fail. * * TODO: Remove once exit() executes safely in mongo server processes. */ static void shortCircuitExit() { - quickExit(EXIT_FAILURE); + quickExit(ExitCode::fail); } MONGO_INITIALIZER(RegisterShortCircuitExitHandler)(InitializerContext*) { diff --git a/src/mongo/db/mongod_main.cpp b/src/mongo/db/mongod_main.cpp index 9e53e29420f..fdf35fa7b88 100644 --- a/src/mongo/db/mongod_main.cpp +++ b/src/mongo/db/mongod_main.cpp @@ -203,6 +203,7 @@ #include "mongo/util/concurrency/thread_name.h" #include "mongo/util/exception_filter_win32.h" #include "mongo/util/exit.h" +#include "mongo/util/exit_code.h" #include "mongo/util/fail_point.h" #include "mongo/util/fast_clock_source_factory.h" #include "mongo/util/latch_analyzer.h" @@ -415,7 +416,7 @@ ExitCode _initAndListen(ServiceContext* serviceContext, int listenPort) { "Error setting up listener: {error}", "Error setting up listener", "error"_attr = res); - return EXIT_NET_ERROR; + return ExitCode::netError; } serviceContext->setTransportLayer(std::move(tl)); } @@ -437,7 +438,7 @@ ExitCode _initAndListen(ServiceContext* serviceContext, int listenPort) { #ifdef MONGO_CONFIG_WIREDTIGER_ENABLED if (EncryptionHooks::get(serviceContext)->restartRequired()) { - exitCleanly(EXIT_CLEAN); + exitCleanly(ExitCode::clean); } #endif @@ -472,14 +473,14 @@ ExitCode _initAndListen(ServiceContext* serviceContext, int listenPort) { "are not using --profile", "Running the selected storage engine with profiling is not supported", "storageEngine"_attr = storageGlobalParams.engine); - exitCleanly(EXIT_BADOPTIONS); + exitCleanly(ExitCode::badOptions); } if (storageGlobalParams.repair && replSettings.usingReplSets()) { LOGV2_ERROR(5019200, "Cannot specify both repair and replSet at the same time (remove --replSet to " "be able to --repair)"); - exitCleanly(EXIT_BADOPTIONS); + exitCleanly(ExitCode::badOptions); } logMongodStartupWarnings(storageGlobalParams, serverGlobalParams, serviceContext); @@ -506,7 +507,7 @@ ExitCode _initAndListen(ServiceContext* serviceContext, int listenPort) { "** IMPORTANT: {error}", "Wrong mongod version", "error"_attr = error.toStatus().reason()); - exitCleanly(EXIT_NEED_DOWNGRADE); + exitCleanly(ExitCode::needDowngrade); } // Ensure FCV document exists and is initialized in-memory. Fatally asserts if there is an @@ -538,7 +539,7 @@ ExitCode _initAndListen(ServiceContext* serviceContext, int listenPort) { if (storageGlobalParams.upgrade) { LOGV2(20537, "Finished checking dbs"); - exitCleanly(EXIT_CLEAN); + exitCleanly(ExitCode::clean); } // Start up health log writer thread. @@ -562,12 +563,12 @@ ExitCode _initAndListen(ServiceContext* serviceContext, int listenPort) { "Unable to verify system indexes", "error"_attr = redact(status)); if (status == ErrorCodes::AuthSchemaIncompatible) { - exitCleanly(EXIT_NEED_UPGRADE); + exitCleanly(ExitCode::needUpgrade); } else if (status == ErrorCodes::NotWritablePrimary) { // Try creating the indexes if we become primary. If we do not become primary, // the master will create the indexes and we will replicate them. } else { - quickExit(EXIT_FAILURE); + quickExit(ExitCode::fail); } } @@ -588,7 +589,7 @@ ExitCode _initAndListen(ServiceContext* serviceContext, int listenPort) { "To manually repair the 'authSchema' document in the admin.system.version " "collection, start up with --setParameter " "startupAuthSchemaValidation=false to disable validation"); - exitCleanly(EXIT_NEED_UPGRADE); + exitCleanly(ExitCode::needUpgrade); } if (foundSchemaVersion <= AuthorizationManager::schemaVersion26Final) { @@ -598,11 +599,11 @@ ExitCode _initAndListen(ServiceContext* serviceContext, int listenPort) { "removed from MongoDB 4.0. In order to upgrade the auth schema, first downgrade " "MongoDB binaries to version 3.6 and then run the authSchemaUpgrade command. See " "http://dochub.mongodb.org/core/3.0-upgrade-to-scram-sha-1"); - exitCleanly(EXIT_NEED_UPGRADE); + exitCleanly(ExitCode::needUpgrade); } } else if (globalAuthzManager->isAuthEnabled()) { LOGV2_ERROR(20569, "Auth must be disabled when starting without auth schema validation"); - exitCleanly(EXIT_BADOPTIONS); + exitCleanly(ExitCode::badOptions); } else { // If authSchemaValidation is disabled and server is running without auth, // warn the user and continue startup without authSchema metadata checks. @@ -808,7 +809,7 @@ ExitCode _initAndListen(ServiceContext* serviceContext, int listenPort) { "Error starting service entry point: {error}", "Error starting service entry point", "error"_attr = start); - return EXIT_NET_ERROR; + return ExitCode::netError; } if (!storageGlobalParams.repair) { @@ -818,12 +819,12 @@ ExitCode _initAndListen(ServiceContext* serviceContext, int listenPort) { "Error starting listener: {error}", "Error starting listener", "error"_attr = start); - return EXIT_NET_ERROR; + return ExitCode::netError; } } if (!initialize_server_global_state::writePidFile()) { - quickExit(EXIT_FAILURE); + quickExit(ExitCode::fail); } // Startup options are written to the audit log at the end of startup so that cluster server @@ -843,7 +844,7 @@ ExitCode _initAndListen(ServiceContext* serviceContext, int listenPort) { if (MONGO_unlikely(shutdownAtStartup.shouldFail())) { LOGV2(20556, "Starting clean exit via failpoint"); - exitCleanly(EXIT_CLEAN); + exitCleanly(ExitCode::clean); } MONGO_IDLE_THREAD_BLOCK; @@ -858,22 +859,22 @@ ExitCode initAndListen(ServiceContext* service, int listenPort) { "Exception in initAndListen: {error}, terminating", "DBException in initAndListen, terminating", "error"_attr = e.toString()); - return EXIT_UNCAUGHT; + return ExitCode::uncaught; } catch (std::exception& e) { LOGV2_ERROR(20558, "Exception in initAndListen std::exception: {error}, terminating", "std::exception in initAndListen, terminating", "error"_attr = e.what()); - return EXIT_UNCAUGHT; + return ExitCode::uncaught; } catch (int& n) { LOGV2_ERROR(20559, "Exception in initAndListen int: {reason}, terminating", "Exception in initAndListen, terminating", "reason"_attr = n); - return EXIT_UNCAUGHT; + return ExitCode::uncaught; } catch (...) { LOGV2_ERROR(20560, "Exception in initAndListen, terminating"); - return EXIT_UNCAUGHT; + return ExitCode::uncaught; } } @@ -969,19 +970,19 @@ void startupConfigActions(const std::vector<std::string>& args) { if (command[0].compare("dbpath") == 0) { std::cout << storageGlobalParams.dbpath << endl; - quickExit(EXIT_SUCCESS); + quickExit(ExitCode::clean); } if (command[0].compare("run") != 0) { std::cout << "Invalid command: " << command[0] << endl; printMongodHelp(moe::startupOptions); - quickExit(EXIT_FAILURE); + quickExit(ExitCode::fail); } if (command.size() > 1) { std::cout << "Too many parameters to 'run' command" << endl; printMongodHelp(moe::startupOptions); - quickExit(EXIT_FAILURE); + quickExit(ExitCode::fail); } } @@ -999,10 +1000,10 @@ void startupConfigActions(const std::vector<std::string>& args) { auto status = shutdownProcessByDBPathPidFile(storageGlobalParams.dbpath); if (!status.isOK()) { std::cerr << status.reason() << std::endl; - quickExit(EXIT_FAILURE); + quickExit(ExitCode::fail); } - quickExit(EXIT_SUCCESS); + quickExit(ExitCode::clean); } #endif } @@ -1473,7 +1474,7 @@ int mongod_main(int argc, char* argv[]) { "Error during global initialization: {error}", "Error during global initialization", "error"_attr = status); - quickExit(EXIT_FAILURE); + quickExit(ExitCode::fail); } auto* service = [] { @@ -1491,7 +1492,7 @@ int mongod_main(int argc, char* argv[]) { "Error creating service context: {error}", "Error creating service context", "error"_attr = redact(cause)); - quickExit(EXIT_FAILURE); + quickExit(ExitCode::fail); } }(); @@ -1514,7 +1515,7 @@ int mongod_main(int argc, char* argv[]) { Status err = mongo::exceptionToStatus(); LOGV2(6169900, "Error rotating audit log", "error"_attr = err); - quickExit(ExitCode::EXIT_AUDIT_ROTATE_ERROR); + quickExit(ExitCode::auditRotateError); } setUpCollectionShardingState(service); @@ -1531,7 +1532,7 @@ int mongod_main(int argc, char* argv[]) { cmdline_utils::censorArgvArray(argc, argv); if (!initialize_server_global_state::checkSocketPath()) - quickExit(EXIT_FAILURE); + quickExit(ExitCode::fail); // There is no single-threaded guarantee beyond this point. ThreadSafetyContext::getThreadSafetyContext()->allowMultiThreading(); diff --git a/src/mongo/db/mongod_options_init.cpp b/src/mongo/db/mongod_options_init.cpp index 34d0ac03e2d..8c749dff58a 100644 --- a/src/mongo/db/mongod_options_init.cpp +++ b/src/mongo/db/mongod_options_init.cpp @@ -46,7 +46,7 @@ MONGO_INITIALIZER_GENERAL(MongodOptions, ("EndStartupOptionValidation")) (InitializerContext* context) { if (!handlePreValidationMongodOptions(moe::startupOptionsParsed, context->args())) { - quickExit(EXIT_SUCCESS); + quickExit(ExitCode::clean); } // Run validation, but tell the Environment that we don't want it to be set as "valid", // since we may be making it invalid in the canonicalization process. @@ -64,7 +64,7 @@ MONGO_INITIALIZER_GENERAL(CoreOptions_Store, if (!ret.isOK()) { std::cerr << ret.toString() << std::endl; std::cerr << "try '" << context->args()[0] << " --help' for more information" << std::endl; - quickExit(EXIT_BADOPTIONS); + quickExit(ExitCode::badOptions); } } diff --git a/src/mongo/db/process_health/fault_manager.cpp b/src/mongo/db/process_health/fault_manager.cpp index 20540717347..1b8a31a0bda 100644 --- a/src/mongo/db/process_health/fault_manager.cpp +++ b/src/mongo/db/process_health/fault_manager.cpp @@ -192,7 +192,7 @@ FaultManager::FaultManager(ServiceContext* svcCtx, "Fault manager progress monitor is terminating the server", "cause"_attr = cause); // This calls the exit_group syscall on Linux - ::_exit(ExitCode::EXIT_PROCESS_HEALTH_CHECK); + ::_exit(static_cast<int>(ExitCode::processHealthCheck)); }) { invariant(_svcCtx); invariant(_svcCtx->getFastClockSource()); diff --git a/src/mongo/db/startup_recovery.cpp b/src/mongo/db/startup_recovery.cpp index b4d9b4e8fe7..bc23d3a94d5 100644 --- a/src/mongo/db/startup_recovery.cpp +++ b/src/mongo/db/startup_recovery.cpp @@ -55,6 +55,7 @@ #include "mongo/db/storage/storage_repair_observer.h" #include "mongo/logv2/log.h" #include "mongo/util/exit.h" +#include "mongo/util/exit_code.h" #include "mongo/util/fail_point.h" #include "mongo/util/quick_exit.h" @@ -457,7 +458,7 @@ void startupRepair(OperationContext* opCtx, StorageEngine* storageEngine) { if (MONGO_unlikely(exitBeforeDataRepair.shouldFail())) { LOGV2(21006, "Exiting because 'exitBeforeDataRepair' fail point was set."); - quickExit(EXIT_ABRUPT); + quickExit(ExitCode::abrupt); } // Repair, restore, and initialize the featureCompatibilityVersion document before allowing @@ -511,7 +512,7 @@ void startupRepair(OperationContext* opCtx, StorageEngine* storageEngine) { if (MONGO_unlikely(exitBeforeRepairInvalidatesConfig.shouldFail())) { LOGV2(21008, "Exiting because 'exitBeforeRepairInvalidatesConfig' fail point was set."); - quickExit(EXIT_ABRUPT); + quickExit(ExitCode::abrupt); } auto repairObserver = StorageRepairObserver::get(opCtx->getServiceContext()); diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp index 472e1225d5a..cd1bef9b1e5 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp @@ -35,6 +35,7 @@ ID, DLEVEL, {logv2::LogComponent::kReplicationRollback}, MESSAGE, ##__VA_ARGS__) #include "mongo/platform/basic.h" +#include "mongo/util/exit_code.h" #ifdef _WIN32 #define NVALGRIND @@ -725,7 +726,7 @@ void WiredTigerKVEngine::cleanShutdown() { "initialDataTimestamp and enableMajorityReadConcern is false", "stableTimestamp"_attr = stableTimestamp, "initialDataTimestamp"_attr = initialDataTimestamp); - quickExit(EXIT_SUCCESS); + quickExit(ExitCode::clean); } if (_fileVersion.shouldDowngrade(!_recoveryTimestamp.isNull())) { diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_options_init.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_options_init.cpp index 9773f267e05..d962647e91c 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_options_init.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_options_init.cpp @@ -46,7 +46,7 @@ MONGO_STARTUP_OPTIONS_STORE(WiredTigerOptions)(InitializerContext* context) { if (!ret.isOK()) { std::cerr << ret.toString() << std::endl; std::cerr << "try '" << context->args()[0] << " --help' for more information" << std::endl; - ::_exit(EXIT_BADOPTIONS); + ::_exit(static_cast<int>(ExitCode::badOptions)); } } } // namespace mongo diff --git a/src/mongo/db/traffic_reader_main.cpp b/src/mongo/db/traffic_reader_main.cpp index 5f257cf627c..59bbf795b5f 100644 --- a/src/mongo/db/traffic_reader_main.cpp +++ b/src/mongo/db/traffic_reader_main.cpp @@ -40,6 +40,7 @@ #include "mongo/base/initializer.h" #include "mongo/db/traffic_reader.h" +#include "mongo/util/exit_code.h" #include "mongo/util/signal_handlers.h" #include "mongo/util/text.h" @@ -55,7 +56,7 @@ int main(int argc, char* argv[]) { Status status = mongo::runGlobalInitializers(std::vector<std::string>(argv, argv + argc)); if (!status.isOK()) { std::cerr << "Failed global initialization: " << status << std::endl; - return EXIT_FAILURE; + return static_cast<int>(ExitCode::fail); } startSignalProcessingThread(); @@ -86,7 +87,7 @@ int main(int argc, char* argv[]) { std::cout << "Mongo Traffic Reader Help: \n\n\t./mongotrafficreader " "-i trafficinput.txt -o mongotrafficreader_dump.bson \n\n" << desc << std::endl; - return EXIT_SUCCESS; + return static_cast<int>(ExitCode::clean); } // User can specify a --input param and it must point to a valid file @@ -95,7 +96,7 @@ int main(int argc, char* argv[]) { if (!boost::filesystem::exists(inputFile.c_str())) { std::cout << "Error: Specified file does not exist (" << inputFile.c_str() << ")" << std::endl; - return EXIT_FAILURE; + return static_cast<int>(ExitCode::fail); } // Open the connection to the input file @@ -114,7 +115,7 @@ int main(int argc, char* argv[]) { outputStream.open(outputFile, std::ios::out | std::ios::trunc | std::ios::binary); if (!outputStream.is_open()) { std::cerr << "Error writing to file: " << outputFile << std::endl; - return EXIT_FAILURE; + return static_cast<int>(ExitCode::fail); } } else { // output to std::cout @@ -124,7 +125,7 @@ int main(int argc, char* argv[]) { } } catch (const boost::program_options::error& ex) { std::cerr << ex.what() << '\n'; - return EXIT_FAILURE; + return static_cast<int>(ExitCode::fail); } mongo::trafficRecordingFileToMongoReplayFile(inputFd, outputStream); diff --git a/src/mongo/dbtests/framework.cpp b/src/mongo/dbtests/framework.cpp index e6a21724981..bbc9c9f2ea8 100644 --- a/src/mongo/dbtests/framework.cpp +++ b/src/mongo/dbtests/framework.cpp @@ -58,6 +58,7 @@ #include "mongo/scripting/engine.h" #include "mongo/util/assert_util.h" #include "mongo/util/exit.h" +#include "mongo/util/exit_code.h" #include "mongo/util/periodic_runner_factory.h" #include "mongo/util/scopeguard.h" #include "mongo/util/version.h" @@ -71,7 +72,7 @@ namespace dbtests { int runDbTests(int argc, char** argv) { if (frameworkGlobalParams.suites.empty()) { LOGV2_ERROR(5733802, "The [suite] argument is required for dbtest and not specified here."); - return EXIT_FAILURE; + return static_cast<int>(ExitCode::fail); } frameworkGlobalParams.perfHist = 1; diff --git a/src/mongo/dbtests/framework_options_init.cpp b/src/mongo/dbtests/framework_options_init.cpp index ebabe8f329a..702c28589e6 100644 --- a/src/mongo/dbtests/framework_options_init.cpp +++ b/src/mongo/dbtests/framework_options_init.cpp @@ -44,7 +44,7 @@ MONGO_GENERAL_STARTUP_OPTIONS_REGISTER(FrameworkOptions)(InitializerContext* con MONGO_STARTUP_OPTIONS_VALIDATE(FrameworkOptions)(InitializerContext* context) { if (!handlePreValidationTestFrameworkOptions(moe::startupOptionsParsed, context->args())) { - quickExit(EXIT_SUCCESS); + quickExit(ExitCode::clean); } uassertStatusOK(moe::startupOptionsParsed.validate()); } @@ -54,7 +54,7 @@ MONGO_STARTUP_OPTIONS_STORE(FrameworkOptions)(InitializerContext* context) { if (!ret.isOK()) { std::cerr << ret.toString() << std::endl; std::cerr << "try '" << context->args()[0] << " --help' for more information" << std::endl; - quickExit(EXIT_BADOPTIONS); + quickExit(ExitCode::badOptions); } } diff --git a/src/mongo/embedded/embedded.cpp b/src/mongo/embedded/embedded.cpp index 907e82e655a..df5f9ab2356 100644 --- a/src/mongo/embedded/embedded.cpp +++ b/src/mongo/embedded/embedded.cpp @@ -72,6 +72,7 @@ #include "mongo/scripting/dbdirectclient_factory.h" #include "mongo/util/background.h" #include "mongo/util/exit.h" +#include "mongo/util/exit_code.h" #include "mongo/util/periodic_runner_factory.h" #include "mongo/util/quick_exit.h" #include "mongo/util/time_support.h" @@ -303,7 +304,7 @@ ServiceContext* initialize(const char* yaml_config) { logv2::LogOptions(LogComponent::kControl, logv2::FatalMode::kContinue), "** IMPORTANT: {error_toStatus_reason}", "error_toStatus_reason"_attr = error.toStatus().reason()); - quickExit(EXIT_NEED_DOWNGRADE); + quickExit(ExitCode::needDowngrade); } // Ensure FCV document exists and is initialized in-memory. Fatally asserts if there is an @@ -316,7 +317,7 @@ ServiceContext* initialize(const char* yaml_config) { if (storageGlobalParams.upgrade) { LOGV2(22553, "finished checking dbs"); - exitCleanly(EXIT_CLEAN); + exitCleanly(ExitCode::clean); } // This is for security on certain platforms (nonce generation) diff --git a/src/mongo/embedded/mongo_embedded/mongo_embedded_test.cpp b/src/mongo/embedded/mongo_embedded/mongo_embedded_test.cpp index e021e875db1..710e4fbbc2f 100644 --- a/src/mongo/embedded/mongo_embedded/mongo_embedded_test.cpp +++ b/src/mongo/embedded/mongo_embedded/mongo_embedded_test.cpp @@ -46,6 +46,7 @@ #include "mongo/unittest/temp_dir.h" #include "mongo/unittest/thread_assertion_monitor.h" #include "mongo/unittest/unittest.h" +#include "mongo/util/exit_code.h" #include "mongo/util/options_parser/environment.h" #include "mongo/util/options_parser/option_section.h" #include "mongo/util/options_parser/options_parser.h" @@ -679,14 +680,14 @@ int main(const int argc, const char* const* const argv) { auto ret = mongo::embedded::addMongoEmbeddedTestOptions(&options); if (!ret.isOK()) { std::cerr << ret << std::endl; - return EXIT_FAILURE; + return static_cast<int>(mongo::ExitCode::fail); } ret = moe::OptionsParser().run( options, std::vector<std::string>(argv, argv + argc), &environment); if (!ret.isOK()) { std::cerr << options.helpString(); - return EXIT_FAILURE; + return static_cast<int>(mongo::ExitCode::fail); } if (environment.count("tempPath")) { ::mongo::unittest::TempDir::setTempPath(environment["tempPath"].as<std::string>()); @@ -709,13 +710,13 @@ int main(const int argc, const char* const* const argv) { ret = mongo::runGlobalInitializers(std::vector<std::string>{argv, argv + argc}); if (!ret.isOK()) { std::cerr << "Global initilization failed"; - return EXIT_FAILURE; + return static_cast<int>(mongo::ExitCode::fail); } ret = mongo::runGlobalDeinitializers(); if (!ret.isOK()) { std::cerr << "Global deinitilization failed"; - return EXIT_FAILURE; + return static_cast<int>(mongo::ExitCode::fail); } // Check so we can initialize the library without providing init params @@ -724,14 +725,14 @@ int main(const int argc, const char* const* const argv) { std::cerr << "mongo_embedded_v1_init() failed with " << mongo_embedded_v1_status_get_error(status.get()) << ": " << mongo_embedded_v1_status_get_explanation(status.get()) << std::endl; - return EXIT_FAILURE; + return static_cast<int>(mongo::ExitCode::fail); } if (mongo_embedded_v1_lib_fini(lib, status.get()) != MONGO_EMBEDDED_V1_SUCCESS) { std::cerr << "mongo_embedded_v1_fini() failed with " << mongo_embedded_v1_status_get_error(status.get()) << ": " << mongo_embedded_v1_status_get_explanation(status.get()) << std::endl; - return EXIT_FAILURE; + return static_cast<int>(mongo::ExitCode::fail); } // Initialize the library with a log callback and test so we receive at least one callback @@ -784,7 +785,7 @@ int main(const int argc, const char* const* const argv) { if (!receivedCallback) { std::cerr << "Did not get a log callback." << std::endl; - return EXIT_FAILURE; + return static_cast<int>(mongo::ExitCode::fail); } const auto result = ::mongo::unittest::Suite::run(std::vector<std::string>(), "", "", 1); diff --git a/src/mongo/embedded/mongoc_embedded/mongoc_embedded_test.cpp b/src/mongo/embedded/mongoc_embedded/mongoc_embedded_test.cpp index fc67b87f200..6e6fb15509b 100644 --- a/src/mongo/embedded/mongoc_embedded/mongoc_embedded_test.cpp +++ b/src/mongo/embedded/mongoc_embedded/mongoc_embedded_test.cpp @@ -45,6 +45,7 @@ #include "mongo/logv2/log.h" #include "mongo/unittest/temp_dir.h" #include "mongo/unittest/unittest.h" +#include "mongo/util/exit_code.h" #include "mongo/util/options_parser/environment.h" #include "mongo/util/options_parser/option_section.h" #include "mongo/util/options_parser/options_parser.h" @@ -270,13 +271,13 @@ int main(int argc, char** argv) { auto ret = mongo::embedded::addMongocEmbeddedTestOptions(&options); if (!ret.isOK()) { std::cerr << ret << std::endl; - return EXIT_FAILURE; + return static_cast<int>(ExitCode::fail); } ret = parser.run(options, std::vector<std::string>(argv, argv + argc), &environment); if (!ret.isOK()) { std::cerr << options.helpString(); - return EXIT_FAILURE; + return static_cast<int>(ExitCode::fail); } if (environment.count("tempPath")) { ::mongo::unittest::TempDir::setTempPath(environment["tempPath"].as<std::string>()); @@ -290,13 +291,13 @@ int main(int argc, char** argv) { ret = mongo::runGlobalInitializers(std::vector<std::string>{}); if (!ret.isOK()) { std::cerr << "Global initilization failed"; - return EXIT_FAILURE; + return static_cast<int>(ExitCode::fail); } ret = mongo::runGlobalDeinitializers(); if (!ret.isOK()) { std::cerr << "Global deinitilization failed"; - return EXIT_FAILURE; + return static_cast<int>(ExitCode::fail); } mongo::StatusPtr status(mongo_embedded_v1_status_create()); @@ -310,14 +311,14 @@ int main(int argc, char** argv) { global_lib_handle = mongo_embedded_v1_lib_init(¶ms, status.get()); if (global_lib_handle == nullptr) { std::cerr << "Error: " << mongo_embedded_v1_status_get_explanation(status.get()); - return EXIT_FAILURE; + return static_cast<int>(ExitCode::fail); } auto result = ::mongo::unittest::Suite::run(std::vector<std::string>(), "", "", 1); if (mongo_embedded_v1_lib_fini(global_lib_handle, status.get()) != MONGO_EMBEDDED_V1_SUCCESS) { std::cerr << "Error: " << mongo_embedded_v1_status_get_explanation(status.get()); - return EXIT_FAILURE; + return static_cast<int>(ExitCode::fail); } mongoc_cleanup(); diff --git a/src/mongo/embedded/stitch_support/stitch_support_test.cpp b/src/mongo/embedded/stitch_support/stitch_support_test.cpp index fa0d4ecd55e..291771ac82e 100644 --- a/src/mongo/embedded/stitch_support/stitch_support_test.cpp +++ b/src/mongo/embedded/stitch_support/stitch_support_test.cpp @@ -36,6 +36,7 @@ #include "mongo/base/initializer.h" #include "mongo/bson/json.h" #include "mongo/unittest/unittest.h" +#include "mongo/util/exit_code.h" #include "mongo/util/quick_exit.h" #include "mongo/util/scopeguard.h" @@ -637,13 +638,13 @@ int main(const int argc, const char* const* const argv) { auto ret = mongo::runGlobalInitializers(std::vector<std::string>{argv, argv + argc}); if (!ret.isOK()) { std::cerr << "Global initilization failed"; - return EXIT_FAILURE; + return static_cast<int>(mongo::ExitCode::fail); } ret = mongo::runGlobalDeinitializers(); if (!ret.isOK()) { std::cerr << "Global deinitilization failed"; - return EXIT_FAILURE; + return static_cast<int>(mongo::ExitCode::fail); } const auto result = ::mongo::unittest::Suite::run(std::vector<std::string>(), "", "", 1); diff --git a/src/mongo/logv2/file_rotate_sink.cpp b/src/mongo/logv2/file_rotate_sink.cpp index 4070cd71610..157a6990369 100644 --- a/src/mongo/logv2/file_rotate_sink.cpp +++ b/src/mongo/logv2/file_rotate_sink.cpp @@ -40,6 +40,7 @@ #include "mongo/logv2/json_formatter.h" #include "mongo/logv2/log_detail.h" #include "mongo/logv2/shared_access_fstream.h" +#include "mongo/util/exit_code.h" #include "mongo/util/quick_exit.h" #include "mongo/util/stacktrace.h" #include "mongo/util/string_map.h" @@ -209,7 +210,7 @@ void FileRotateSink::consume(const boost::log::record_view& rec, } printStackTrace(std::cerr); - quickExitWithoutLogging(EXIT_FAILURE); + quickExitWithoutLogging(ExitCode::fail); } } diff --git a/src/mongo/logv2/logv2_test.cpp b/src/mongo/logv2/logv2_test.cpp index fdf1cadedd0..91d9327f06a 100644 --- a/src/mongo/logv2/logv2_test.cpp +++ b/src/mongo/logv2/logv2_test.cpp @@ -63,6 +63,7 @@ #include "mongo/unittest/death_test.h" #include "mongo/unittest/temp_dir.h" #include "mongo/unittest/unittest.h" +#include "mongo/util/exit_code.h" #include "mongo/util/string_map.h" #include "mongo/util/uuid.h" @@ -396,7 +397,7 @@ public: } else { // Reentrance of consume(), which could cause deadlock. Exit normally, causing the death // test to fail. - exit(0); + exit(static_cast<int>(ExitCode::clean)); } } diff --git a/src/mongo/platform/visibility_test1.cpp b/src/mongo/platform/visibility_test1.cpp index 33341d8a5e0..f52253eedd7 100644 --- a/src/mongo/platform/visibility_test1.cpp +++ b/src/mongo/platform/visibility_test1.cpp @@ -30,10 +30,12 @@ #include "mongo/platform/basic.h" #include "mongo/platform/visibility_test_lib1.h" +#include "mongo/util/exit_code.h" #include <cstdlib> int main(int argc, char* argv[]) { mongo::visibility_test_lib1::Base b("hello"); - return (b.name() == "hello") ? EXIT_SUCCESS : EXIT_FAILURE; + return (b.name() == "hello") ? static_cast<int>(mongo::ExitCode::clean) + : static_cast<int>(mongo::ExitCode::fail); } diff --git a/src/mongo/platform/visibility_test2.cpp b/src/mongo/platform/visibility_test2.cpp index baf69b36412..56621f7b167 100644 --- a/src/mongo/platform/visibility_test2.cpp +++ b/src/mongo/platform/visibility_test2.cpp @@ -30,10 +30,12 @@ #include "mongo/platform/basic.h" #include "mongo/platform/visibility_test_lib2.h" +#include "mongo/util/exit_code.h" #include <cstdlib> int main(int argc, char* argv[]) { mongo::visibility_test_lib2::Derived d("hello", argc); - return (d.value() == argc) ? EXIT_SUCCESS : EXIT_FAILURE; + return (d.value() == argc) ? static_cast<int>(mongo::ExitCode::clean) + : static_cast<int>(mongo::ExitCode::fail); } diff --git a/src/mongo/s/mongos_main.cpp b/src/mongo/s/mongos_main.cpp index 222aabccdf3..5db803ba9bd 100644 --- a/src/mongo/s/mongos_main.cpp +++ b/src/mongo/s/mongos_main.cpp @@ -108,6 +108,7 @@ #include "mongo/util/concurrency/thread_name.h" #include "mongo/util/exception_filter_win32.h" #include "mongo/util/exit.h" +#include "mongo/util/exit_code.h" #include "mongo/util/fast_clock_source_factory.h" #include "mongo/util/latch_analyzer.h" #include "mongo/util/net/ocsp/ocsp_manager.h" @@ -670,7 +671,7 @@ ExitCode runMongosServer(ServiceContext* serviceContext) { LOGV2_ERROR(6067901, "Load balancer port must be different from the normal ingress port.", "port"_attr = serverGlobalParams.port); - quickExit(EXIT_BADOPTIONS); + quickExit(ExitCode::badOptions); } auto tl = transport::TransportLayerManager::createWithConfig( @@ -681,7 +682,7 @@ ExitCode runMongosServer(ServiceContext* serviceContext) { "Error setting up listener: {error}", "Error setting up listener", "error"_attr = res); - return EXIT_NET_ERROR; + return ExitCode::netError; } serviceContext->setTransportLayer(std::move(tl)); @@ -704,7 +705,7 @@ ExitCode runMongosServer(ServiceContext* serviceContext) { DBClientReplicaSet::setAuthPooledSecondaryConn(false); if (getHostName().empty()) { - quickExit(EXIT_BADOPTIONS); + quickExit(ExitCode::badOptions); } ReadWriteConcernDefaults::create(serviceContext, readWriteConcernDefaultsCacheLookupMongoS); @@ -719,14 +720,14 @@ ExitCode runMongosServer(ServiceContext* serviceContext) { if (ex.code() == ErrorCodes::CallbackCanceled) { invariant(globalInShutdownDeprecated()); LOGV2(22850, "Shutdown called before mongos finished starting up"); - return EXIT_CLEAN; + return ExitCode::clean; } LOGV2_ERROR(22857, "Error initializing sharding system: {error}", "Error initializing sharding system", "error"_attr = redact(ex)); - return EXIT_SHARDING_ERROR; + return ExitCode::shardingError; } Grid::get(serviceContext) @@ -754,7 +755,7 @@ ExitCode runMongosServer(ServiceContext* serviceContext) { "Error initializing authorization data: {error}", "Error initializing authorization data", "error"_attr = status); - return EXIT_SHARDING_ERROR; + return ExitCode::shardingError; } // Construct the sharding uptime reporter after the startup parameters have been parsed in order @@ -782,7 +783,7 @@ ExitCode runMongosServer(ServiceContext* serviceContext) { "Error completing initial health check: {error}", "Error completing initial health check", "error"_attr = redact(status)); - return EXIT_PROCESS_HEALTH_CHECK; + return ExitCode::processHealthCheck; } SessionKiller::set(serviceContext, @@ -800,7 +801,7 @@ ExitCode runMongosServer(ServiceContext* serviceContext) { "Error starting service entry point: {error}", "Error starting service entry point", "error"_attr = redact(status)); - return EXIT_NET_ERROR; + return ExitCode::netError; } status = serviceContext->getTransportLayer()->start(); @@ -809,11 +810,11 @@ ExitCode runMongosServer(ServiceContext* serviceContext) { "Error starting transport layer: {error}", "Error starting transport layer", "error"_attr = redact(status)); - return EXIT_NET_ERROR; + return ExitCode::netError; } if (!initialize_server_global_state::writePidFile()) { - return EXIT_ABRUPT; + return ExitCode::abrupt; } // Startup options are written to the audit log at the end of startup so that cluster server @@ -872,7 +873,7 @@ ExitCode main(ServiceContext* serviceContext) { LOGV2_OPTIONS(22852, {LogComponent::kDefault}, "cannot mix localhost and ip addresses in configdbs"); - return EXIT_BADOPTIONS; + return ExitCode::badOptions; } } @@ -917,7 +918,7 @@ ExitCode mongos_main(int argc, char* argv[]) { setMongos(); if (argc < 1) - return EXIT_BADOPTIONS; + return ExitCode::badOptions; setupSignalHandlers(); @@ -930,7 +931,7 @@ ExitCode mongos_main(int argc, char* argv[]) { "Error during global initialization: {error}", "Error during global initialization", "error"_attr = status); - return EXIT_ABRUPT; + return ExitCode::abrupt; } try { @@ -946,7 +947,7 @@ ExitCode mongos_main(int argc, char* argv[]) { "Error creating service context: {error}", "Error creating service context", "error"_attr = redact(cause)); - return EXIT_ABRUPT; + return ExitCode::abrupt; } // Attempt to rotate the audit log pre-emptively on startup to avoid any potential conflicts @@ -958,7 +959,7 @@ ExitCode mongos_main(int argc, char* argv[]) { Status err = mongo::exceptionToStatus(); LOGV2(6169901, "Error rotating audit log", "error"_attr = err); - quickExit(ExitCode::EXIT_AUDIT_ROTATE_ERROR); + quickExit(ExitCode::auditRotateError); } registerShutdownTask(cleanupTask); @@ -974,7 +975,7 @@ ExitCode mongos_main(int argc, char* argv[]) { try { if (!initialize_server_global_state::checkSocketPath()) - return EXIT_ABRUPT; + return ExitCode::abrupt; startSignalProcessingThread(); @@ -984,16 +985,16 @@ ExitCode mongos_main(int argc, char* argv[]) { "uncaught DBException in mongos main: {error}", "uncaught DBException in mongos main", "error"_attr = redact(e)); - return EXIT_UNCAUGHT; + return ExitCode::uncaught; } catch (const std::exception& e) { LOGV2_ERROR(22863, "uncaught std::exception in mongos main: {error}", "uncaught std::exception in mongos main", "error"_attr = redact(e.what())); - return EXIT_UNCAUGHT; + return ExitCode::uncaught; } catch (...) { LOGV2_ERROR(22864, "uncaught unknown exception in mongos main"); - return EXIT_UNCAUGHT; + return ExitCode::uncaught; } } diff --git a/src/mongo/s/mongos_options_init.cpp b/src/mongo/s/mongos_options_init.cpp index b0c96991f52..6a1a50693d7 100644 --- a/src/mongo/s/mongos_options_init.cpp +++ b/src/mongo/s/mongos_options_init.cpp @@ -55,7 +55,7 @@ MONGO_INITIALIZER_GENERAL(MongosOptions, ("EndStartupOptionValidation")) (InitializerContext* context) { if (!handlePreValidationMongosOptions(moe::startupOptionsParsed, context->args())) { - quickExit(EXIT_SUCCESS); + quickExit(ExitCode::clean); } // Run validation, but tell the Environment that we don't want it to be set as "valid", // since we may be making it invalid in the canonicalization process. @@ -73,7 +73,7 @@ MONGO_INITIALIZER_GENERAL(CoreOptions_Store, if (!ret.isOK()) { std::cerr << ret.toString() << std::endl; std::cerr << "try '" << context->args()[0] << " --help' for more information" << std::endl; - quickExit(EXIT_BADOPTIONS); + quickExit(ExitCode::badOptions); } } diff --git a/src/mongo/scripting/mozjs/mongo.cpp b/src/mongo/scripting/mozjs/mongo.cpp index 849d74aca36..6518fb14c48 100644 --- a/src/mongo/scripting/mozjs/mongo.cpp +++ b/src/mongo/scripting/mozjs/mongo.cpp @@ -53,6 +53,7 @@ #include "mongo/scripting/mozjs/valuewriter.h" #include "mongo/scripting/mozjs/wrapconstrainedmethod.h" #include "mongo/util/assert_util.h" +#include "mongo/util/exit_code.h" #include "mongo/util/quick_exit.h" namespace mongo { @@ -696,7 +697,10 @@ void MongoExternalInfo::Functions::load::call(JSContext* cx, JS::CallArgs args) } void MongoExternalInfo::Functions::quit::call(JSContext* cx, JS::CallArgs args) { - quickExit(args.get(0).isNumber() ? args.get(0).toNumber() : 0); + auto arg = args.get(0); + quickExit(((arg.isNumber()) && (arg.toNumber() >= 0) && (arg.toNumber() <= 255)) + ? static_cast<ExitCode>(arg.toNumber()) + : ExitCode::clean); } void MongoExternalInfo::Functions::_forgetReplSet::call(JSContext* cx, JS::CallArgs args) { diff --git a/src/mongo/shell/mongo_main.cpp b/src/mongo/shell/mongo_main.cpp index 51ccb760ee7..7b1dd9dce47 100644 --- a/src/mongo/shell/mongo_main.cpp +++ b/src/mongo/shell/mongo_main.cpp @@ -74,6 +74,7 @@ #include "mongo/util/ctype.h" #include "mongo/util/errno_util.h" #include "mongo/util/exit.h" +#include "mongo/util/exit_code.h" #include "mongo/util/file.h" #include "mongo/util/net/ocsp/ocsp_manager.h" #include "mongo/util/net/ssl_options.h" @@ -306,7 +307,7 @@ void killOps() { } extern "C" void quitNicely(int sig) { - shutdown(EXIT_CLEAN); + shutdown(ExitCode::clean); } // the returned string is allocated with strdup() or malloc() and must be freed by calling free() @@ -354,7 +355,7 @@ std::string getURIFromArgs(const std::string& arg, if ((arg.find('/') != std::string::npos) && (host.size() || port.size())) { std::cerr << "If a full URI is provided, you cannot also specify --host or --port" << std::endl; - quickExit(-1); + quickExit(ExitCode::badOptions); } const auto parseDbHost = [port](const std::string& db, const std::string& host) -> std::string { @@ -422,7 +423,7 @@ std::string getURIFromArgs(const std::string& arg, std::cerr << "connection string bears different port than provided by --port" << std::endl; - quickExit(-1); + quickExit(ExitCode::badOptions); } ss << ':' << uriEncode(myport); } else if (port.size()) { @@ -900,7 +901,8 @@ int mongo_main(int argc, char* argv[]) { pids.begin(), pids.end(), std::ostream_iterator<ProcessId>(std::cout, " ")); std::cout << std::endl; - if (mongo::shell_utils::KillMongoProgramInstances() != EXIT_SUCCESS) { + if (mongo::shell_utils::KillMongoProgramInstances() != + static_cast<int>(ExitCode::clean)) { std::cout << "one more more child processes exited with an error during " << shellGlobalParams.files[i] << std::endl; std::cout << "exiting with code " << static_cast<int>(kProcessTerminationError) diff --git a/src/mongo/shell/servers.js b/src/mongo/shell/servers.js index c31bc887c69..1fbc8c04a43 100644 --- a/src/mongo/shell/servers.js +++ b/src/mongo/shell/servers.js @@ -1085,7 +1085,7 @@ MongoRunner.StopError.prototype.constructor = MongoRunner.StopError; // Constants for exit codes of MongoDB processes // On Windows, std::abort causes the process to exit with return code 14. -MongoRunner.EXIT_ABORT = _isWindows() ? 14 : -6; +MongoRunner.EXIT_ABORT = _isWindows() ? 14 : 6; MongoRunner.EXIT_CLEAN = 0; MongoRunner.EXIT_BADOPTIONS = 2; MongoRunner.EXIT_REPLICATION_ERROR = 3; @@ -1093,7 +1093,7 @@ MongoRunner.EXIT_NEED_UPGRADE = 4; MongoRunner.EXIT_SHARDING_ERROR = 5; // SIGKILL is translated to TerminateProcess() on Windows, which causes the program to // terminate with exit code 1. -MongoRunner.EXIT_SIGKILL = _isWindows() ? 1 : -9; +MongoRunner.EXIT_SIGKILL = _isWindows() ? 1 : 9; MongoRunner.EXIT_KILL = 12; MongoRunner.EXIT_ABRUPT = 14; MongoRunner.EXIT_NTSERVICE_ERROR = 20; @@ -1143,7 +1143,7 @@ var stopMongoProgram = function(conn, signal, opts, waitpid) { "it is usually the object returned from MongoRunner.runMongod/s"); } - signal = parseInt(signal) || 15; + signal = parseInt(signal) || SIGTERM; opts = opts || {}; waitpid = (waitpid === undefined) ? true : waitpid; diff --git a/src/mongo/shell/shell_options_init.cpp b/src/mongo/shell/shell_options_init.cpp index b89b024a2b6..6924eaa1954 100644 --- a/src/mongo/shell/shell_options_init.cpp +++ b/src/mongo/shell/shell_options_init.cpp @@ -40,7 +40,7 @@ namespace mongo { MONGO_STARTUP_OPTIONS_VALIDATE(MongoShellOptions)(InitializerContext* context) { if (!handlePreValidationMongoShellOptions(moe::startupOptionsParsed, context->args())) { - quickExit(EXIT_SUCCESS); + quickExit(ExitCode::clean); } uassertStatusOK(moe::startupOptionsParsed.validate()); } @@ -50,7 +50,7 @@ MONGO_STARTUP_OPTIONS_STORE(MongoShellOptions)(InitializerContext* context) { if (!ret.isOK()) { std::cerr << ret.toString() << std::endl; std::cerr << "try '" << context->args()[0] << " --help' for more information" << std::endl; - quickExit(EXIT_BADOPTIONS); + quickExit(ExitCode::badOptions); } } } // namespace mongo diff --git a/src/mongo/shell/shell_utils_launcher.cpp b/src/mongo/shell/shell_utils_launcher.cpp index 6518ec284c0..195dc6b19f9 100644 --- a/src/mongo/shell/shell_utils_launcher.cpp +++ b/src/mongo/shell/shell_utils_launcher.cpp @@ -72,6 +72,7 @@ #include "mongo/util/ctype.h" #include "mongo/util/destructor_guard.h" #include "mongo/util/exit.h" +#include "mongo/util/exit_code.h" #include "mongo/util/net/hostandport.h" #include "mongo/util/quick_exit.h" #include "mongo/util/scopeguard.h" @@ -304,7 +305,7 @@ bool ProgramRegistry::waitForPid(const ProcessId pid, const bool block, int* con if (WIFEXITED(status)) { code = WEXITSTATUS(status); } else if (WIFSIGNALED(status)) { - code = -WTERMSIG(status); + code = WTERMSIG(status); } else { MONGO_UNREACHABLE; } @@ -821,7 +822,7 @@ void ProgramRunner::launchProcess(int child_stdout) { if (dup2(child_stdout, STDOUT_FILENO) == -1 || dup2(child_stdout, STDERR_FILENO) == -1) { // Async signal unsafe code reporting a terminal error condition. perror("Unable to dup2 child output: "); - _exit(-1); // do not pass go, do not call atexit handlers + _exit(static_cast<int>(ExitCode::fail)); // do not pass go, do not call atexit handlers } execve(argvStorage[0], @@ -831,7 +832,7 @@ void ProgramRunner::launchProcess(int child_stdout) { // Async signal unsafe code reporting a terminal error condition. perror(execErrMsg.c_str()); - _exit(-1); + _exit(static_cast<int>(ExitCode::fail)); } #endif @@ -1146,13 +1147,13 @@ int killDb(int port, ProcessId _pid, int signal, const BSONObj& opt, bool waitPi return 0; } - int exitCode = EXIT_FAILURE; + int exitCode = static_cast<int>(ExitCode::fail); try { LOGV2_INFO(22819, "Waiting for process to terminate.", "pid"_attr = pid); registry.waitForPid(pid, true, &exitCode); } catch (...) { LOGV2_WARNING(22828, "Process failed to terminate.", "pid"_attr = pid); - return EXIT_FAILURE; + return static_cast<int>(ExitCode::fail); } if (signal == SIGKILL) { @@ -1244,11 +1245,11 @@ BSONObj ConvertTrafficRecordingToBSON(const BSONObj& a, void* data) { int KillMongoProgramInstances() { vector<ProcessId> pids; registry.getRegisteredPids(pids); - int returnCode = EXIT_SUCCESS; + int returnCode = static_cast<int>(ExitCode::clean); for (auto&& pid : pids) { int port = registry.portForPid(pid); int code = killDb(port != -1 ? port : 0, pid, SIGTERM); - if (code != EXIT_SUCCESS) { + if (code != static_cast<int>(ExitCode::clean)) { LOGV2_INFO( 22823, "Process exited with error code", "pid"_attr = pid, "code"_attr = code); returnCode = code; diff --git a/src/mongo/stdx/set_terminate_dispatch_test.cpp b/src/mongo/stdx/set_terminate_dispatch_test.cpp index b796fc257a3..41338ad619e 100644 --- a/src/mongo/stdx/set_terminate_dispatch_test.cpp +++ b/src/mongo/stdx/set_terminate_dispatch_test.cpp @@ -34,6 +34,7 @@ #include <iostream> #include "mongo/stdx/thread.h" +#include "mongo/util/exit_code.h" namespace { @@ -41,7 +42,7 @@ namespace stdx = ::mongo::stdx; void writeFeedbackAndCleanlyExit() { std::cout << "Entered terminate handler." << std::endl; - exit(EXIT_SUCCESS); + exit(static_cast<int>(mongo::ExitCode::clean)); } void testTerminateDispatch() { @@ -49,11 +50,11 @@ void testTerminateDispatch() { stdx::set_terminate(writeFeedbackAndCleanlyExit); std::cout << "Calling terminate." << std::endl; std::terminate(); - exit(EXIT_FAILURE); + exit(static_cast<int>(mongo::ExitCode::fail)); } } // namespace int main() { testTerminateDispatch(); - return EXIT_FAILURE; + return static_cast<int>(mongo::ExitCode::fail); } diff --git a/src/mongo/stdx/set_terminate_from_main_die_in_thread_test.cpp b/src/mongo/stdx/set_terminate_from_main_die_in_thread_test.cpp index f887039e95c..bb58459b597 100644 --- a/src/mongo/stdx/set_terminate_from_main_die_in_thread_test.cpp +++ b/src/mongo/stdx/set_terminate_from_main_die_in_thread_test.cpp @@ -34,6 +34,7 @@ #include <iostream> #include "mongo/stdx/thread.h" +#include "mongo/util/exit_code.h" namespace { @@ -41,7 +42,7 @@ namespace stdx = ::mongo::stdx; void writeFeedbackAndCleanlyExit() { std::cout << "Entered terminate handler." << std::endl; - exit(EXIT_SUCCESS); + exit(static_cast<int>(mongo::ExitCode::clean)); } void testTerminateDispatch() { @@ -53,11 +54,11 @@ void testTerminateDispatch() { std::terminate(); }} .join(); - exit(EXIT_FAILURE); + exit(static_cast<int>(mongo::ExitCode::fail)); } } // namespace int main() { testTerminateDispatch(); - return EXIT_FAILURE; + return static_cast<int>(mongo::ExitCode::fail); } diff --git a/src/mongo/stdx/set_terminate_from_thread_die_in_main_test.cpp b/src/mongo/stdx/set_terminate_from_thread_die_in_main_test.cpp index 54a043073ce..2b251e00c55 100644 --- a/src/mongo/stdx/set_terminate_from_thread_die_in_main_test.cpp +++ b/src/mongo/stdx/set_terminate_from_thread_die_in_main_test.cpp @@ -34,6 +34,7 @@ #include <iostream> #include "mongo/stdx/thread.h" +#include "mongo/util/exit_code.h" namespace { @@ -41,7 +42,7 @@ namespace stdx = ::mongo::stdx; void writeFeedbackAndCleanlyExit() { std::cout << "Entered terminate handler." << std::endl; - exit(EXIT_SUCCESS); + exit(static_cast<int>(mongo::ExitCode::clean)); } void testTerminateDispatch() { @@ -53,11 +54,11 @@ void testTerminateDispatch() { .join(); std::cout << "Calling terminate." << std::endl; std::terminate(); - exit(EXIT_FAILURE); + exit(static_cast<int>(mongo::ExitCode::fail)); } } // namespace int main() { testTerminateDispatch(); - return EXIT_FAILURE; + return static_cast<int>(mongo::ExitCode::fail); } diff --git a/src/mongo/stdx/set_terminate_from_thread_die_in_thread_test.cpp b/src/mongo/stdx/set_terminate_from_thread_die_in_thread_test.cpp index 119d5b44c5d..6bd5f0bffea 100644 --- a/src/mongo/stdx/set_terminate_from_thread_die_in_thread_test.cpp +++ b/src/mongo/stdx/set_terminate_from_thread_die_in_thread_test.cpp @@ -34,6 +34,7 @@ #include <iostream> #include "mongo/stdx/thread.h" +#include "mongo/util/exit_code.h" namespace { @@ -41,7 +42,7 @@ namespace stdx = ::mongo::stdx; void writeFeedbackAndCleanlyExit() { std::cout << "Entered terminate handler." << std::endl; - exit(EXIT_SUCCESS); + exit(static_cast<int>(mongo::ExitCode::clean)); } void testTerminateDispatch() { @@ -57,11 +58,11 @@ void testTerminateDispatch() { std::terminate(); }} .join(); - exit(EXIT_FAILURE); + exit(static_cast<int>(mongo::ExitCode::fail)); } } // namespace int main() { testTerminateDispatch(); - return EXIT_FAILURE; + return static_cast<int>(mongo::ExitCode::fail); } diff --git a/src/mongo/stdx/sigaltstack_location_test.cpp b/src/mongo/stdx/sigaltstack_location_test.cpp index 7fdc474dc74..e65b46cdfd8 100644 --- a/src/mongo/stdx/sigaltstack_location_test.cpp +++ b/src/mongo/stdx/sigaltstack_location_test.cpp @@ -28,6 +28,7 @@ */ #include "mongo/stdx/thread.h" +#include "mongo/util/exit_code.h" #include <condition_variable> #include <exception> @@ -47,7 +48,7 @@ int main() { std::cout << "`sigaltstack` testing skipped on this platform." << std::endl; - return EXIT_SUCCESS; + return static_cast<int>(mongo::ExitCode::clean); } #else // MONGO_HAS_SIGALTSTACK @@ -66,7 +67,7 @@ void unblockSignal(int sig) { sigaddset(&sigset, sig); if (sigprocmask(SIG_UNBLOCK, &sigset, nullptr)) { perror("sigprocmask"); - exit(EXIT_FAILURE); + exit(static_cast<int>(mongo::ExitCode::fail)); } } @@ -80,7 +81,7 @@ void installAction(int sig, sigAction_t* action) { sigemptyset(&sa.sa_mask); if (sigaction(sig, &sa, nullptr)) { perror("sigaction"); - exit(EXIT_FAILURE); + exit(static_cast<int>(mongo::ExitCode::fail)); } } @@ -133,7 +134,7 @@ int stackLocationTest() { if (stackLocationTestChildInfo.ss.ss_flags & SS_DISABLE) { std::cerr << "Child thread unexpectedly had sigaltstack disabled." << std::endl; - exit(EXIT_FAILURE); + exit(static_cast<int>(mongo::ExitCode::fail)); } uintptr_t altStackBegin = reinterpret_cast<uintptr_t>(stackLocationTestChildInfo.ss.ss_sp); @@ -147,9 +148,9 @@ int stackLocationTest() { if (handlerLocal < altStackBegin || handlerLocal >= altStackEnd) { std::cerr << "Handler local address " << Hex(handlerLocal) << " was outside of: [" << Hex(altStackBegin) << ", " << Hex(altStackEnd) << ")" << std::endl; - exit(EXIT_FAILURE); + exit(static_cast<int>(mongo::ExitCode::fail)); } - return EXIT_SUCCESS; + return static_cast<int>(mongo::ExitCode::clean); } static sigjmp_buf sigjmp; @@ -218,7 +219,7 @@ int recursionTestImpl(bool useSigAltStack) { } }); childThread.join(); - return EXIT_SUCCESS; + return static_cast<int>(mongo::ExitCode::clean); } /** @@ -236,7 +237,7 @@ int recursionTest() { int recursionDeathTest() { if (pid_t kidPid = fork(); kidPid == -1) { perror("fork"); - return EXIT_FAILURE; + return static_cast<int>(mongo::ExitCode::fail); } else if (kidPid == 0) { // Child process: run the recursion test with no sigaltstack protection. return recursionTestImpl(false); @@ -245,22 +246,22 @@ int recursionDeathTest() { int wstatus; if (pid_t waited = waitpid(kidPid, &wstatus, 0); waited == -1) { perror("waitpid"); - return EXIT_FAILURE; + return static_cast<int>(mongo::ExitCode::fail); } if (WIFEXITED(wstatus)) { std::cerr << "child unexpectedly exited with: " << WEXITSTATUS(wstatus) << std::endl; - return EXIT_FAILURE; + return static_cast<int>(mongo::ExitCode::fail); } if (!WIFSIGNALED(wstatus)) { std::cerr << "child did not die from a signal" << std::endl; - return EXIT_FAILURE; + return static_cast<int>(mongo::ExitCode::fail); } int kidSignal = WTERMSIG(wstatus); if (kidSignal != SIGSEGV) { std::cerr << "child died from the wrong signal: " << kidSignal << std::endl; - return EXIT_FAILURE; + return static_cast<int>(mongo::ExitCode::fail); } - return EXIT_SUCCESS; + return static_cast<int>(mongo::ExitCode::clean); } } @@ -283,13 +284,13 @@ int runTests() { }; for (auto& test : kTests) { std::cout << "\n===== " << test.name << " begin:" << std::endl; - if (int r = test.func(); r != EXIT_SUCCESS) { + if (int r = test.func(); r != static_cast<int>(mongo::ExitCode::clean)) { std::cout << test.name << " FAIL" << std::endl; return r; } std::cout << "===== " << test.name << " PASS" << std::endl; } - return EXIT_SUCCESS; + return static_cast<int>(mongo::ExitCode::clean); } } // namespace diff --git a/src/mongo/tools/bridge.cpp b/src/mongo/tools/bridge.cpp index a95b98f1be7..b4ffd1f9a21 100644 --- a/src/mongo/tools/bridge.cpp +++ b/src/mongo/tools/bridge.cpp @@ -509,16 +509,16 @@ int bridgeMain(int argc, char** argv) { if (auto status = serviceContext->getTransportLayer()->setup(); !status.isOK()) { LOGV2(22922, "Error setting up transport layer", "error"_attr = status); - return EXIT_NET_ERROR; + return static_cast<int>(ExitCode::netError); } if (auto status = serviceContext->getTransportLayer()->start(); !status.isOK()) { LOGV2(22923, "Error starting transport layer", "error"_attr = status); - return EXIT_NET_ERROR; + return static_cast<int>(ExitCode::netError); } serviceContext->notifyStartupComplete(); - return waitForShutdown(); + return static_cast<int>(waitForShutdown()); } } // namespace mongo diff --git a/src/mongo/tools/mongobridge_options_init.cpp b/src/mongo/tools/mongobridge_options_init.cpp index f27a73c6aeb..f0023ed7c10 100644 --- a/src/mongo/tools/mongobridge_options_init.cpp +++ b/src/mongo/tools/mongobridge_options_init.cpp @@ -41,7 +41,7 @@ namespace mongo { MONGO_STARTUP_OPTIONS_VALIDATE(MongoBridgeOptions)(InitializerContext* context) { if (!handlePreValidationMongoBridgeOptions(moe::startupOptionsParsed)) { - quickExit(EXIT_SUCCESS); + quickExit(ExitCode::clean); } uassertStatusOK(moe::startupOptionsParsed.validate()); } @@ -51,7 +51,7 @@ MONGO_STARTUP_OPTIONS_STORE(MongoBridgeOptions)(InitializerContext* context) { if (!ret.isOK()) { std::cerr << ret.toString() << std::endl; std::cerr << "try '" << context->args()[0] << " --help' for more information" << std::endl; - quickExit(EXIT_BADOPTIONS); + quickExit(ExitCode::badOptions); } if (moe::startupOptionsParsed.count("net.compression.compressors")) { @@ -59,7 +59,7 @@ MONGO_STARTUP_OPTIONS_STORE(MongoBridgeOptions)(InitializerContext* context) { moe::startupOptionsParsed["net.compression.compressors"].as<std::string>()); if (!ret.isOK()) { std::cerr << ret.toString() << std::endl; - quickExit(EXIT_BADOPTIONS); + quickExit(ExitCode::badOptions); } } } diff --git a/src/mongo/unittest/death_test.cpp b/src/mongo/unittest/death_test.cpp index 40dc410aa22..d7f48112953 100644 --- a/src/mongo/unittest/death_test.cpp +++ b/src/mongo/unittest/death_test.cpp @@ -292,7 +292,7 @@ void DeathTestBase::Subprocess::monitorChild(FILE* pf) { if (WIFSIGNALED(stat) || (WIFEXITED(stat) && WEXITSTATUS(stat) != 0)) { // Exited with a signal or non-zero code. Validate the expected message. #if defined(TSAN_ENABLED_) - if (WEXITSTATUS(stat) == EXIT_THREAD_SANITIZER) { + if (WEXITSTATUS(stat) == static_cast<int>(ExitCode::threadSanitizer)) { FAIL( "Death test exited with Thread Sanitizer exit code, search test output for " "'ThreadSanitizer' for more information"); @@ -330,7 +330,7 @@ void DeathTestBase::Subprocess::prepareChild(int (&pipes)[2]) { // Our callback handler exits with the default TSAN exit code so we can check in the death test // framework Without this, the use could override the exit code and get a false positive that // the test passes in TSAN builds. - __sanitizer_set_death_callback(+[] { _exit(EXIT_THREAD_SANITIZER); }); + __sanitizer_set_death_callback(+[] { _exit(static_cast<int>(ExitCode::threadSanitizer)); }); #endif } @@ -347,7 +347,7 @@ void DeathTestBase::Subprocess::invokeTest() { } // To fail the test, we must exit with a successful error code, because the parent process // is checking for the child to die with an exit code indicating an error. - quickExit(EXIT_SUCCESS); + quickExit(ExitCode::clean); } #endif // DEATH_TEST_ENABLED diff --git a/src/mongo/unittest/integration_test_main.cpp b/src/mongo/unittest/integration_test_main.cpp index d508b550c25..8dd2949fc6f 100644 --- a/src/mongo/unittest/integration_test_main.cpp +++ b/src/mongo/unittest/integration_test_main.cpp @@ -46,6 +46,7 @@ #include "mongo/logv2/log.h" #include "mongo/transport/transport_layer_asio.h" #include "mongo/unittest/unittest.h" +#include "mongo/util/exit_code.h" #include "mongo/util/options_parser/environment.h" #include "mongo/util/options_parser/option_section.h" #include "mongo/util/options_parser/options_parser.h" @@ -114,7 +115,7 @@ MONGO_STARTUP_OPTIONS_VALIDATE(IntegrationTestOptions)(InitializerContext*) { if (env.count("help")) { std::cout << opts.helpString() << std::endl; - quickExit(EXIT_SUCCESS); + quickExit(ExitCode::clean); } } diff --git a/src/mongo/unittest/unittest.cpp b/src/mongo/unittest/unittest.cpp index 55956771d9a..cca577e3e87 100644 --- a/src/mongo/unittest/unittest.cpp +++ b/src/mongo/unittest/unittest.cpp @@ -54,6 +54,7 @@ #include "mongo/logv2/plain_formatter.h" #include "mongo/platform/mutex.h" #include "mongo/util/assert_util.h" +#include "mongo/util/exit_code.h" #include "mongo/util/pcre.h" #include "mongo/util/signal_handlers_synchronous.h" #include "mongo/util/stacktrace.h" @@ -478,7 +479,7 @@ int Suite::run(const std::vector<std::string>& suites, int runsPerTest) { if (suitesMap().empty()) { LOGV2_ERROR(23061, "no suites registered."); - return EXIT_FAILURE; + return static_cast<int>(ExitCode::fail); } for (unsigned int i = 0; i < suites.size(); i++) { @@ -486,7 +487,7 @@ int Suite::run(const std::vector<std::string>& suites, LOGV2_ERROR(23062, "invalid test suite, use --list to see valid names", "suite"_attr = suites[i]); - return EXIT_FAILURE; + return static_cast<int>(ExitCode::fail); } } diff --git a/src/mongo/unittest/unittest_main.cpp b/src/mongo/unittest/unittest_main.cpp index 063a086a047..bb0c6692ba7 100644 --- a/src/mongo/unittest/unittest_main.cpp +++ b/src/mongo/unittest/unittest_main.cpp @@ -42,6 +42,7 @@ #include "mongo/unittest/temp_dir.h" #include "mongo/unittest/unittest.h" #include "mongo/unittest/unittest_options_gen.h" +#include "mongo/util/exit_code.h" #include "mongo/util/options_parser/environment.h" #include "mongo/util/options_parser/option_section.h" #include "mongo/util/options_parser/options_parser.h" @@ -77,7 +78,7 @@ int main(int argc, char** argv) { Status status = mongo::unittest::addUnitTestOptions(&options); if (!status.isOK()) { std::cerr << status; - return EXIT_FAILURE; + return static_cast<int>(mongo::ExitCode::fail); } moe::OptionsParser parser; @@ -85,7 +86,7 @@ int main(int argc, char** argv) { Status ret = parser.run(options, argVec, &environment); if (!ret.isOK()) { std::cerr << options.helpString(); - return EXIT_FAILURE; + return static_cast<int>(mongo::ExitCode::fail); } bool list = false; @@ -116,7 +117,7 @@ int main(int argc, char** argv) { std::cerr << "The string for the --verbose option cannot contain characters other than 'v'" << std::endl; std::cerr << options.helpString(); - return EXIT_FAILURE; + return static_cast<int>(mongo::ExitCode::fail); } mongo::unittest::setMinimumLoggedSeverity(mongo::logv2::LogSeverity::Debug(verbose.size())); @@ -125,7 +126,7 @@ int main(int argc, char** argv) { for (auto name : suiteNames) { std::cout << name << std::endl; } - return EXIT_SUCCESS; + return static_cast<int>(mongo::ExitCode::clean); } auto result = ::mongo::unittest::Suite::run(suites, filter, fileNameFilter, repeat); diff --git a/src/mongo/util/assert_util.cpp b/src/mongo/util/assert_util.cpp index 4bcbc0be155..1f7b1e30b14 100644 --- a/src/mongo/util/assert_util.cpp +++ b/src/mongo/util/assert_util.cpp @@ -225,7 +225,7 @@ MONGO_COMPILER_NOINLINE void fassertFailedNoTraceWithLocation(int msgid, "line"_attr = line); breakpoint(); LOGV2_FATAL_CONTINUE(23092, "\n\n***aborting after fassert() failure\n\n"); - quickExit(EXIT_ABRUPT); + quickExit(ExitCode::abrupt); } MONGO_COMPILER_NORETURN void fassertFailedWithStatusWithLocation(int msgid, @@ -257,7 +257,7 @@ MONGO_COMPILER_NORETURN void fassertFailedWithStatusNoTraceWithLocation(int msgi "line"_attr = line); breakpoint(); LOGV2_FATAL_CONTINUE(23096, "\n\n***aborting after fassert() failure\n\n"); - quickExit(EXIT_ABRUPT); + quickExit(ExitCode::abrupt); } MONGO_COMPILER_NOINLINE void uassertedWithLocation(const Status& status, diff --git a/src/mongo/util/assert_util_test.cpp b/src/mongo/util/assert_util_test.cpp index ff2f0243aef..5b5816105d2 100644 --- a/src/mongo/util/assert_util_test.cpp +++ b/src/mongo/util/assert_util_test.cpp @@ -37,6 +37,7 @@ #include "mongo/unittest/death_test.h" #include "mongo/unittest/unittest.h" #include "mongo/util/assert_util.h" +#include "mongo/util/exit_code.h" #include "mongo/util/quick_exit.h" #include "mongo/util/str.h" @@ -325,7 +326,7 @@ DEATH_TEST_REGEX(TassertTerminationTest, tassertUncleanLogMsg, "4457002.*Detected prior failed tripwire assertions") { doTassert(); - quickExit(EXIT_ABRUPT); + quickExit(ExitCode::abrupt); } DEATH_TEST(TassertTerminationTest, mongoUnreachableNonFatal, "Hit a MONGO_UNREACHABLE_TASSERT!") { diff --git a/src/mongo/util/exception_filter_win32.cpp b/src/mongo/util/exception_filter_win32.cpp index 8f91797b8d1..54ca6717400 100644 --- a/src/mongo/util/exception_filter_win32.cpp +++ b/src/mongo/util/exception_filter_win32.cpp @@ -193,7 +193,7 @@ LONG WINAPI exceptionFilter(struct _EXCEPTION_POINTERS* excPointers) { // Don't go through normal shutdown procedure. It may make things worse. // Do not go through _exit or ExitProcess(), terminate immediately LOGV2_FATAL_CONTINUE(23137, "*** immediate exit due to unhandled exception"); - TerminateProcess(GetCurrentProcess(), EXIT_ABRUPT); + TerminateProcess(GetCurrentProcess(), static_cast<UINT>(ExitCode::abrupt)); // We won't reach here return EXCEPTION_EXECUTE_HANDLER; diff --git a/src/mongo/util/exit.cpp b/src/mongo/util/exit.cpp index 6352fc1dd52..14359a797f9 100644 --- a/src/mongo/util/exit.cpp +++ b/src/mongo/util/exit.cpp @@ -31,6 +31,7 @@ #include "mongo/platform/basic.h" #include "mongo/util/exit.h" +#include "mongo/util/exit_code.h" #include <boost/optional.hpp> #include <functional> @@ -40,6 +41,7 @@ #include "mongo/platform/mutex.h" #include "mongo/stdx/condition_variable.h" #include "mongo/stdx/thread.h" +#include "mongo/util/assert_util.h" #include "mongo/util/quick_exit.h" #define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kControl @@ -173,7 +175,7 @@ void shutdownNoTerminate(const ShutdownTaskArgs& shutdownArgs) { { stdx::lock_guard<Latch> lock(shutdownMutex); shutdownTasksInProgress = false; - shutdownExitCode.emplace(EXIT_CLEAN); + shutdownExitCode.emplace(ExitCode::clean); } shutdownTasksComplete.notify_all(); diff --git a/src/mongo/util/exit_code.h b/src/mongo/util/exit_code.h index d34c7e388ab..313fe0fbc68 100644 --- a/src/mongo/util/exit_code.h +++ b/src/mongo/util/exit_code.h @@ -35,32 +35,39 @@ namespace mongo { -enum ExitCode : int { - EXIT_CLEAN = 0, - EXIT_BADOPTIONS = 2, - EXIT_REPLICATION_ERROR = 3, - EXIT_NEED_UPGRADE = 4, - EXIT_SHARDING_ERROR = 5, - EXIT_KILL = 12, - EXIT_ABRUPT = 14, - EXIT_NTSERVICE_ERROR = 20, - EXIT_JAVA = 21, - EXIT_OOM_MALLOC = 42, - EXIT_OOM_REALLOC = 43, - EXIT_FS = 45, - EXIT_CLOCK_SKEW = 47, // OpTime clock skew, deprecated - EXIT_NET_ERROR = 48, - EXIT_WINDOWS_SERVICE_STOP = 49, - EXIT_POSSIBLE_CORRUPTION = - 60, // this means we detected a possible corruption situation, like a buf overflow - EXIT_WATCHDOG = 61, // Internal Watchdog has terminated mongod - EXIT_NEED_DOWNGRADE = - 62, // The current binary version is not appropriate to run on the existing datafiles. - EXIT_THREAD_SANITIZER = 66, // Default Exit code for Thread Sanitizer failures - EXIT_PROCESS_HEALTH_CHECK = 67, // Process health check triggered the crash. - EXIT_UNCAUGHT = 100, // top level exception that wasn't caught - EXIT_TEST = 101, - EXIT_AUDIT_ROTATE_ERROR = 102 // The startup rotation of audit logs failed +enum class ExitCode { + clean = 0, + fail = 1, + badOptions = 2, + replicationError = 3, + needUpgrade = 4, + shardingError = 5, + kill = 12, + abrupt = 14, +#ifdef _WIN32 + ntServiceError = 20, +#endif // _WIN32 + java [[deprecated]] = 21, + oomMalloc [[deprecated]] = 42, + oomRealloc [[deprecated]] = 43, + fs [[deprecated]] = 45, + clockSkew [[deprecated]] = 47, // OpTime + netError = 48, +#ifdef _WIN32 + windowsServiceStop [[deprecated]] = 49, +#endif // _WIN32 + launcherMiddleError = 50, + launcherError = 51, + possibleCorruption [[deprecated]] = 60, // e.g. buffer overflow + watchdog = 61, // Internal Watchdog has terminated mongod + needDowngrade = 62, // This exe can't use the existing data files + reservedBegin = 64, // FreeBSD uses this range. Avoiding to prevent confusion. + reservedEnd = 78, // FreeBSD uses this range. Avoiding to prevent confusion. + threadSanitizer = 86, // Default exit code for Thread Sanitizer failures + processHealthCheck = 87, // Process health check triggered the crash. + uncaught = 100, // top level exception that wasn't caught + test [[deprecated]] = 101, + auditRotateError = 102 // The startup rotation of audit logs failed }; } // namespace mongo diff --git a/src/mongo/util/net/socket_utils.cpp b/src/mongo/util/net/socket_utils.cpp index e0d74e40986..4d877c3e06e 100644 --- a/src/mongo/util/net/socket_utils.cpp +++ b/src/mongo/util/net/socket_utils.cpp @@ -76,7 +76,7 @@ const struct WinsockInit { "ERROR: wsastartup failed {error}", "ERROR: wsastartup failed", "error"_attr = errorMessage(systemError(e))); - quickExit(EXIT_NTSERVICE_ERROR); + quickExit(ExitCode::ntServiceError); } } } winsock_init; diff --git a/src/mongo/util/ntservice.cpp b/src/mongo/util/ntservice.cpp index fe3507f3693..46dc56ce38c 100644 --- a/src/mongo/util/ntservice.cpp +++ b/src/mongo/util/ntservice.cpp @@ -42,6 +42,7 @@ #include "mongo/stdx/thread.h" #include "mongo/util/assert_util.h" #include "mongo/util/exit.h" +#include "mongo/util/exit_code.h" #include "mongo/util/options_parser/environment.h" #include "mongo/util/quick_exit.h" #include "mongo/util/signal_handlers.h" @@ -112,12 +113,12 @@ void configureService(ServiceCallback serviceCallback, LOGV2(23287, "--install cannot be used with option", "option"_attr = disallowedOptions[badOption]); - quickExit(EXIT_BADOPTIONS); + quickExit(ExitCode::badOptions); } if (!params.count("systemLog.destination") || params["systemLog.destination"].as<std::string>() != "file") { LOGV2(23288, "--install has to be used with a log file for server output"); - quickExit(EXIT_BADOPTIONS); + quickExit(ExitCode::badOptions); } installService = true; } @@ -126,12 +127,12 @@ void configureService(ServiceCallback serviceCallback, LOGV2(23289, "--reinstall cannot be used with option", "option"_attr = disallowedOptions[badOption]); - quickExit(EXIT_BADOPTIONS); + quickExit(ExitCode::badOptions); } if (!params.count("systemLog.destination") || params["systemLog.destination"].as<std::string>() != "file") { LOGV2(23290, "--reinstall has to be used with a log file for server output"); - quickExit(EXIT_BADOPTIONS); + quickExit(ExitCode::badOptions); } reinstallService = true; } @@ -140,7 +141,7 @@ void configureService(ServiceCallback serviceCallback, LOGV2(23291, "--remove cannot be used with option", "option"_attr = disallowedOptions[badOption]); - quickExit(EXIT_BADOPTIONS); + quickExit(ExitCode::badOptions); } removeService = true; } @@ -149,7 +150,7 @@ void configureService(ServiceCallback serviceCallback, LOGV2(23292, "--service cannot be used with option", "option"_attr = disallowedOptions[badOption]); - quickExit(EXIT_BADOPTIONS); + quickExit(ExitCode::badOptions); } _startService = true; } @@ -159,7 +160,7 @@ void configureService(ServiceCallback serviceCallback, LOGV2(23293, "--serviceName cannot be used with option", "option"_attr = disallowedOptions[badOption]); - quickExit(EXIT_BADOPTIONS); + quickExit(ExitCode::badOptions); } _serviceName = toWideString( params["processManagement.windowsService.serviceName"].as<string>().c_str()); @@ -169,7 +170,7 @@ void configureService(ServiceCallback serviceCallback, LOGV2(23294, "--serviceDisplayName cannot be used with option", "option"_attr = disallowedOptions[badOption]); - quickExit(EXIT_BADOPTIONS); + quickExit(ExitCode::badOptions); } windowsServiceDisplayName = toWideString( params["processManagement.windowsService.displayName"].as<string>().c_str()); @@ -179,7 +180,7 @@ void configureService(ServiceCallback serviceCallback, LOGV2(23295, "--serviceDescription cannot be used with option", "option"_attr = disallowedOptions[badOption]); - quickExit(EXIT_BADOPTIONS); + quickExit(ExitCode::badOptions); } windowsServiceDescription = toWideString( params["processManagement.windowsService.description"].as<string>().c_str()); @@ -189,7 +190,7 @@ void configureService(ServiceCallback serviceCallback, LOGV2(23296, "--serviceUser cannot be used with option", "option"_attr = disallowedOptions[badOption]); - quickExit(EXIT_BADOPTIONS); + quickExit(ExitCode::badOptions); } windowsServiceUser = toWideString( params["processManagement.windowsService.serviceUser"].as<string>().c_str()); @@ -199,7 +200,7 @@ void configureService(ServiceCallback serviceCallback, LOGV2(23297, "--servicePassword cannot be used with option", "option"_attr = disallowedOptions[badOption]); - quickExit(EXIT_BADOPTIONS); + quickExit(ExitCode::badOptions); } windowsServicePassword = toWideString( params["processManagement.windowsService.servicePassword"].as<string>().c_str()); @@ -217,10 +218,10 @@ void configureService(ServiceCallback serviceCallback, windowsServicePassword, argv, reinstallService); - quickExit(EXIT_CLEAN); + quickExit(ExitCode::clean); } else if (removeService) { removeServiceOrDie(_serviceName); - quickExit(EXIT_CLEAN); + quickExit(ExitCode::clean); } } @@ -310,7 +311,7 @@ void installServiceOrDie(const wstring& serviceName, LOGV2(23299, "Error connecting to the Service Control Manager", "__error__"_attr = windows::GetErrMsg(err)); - quickExit(EXIT_NTSERVICE_ERROR); + quickExit(ExitCode::ntServiceError); } SC_HANDLE schService = nullptr; @@ -336,7 +337,7 @@ void installServiceOrDie(const wstring& serviceName, } ::CloseServiceHandle(schSCManager); - quickExit(EXIT_NTSERVICE_ERROR); + quickExit(ExitCode::ntServiceError); } else { break; } @@ -362,7 +363,7 @@ void installServiceOrDie(const wstring& serviceName, DWORD err = ::GetLastError(); LOGV2(23301, "Error creating service", "__error__"_attr = windows::GetErrMsg(err)); ::CloseServiceHandle(schSCManager); - quickExit(EXIT_NTSERVICE_ERROR); + quickExit(ExitCode::ntServiceError); } LOGV2(23302, @@ -467,7 +468,7 @@ void installServiceOrDie(const wstring& serviceName, ::CloseServiceHandle(schSCManager); if (!serviceInstalled) - quickExit(EXIT_NTSERVICE_ERROR); + quickExit(ExitCode::ntServiceError); } void removeServiceOrDie(const wstring& serviceName) { @@ -479,7 +480,7 @@ void removeServiceOrDie(const wstring& serviceName) { LOGV2(23308, "Error connecting to the Service Control Manager", "__error__"_attr = windows::GetErrMsg(err)); - quickExit(EXIT_NTSERVICE_ERROR); + quickExit(ExitCode::ntServiceError); } SC_HANDLE schService = ::OpenService(schSCManager, serviceName.c_str(), SERVICE_ALL_ACCESS); @@ -488,7 +489,7 @@ void removeServiceOrDie(const wstring& serviceName) { "Could not find a service named to remove", "serviceName"_attr = toUtf8String(serviceName)); ::CloseServiceHandle(schSCManager); - quickExit(EXIT_NTSERVICE_ERROR); + quickExit(ExitCode::ntServiceError); } SERVICE_STATUS serviceStatus; @@ -520,7 +521,7 @@ void removeServiceOrDie(const wstring& serviceName) { } if (!serviceRemoved) - quickExit(EXIT_NTSERVICE_ERROR); + quickExit(ExitCode::ntServiceError); } bool reportStatus(DWORD reportState, DWORD waitHint, DWORD exitCode) { @@ -549,7 +550,7 @@ bool reportStatus(DWORD reportState, DWORD waitHint, DWORD exitCode) { ssStatus.dwCurrentState = reportState; // Only report ERROR_SERVICE_SPECIFIC_ERROR when the exit is not clean - if (reportState == SERVICE_STOPPED && exitCode != EXIT_CLEAN) + if (reportState == SERVICE_STOPPED && exitCode != static_cast<DWORD>(ExitCode::clean)) ssStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; else ssStatus.dwWin32ExitCode = NO_ERROR; @@ -605,7 +606,7 @@ static void WINAPI initService(DWORD argc, LPTSTR* argv) { // serviceStop(); - reportStatus(SERVICE_STOPPED, 0, exitCode); + reportStatus(SERVICE_STOPPED, 0, static_cast<DWORD>(exitCode)); } static void serviceShutdown(const char* controlCodeName) { @@ -661,9 +662,9 @@ void startService() { LOGV2( 23316, "Trying to start Windows service", "serviceName"_attr = toUtf8String(_serviceName)); if (StartServiceCtrlDispatcherW(dispTable)) { - quickExit(EXIT_CLEAN); + quickExit(ExitCode::clean); } else { - ::exit(EXIT_NTSERVICE_ERROR); + ::exit(static_cast<int>(ExitCode::ntServiceError)); } } diff --git a/src/mongo/util/options_parser/options_parser.h b/src/mongo/util/options_parser/options_parser.h index 411323a267d..76e8027c075 100644 --- a/src/mongo/util/options_parser/options_parser.h +++ b/src/mongo/util/options_parser/options_parser.h @@ -66,7 +66,7 @@ class Value; * Status ret = parser.run(options, argv, env, &environment); * if (!ret.isOK()) { * cerr << options.helpString() << std::endl; - * exit(EXIT_FAILURE); + * exit(ExitCode::fail); * } * * bool displayHelp; @@ -74,11 +74,11 @@ class Value; * if (!ret.isOK()) { * // Help is a switch, so it should always be set * cout << "Should not get here" << std::endl; - * exit(EXIT_FAILURE); + * exit(ExitCode::fail); * } * if (displayHelp) { * cout << options.helpString() << std::endl; - * exit(EXIT_SUCCESS); + * exit(ExitCode::clean); * } * * // Get the value of port from the environment diff --git a/src/mongo/util/options_parser/options_parser_init.cpp b/src/mongo/util/options_parser/options_parser_init.cpp index 73272cb8ab5..ea73e13c00a 100644 --- a/src/mongo/util/options_parser/options_parser_init.cpp +++ b/src/mongo/util/options_parser/options_parser_init.cpp @@ -49,7 +49,7 @@ MONGO_STARTUP_OPTIONS_PARSE(StartupOptions)(InitializerContext* context) { std::cerr << ret.reason() << std::endl; // TODO: Figure out if there's a use case for this help message ever being different std::cerr << "try '" << context->args()[0] << " --help' for more information" << std::endl; - quickExit(EXIT_BADOPTIONS); + quickExit(ExitCode::badOptions); } } @@ -62,7 +62,7 @@ MONGO_INITIALIZER_GENERAL(OutputConfig, uassertStatusOK(startupOptionsParsed.get(Key("outputConfig"), &output)); if (output) { std::cout << startupOptionsParsed.toYAML() << std::endl; - quickExit(EXIT_CLEAN); + quickExit(ExitCode::clean); } } } diff --git a/src/mongo/util/quick_exit.cpp b/src/mongo/util/quick_exit.cpp index b934067fd8c..2b1e31814e1 100644 --- a/src/mongo/util/quick_exit.cpp +++ b/src/mongo/util/quick_exit.cpp @@ -32,6 +32,8 @@ #include "mongo/platform/basic.h" #include "mongo/config.h" +#include "mongo/util/assert_util.h" +#include "mongo/util/exit_code.h" #if defined(MONGO_CONFIG_HAVE_HEADER_UNISTD_H) #include <unistd.h> @@ -75,7 +77,7 @@ namespace { stdx::mutex* const quickExitMutex = new stdx::mutex; } // namespace -void quickExitWithoutLogging(int code) { +void quickExitWithoutLogging(ExitCode code) { // Ensure that only one thread invokes the last rites here. No // RAII here - we never want to unlock this. if (quickExitMutex) @@ -103,9 +105,9 @@ void quickExitWithoutLogging(int code) { // multiple threads. Each call to _exit shuts down the CRT, and so subsequent calls into the // CRT result in undefined behavior. Bypass _exit CRT shutdown code and call TerminateProcess // directly instead to match GLibc's _exit which calls the syscall exit_group. - ::TerminateProcess(GetCurrentProcess(), code); + ::TerminateProcess(GetCurrentProcess(), static_cast<UINT>(code)); #else - ::_exit(code); + ::_exit(static_cast<int>(code)); #endif } diff --git a/src/mongo/util/quick_exit.h b/src/mongo/util/quick_exit.h index 5523cd37e5c..1d4fdfb7d16 100644 --- a/src/mongo/util/quick_exit.h +++ b/src/mongo/util/quick_exit.h @@ -29,6 +29,7 @@ #include "mongo/platform/compiler.h" #include "mongo/util/assert_util.h" +#include "mongo/util/exit_code.h" #include "mongo/util/testing_proctor.h" namespace mongo { @@ -46,14 +47,18 @@ namespace mongo { * inline wrapper around quickExitWithoutLogging - the pre-exit checks and logging need to refer * to mongo symbols, which aren't permitted in quick_exit.cpp. */ -MONGO_COMPILER_NORETURN void quickExitWithoutLogging(int); +MONGO_COMPILER_NORETURN void quickExitWithoutLogging(ExitCode); -MONGO_COMPILER_NORETURN inline void quickExit(int code) { +MONGO_COMPILER_NORETURN inline void quickExit(ExitCode code) { warnIfTripwireAssertionsOccurred(); - if (code == EXIT_CLEAN) { + if (code == ExitCode::clean) { TestingProctor::instance().exitAbruptlyIfDeferredErrors(false); } quickExitWithoutLogging(code); } +MONGO_COMPILER_NORETURN inline void quickExit(int code) { + quickExit(static_cast<ExitCode>(code)); +} + } // namespace mongo diff --git a/src/mongo/util/signal_handlers.cpp b/src/mongo/util/signal_handlers.cpp index 065640b1857..df045cbdb89 100644 --- a/src/mongo/util/signal_handlers.cpp +++ b/src/mongo/util/signal_handlers.cpp @@ -49,6 +49,7 @@ #include "mongo/util/assert_util.h" #include "mongo/util/concurrency/idle_thread_block.h" #include "mongo/util/exit.h" +#include "mongo/util/exit_code.h" #include "mongo/util/quick_exit.h" #include "mongo/util/scopeguard.h" #include "mongo/util/signal_handlers_synchronous.h" @@ -85,7 +86,7 @@ void consoleTerminate(const char* controlCodeName) { "Received event {controlCode}, will terminate after current command ends", "Received event, will terminate after current command ends", "controlCode"_attr = controlCodeName); - exitCleanly(EXIT_KILL); + exitCleanly(ExitCode::kill); } BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) { @@ -156,7 +157,7 @@ void eventProcessingThread() { setThreadName("eventTerminate"); LOGV2(23376, "shutdown event signaled, will terminate after current cmd ends"); - exitCleanly(EXIT_CLEAN); + exitCleanly(ExitCode::clean); } #else @@ -266,7 +267,7 @@ void handleOneSignal(const SignalWaitResult& waited, LogRotationState* rotation) // interrupt/terminate signal LOGV2(23381, "will terminate after current cmd ends"); - exitCleanly(EXIT_CLEAN); + exitCleanly(ExitCode::clean); } /** diff --git a/src/mongo/util/signal_handlers_synchronous.cpp b/src/mongo/util/signal_handlers_synchronous.cpp index 51785ca7e25..1da0d85af78 100644 --- a/src/mongo/util/signal_handlers_synchronous.cpp +++ b/src/mongo/util/signal_handlers_synchronous.cpp @@ -103,7 +103,7 @@ void endProcessWithSignal(int signalNum) { RaiseException(STATUS_EXIT_ABRUPT, EXCEPTION_NONCONTINUABLE, 0, nullptr); } __except (sehExceptionFilter(GetExceptionCode(), GetExceptionInformation())) { // The exception filter exits the process - quickExit(EXIT_ABRUPT); + quickExit(ExitCode::abrupt); } } @@ -181,7 +181,7 @@ class MallocFreeOStreamGuard { public: explicit MallocFreeOStreamGuard() : _lk(_streamMutex, stdx::defer_lock) { if (terminateDepth++) { - quickExit(EXIT_ABRUPT); + quickExit(ExitCode::abrupt); } _lk.lock(); } @@ -362,7 +362,7 @@ void reportOutOfMemoryErrorAndExit() { mallocFreeOStream << "out of memory."; writeMallocFreeStreamToLog(); printStackTraceNoRecursion(); - quickExit(EXIT_ABRUPT); + quickExit(ExitCode::abrupt); } void clearSignalMask() { diff --git a/src/mongo/util/testing_proctor.h b/src/mongo/util/testing_proctor.h index f313ec9d8dc..2c938d7540d 100644 --- a/src/mongo/util/testing_proctor.h +++ b/src/mongo/util/testing_proctor.h @@ -61,7 +61,7 @@ public: void setEnabled(bool enable); /** - * Quick exits with EXIT_ABRUPT if any deferred errors have occurred. + * Quick exits with ExitCode::abrupt if any deferred errors have occurred. */ void exitAbruptlyIfDeferredErrors(bool verbose = true) const; diff --git a/src/mongo/watchdog/watchdog.cpp b/src/mongo/watchdog/watchdog.cpp index 4e16d34adef..574068b762e 100644 --- a/src/mongo/watchdog/watchdog.cpp +++ b/src/mongo/watchdog/watchdog.cpp @@ -168,7 +168,7 @@ void WatchdogPeriodicThread::doLoop() { 23415, "Watchdog was interrupted, shutting down, reason: {e_toStatus}", "e_toStatus"_attr = e.toStatus()); - exitCleanly(ExitCode::EXIT_ABRUPT); + exitCleanly(ExitCode::abrupt); } // This interruption ends the WatchdogPeriodicThread. This means it is possible to @@ -452,7 +452,7 @@ void checkFile(OperationContext* opCtx, const boost::filesystem::path& file) { } void watchdogTerminate() { - ::TerminateProcess(::GetCurrentProcess(), ExitCode::EXIT_WATCHDOG); + ::TerminateProcess(::GetCurrentProcess(), static_cast<UINT>(ExitCode::watchdog)); } #else @@ -583,7 +583,7 @@ void checkFile(OperationContext* opCtx, const boost::filesystem::path& file) { void watchdogTerminate() { // This calls the exit_group syscall on Linux - ::_exit(ExitCode::EXIT_WATCHDOG); + ::_exit(static_cast<int>(ExitCode::watchdog)); } #endif |