[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