[Fedora-directory-commits] ldapserver/ldap/servers/slapd log.h, 1.4, 1.4.2.1 log.c, 1.6.2.4, 1.6.2.5

Noriko Hosoi (nhosoi) fedora-directory-commits at redhat.com
Fri Dec 21 21:35:10 UTC 2007


Author: nhosoi

Update of /cvs/dirsec/ldapserver/ldap/servers/slapd
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv11544

Modified Files:
      Tag: Directory71RtmBranch
	log.h log.c 
Log Message:
Resolves: #202890
Summary: 202890: Crash at startup with 0kB rotationinfo files
Note: applying the fixes in HEAD to Directory71RtmBranch



Index: log.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/log.h,v
retrieving revision 1.4
retrieving revision 1.4.2.1
diff -u -r1.4 -r1.4.2.1
--- log.h	19 Apr 2005 22:07:36 -0000	1.4
+++ log.h	21 Dec 2007 21:35:08 -0000	1.4.2.1
@@ -69,6 +69,7 @@
 #define LOG_EXCEEDED 		2		/*err: > max logs allowed */
 #define LOG_ROTATE		3		/*ok; go to the next log */
 #define LOG_UNABLE_TO_OPENFILE  4
+#define LOG_DONE		5
 
 #define LOG_UNIT_UNKNOWN	0
 #define LOG_UNIT_MONTHS 	1
@@ -91,6 +92,8 @@
 
 #define LOG_BUFFER_MAXSIZE          512 * 1024
 
+#define PREVLOGFILE	"Previous Log File:"
+
 /* see log.c for why this is done */
 #ifdef XP_WIN32
 typedef FILE *LOGFD;


Index: log.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/log.c,v
retrieving revision 1.6.2.4
retrieving revision 1.6.2.5
diff -u -r1.6.2.4 -r1.6.2.5
--- log.c	19 Mar 2006 18:37:45 -0000	1.6.2.4
+++ log.c	21 Dec 2007 21:35:08 -0000	1.6.2.5
@@ -58,6 +58,9 @@
 #include "proto-ntutil.h"
 extern HANDLE hSlapdEventSource;
 extern LPTSTR pszServerName;
+#define _PSEP '\\'
+#else
+#define _PSEP '/'
 #endif
 /**************************************************************************
  * GLOBALS, defines, and ...
@@ -114,12 +117,14 @@
 static int 	log__error_rotationinfof(char *pathname);
 static int 	log__audit_rotationinfof(char *pathname);
 static int 	log__extract_logheader (FILE *fp, long  *f_ctime, int *f_size);
+static int	log__check_prevlogs (FILE *fp, char *filename);
 static int 	log__getfilesize(LOGFD fp);
 static int 	log__enough_freespace(char  *path);
 
 static int 	vslapd_log_error(LOGFD fp, char *subsystem, char *fmt, va_list ap );
 static int 	vslapd_log_access(char *fmt, va_list ap );
 static void	log_convert_time (time_t ctime, char *tbuf, int type);
+static time_t	log_reverse_convert_time (char *tbuf);
 static LogBufferInfo *log_create_buffer(size_t sz);
 static void	log_append_buffer2(time_t tnl, LogBufferInfo *lbi, char *msg1, size_t size1, char *msg2, size_t size2);
 static void	log_flush_buffer(LogBufferInfo *lbi, int type, int sync_now);
@@ -2128,8 +2133,8 @@
 	logp = loginfo.log_access_logchain;
 	while ( logp) {
 		log_convert_time (logp->l_ctime, tbuf, 1 /*short*/);
-		PR_snprintf(buffer, sizeof(buffer), "LOGINFO:Previous Log File:%s.%s (%lu) (%u)\n",
-                        loginfo.log_access_file, tbuf, logp->l_ctime, logp->l_size);
+		PR_snprintf(buffer, sizeof(buffer), "LOGINFO:%s%s.%s (%lu) (%u)\n",
+			PREVLOGFILE, loginfo.log_access_file, tbuf, logp->l_ctime, logp->l_size);
 		LOG_WRITE(fpinfo, buffer, strlen(buffer), 0);
 		logp = logp->l_next;
 	}
@@ -2429,6 +2434,130 @@
     
 	return 1;
 }
+
+#define ERRORSLOG 1
+#define ACCESSLOG 2
+#define AUDITLOG  3
+
+static int
+log__fix_rotationinfof(char *pathname)
+{
+	char		*logsdir = NULL;
+	time_t		now;
+	PRDir		*dirptr = NULL;
+	PRDirEntry	*dirent = NULL;
+	PRDirFlags	dirflags = PR_SKIP_BOTH & PR_SKIP_HIDDEN;
+	char		*log_type = NULL;
+	int			log_type_id;
+	int			rval = LOG_ERROR;
+	char		*p;
+
+	/* rotation info file is broken; can't trust the contents */
+	time (&now);
+	loginfo.log_error_ctime = now;
+	logsdir = slapi_ch_strdup(pathname);
+	p = strrchr(logsdir, _PSEP);
+	if (NULL == p) /* pathname is not path/filename.rotationinfo; do nothing */
+		goto done;
+
+	*p = '\0';
+	log_type = ++p;
+	p = strchr(log_type, '.');
+	if (NULL == p) /* file is not rotationinfo; do nothing */
+		goto done;
+	*p = '\0';
+
+	if (0 == strcmp(log_type, "errors"))
+		log_type_id = ERRORSLOG;
+	else if (0 == strcmp(log_type, "access"))
+		log_type_id = ACCESSLOG;
+	else if (0 == strcmp(log_type, "audit"))
+		log_type_id = AUDITLOG;
+	else 
+		goto done; /* file is not errors nor access nor audit; do nothing */
+
+	if (!(dirptr = PR_OpenDir(logsdir)))
+		goto done;
+
+	switch (log_type_id) {
+	case ERRORSLOG:
+		loginfo.log_numof_error_logs = 0;
+		loginfo.log_error_logchain = NULL;
+		break;
+	case ACCESSLOG:
+		loginfo.log_numof_access_logs = 0;
+		loginfo.log_access_logchain = NULL;
+		break;
+	case AUDITLOG:
+		loginfo.log_numof_audit_logs = 0;
+		loginfo.log_audit_logchain = NULL;
+		break;
+	}
+	/* read the directory entries into a linked list */
+	for (dirent = PR_ReadDir(dirptr, dirflags); dirent ;
+		dirent = PR_ReadDir(dirptr, dirflags)) {
+		if (0 == strcmp(log_type, dirent->name)) {
+			switch (log_type_id) {
+			case ERRORSLOG:
+				loginfo.log_numof_error_logs++;
+				break;
+			case ACCESSLOG:
+				loginfo.log_numof_access_logs++;
+				break;
+			case AUDITLOG:
+				loginfo.log_numof_audit_logs++;
+				break;
+			}
+		} else if (0 == strncmp(log_type, dirent->name, strlen(log_type)) &&
+			(p = strrchr(dirent->name, '.')) != NULL &&
+			15 == strlen(++p) &&
+			NULL != strchr(p, '-')) { /* e.g., errors.20051123-165135 */
+			struct	logfileinfo	*logp;
+			char *q;
+			int ignoreit = 0;
+
+			for (q = p; q && *q; q++) {
+				if (*q != '-' && !isdigit(*q))
+					ignoreit = 1;
+			}
+			if (ignoreit)
+				continue;
+
+			logp = (struct logfileinfo *) slapi_ch_malloc (sizeof (struct logfileinfo));
+			logp->l_ctime = log_reverse_convert_time(p);
+			switch (log_type_id) {
+			case ERRORSLOG:
+				logp->l_size = loginfo.log_error_maxlogsize; /* dummy */
+				logp->l_next = loginfo.log_error_logchain;
+				loginfo.log_error_logchain = logp;
+				loginfo.log_numof_error_logs++;
+				break;
+			case ACCESSLOG:
+				logp->l_size = loginfo.log_access_maxlogsize;
+				logp->l_next = loginfo.log_access_logchain;
+				loginfo.log_access_logchain = logp;
+				loginfo.log_numof_access_logs++;
+				break;
+			case AUDITLOG:
+				logp->l_size =loginfo.log_audit_maxlogsize; 
+				logp->l_next = loginfo.log_audit_logchain;
+				loginfo.log_audit_logchain = logp;
+				loginfo.log_numof_audit_logs++;
+				break;
+			}
+		}
+	}
+	rval = LOG_SUCCESS;
+done:
+	if (NULL != dirptr)
+		PR_CloseDir(dirptr);
+	slapi_ch_free_string(&logsdir);
+	return rval;
+}
+#undef ERRORSLOG
+#undef ACCESSLOG
+#undef AUDITLOG
+
 /******************************************************************************
 * log__access_rotationinfof
 *
@@ -2445,8 +2574,8 @@
 	int		main_log = 1;
 	time_t		now;
 	FILE		*fp;
+	int		rval, logfile_type = LOGFILE_REOPENED;
 
-	
 	/*
 	** Okay -- I confess, we want to use NSPR calls but I want to
 	** use fgets and not use PR_Read() and implement a complicated
@@ -2464,7 +2593,7 @@
 	** We have reopened the log access file. Now we need to read the
 	** log file info and update the values.
 	*/
-	while (log__extract_logheader(fp, &f_ctime, &f_size) == LOG_CONTINUE) {
+	while ((rval = log__extract_logheader(fp, &f_ctime, &f_size)) == LOG_CONTINUE) {
 		/* first we would get the main log info */
 		if (f_ctime == 0 && f_size == 0)
 			continue;
@@ -2497,16 +2626,94 @@
 		}
 		loginfo.log_numof_access_logs++;
 	}
+	if (LOG_DONE == rval)
+		rval = log__check_prevlogs(fp, pathname);
+	fclose (fp);
+
+	if (LOG_ERROR == rval)
+		if (LOG_SUCCESS == log__fix_rotationinfof(pathname))
+			logfile_type = LOGFILE_NEW;
 
 	/* Check if there is a rotation overdue */
 	if (loginfo.log_access_rotationsync_enabled &&
 		loginfo.log_access_rotationunit != LOG_UNIT_HOURS &&
 		loginfo.log_access_rotationunit != LOG_UNIT_MINS &&
-		loginfo.log_access_ctime < loginfo.log_access_rotationsyncclock - loginfo.log_access_rotationtime_secs) {
-		loginfo.log_access_rotationsyncclock -= loginfo.log_access_rotationtime_secs;
+		loginfo.log_access_ctime < loginfo.log_access_rotationsyncclock - PR_ABS(loginfo.log_access_rotationtime_secs)) {
+		loginfo.log_access_rotationsyncclock -= PR_ABS(loginfo.log_access_rotationtime_secs);
 	}
-	fclose (fp);
-	return LOGFILE_REOPENED;
+	return logfile_type;
+}
+
+/*
+* log__check_prevlogs
+* 
+* check if a given prev log file (e.g., /opt/fedora-ds/slapd-fe/logs/errors.20051201-101347)
+* is found in the rotationinfo file.
+*/
+static int
+log__check_prevlogs (FILE *fp, char *pathname)
+{
+	char		buf[BUFSIZ], *p;
+	char		*logsdir = NULL;
+	int			rval = LOG_CONTINUE;
+	char		*log_type = NULL;
+	PRDir		*dirptr = NULL;
+	PRDirEntry	*dirent = NULL;
+	PRDirFlags	dirflags = PR_SKIP_BOTH & PR_SKIP_HIDDEN;
+
+	logsdir = slapi_ch_strdup(pathname);
+	p = strrchr(logsdir, _PSEP);
+	if (NULL == p) /* pathname is not path/filename.rotationinfo; do nothing */
+		goto done;
+
+	*p = '\0';
+	log_type = ++p;
+	p = strchr(log_type, '.');
+	if (NULL == p) /* file is not rotationinfo; do nothing */
+		goto done;
+	*p = '\0';
+
+	if (0 != strcmp(log_type, "errors") &&
+		0 != strcmp(log_type, "access") &&
+		0 != strcmp(log_type, "audit"))
+		goto done; /* file is not errors nor access nor audit; do nothing */
+
+	if (!(dirptr = PR_OpenDir(logsdir)))
+		goto done;
+
+	for (dirent = PR_ReadDir(dirptr, dirflags); dirent ;
+		dirent = PR_ReadDir(dirptr, dirflags)) {
+		if (0 == strncmp(log_type, dirent->name, strlen(log_type)) &&
+			(p = strrchr(dirent->name, '.')) != NULL &&
+			15 == strlen(++p) &&
+			NULL != strchr(p, '-')) { /* e.g., errors.20051123-165135 */
+			char *q;
+			int ignoreit = 0;
+
+			for (q = p; q && *q; q++) {
+				if (*q != '-' && !isdigit(*q))
+					ignoreit = 1;
+			}
+			if (ignoreit)
+				continue;
+
+			fseek(fp, 0 ,SEEK_SET);
+			buf[BUFSIZ-1] = '\0';
+			while (fgets(buf, BUFSIZ - 1, fp)) {
+				if (strstr(buf, dirent->name)) {
+					rval = LOG_CONTINUE;	/* found in .rotationinfo */
+					continue;
+				}	
+			}
+			rval = LOG_ERROR;	/* not found in .rotationinfo */
+			break;
+		}
+	}
+done:
+	if (NULL != dirptr)
+		PR_CloseDir(dirptr);
+	slapi_ch_free_string(&logsdir);
+	return rval;
 }
 
 /******************************************************************************
@@ -2528,8 +2735,9 @@
 	if ( fp == NULL)
 		return LOG_ERROR;
 
-	if (fgets(buf, BUFSIZ, fp) == NULL) {
-		return LOG_ERROR;
+	buf[BUFSIZ-1] = '\0'; /* for safety */
+	if (fgets(buf, BUFSIZ - 1, fp) == NULL) {
+		return LOG_DONE;
 	}
 
 	if ((p=strstr(buf, "LOGINFO")) == NULL) {
@@ -2568,6 +2776,23 @@
 	/* Now p must hold the size value */
 	*f_size = atoi(p);
 
+	/* check if the Previous Log file really exists */
+	if ((p = strstr(buf, PREVLOGFILE)) != NULL) {
+		p += strlen(PREVLOGFILE);
+		s = strchr(p, ' ');
+		if (NULL == s) {
+			s = strchr(p, '(');
+			if (NULL != s) {
+				*s = '\0';
+			}
+		} else {
+			*s = '\0';
+		}
+		if (PR_SUCCESS != PR_Access(p, PR_ACCESS_EXISTS)) {
+			return LOG_ERROR;
+		}
+	}
+
 	return LOG_CONTINUE;
 	
 }
@@ -2719,13 +2944,17 @@
 	   default:
 		return NULL;
 	}
-	list = (char **) slapi_ch_calloc(1, num * sizeof(char *));
+	list = (char **) slapi_ch_calloc(1, (num + 1) * sizeof(char *));
 	i = 0;
 	while (logp) {
 		log_convert_time (logp->l_ctime, tbuf, 1 /*short */);
 		PR_snprintf(buf, sizeof(buf), "%s.%s", file, tbuf);
 		list[i] = slapi_ch_strdup(buf);
 		i++;
+		if (i == num) { /* mismatch b/w num and logchain;
+						   cut the chain and save the process */
+			break;
+		}
 		logp = logp->l_next;
 	}
 	list[i] = NULL;
@@ -3066,7 +3295,7 @@
 	int		main_log = 1;
 	time_t		now;
 	FILE		*fp;
-
+	int		rval, logfile_type = LOGFILE_REOPENED;
 	
 	/*
 	** Okay -- I confess, we want to use NSPR calls but I want to
@@ -3085,7 +3314,7 @@
 	** We have reopened the log error file. Now we need to read the
 	** log file info and update the values.
 	*/
-	while (log__extract_logheader(fp, &f_ctime, &f_size) == LOG_CONTINUE) {
+	while ((rval = log__extract_logheader(fp, &f_ctime, &f_size)) == LOG_CONTINUE) {
 		/* first we would get the main log info */
 		if (f_ctime == 0 && f_size == 0)
 			continue;
@@ -3118,17 +3347,23 @@
 		}
 		loginfo.log_numof_error_logs++;
 	}
+	if (LOG_DONE == rval)
+		rval = log__check_prevlogs(fp, pathname);
+	fclose (fp);
+
+	if (LOG_ERROR == rval)
+		if (LOG_SUCCESS == log__fix_rotationinfof(pathname))
+			logfile_type = LOGFILE_NEW;
 
 	/* Check if there is a rotation overdue */
 	if (loginfo.log_error_rotationsync_enabled &&
 		loginfo.log_error_rotationunit != LOG_UNIT_HOURS &&
 		loginfo.log_error_rotationunit != LOG_UNIT_MINS &&
-		loginfo.log_error_ctime < loginfo.log_error_rotationsyncclock - loginfo.log_error_rotationtime_secs) {
-		loginfo.log_error_rotationsyncclock -= loginfo.log_error_rotationtime_secs;
+		loginfo.log_error_ctime < loginfo.log_error_rotationsyncclock - PR_ABS(loginfo.log_error_rotationtime_secs)) {
+		loginfo.log_error_rotationsyncclock -= PR_ABS(loginfo.log_error_rotationtime_secs);
 	}
 
-	fclose (fp);
-	return LOGFILE_REOPENED;
+	return logfile_type;
 }
 
 /******************************************************************************
@@ -3147,7 +3382,7 @@
 	int		main_log = 1;
 	time_t		now;
 	FILE		*fp;
-
+	int		rval, logfile_type = LOGFILE_REOPENED;
 	
 	/*
 	** Okay -- I confess, we want to use NSPR calls but I want to
@@ -3166,7 +3401,7 @@
 	** We have reopened the log audit file. Now we need to read the
 	** log file info and update the values.
 	*/
-	while (log__extract_logheader(fp, &f_ctime, &f_size) == LOG_CONTINUE) {
+	while ((rval = log__extract_logheader(fp, &f_ctime, &f_size)) == LOG_CONTINUE) {
 		/* first we would get the main log info */
 		if (f_ctime == 0 && f_size == 0)
 			continue;
@@ -3199,17 +3434,23 @@
 		}
 		loginfo.log_numof_audit_logs++;
 	}
+	if (LOG_DONE == rval)
+		rval = log__check_prevlogs(fp, pathname);
+	fclose (fp);
+
+	if (LOG_ERROR == rval)
+		if (LOG_SUCCESS == log__fix_rotationinfof(pathname))
+			logfile_type = LOGFILE_NEW;
 
 	/* Check if there is a rotation overdue */
 	if (loginfo.log_audit_rotationsync_enabled &&
 		loginfo.log_audit_rotationunit != LOG_UNIT_HOURS &&
 		loginfo.log_audit_rotationunit != LOG_UNIT_MINS &&
-		loginfo.log_audit_ctime < loginfo.log_audit_rotationsyncclock - loginfo.log_audit_rotationtime_secs) {
-		loginfo.log_audit_rotationsyncclock -= loginfo.log_audit_rotationtime_secs;
+		loginfo.log_audit_ctime < loginfo.log_audit_rotationsyncclock - PR_ABS(loginfo.log_audit_rotationtime_secs)) {
+		loginfo.log_audit_rotationsyncclock -= PR_ABS(loginfo.log_audit_rotationtime_secs);
 	}
 
-	fclose (fp);
-	return LOGFILE_REOPENED;
+	return logfile_type;
 }
 
 /******************************************************************************
@@ -3336,8 +3577,8 @@
 	logp = loginfo.log_error_logchain;
 	while ( logp) {
 		log_convert_time (logp->l_ctime, tbuf, 1 /*short */);
-		PR_snprintf(buffer, sizeof(buffer), "LOGINFO:Previous Log File:%s.%s (%lu) (%u)\n",
-                        loginfo.log_error_file,	tbuf, logp->l_ctime, logp->l_size);
+		PR_snprintf(buffer, sizeof(buffer), "LOGINFO:%s%s.%s (%lu) (%u)\n",
+			PREVLOGFILE, loginfo.log_error_file, tbuf, logp->l_ctime, logp->l_size);
 		LOG_WRITE(fpinfo, buffer, strlen(buffer), 0);
 		logp = logp->l_next;
 	}
@@ -3457,8 +3698,8 @@
 	logp = loginfo.log_audit_logchain;
 	while ( logp) {
 		log_convert_time (logp->l_ctime, tbuf, 1 /*short */);	
-		PR_snprintf(buffer, sizeof(buffer), "LOGINFO:Previous Log File:%s.%s (%d) (%d)\n",
-                        loginfo.log_audit_file, tbuf, (int)logp->l_ctime, logp->l_size);
+		PR_snprintf(buffer, sizeof(buffer), "LOGINFO:%s%s.%s (%d) (%d)\n",
+			PREVLOGFILE, loginfo.log_audit_file, tbuf, (int)logp->l_ctime, logp->l_size);
 		LOG_WRITE(fpinfo, buffer, strlen(buffer), 0);
 		logp = logp->l_next;
 	}
@@ -3629,7 +3870,6 @@
 static void
 log_convert_time (time_t ctime, char *tbuf, int type)
 {
-
 	struct tm               *tmsp, tms;
 
 #ifdef _WIN32
@@ -3649,6 +3889,27 @@
 
 }
 
+/*
+ * log_reverse_convert_time
+ *	convert the given string formatted time (output from log_convert_time)
+ *  into time_t
+ */
+static time_t
+log_reverse_convert_time(char *tbuf)
+{
+	struct tm tm;
+
+	if (strchr(tbuf, '-')) { /* short format */
+		strptime(tbuf, "%Y%m%d-%H%M%S", &tm);
+	} else if (strchr(tbuf, '/') && strchr(tbuf, ':')) { /* long format */
+		strptime(tbuf, "%d/%b/%Y:%H:%M:%S", &tm);
+	} else {
+		return 0;
+	}
+
+	return mktime(&tm);
+}
+
 int
 check_log_max_size( char *maxdiskspace_str,
                     char *mlogsize_str,




More information about the Fedora-directory-commits mailing list