[Pacemaker] [PATCH 6/8 ] Restore old logfile open/seek/write/close behaviour.

Bernd Schubert bs_lists at aakef.fastmail.fm
Wed Sep 15 18:17:46 EDT 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