summaryrefslogtreecommitdiff
path: root/src/mongo/db/mongod_main.cpp
diff options
context:
space:
mode:
authorSara Golemon <sara.golemon@mongodb.com>2021-05-11 17:01:57 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-05-26 07:34:50 +0000
commita07dc78e49c53de539dff92748334cd7fbe2e2a9 (patch)
tree4a4ce1c5e77e4068d0d0226f7f68570409600f49 /src/mongo/db/mongod_main.cpp
parentda10c9aff0b4f1dface979ddd0605e6d142488c5 (diff)
downloadmongo-a07dc78e49c53de539dff92748334cd7fbe2e2a9.tar.gz
SERVER-56677 Refactor --shutdown handling
Diffstat (limited to 'src/mongo/db/mongod_main.cpp')
-rw-r--r--src/mongo/db/mongod_main.cpp99
1 files changed, 60 insertions, 39 deletions
diff --git a/src/mongo/db/mongod_main.cpp b/src/mongo/db/mongod_main.cpp
index 54b3f7f70bd..a3879a152c6 100644
--- a/src/mongo/db/mongod_main.cpp
+++ b/src/mongo/db/mongod_main.cpp
@@ -842,6 +842,63 @@ MONGO_INITIALIZER_GENERAL(ForkServer, ("EndStartupOptionHandling"), ("default"))
mongo::forkServerOrDie();
}
+#ifdef __linux__
+/**
+ * Read the pid file from the dbpath for the process ID used by this instance of the server.
+ * Use that process number to kill the running server.
+ *
+ * Equivalent to: `kill -SIGTERM $(cat $DBPATH/mongod.lock)`
+ *
+ * Performs additional checks to make sure the PID as read is reasonable (>= 1)
+ * and can be found in the /proc filesystem.
+ */
+Status shutdownProcessByDBPathPidFile(const std::string& dbpath) {
+ auto pidfile = (boost::filesystem::path(dbpath) / kLockFileBasename.toString()).string();
+ if (!boost::filesystem::exists(pidfile)) {
+ return {ErrorCodes::OperationFailed,
+ str::stream() << "There doesn't seem to be a server running with dbpath: "
+ << dbpath};
+ }
+
+ pid_t pid;
+ try {
+ std::ifstream f(pidfile.c_str());
+ f >> pid;
+ } catch (const std::exception& ex) {
+ return {ErrorCodes::OperationFailed,
+ str::stream() << "Error reading pid from lock file [" << pidfile
+ << "]: " << ex.what()};
+ }
+
+ if (pid <= 0) {
+ return {ErrorCodes::OperationFailed,
+ str::stream() << "Invalid process ID '" << pid
+ << "' read from pidfile: " << pidfile};
+ }
+
+ std::string procPath = str::stream() << "/proc/" << pid;
+ if (!boost::filesystem::exists(procPath)) {
+ return {ErrorCodes::OperationFailed,
+ str::stream() << "Process ID '" << pid << "' read from pidfile '" << pidfile
+ << "' does not appear to be running"};
+ }
+
+ std::cout << "Killing process with pid: " << pid << std::endl;
+ int ret = kill(pid, SIGTERM);
+ if (ret) {
+ int e = errno;
+ return {ErrorCodes::OperationFailed,
+ str::stream() << "Failed to kill process: " << errnoWithDescription(e)};
+ }
+
+ while (boost::filesystem::exists(pidfile)) {
+ sleepsecs(1);
+ }
+
+ return Status::OK();
+}
+#endif // __linux__
+
/*
* This function should contain the startup "actions" that we take based on the startup config.
* It is intended to separate the actions from "storage" and "validation" of our startup
@@ -883,48 +940,12 @@ void startupConfigActions(const std::vector<std::string>& args) {
#ifdef __linux__
if (moe::startupOptionsParsed.count("shutdown") &&
moe::startupOptionsParsed["shutdown"].as<bool>() == true) {
- bool failed = false;
-
- std::string name =
- (boost::filesystem::path(storageGlobalParams.dbpath) / kLockFileBasename.toString())
- .string();
- if (!boost::filesystem::exists(name) || boost::filesystem::file_size(name) == 0)
- failed = true;
-
- pid_t pid;
- std::string procPath;
- if (!failed) {
- try {
- std::ifstream f(name.c_str());
- f >> pid;
- procPath = (str::stream() << "/proc/" << pid);
- if (!boost::filesystem::exists(procPath))
- failed = true;
- } catch (const std::exception& e) {
- std::cerr << "Error reading pid from lock file [" << name << "]: " << e.what()
- << endl;
- failed = true;
- }
- }
-
- if (failed) {
- std::cerr << "There doesn't seem to be a server running with dbpath: "
- << storageGlobalParams.dbpath << std::endl;
- quickExit(EXIT_FAILURE);
- }
-
- std::cout << "killing process with pid: " << pid << endl;
- int ret = kill(pid, SIGTERM);
- if (ret) {
- int e = errno;
- std::cerr << "failed to kill process: " << errnoWithDescription(e) << endl;
+ auto status = shutdownProcessByDBPathPidFile(storageGlobalParams.dbpath);
+ if (!status.isOK()) {
+ std::cerr << status.reason() << std::endl;
quickExit(EXIT_FAILURE);
}
- while (boost::filesystem::exists(procPath)) {
- sleepsecs(1);
- }
-
quickExit(EXIT_SUCCESS);
}
#endif