[Toybox] [PATCH] fix dmesg default size/level filtering/performance
enh
enh at google.com
Mon Nov 24 17:26:06 PST 2014
* the kernel buffer hasn't defaulted to 16KiB for a very long time.
i'm not sure why the original code said < 2 rather than <= 0 (or 1KiB,
say), but i've left that as it was.
* there's also a bug with the filtering out of level markers; they can
be more than one digit. (this is true of all kernels, not just Android
ones.)
* finally, the use of xputc for every character makes the toybox dmesg
human-noticeably slow. writing line at a time is orders of magnitude
faster/fewer syscalls.
here's the patch, which attempts to imitate your style:
diff --git a/generated/help.h b/generated/help.h
index 6c017cf..1a44a37 100644
--- a/generated/help.h
+++ b/generated/help.h
@@ -54,7 +54,7 @@
#define help_hostname "usage: hostname [newname]\n\nGet/Set the
current hostname\n\n"
-#define help_dmesg "usage: dmesg [-n level] [-s bufsize] |
-c\n\nPrint or control the kernel ring buffer.\n\n-n Set kernel
logging level (1-9).\n-s Size of buffer to read (in bytes), default
16384.\n-c Clear the ring buffer after printing.\n\n"
+#define help_dmesg "usage: dmesg [-n level] [-s bufsize] |
-c\n\nPrint or control the kernel ring buffer.\n\n-n Set kernel
logging level (1-9).\n-s Size of buffer to read (in bytes), default
kernel buffer size.\n-c Clear the ring buffer after printing.\n\n"
#define help_yes "usage: yes [args...]\n\nRepeatedly output line
until killed. If no args, output 'y'.\n\n\n"
diff --git a/toys/lsb/dmesg.c b/toys/lsb/dmesg.c
index 1003256..d4a2b66 100644
--- a/toys/lsb/dmesg.c
+++ b/toys/lsb/dmesg.c
@@ -15,7 +15,7 @@ config DMESG
Print or control the kernel ring buffer.
-n Set kernel logging level (1-9).
- -s Size of buffer to read (in bytes), default 16384.
+ -s Size of buffer to read (in bytes), default kernel buffer size.
-c Clear the ring buffer after printing.
*/
@@ -34,22 +34,34 @@ void dmesg_main(void)
if (toys.optflags & 2) {
if (klogctl(8, NULL, TT.level)) error_exit("klogctl");
} else {
- int size, i, last = '\n';
- char *data;
+ int size, i;
+ char *data, *end;
// Figure out how much data we need, and fetch it.
size = TT.size;
- if (size<2) size = 16384;
+ if (size < 2) size = klogctl(10, 0, 0); // SYSLOG_ACTION_SIZE_BUFFER.
+ if (size < 0) size = 16384;
data = xmalloc(size);
size = klogctl(3 + (toys.optflags&1), data, size);
if (size < 0) error_exit("klogctl");
- // Display data, filtering out level markers.
+ // Display data, filtering out level markers (<\d+>).
for (i=0; i<size; ) {
- if (last=='\n' && data[i]=='<') i += 3;
- else xputc(last = data[i++]);
+ if (data[i]=='<') {
+ end = strchr(data+i, '>');
+ if (end) i = end-data+1;
+ } else {
+ end = strchr(data+i, '\n');
+ if (end) {
+ xwrite(1, data+i, end-(data+i)+1);
+ i += end - (data+i) + 1;
+ } else {
+ xwrite(1, data+i, size-i);
+ xputc('\n');
+ i = size;
+ }
+ }
}
- if (last!='\n') xputc('\n');
if (CFG_TOYBOX_FREE) free(data);
}
}
i'm assuming no one actually cares about the old Android "implicit -r"
behavior. if i get a complaint, adding -r is trivial. (once i learn
how to add an option at all :-) )
1416878766.0
More information about the Toybox
mailing list