svn commit: trunk/busybox: include sysklogd

vda at busybox.net vda at busybox.net
Thu Jan 4 21:22:12 UTC 2007


Author: vda
Date: 2007-01-04 13:22:11 -0800 (Thu, 04 Jan 2007)
New Revision: 17159

Log:
syslogd: start using bb_common_bufsiz1 instead of stack/malloc
logger: optimize, also use bb_common_bufsiz1 (~40 bytes)
tested to eat arbitrarily-sized input at high speed - ok


Modified:
   trunk/busybox/include/usage.h
   trunk/busybox/sysklogd/logger.c
   trunk/busybox/sysklogd/syslogd.c


Changeset:
Modified: trunk/busybox/include/usage.h
===================================================================
--- trunk/busybox/include/usage.h	2007-01-04 20:24:28 UTC (rev 17158)
+++ trunk/busybox/include/usage.h	2007-01-04 21:22:11 UTC (rev 17159)
@@ -3009,19 +3009,19 @@
        "System logging utility.\n" \
        "Note that this version of syslogd ignores /etc/syslog.conf." \
        "\n\nOptions:" \
-       "\n	-m MIN	Minutes between MARK lines (default=20, 0=off)" \
-       "\n	-n	Run as a foreground process" \
-       "\n	-O FILE	Use an alternate log file (default=/var/log/messages)" \
-       "\n	-l n	Sets the local log level of messages to n" \
-       "\n	-S	Make logging output smaller" \
+       "\n	-m MIN		Minutes between MARK lines (default=20, 0=off)" \
+       "\n	-n		Run as a foreground process" \
+       "\n	-O FILE		Use an alternate log file (default=/var/log/messages)" \
+       "\n	-l n		Sets the local log level of messages to n" \
+       "\n	-S		Make logging output smaller" \
 	USE_FEATURE_ROTATE_LOGFILE( \
-       "\n	-s SIZE	Max size (KB) before rotate (default=200KB, 0=off)" \
-       "\n	-b NUM	Number of rotated logs to keep (default=1, max=99, 0=purge)") \
+       "\n	-s SIZE		Max size (KB) before rotate (default=200KB, 0=off)" \
+       "\n	-b NUM		Number of rotated logs to keep (default=1, max=99, 0=purge)") \
 	USE_FEATURE_REMOTE_LOG( \
        "\n	-R HOST[:PORT]	Log to IP or hostname on PORT (default PORT=514/UDP)" \
-       "\n	-L	Log locally and via network logging (default is network only)") \
+       "\n	-L		Log locally and via network logging (default is network only)") \
 	USE_FEATURE_IPC_SYSLOG( \
-       "\n	-C[size(KiB)]	Log to a circular buffer (read the buffer using logread)")
+       "\n	-C[size(KiB)]	Log to a shared mem buffer (read the buffer using logread)")
 	/* NB: -Csize shouldn't have space (because size is optional) */
 #define syslogd_example_usage \
        "$ syslogd -R masterlog:514\n" \

Modified: trunk/busybox/sysklogd/logger.c
===================================================================
--- trunk/busybox/sysklogd/logger.c	2007-01-04 20:24:28 UTC (rev 17158)
+++ trunk/busybox/sysklogd/logger.c	2007-01-04 21:22:11 UTC (rev 17159)
@@ -8,13 +8,6 @@
  */
 
 #include "busybox.h"
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <string.h>
-#include <stdlib.h>
 
 #if !defined CONFIG_SYSLOGD
 
@@ -93,49 +86,40 @@
 	char *opt_p, *opt_t;
 	int pri = LOG_USER | LOG_NOTICE;
 	int option = 0;
-	int c, i;
-	char buf[1024], name[128];
+	char name[80];
 
 	/* Fill out the name string early (may be overwritten later) */
 	bb_getpwuid(name, geteuid(), sizeof(name));
 
 	/* Parse any options */
 	opt = getopt32(argc, argv, "p:st:", &opt_p, &opt_t);
+	argc -= optind;
+	argv += optind;
 	if (opt & 0x1) pri = pencode(opt_p); // -p
 	if (opt & 0x2) option |= LOG_PERROR; // -s
 	if (opt & 0x4) safe_strncpy(name, opt_t, sizeof(name)); // -t
 
 	openlog(name, option, 0);
-	if (optind == argc) {
-		do {
-			/* read from stdin */
-			i = 0;
-			while ((c = getc(stdin)) != EOF && c != '\n' &&
-					i < (sizeof(buf)-1)) {
-				buf[i++] = c;
+	if (!argc) {
+		while (fgets(bb_common_bufsiz1, BUFSIZ, stdin)) {
+			if (bb_common_bufsiz1[0]
+			 && NOT_LONE_CHAR(bb_common_bufsiz1, '\n')
+			) {
+				/* Neither "" nor "\n" */
+				syslog(pri, "%s", bb_common_bufsiz1);
 			}
-			if (i > 0) {
-				buf[i++] = '\0';
-				syslog(pri, "%s", buf);
-			}
-		} while (c != EOF);
+		}
 	} else {
 		char *message = NULL;
-		int len = argc - optind; /* for the space between the args
-					    and  '\0' */
-		opt = len;
-		argv += optind;
-		for (i = 0; i < opt; i++) {
-			len += strlen(*argv);
+		int len = 1; /* for NUL */
+		int pos = 0;
+		do {
+			len += strlen(*argv) + 1;
 			message = xrealloc(message, len);
-			if(!i)
-				message[0] = '\0';
-			else
-				strcat(message, " ");
-			strcat(message, *argv);
-			argv++;
-		}
-		syslog(pri, "%s", message);
+			sprintf(message + pos, " %s", *argv),
+			pos = len;
+		} while (*++argv);
+		syslog(pri, "%s", message + 1); /* skip leading " " */
 	}
 
 	closelog();

Modified: trunk/busybox/sysklogd/syslogd.c
===================================================================
--- trunk/busybox/sysklogd/syslogd.c	2007-01-04 20:24:28 UTC (rev 17158)
+++ trunk/busybox/sysklogd/syslogd.c	2007-01-04 21:22:11 UTC (rev 17159)
@@ -56,13 +56,23 @@
 static struct sockaddr_in remoteAddr;
 #endif
 
+/* We are using bb_common_bufsiz1 for buffering: */
+enum { MAX_READ = (BUFSIZ/6) & ~0xf };
+/* We recv into this... (size: MAX_READ ~== BUFSIZ/6) */
+#define RECVBUF  bb_common_bufsiz1
+/* ...then copy here, escaping control chars */
+/* (can grow x2 + 1 max ~== BUFSIZ/3) */
+#define PARSEBUF (bb_common_bufsiz1 + MAX_READ)
+/* ...then sprintf into this, adding timestamp (15 chars),
+ * host (64), fac.prio (20) to the message */
+/* (growth by: 15 + 64 + 20 + delims = ~110) */
+#define PRINTBUF (bb_common_bufsiz1 + 3*MAX_READ + 0x10)
+/* totals: BUFSIZ/6 + BUFSIZ/3 + BUFSIZ/3 = BUFSIZ - BUFSIZ/6
+ * -- we have BUFSIZ/6 extra at the ent of PRINTBUF
+ * which covers needed ~110 extra bytes (and much more) */
 
-/* NB: we may need 2x this amount on stack... */
-enum { MAX_READ = 1024 };
 
-
-/* options */
-/* Correct regardless of combination of CONFIG_xxx */
+/* Options */
 enum {
 	OPTBIT_mark = 0, // -m
 	OPTBIT_nofork, // -n
@@ -175,11 +185,12 @@
 	}
 }
 
-/* write message to buffer */
+/* Write message to shared mem buffer */
 static void log_to_shmem(const char *msg, int len)
 {
-	static /*const*/ struct sembuf SMwup[1] = { {1, -1, IPC_NOWAIT} };
-	static /*const*/ struct sembuf SMwdn[3] = { {0, 0}, {1, 0}, {1, +1} };
+	/* Why libc insists on these being rw? */
+	static struct sembuf SMwup[1] = { {1, -1, IPC_NOWAIT} };
+	static struct sembuf SMwdn[3] = { {0, 0}, {1, 0}, {1, +1} };
 
 	int old_tail, new_tail;
 	char *c;
@@ -362,9 +373,9 @@
 	}
 }
 
-/* len parameter is used only for "is there a timestamp?" check
+/* len parameter is used only for "is there a timestamp?" check.
  * NB: some callers cheat and supply 0 when they know
- * that there is no timestamp, short-cutting the test */
+ * that there is no timestamp, short-cutting the test. */
 static void timestamp_and_log(int pri, char *msg, int len)
 {
 	time_t now;
@@ -385,31 +396,29 @@
 	if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) {
 		if (LOG_PRI(pri) < logLevel) {
 			if (option_mask32 & OPT_small)
-				msg = xasprintf("%s %s\n", timestamp, msg);
+				sprintf(PRINTBUF, "%s %s\n", timestamp, msg);
 			else {
 				char res[20];
 				parse_fac_prio_20(pri, res);
-				msg = xasprintf("%s %s %s %s\n", timestamp, localHostName, res, msg);
+				sprintf(PRINTBUF, "%s %s %s %s\n", timestamp, localHostName, res, msg);
 			}
-			log_locally(msg);
-			free(msg);
+			log_locally(PRINTBUF);
 		}
 	}
 }
 
 static void split_escape_and_log(char *tmpbuf, int len)
 {
-	char line[len * 2 + 1]; /* gcc' cheap alloca */
 	char *p = tmpbuf;
 
 	tmpbuf += len;
 	while (p < tmpbuf) {
 		char c;
-		char *q = line;
+		char *q = PARSEBUF;
 		int pri = (LOG_USER | LOG_NOTICE);
 
 		if (*p == '<') {
-			/* Parse the magic priority number. */
+			/* Parse the magic priority number */
 			pri = bb_strtou(p + 1, &p, 10);
 			if (*p == '>') p++;
 			if (pri & ~(LOG_FACMASK | LOG_PRIMASK)) {
@@ -427,8 +436,8 @@
 			*q++ = c;
 		}
 		*q = '\0';
-		/* now log it */
-		timestamp_and_log(pri, line, q - line);
+		/* Now log it */
+		timestamp_and_log(pri, PARSEBUF, q - PARSEBUF);
 	}
 }
 
@@ -509,11 +518,10 @@
 
 		if (FD_ISSET(sock_fd, &fds)) {
 			int i;
-#define tmpbuf bb_common_bufsiz1
-			i = recv(sock_fd, tmpbuf, MAX_READ, 0);
+			i = recv(sock_fd, RECVBUF, MAX_READ - 1, 0);
 			if (i <= 0)
 				bb_perror_msg_and_die("UNIX socket error");
-			/* TODO: maybe supress duplicates? */
+			/* TODO: maybe suppress duplicates? */
 #if ENABLE_FEATURE_REMOTE_LOG
 			/* We are not modifying log messages in any way before send */
 			/* Remote site cannot trust _us_ anyway and need to do validation again */
@@ -523,15 +531,14 @@
 				}
 				if (-1 != remoteFD) {
 					/* send message to remote logger, ignore possible error */
-					sendto(remoteFD, tmpbuf, i, MSG_DONTWAIT,
+					sendto(remoteFD, RECVBUF, i, MSG_DONTWAIT,
 						(struct sockaddr *) &remoteAddr,
 						sizeof(remoteAddr));
 				}
 			}
 #endif
-			tmpbuf[i] = '\0';
-			split_escape_and_log(tmpbuf, i);
-#undef tmpbuf
+			RECVBUF[i] = '\0';
+			split_escape_and_log(RECVBUF, i);
 		} /* FD_ISSET() */
 	} /* for */
 }




More information about the busybox-cvs mailing list