summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorChris Hall <chris.hall@highwayman.com>2011-05-18 11:07:04 +0100
committerChris Hall <chris.hall@highwayman.com>2011-05-18 11:07:04 +0100
commit5f5809b14e76311d6fab751fe114b2ef495af10c (patch)
tree2e45bf41bbf577aaf8a43288cf40bef2b4daed5b /lib
parent764827bdcf1d4188593efa1c5c4e1214f12e3d5e (diff)
downloadquagga-5f5809b14e76311d6fab751fe114b2ef495af10c.tar.bz2
quagga-5f5809b14e76311d6fab751fe114b2ef495af10c.tar.xz
Improve writing of pid lock file and error reporting.
Added fsync() after writing the pid to the lock file to push the result to the file system immediately. Any error in the procedure is now treated as fatal, and the daemon will exit(1). (Previously only the open and the lock had to succeed.) Any error is logged and is (now) output to stderr. If the pid file is locked, the error message reports the pid which owns the lock.
Diffstat (limited to 'lib')
-rw-r--r--lib/pid_output.c92
1 files changed, 58 insertions, 34 deletions
diff --git a/lib/pid_output.c b/lib/pid_output.c
index 17081dad..df1862bb 100644
--- a/lib/pid_output.c
+++ b/lib/pid_output.c
@@ -59,50 +59,74 @@ pid_output (const char *path)
pid_t
pid_output (const char *path)
{
- int tmp;
- int fd;
- pid_t pid;
- char buf[16];
- struct flock lock;
- mode_t oldumask;
+ const char* fail ;
+ int err ;
+
+ pid_t pid ;
+ mode_t oldumask ;
+ int fd ;
+ struct flock lock ;
+ char buf[32] ;
+ size_t pidsize ;
pid = getpid ();
oldumask = umask(0777 & ~PIDFILE_MASK);
- fd = open (path, O_RDWR | O_CREAT, PIDFILE_MASK);
+
+ fail = "Failed to open pid lock file '%s' for pid %d (%s)" ;
+ fd = open (path, O_RDWR | O_CREAT, PIDFILE_MASK) ;
+ err = errno ;
+
+ umask(oldumask);
+
if (fd < 0)
- {
- zlog_err("Can't create pid lock file %s (%s), exiting",
- path, errtoa(errno, 0).str);
- umask(oldumask);
- exit(1);
- }
- else
- {
- size_t pidsize;
+ goto failed_err ;
- umask(oldumask);
- memset (&lock, 0, sizeof(lock));
+ memset (&lock, 0, sizeof(lock));
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
- lock.l_type = F_WRLCK;
- lock.l_whence = SEEK_SET;
+ if (fcntl(fd, F_SETLK, &lock) < 0)
+ {
+ fail = "Failed to write lock pid lock file '%s' for pid %d (%s)" ;
+ err = errno ;
- if (fcntl(fd, F_SETLK, &lock) < 0)
+ if ((err == EACCES) || (err == EAGAIN))
{
- zlog_err("Could not lock pid_file %s, exiting", path);
- exit(1);
- }
-
- sprintf (buf, "%d\n", (int) pid);
- pidsize = strlen(buf);
- if ((tmp = write (fd, buf, pidsize)) != (int)pidsize)
- zlog_err("Could not write pid %d to pid_file %s, rc was %d: %s",
- (int)pid,path,tmp, errtoa(errno, 0).str);
- else if (ftruncate(fd, pidsize) < 0)
- zlog_err("Could not truncate pid_file %s to %u bytes: %s",
- path,(u_int)pidsize, errtoa(errno, 0).str);
- }
+ fail = "Failed to write lock pid lock file '%s', "
+ "blocked by pid %d (%s)" ;
+ fcntl(fd, F_GETLK, &lock) ;
+ pid = lock.l_pid ;
+ } ;
+
+ goto failed_err ;
+ } ;
+
+ pidsize = sprintf (buf, "%d\n", (int)pid) ;
+
+ fail = "Failed to write pid to pid lock file '%s' for pid %d (%s)" ;
+ if (write(fd, buf, pidsize) != (ssize_t)pidsize)
+ goto failed ;
+
+ fail = "Failed to truncate pid lock file '%s' to length for pid %d (%s)" ;
+ if (ftruncate(fd, pidsize) < 0)
+ goto failed ;
+
+ fail = "Failed to fsync pid lock file '%s' for pid %d (%s)" ;
+ if (fsync(fd) < 0)
+ goto failed ;
+
return pid;
+
+failed:
+ err = errno ;
+
+failed_err:
+ zlog_err(fail, path, (int)pid, errtoa(err, 0).str) ;
+ fprintf(stderr, fail, path, (int)pid, errtoa(err, 0).str) ;
+ fprintf(stderr, "\n") ;
+
+ exit(1) ;
}
#endif /* HAVE_FCNTL */