[Pacemaker] [PATCH 6/8 ] Restore old logfile open/seek/write/close behaviour.
Bernd Schubert
bs_lists at aakef.fastmail.fm
Wed Sep 15 22:17:46 UTC 2010
cl_log: Restore old logfile open/seek/write/close behaviour.
This patch actually does not completely revert commit 2435:ada347da564d,
but adds a layer to support both, open/write/close and and
open-once, write, close/open-for signal handlers
It also changes a marco into a static function. And also uses
system IO (open/close/write) instead of libc IO (fopen/fclose/fwrite).
Libc IO has a buffer, which is not suitable for log files (in case of
a stonith, all the buffer and which might large, will be missing in
log files.
Signed-off-by: Bernd Schubert <bschubert at ddn.com>
diff --git a/lib/clplumbing/cl_log.c b/lib/clplumbing/cl_log.c
--- a/lib/clplumbing/cl_log.c
+++ b/lib/clplumbing/cl_log.c
@@ -74,6 +74,7 @@ static IPC_Message* ChildLogIPCMessage(i
static void FreeChildLogIPCMessage(IPC_Message* msg);
static gboolean send_dropped_message(gboolean use_pri_str, IPC_Channel *chan);
static int cl_set_logging_wqueue_maxlen(int qlen);
+static char * syslog_timestamp(TIME_T t);
static int use_logging_daemon = FALSE;
static int conn_logd_time = 0;
@@ -92,6 +93,10 @@ int debug_level = 0;
static GDestroyNotify destroy_logging_channel_callback;
static void (*create_logging_channel_callback)(IPC_Channel* chan);
static gboolean logging_chan_in_main_loop = FALSE;
+static gboolean have_signal_handler = FALSE;
+
+static int debug_fd = -1;
+static int log_fd = -1;
/***********************
*debug use only, do not use this function in your program
@@ -477,54 +482,79 @@ prio2str(int priority)
"(undef)" : log_prio[logpri];
}
-/* print log line to a FILE *f */
-#define print_logline(fp,entity,entity_pid,ts,pristr,buf) { \
- fprintf(fp, "%s[%d]: %s ",entity,entity_pid,ha_timestamp(ts)); \
- if (pristr) \
- fprintf(fp,"%s: %s\n",pristr,buf); \
- else \
- fprintf(fp,"%s\n",buf); \
- }
+/* print log line to a string */
+static char *
+logline(char *dest, int max_length, const char * entity,
+ int entity_pid, TIME_T ts, const char * pristr, const char * msg)
+{
+ static struct utsname un;
+
+ uname(&un);
+
+ if (!syslogformatfile) {
+ snprintf(dest, max_length, "%s[%d]: %s %s: %s"
+ , entity, entity_pid
+ , ha_timestamp(ts)
+ , (pristr ? pristr : "")
+ , msg);
+ } else {
+ /*
+ * Jul 14 21:45:18 beam logd: [1056]: info: setting log file to /dev/null
+ */
+ snprintf(dest, max_length, "%s %s %s: [%d]: %s%s%s\n"
+ , syslog_timestamp(ts)
+ , un.nodename, entity, entity_pid
+ , (pristr ? pristr : "")
+ , (pristr ? ": " : "")
+ , msg);
+ }
+
+ return dest;
+}
-static char * syslog_timestamp(TIME_T t);
+/* print log line to the given file handle */
+static void
+print_logline(FILE* fh, const char * entity,
+ int entity_pid, TIME_T ts, const char * pristr, const char * buf)
+{
+ char log_str[MAXLINE];
+
+ logline(log_str, MAXLINE, entity, entity_pid, ts, pristr, buf);
+ fprintf(fh, "%s\n", log_str);
+}
static void
-append_log(FILE * fp, const char * entity, int entity_pid
-, TIME_T timestamp, const char * pristr, const char * msg)
+append_log(int fd, const char * entity, int entity_pid,
+ TIME_T ts, const char * pristr, const char * msg)
{
- static int got_uname = FALSE;
- static struct utsname un;
-
- if (!syslogformatfile) {
- print_logline(fp, entity, entity_pid, timestamp, pristr, msg);
- return;
+ char log_str[MAXLINE];
+ int rc;
+
+ logline(log_str, MAXLINE, entity, entity_pid, ts, pristr, msg);
+
+ /* write() is better here, as fprintf() and fwrite() may use
+ * a rather large libc buffer which we would need to flush */
+ rc = write(fd, log_str, strlen(log_str));
+ if (rc == -1) {
+ /* writing to the log file failed, try stderr */
+ syslog(LOG_ERR, "Failed to write to log file: %s\n",
+ strerror(errno));
}
- if (!got_uname) {
- uname(&un);
- }
- /*
- * Jul 14 21:45:18 beam logd: [1056]: info: setting log file to /dev/null
- */
- fprintf(fp, "%s %s %s: [%d]: %s%s%s\n"
- , syslog_timestamp(timestamp)
- , un.nodename, entity, entity_pid
- , (pristr ? pristr : "")
- , (pristr ? ": " : "")
- , msg);
}
/*
* Just open the given file name
*/
-static FILE *
+static int
open_log_file(const char * fname)
{
- FILE * fp = fopen(fname ,"a");
- if (!fp) {
+ int mode = S_IRUSR | S_IWUSR | S_IRGRP;
+ int fd = open(fname, O_WRONLY | O_APPEND | O_CREAT, mode);
+ if (!fd) {
syslog(LOG_ERR, "Failed to open log file %s: %s\n" ,
fname, strerror(errno));
}
- return fp;
+ return fd;
}
/*
@@ -562,26 +592,20 @@ cl_direct_log(int priority, const char*
}
if (debugfile_name != NULL) {
- static FILE * debug_fp = NULL;
- if (!debug_fp) {
- /* As performance optimization we keep the file-handle
- * open all the time */
- debug_fp = open_log_file(debugfile_name);
+ if (debug_fd != -1) {
+ debug_fd = open_log_file(debugfile_name);
}
- if (debug_fp)
- append_log(debug_fp ,entity, entity_pid, ts, pristr,
+ if (debug_fd != -1)
+ append_log(debug_fd ,entity, entity_pid, ts, pristr,
buf);
}
if (priority != LOG_DEBUG && logfile_name != NULL) {
- static FILE * log_fp = NULL;
- if (!log_fp) {
- /* As performance optimization we keep the file-handle
- * open all the time */
- log_fp = open_log_file(logfile_name);
+ if (log_fd != -1) {
+ log_fd = open_log_file(logfile_name);
}
- if (log_fp)
- append_log(log_fp ,entity, entity_pid, ts, pristr,
+ if (log_fd != -1)
+ append_log(log_fd ,entity, entity_pid, ts, pristr,
buf);
}
@@ -589,6 +613,17 @@ cl_direct_log(int priority, const char*
return_to_dropped_privs();
}
+ /* As performance optimization we try to keep the file descriptor
+ * open all the time, but as logrotation needs to work, the calling
+ * program needs a signal handler. Therefore we close fd's, if the
+ * caller did not tell us it has the signal handler */
+ if (have_signal_handler == FALSE) {
+ close(debug_fd);
+ close(log_fd);
+ debug_fd = -1;
+ log_fd = -1;
+ }
+
return;
}
More information about the Pacemaker
mailing list