Gitweb:
http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=4c38b8e47f0...
Commit: 4c38b8e47f03c54eee563a11446518c147fa9ec1
Parent: 0031db202e1b6584c5069f7f3139c1303257a3aa
Author: Christine Caulfield <ccaulfie(a)redhat.com>
AuthorDate: Thu Feb 26 10:41:07 2015 +0000
Committer: Christine Caulfield <ccaulfie(a)redhat.com>
CommitterDate: Thu Feb 26 10:41:07 2015 +0000
logt: fix race that could cause a coredump when files are reopened
Open a second fp in the main thread which is then swapped and closed
in the actual log thread. This prevents a closed fp being used if a
log m1133724essage arrives while the a logfile is being closed and
reopened.
rhbz#1133724
Signed-off-by: Christine Caulfield <ccaulfie(a)redhat.com>
---
common/liblogthread/liblogthread.c | 36 +++++++++++++++++++++++++++---------
1 files changed, 27 insertions(+), 9 deletions(-)
diff --git a/common/liblogthread/liblogthread.c b/common/liblogthread/liblogthread.c
index ba96a2a..8c1f422 100644
--- a/common/liblogthread/liblogthread.c
+++ b/common/liblogthread/liblogthread.c
@@ -38,6 +38,7 @@ static int logt_logfile_priority;
static char logt_name[PATH_MAX];
static char logt_logfile[PATH_MAX];
static FILE *logt_logfile_fp;
+static FILE *new_logt_logfile_fp;
static char *_time(time_t *t)
{
@@ -93,6 +94,13 @@ static void *thread_fn(void *arg)
prev_dropped = dropped;
dropped = 0;
+
+ if (new_logt_logfile_fp) {
+ fclose(logt_logfile_fp);
+ logt_logfile_fp = new_logt_logfile_fp;
+ new_logt_logfile_fp = NULL;
+ }
+
pthread_mutex_unlock(&mutex);
if (prev_dropped) {
@@ -170,20 +178,30 @@ static void _conf(const char *name, int mode, int syslog_facility,
strncpy(logt_logfile, logfile, PATH_MAX);
if (logt_mode & LOG_MODE_OUTPUT_FILE && logt_logfile[0]) {
- if (logt_logfile_fp) {
- fclose(logt_logfile_fp);
- logt_logfile_fp = NULL;
- }
- logt_logfile_fp = fopen(logt_logfile, "a+");
- if (logt_logfile_fp != NULL) {
- fd = fileno(logt_logfile_fp);
- fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
- }
+ /* Don't close the existing fp in this thread, let the main logthread do it
later */
+ if (!logt_logfile_fp) {
+ logt_logfile_fp = fopen(logt_logfile, "a+");
+ if (logt_logfile_fp != NULL) {
+ fd = fileno(logt_logfile_fp);
+ fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
+ }
+ }
+ else {
+ new_logt_logfile_fp = fopen(logt_logfile, "a+");
+ if (new_logt_logfile_fp != NULL) {
+ fd = fileno(new_logt_logfile_fp);
+ fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
+ }
+ }
} else {
if (logt_logfile_fp) {
fclose(logt_logfile_fp);
logt_logfile_fp = NULL;
}
+ if (new_logt_logfile_fp) {
+ fclose(new_logt_logfile_fp);
+ new_logt_logfile_fp = NULL;
+ }
}
if (logt_mode & LOG_MODE_OUTPUT_SYSLOG) {