andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 4 months ago
Clone

Blame 0022-Ticket-527-ns-slapd-segfaults-if-it-cannot-rename-th.patch

dc8c34
From 00e77c9c16be9f9cc10e6d5833e5e5ceb2ec61ad Mon Sep 17 00:00:00 2001
dc8c34
From: Mark Reynolds <mreynolds@redhat.com>
dc8c34
Date: Thu, 6 Dec 2012 14:52:40 -0500
dc8c34
Subject: [PATCH 22/22] Ticket 527 - ns-slapd segfaults if it cannot rename
dc8c34
 the logs
dc8c34
dc8c34
Bug Description:  If we can not rename a log file, triggered by log rotation,
dc8c34
                  we try and log a message stating this error, but trying to
dc8c34
                  log this new message triggers log rotation again.  This leads
dc8c34
                  to an infinite loop and a stack overflow.
dc8c34
dc8c34
Fix Description:  Created a new logging function that does not do a rotation check.
dc8c34
                  We use this new function for all emergency error logging.
dc8c34
dc8c34
https://fedorahosted.org/389/ticket/527
dc8c34
dc8c34
Reviewed by: richm(Thanks!)
dc8c34
(cherry picked from commit 4e9aab8a172c8636ea78a9d1230c78c76268efd7)
dc8c34
(cherry picked from commit 85261ef0161df156ea3991a77046aabda6c34cf4)
dc8c34
---
dc8c34
 ldap/servers/slapd/log.c | 63 ++++++++++++++++++++++++++++++++++++++++--------
dc8c34
 1 file changed, 53 insertions(+), 10 deletions(-)
dc8c34
dc8c34
diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c
dc8c34
index e622485..e65b247 100644
dc8c34
--- a/ldap/servers/slapd/log.c
dc8c34
+++ b/ldap/servers/slapd/log.c
dc8c34
@@ -138,6 +138,7 @@ static void	log_append_buffer2(time_t tnl, LogBufferInfo *lbi, char *msg1, size_
dc8c34
 static void	log_flush_buffer(LogBufferInfo *lbi, int type, int sync_now);
dc8c34
 static void	log_write_title(LOGFD fp);
dc8c34
 static void log__error_emergency(const char *errstr, int reopen, int locked);
dc8c34
+static void vslapd_log_emergency_error(LOGFD fp, const char *msg, int locked);
dc8c34
 
dc8c34
 static int
dc8c34
 slapd_log_error_proc_internal(
dc8c34
@@ -1834,6 +1835,57 @@ slapd_log_error_proc_internal(
dc8c34
 	return( rc );
dc8c34
 }
dc8c34
 
dc8c34
+/*
dc8c34
+ *  Directly write the already formatted message to the error log
dc8c34
+ */
dc8c34
+static void
dc8c34
+vslapd_log_emergency_error(LOGFD fp, const char *msg, int locked)
dc8c34
+{
dc8c34
+    time_t    tnl;
dc8c34
+    long      tz;
dc8c34
+    struct tm *tmsp, tms;
dc8c34
+    char      tbuf[ TBUFSIZE ];
dc8c34
+    char      buffer[SLAPI_LOG_BUFSIZ];
dc8c34
+    char      sign;
dc8c34
+    int       size;
dc8c34
+
dc8c34
+    tnl = current_time();
dc8c34
+#ifdef _WIN32
dc8c34
+    {
dc8c34
+        struct tm *pt = localtime( &tnl );
dc8c34
+        tmsp = &tm;;
dc8c34
+        memcpy(&tms, pt, sizeof(struct tm) );
dc8c34
+    }
dc8c34
+#else
dc8c34
+    (void)localtime_r( &tnl, &tms );
dc8c34
+    tmsp = &tm;;
dc8c34
+#endif
dc8c34
+#ifdef BSD_TIME
dc8c34
+    tz = tmsp->tm_gmtoff;
dc8c34
+#else /* BSD_TIME */
dc8c34
+    tz = - timezone;
dc8c34
+    if ( tmsp->tm_isdst ) {
dc8c34
+        tz += 3600;
dc8c34
+    }
dc8c34
+#endif /* BSD_TIME */
dc8c34
+    sign = ( tz >= 0 ? '+' : '-' );
dc8c34
+    if ( tz < 0 ) {
dc8c34
+        tz = -tz;
dc8c34
+    }
dc8c34
+    (void)strftime( tbuf, (size_t)TBUFSIZE, "%d/%b/%Y:%H:%M:%S", tmsp);
dc8c34
+    sprintf( buffer, "[%s %c%02d%02d] - %s", tbuf, sign, (int)( tz / 3600 ), (int)( tz % 3600 ), msg);
dc8c34
+    size = strlen(buffer);
dc8c34
+
dc8c34
+    if(!locked)
dc8c34
+        LOG_ERROR_LOCK_WRITE();
dc8c34
+
dc8c34
+    slapi_write_buffer((fp), (buffer), (size));
dc8c34
+    PR_Sync(fp);
dc8c34
+
dc8c34
+    if(!locked)
dc8c34
+        LOG_ERROR_UNLOCK_WRITE();
dc8c34
+}
dc8c34
+
dc8c34
 static int
dc8c34
 vslapd_log_error(
dc8c34
     LOGFD	fp,
dc8c34
@@ -3102,9 +3154,6 @@ char rootpath[4];
dc8c34
 		PR_snprintf(buffer, sizeof(buffer),
dc8c34
 			  		"log__enough_freespace: Unable to get the free space (errno:%d)\n",
dc8c34
 					errno);
dc8c34
-		/* This function could be called in the ERROR WRITE LOCK,
dc8c34
-		 * which causes the self deadlock if you call LDAPDebug for logging.
dc8c34
-		 * Thus, instead of LDAPDebug, call log__error_emergency with locked == 1. */
dc8c34
 		log__error_emergency(buffer, 0, 1);
dc8c34
 		return 1;
dc8c34
 	} else {
dc8c34
@@ -3351,9 +3400,6 @@ delete_logfile:
dc8c34
 	PR_snprintf (buffer, sizeof(buffer), "%s.%s", loginfo.log_error_file, tbuf);
dc8c34
 	if (PR_Delete(buffer) != PR_SUCCESS) {
dc8c34
 		PRErrorCode prerr = PR_GetError();
dc8c34
-		/* This function could be called in the ERROR WRITE LOCK,
dc8c34
-		 * which causes the self deadlock if you call LDAPDebug for logging.
dc8c34
-		 * Thus, instead of LDAPDebug, call log__error_emergency with locked == 1. */
dc8c34
 		PR_snprintf(buffer, sizeof(buffer),
dc8c34
 				"LOGINFO:Unable to remove file:%s.%s error %d (%s)\n",
dc8c34
 				loginfo.log_error_file, tbuf, prerr, slapd_pr_strerror(prerr));
dc8c34
@@ -3713,10 +3759,7 @@ log__error_emergency(const char *errstr, int reopen, int locked)
dc8c34
 		PRErrorCode prerr = PR_GetError();
dc8c34
 		syslog(LOG_ERR, "Failed to reopen errors log file, " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n", prerr, slapd_pr_strerror(prerr));
dc8c34
 	} else {
dc8c34
-		/* LDAPDebug locks ERROR_LOCK_WRITE internally */
dc8c34
-		if (locked) LOG_ERROR_UNLOCK_WRITE();
dc8c34
-		LDAPDebug(LDAP_DEBUG_ANY, "%s\n", errstr, 0, 0);
dc8c34
-		if (locked) LOG_ERROR_LOCK_WRITE( );
dc8c34
+		vslapd_log_emergency_error(loginfo.log_error_fdes, errstr, locked);
dc8c34
 	}
dc8c34
 	return;
dc8c34
 }
dc8c34
-- 
dc8c34
1.7.11.7
dc8c34