[PATCH] log-simple: Rework engine to write complete message in one pass

Cyrill Gorcunov gorcunov at openvz.org
Fri Mar 1 03:06:58 EST 2013


At the moment we don't write messages which uses own
minimal printf engine in atomic manner. Every time
an argument from pr_() helper met, it get flushed
immediately. This leads into a mess in output.

For examle

 | __sent ack msg: (00.049334) Fetched ack: 15619 8 8 0
 | (00.049385) Waiting for 15619 to trap
 | (00.049400) Daemon 15619 exited trapping
 | 15619(00.049414) Sent msg to daemon 15620 8 0 0
 | (00.049455) Wait for ack 15620-8 on daemon socket
 | 8 8 0
 | Daemon wais for command

So what we need is to provide own buffer in our log-simple.c,
fill it first and only the write it to a file.

So with this patch applied all writes are granular.

 | __sent ack msg: 16667 8 8 0
 | Daemon wais for command
 | (00.034946) Fetched ack: 16667 8 8 0
 | (00.034987) Waiting for 16667 to trap
 | (00.035004) Daemon 16667 exited trapping
 | (00.035041) Sent msg to daemon 16668 8 0 0
 | (00.035058) Wait for ack 16668-8 on daemon socket
 | __fetched msg: 16668 8 0 0

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 include/log.h    |   2 +-
 pie/log-simple.c | 222 ++++++++++++++++++++++---------------------------------
 pie/restorer.c   |   6 +-
 3 files changed, 92 insertions(+), 138 deletions(-)

diff --git a/include/log.h b/include/log.h
index a38f441..7eaec45 100644
--- a/include/log.h
+++ b/include/log.h
@@ -14,7 +14,7 @@ extern int log_get_fd(void);
 extern void log_set_loglevel(unsigned int loglevel);
 extern unsigned int log_get_loglevel(void);
 
-extern int vprint_num(char *buf, int blen, int num, char **ps);
+extern int vprint_num(char *dst, int size, int num);
 
 extern void print_on_level(unsigned int loglevel, const char *format, ...)
 	__attribute__ ((__format__ (__printf__, 2, 3)));
diff --git a/pie/log-simple.c b/pie/log-simple.c
index 36c5c22..d4a7d4a 100644
--- a/pie/log-simple.c
+++ b/pie/log-simple.c
@@ -1,5 +1,7 @@
 #include <stdarg.h>
 #include "syscall.h"
+
+#include "compiler.h"
 #include "log.h"
 #include "log-levels.h"
 
@@ -17,20 +19,22 @@ void log_set_loglevel(unsigned int level)
 	cur_loglevel = level;
 }
 
-static void print_string(const char *msg)
+static int vprint_string(char *dst, int size, char *src)
 {
-	int size = 0;
-	while (msg[size])
-		size++;
-	sys_write(logfd, msg, size);
+	int i;
+
+	for (i = 0; i < size && src[i]; i++)
+		dst[i] = src[i];
+
+	return i;
 }
 
-int vprint_num(char *buf, int blen, int num, char **ps)
+static int vprint_num_l(char *dst, int size, long num)
 {
-	int neg = 0;
-	char *s;
+	char buf[32] = { }, *s;
+	int neg = 0, len;
 
-	s = &buf[blen - 1];
+	s = &buf[31];
 
 	if (num < 0) {
 		neg = 1;
@@ -52,155 +56,105 @@ int vprint_num(char *buf, int blen, int num, char **ps)
 		s--;
 	}
 done:
-	s++;
-	*ps = s;
-	return blen - (s - buf);
-}
-
-static void print_num(int num)
-{
-	char buf[11], *s;
-	int len;
+	s++, len = sizeof(buf) - (s - buf);
 
-	len = vprint_num(buf, sizeof(buf), num, &s);
-	sys_write(logfd, s, len);
+	return vprint_string(dst, min(size, len), s);
 }
 
-static void print_num_l(long num)
+int vprint_num(char *dst, int size, int num)
 {
-	int neg = 0;
-	char buf[21], *s;
-
-	s = &buf[20];
-
-	if (num < 0) {
-		neg = 1;
-		num = -num;
-	} else if (num == 0) {
-		*s = '0';
-		s--;
-		goto done;
-	}
+	return vprint_num_l(dst, size, (long)num);
+}
 
-	while (num > 0) {
-		*s = (num % 10) + '0';
-		s--;
-		num /= 10;
-	}
+#define hexdigit(val)	(char)("0123456789abcdef"[(unsigned long)val & 0xful])
+#define ___e(b, x)	b[sizeof(b) - x]
 
-	if (neg) {
-		*s = '-';
-		s--;
+static int vprint_hex_l(char *dst, int size, unsigned long num)
+{
+	char buf[32] = { };
+	int i, len;
+
+	if (!num) {
+		___e(buf, 1) = '\0';
+		___e(buf, 2) = '0';
+		___e(buf, 3) = 'x';
+		___e(buf, 4) = '0';
+		i = sizeof(buf) - 4;
+	} else {
+		for (i = sizeof(buf) - 2; num > 0 && i >= 2; i--, num /= 16)
+			buf[i] = hexdigit(num);
+		buf[i--] = 'x', buf[i] = '0';
 	}
-done:
-	s++;
-	sys_write(logfd, s, sizeof(buf) - (s - buf));
-}
 
-static void hexdigit(unsigned int v, char *to, char **z)
-{
-	*to = "0123456789abcdef"[v & 0xf];
-	if (*to != '0')
-		*z = to;
-}
+	len = sizeof(buf) - i;
 
-static void print_hex(unsigned int num)
-{
-	char buf[10], *z = &buf[9];
-
-	hexdigit(num >> 0, &buf[9], &z);
-	hexdigit(num >> 4, &buf[8], &z);
-	hexdigit(num >> 8, &buf[7], &z);
-	hexdigit(num >> 12, &buf[6], &z);
-	hexdigit(num >> 16, &buf[5], &z);
-	hexdigit(num >> 20, &buf[4], &z);
-	hexdigit(num >> 24, &buf[3], &z);
-	hexdigit(num >> 28, &buf[2], &z);
-	z -= 2;
-	z[0] = '0';
-	z[1] = 'x';
-
-	sys_write(logfd, z, sizeof(buf) - (z - buf));
+	return vprint_string(dst, min(size, len), &buf[i]);
 }
 
-static void print_hex_l(unsigned long num)
+static int vprint_hex(char *dst, int size, unsigned int num)
 {
-	char buf[18], *z = &buf[17];
-
-	hexdigit(num >> 0, &buf[17], &z);
-	hexdigit(num >> 4, &buf[16], &z);
-	hexdigit(num >> 8, &buf[15], &z);
-	hexdigit(num >> 12, &buf[14], &z);
-	hexdigit(num >> 16, &buf[13], &z);
-	hexdigit(num >> 20, &buf[12], &z);
-	hexdigit(num >> 24, &buf[11], &z);
-	hexdigit(num >> 28, &buf[10], &z);
-
-#if BITS_PER_ULONG == 64
-	hexdigit(num >> 32, &buf[9], &z);
-	hexdigit(num >> 36, &buf[8], &z);
-	hexdigit(num >> 40, &buf[7], &z);
-	hexdigit(num >> 44, &buf[6], &z);
-	hexdigit(num >> 48, &buf[5], &z);
-	hexdigit(num >> 52, &buf[4], &z);
-	hexdigit(num >> 56, &buf[3], &z);
-	hexdigit(num >> 60, &buf[2], &z);
-#endif
-
-	z -= 2;
-	z[0] = '0';
-	z[1] = 'x';
-
-	sys_write(logfd, z, sizeof(buf) - (z - buf));
+	return vprint_hex_l(dst, size, (unsigned long)num);
 }
 
 void print_on_level(unsigned int loglevel, const char *format, ...)
 {
+	const char *s = format;
+	char buf[256] = { };
+	int off, size;
 	va_list args;
-	const char *s = format, *p;
 
 	if (loglevel > cur_loglevel)
 		return;
 
-	va_start(args, format);
-	p = s;
-	while (1) {
-		int along = 0;
+	off = 0, size = sizeof(buf) - 1;
 
-		if (*s != '\0' && *s != '%') {
-			s++;
-			continue;
-		}
-
-		sys_write(logfd, p, s - p);
-		if (*s == '\0')
-			break;
-
-		s++;
-		if (*s == 'l') {
-			along = 1;
-			s++;
-		}
-
-		switch (*s) {
-		case 's':
-			print_string(va_arg(args, char *));
-			break;
-		case 'd':
-			if (along)
-				print_num_l(va_arg(args, long));
-			else
-				print_num(va_arg(args, int));
-			break;
-		case 'x':
-			if (along)
-				print_hex_l(va_arg(args, long));
-			else
-				print_hex(va_arg(args, unsigned int));
+	va_start(args, format);
+	for (; *s; s++) {
+		int aslong = 0, mpos = 1;
+
+		if (*s == '%') {
+			if (s[mpos] == 'l')
+				aslong++, mpos++;
+
+			switch (s[mpos]) {
+			case 's':
+				off += vprint_string(&buf[off], size - off,
+						     va_arg(args, char *));
+				s += mpos;
+				break;
+			case 'x':
+				if (aslong)
+					off += vprint_hex_l(&buf[off], size - off,
+							    va_arg(args, long));
+				else
+					off += vprint_hex(&buf[off], size - off,
+							  va_arg(args, int));
+				s += mpos;
+				break;
+			case 'i':
+			case 'd':
+				if (aslong)
+					off += vprint_num_l(&buf[off], size - off,
+							    va_arg(args, long));
+				else
+					off += vprint_num(&buf[off], size - off,
+							  va_arg(args, int));
+				s += mpos;
+				break;
+			default:
+				buf[off++] = *s;
+				break;
+			}
+		} else
+			buf[off++] = *s;
+
+		if (off >= size) {
+			off = size;
 			break;
 		}
-		s++;
-		p = s;
 	}
 	va_end(args);
+
+	buf[off] = 0;
+	sys_write(logfd, buf, off);
 }
diff --git a/pie/restorer.c b/pie/restorer.c
index 54b9b83..5e893a4 100644
--- a/pie/restorer.c
+++ b/pie/restorer.c
@@ -641,7 +641,7 @@ long __export_restore_task(struct task_restore_core_args *args)
 		}
 
 		for (i = 0; i < args->nr_threads; i++) {
-			char last_pid_buf[16], *s;
+			char last_pid_buf[16];
 
 			/* skip self */
 			if (thread_args[i].pid == args->t->pid)
@@ -653,8 +653,8 @@ long __export_restore_task(struct task_restore_core_args *args)
 				RESTORE_ALIGN_STACK((long)thread_args[i].mem_zone.stack,
 						    sizeof(thread_args[i].mem_zone.stack));
 
-			last_pid_len = vprint_num(last_pid_buf, sizeof(last_pid_buf), thread_args[i].pid - 1, &s);
-			ret = sys_write(fd, s, last_pid_len);
+			last_pid_len = vprint_num(last_pid_buf, sizeof(last_pid_buf), thread_args[i].pid - 1);
+			ret = sys_write(fd, last_pid_buf, last_pid_len);
 			if (ret < 0) {
 				pr_err("Can't set last_pid %ld/%s\n", ret, last_pid_buf);
 				goto core_restore_end;
-- 
1.8.1.2


--J/dobhs11T7y2rNN--


More information about the CRIU mailing list