Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=4c38b8e47f03c5... Commit: 4c38b8e47f03c54eee563a11446518c147fa9ec1 Parent: 0031db202e1b6584c5069f7f3139c1303257a3aa Author: Christine Caulfield ccaulfie@redhat.com AuthorDate: Thu Feb 26 10:41:07 2015 +0000 Committer: Christine Caulfield ccaulfie@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@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) {