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();