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