summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArne Juul <arnej@yahoo-inc.com>2017-09-21 14:03:01 +0000
committerArne Juul <arnej@yahoo-inc.com>2017-09-21 14:03:01 +0000
commitf2fe5453b7cfadf6f5545745c594ab2e3c8dd9f7 (patch)
treedf74ffcbbeb6943e8a464e50e13eb214f3846d00
parent2b137cf2869d382cee327406fe4e8917c53425b1 (diff)
add robustness
* if the machine / container was stopped abruptly, leaving pidfile laying around, this could cause problems at next startup if the pid was reused. Use advisory locks and also check for our own pid.
-rw-r--r--vespalog/src/logger/runserver.cpp37
1 files changed, 26 insertions, 11 deletions
diff --git a/vespalog/src/logger/runserver.cpp b/vespalog/src/logger/runserver.cpp
index 7cbe3711889..efd45288199 100644
--- a/vespalog/src/logger/runserver.cpp
+++ b/vespalog/src/logger/runserver.cpp
@@ -51,15 +51,15 @@ public:
int readPid();
void writePid();
bool writeOpen();
- bool isRunning();
- bool isMine();
+ bool anotherRunning();
+ bool canStealLock();
void cleanUp();
};
void
PidFile::cleanUp()
{
- if (isMine() || !isRunning()) remove(_pidfile);
+ if (!anotherRunning()) remove(_pidfile);
if (_fd >= 0) close(_fd);
_fd = -1;
}
@@ -75,7 +75,6 @@ PidFile::writeOpen()
strerror(errno));
return false;
}
- // XXX should we use locking or not?
if (flock(_fd, LOCK_EX | LOCK_NB) != 0) {
fprintf(stderr, "could not lock pidfile %s: %s\n", _pidfile,
strerror(errno));
@@ -117,18 +116,34 @@ PidFile::readPid()
}
bool
-PidFile::isRunning()
+PidFile::anotherRunning()
{
int pid = readPid();
- if (pid < 1) return false;
+ if (pid < 1 || pid == getpid()) {
+ // no valid pid, or my own pid
+ return false;
+ }
+ if (canStealLock()) {
+ return false;
+ }
return (kill(pid, 0) == 0 || errno == EPERM);
}
bool
-PidFile::isMine()
+PidFile::canStealLock()
{
- int pid = readPid();
- return (pid == getpid());
+ int flags = O_WRONLY | O_NONBLOCK;
+ int desc = open(_pidfile, flags, 0644);
+ if (desc < 0) {
+ return false;
+ }
+ if (flock(desc, LOCK_EX | LOCK_NB) != 0) {
+ close(desc);
+ return false;
+ }
+ flock(desc, LOCK_UN | LOCK_NB);
+ close(desc);
+ return true;
}
using namespace ns_log;
@@ -351,7 +366,7 @@ int main(int argc, char *argv[])
PidFile mypf(pidfile);
if (doStop) {
- if (mypf.isRunning()) {
+ if (mypf.anotherRunning()) {
int pid = mypf.readPid();
if (killcmd != NULL) {
fprintf(stdout, "%s was running with pid %d, running '%s' to stop it\n",
@@ -399,7 +414,7 @@ int main(int argc, char *argv[])
usage(argv[0], 1);
}
- if (mypf.isRunning()) {
+ if (mypf.anotherRunning()) {
fprintf(stderr, "runserver already running with pid %d\n",
mypf.readPid());
exit(0);