src/agent/Watchdog/WatchdogMain.cpp in passenger-5.0.30 vs src/agent/Watchdog/WatchdogMain.cpp in passenger-5.1.0

- old
+ new

@@ -40,10 +40,13 @@ #if !defined(sun) && !defined(__sun) #define HAVE_FLOCK #endif +#ifdef __linux__ +#include <sys/prctl.h> +#endif #include <sys/select.h> #include <sys/types.h> #include <sys/time.h> #ifdef HAVE_FLOCK #include <sys/file.h> @@ -146,13 +149,11 @@ using namespace Passenger::WatchdogAgent; static VariantMap *agentsOptions; static WorkingObjects *workingObjects; -static string oldOomScore; -static void setOomScore(const StaticString &score); static void cleanup(const WorkingObjectsPtr &wo); #include "AgentWatcher.cpp" #include "InstanceDirToucher.cpp" #include "CoreWatcher.cpp" @@ -187,44 +188,10 @@ return fopen("/proc/self/oom_adj", mode); } } /** - * Linux-only way to change OOM killer configuration for - * current process. Requires root privileges, which we - * should have. - */ -static void -setOomScore(const StaticString &score) { - if (score.empty()) { - return; - } - - FILE *f; - OomFileType type; - string filteredScore; - - if (score.at(0) == 'l') { - filteredScore = score.substr(1); - type = OOM_ADJ; - } else { - filteredScore = score; - type = OOM_SCORE_ADJ; - } - f = openOomAdjFileForcedType("w", type); - if (f != NULL) { - size_t ret = fwrite(filteredScore.data(), 1, filteredScore.size(), f); - // We can't do anything about failures, so ignore compiler - // warnings about not doing anything with the result. - (void) ret; - fclose(f); - } else { - P_WARN("setOomScore(" << filteredScore << ", " << type << ") failed due to error: " << strerror(errno)); - } -} - -/** * Set the current process's OOM score to "never kill". */ static string setOomScoreNeverKill() { string oldScore; @@ -356,16 +323,22 @@ ret = syscalls::read(FEEDBACK_FD, &x, 1); return ret == 1 && x == 'c'; } } +string +relative(string filename){ + string dir = filename.substr(filename.find_last_of('/')+1); + return dir; +} + static vector<pid_t> readCleanupPids(const WorkingObjectsPtr &wo) { vector<pid_t> result; foreach (string filename, wo->cleanupPidfiles) { - FILE *f = fopen(filename.c_str(), "r"); + FILE *f = fopen(relative(filename).c_str(), "r"); if (f != NULL) { char buf[33]; size_t ret; ret = fread(buf, 1, 32, f); @@ -386,11 +359,14 @@ static void killCleanupPids(const vector<pid_t> &cleanupPids) { foreach (pid_t pid, cleanupPids) { P_DEBUG("Sending SIGTERM to cleanup PID " << pid); - kill(pid, SIGTERM); + if(kill(pid, SIGTERM) == -1){ + int e = errno; + P_WARN("Failed to send SIGTERM to " << pid << ", error: " << e << " " << strerror(e)); + } } } static void killCleanupPids(const WorkingObjectsPtr &wo) { @@ -798,11 +774,11 @@ * the system administrator will have to restart the web server for Phusion * Passenger to be usable again. So here we disable Linux's OOM killer * for this watchdog. Note that the OOM score is inherited by child processes * so we need to restore it after each fork(). */ - oldOomScore = setOomScoreNeverKill(); + string oldOomScore = setOomScoreNeverKill(); agentsOptions = new VariantMap(); *agentsOptions = initializeAgent(argc, &argv, SHORT_PROGRAM_NAME " watchdog", parseOptions, NULL, 2); agentsOptions->set("original_oom_score", oldOomScore); @@ -924,10 +900,22 @@ wo->reportFile = fd; } } static void +chdirToTmpDir() { + vector<string> pidfiles = agentsOptions->getStrSet("cleanup_pidfiles", false); + if (pidfiles.size() > 0) { + string str = pidfiles.front(); + string dir = str.substr(0,str.find_last_of('/')); + if (dir != "" && chdir(dir.c_str()) == -1) { + throw RuntimeException("Cannot change working directory to " + dir); + } + } +} + +static void lowerPrivilege() { TRACE_POINT(); const VariantMap &options = *agentsOptions; string userName = options.get("user", false); @@ -958,11 +946,13 @@ int e = errno; throw SystemException("Unable to lower " SHORT_PROGRAM_NAME " watchdog's privilege " "to that of user '" + userName + "' and group '" + groupName + "': cannot set user ID to " + toString(pwUser->pw_uid), e); } - +#ifdef __linux__ + prctl(PR_SET_DUMPABLE, 1); +#endif setenv("USER", pwUser->pw_name, 1); setenv("HOME", pwUser->pw_dir, 1); setenv("UID", toString(gid).c_str(), 1); } } @@ -1298,9 +1288,10 @@ TRACE_POINT(); maybeSetsid(); maybeDaemonize(); createPidFile(); openReportFile(wo); + chdirToTmpDir(); lowerPrivilege(); initializeWorkingObjects(wo, instanceDirToucher, uidBeforeLoweringPrivilege); initializeAgentWatchers(wo, watchers); initializeApiServer(wo); UPDATE_TRACE_POINT();