Re: [PATCH 1/1] dmesg: adds the ability to "follow" the klog ring buffer

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The modified patch looks good to me.  I'm not sure how to get around
the whole klogctl(2, ) incomplete output issue.  I'm not too familiar
with the overhead question about klogctl vs open(/proc/klog) + read().
 Are you referring to that open() causes the kernel to call klogctl
instead of having to route the syscall thorugh glibc?  I know that
they both are logically equivalent, so I guess I'll leave that call up
to you since you seem to be more knowledgeable about it.

~Austen

On Wed, May 4, 2011 at 07:43, Karel Zak <kzak@xxxxxxxxxx> wrote:
> On Tue, May 03, 2011 at 09:14:41AM -0500, Austen Dicken wrote:
>> > Then you can use klogctl(2, ...). It waits until the kernel log buffer
>> > is non-empty, so the last_line and usleep() will be unnecessary, and
>> > the implementation will be pretty simple.
>>
>> Agreed. ÂI have decided to change the patch to function this way,
>> which simplifies things
>> immensely.
>
> Unfortunately, it seems that SYSLOG_ACTION_READ (aka klogctl(2, ...))
> is not ideal solution too. Sorry.
>
> The output is incomplete if another process(e.g. syslog daemon) is
> reading the buffer. The buffer (and index into the buffer) is shared
> for all processes, so it's possible to read the information only once.
> For more details see kernel/printk.c (log_start index) in kernel
> sources.
>
> Anyway for debugging or on some non-standard boxes the '-f' option
> could be still usable. I'd like to add --level= and --facility=
> options, so dmesg(1) should be definitely better than the "cat
> /proc/kmsg" command.
>
> I did some changes to the patch to minimize overhead, see below. Maybe
> it would be better to use open(/proc/kmsg) + read() instead of
> klogctl(2, ...) for the -f option to minimize overhead in glibc.
>
> Comments?
>
> Â ÂKarel
>
>
> From 8e2ae5130c8f03e8ab6e28f194e409f8c322daf8 Mon Sep 17 00:00:00 2001
> From: Austen Dicken <cvpcsm@xxxxxxxxx>
> Date: Tue, 3 May 2011 09:14:41 -0500
> Subject: [PATCH] dmesg: adds the ability to "follow" (-f) the klog ring buffer
>
> Co-Author: Karel Zak <kzak@xxxxxxxxxx>
> Signed-off-by: Austen Dicken <cvpcsm@xxxxxxxxx>
> Signed-off-by: Karel Zak <kzak@xxxxxxxxxx>
> ---
> Âsys-utils/dmesg.1 | Â Â5 +++
> Âsys-utils/dmesg.c | Â 88 ++++++++++++++++++++++++++++++-----------------------
> Â2 files changed, 55 insertions(+), 38 deletions(-)
>
> diff --git a/sys-utils/dmesg.1 b/sys-utils/dmesg.1
> index d7af1da..9b4471d 100644
> --- a/sys-utils/dmesg.1
> +++ b/sys-utils/dmesg.1
> @@ -6,6 +6,7 @@ dmesg \- print or control the kernel ring buffer
> Â.SH SYNOPSIS
> Â.B dmesg
> Â.RB [ \-c ]
> +.RB [ \-f ]
> Â.RB [ \-r ]
> Â.RB [ \-n
> Â.IR level ]
> @@ -28,6 +29,10 @@ file to whoever can debug their problem.
> Â.B \-c
> ÂClear the ring buffer contents after printing.
> Â.TP
> +.B \-f
> +Output ring buffer contents as they are added. The output could be incomplete
> +if another process (e.g. syslog daemon) is reading the kernel log buffer.
> +.TP
> Â.B \-r
> ÂPrint the raw message buffer, i.e., don't strip the log level prefixes.
> Â.TP
> diff --git a/sys-utils/dmesg.c b/sys-utils/dmesg.c
> index c3e5659..2f6b30e 100644
> --- a/sys-utils/dmesg.c
> +++ b/sys-utils/dmesg.c
> @@ -40,38 +40,41 @@
> Â#include "nls.h"
> Â#include "strutils.h"
> Â#include "xalloc.h"
> +#include "writeall.h"
>
> Âstatic void __attribute__ ((noreturn)) usage(void)
> Â{
> Â Â Â Âfprintf(stderr,
> - Â Â Â Â Â Â Â _("Usage: %s [-c] [-n level] [-r] [-s bufsize]\n"),
> + Â Â Â Â Â Â Â _("Usage: %s [-c] [-f] [-n level] [-r] [-s bufsize]\n"),
> Â Â Â Â Â Â Â Âprogram_invocation_short_name);
> Â Â Â Âexit(EXIT_FAILURE);
> -
> Â}
>
> Âint main(int argc, char *argv[])
> Â{
> Â Â Â Âchar *buf = NULL;
> - Â Â Â int Âsz;
> + Â Â Â int Âsz = 0;
> Â Â Â Âint Âbufsize = 0;
> - Â Â Â int Âi;
> Â Â Â Âint Ân;
> Â Â Â Âint Âc;
> Â Â Â Âint Âlevel = 0;
> - Â Â Â int Âlastc;
> Â Â Â Âint Âcmd = 3; Â Â Â Â Â /* Read all messages in the ring buffer */
> Â Â Â Âint Âraw = 0;
> + Â Â Â int Âfollow = 0;
>
> Â Â Â Âsetlocale(LC_ALL, "");
> Â Â Â Âbindtextdomain(PACKAGE, LOCALEDIR);
> Â Â Â Âtextdomain(PACKAGE);
>
> - Â Â Â while ((c = getopt(argc, argv, "crn:s:")) != -1) {
> + Â Â Â while ((c = getopt(argc, argv, "cfrn:s:")) != -1) {
> Â Â Â Â Â Â Â Âswitch (c) {
> Â Â Â Â Â Â Â Âcase 'c':
> Â Â Â Â Â Â Â Â Â Â Â Âcmd = 4; Â Â Â Â/* Read and clear all messages */
> Â Â Â Â Â Â Â Â Â Â Â Âbreak;
> + Â Â Â Â Â Â Â case 'f':
> + Â Â Â Â Â Â Â Â Â Â Â cmd = 2;
> + Â Â Â Â Â Â Â Â Â Â Â follow = 1;
> + Â Â Â Â Â Â Â Â Â Â Â break;
> Â Â Â Â Â Â Â Âcase 'n':
> Â Â Â Â Â Â Â Â Â Â Â Âcmd = 8; Â Â Â Â/* Set level of messages */
> Â Â Â Â Â Â Â Â Â Â Â Âlevel = strtol_or_err(optarg, _("failed to parse level"));
> @@ -105,46 +108,55 @@ int main(int argc, char *argv[])
>
> Â Â Â Âif (!bufsize) {
> Â Â Â Â Â Â Â Ân = klogctl(10, NULL, 0); Â Â Â /* read ringbuffer size */
> - Â Â Â Â Â Â Â if (n > 0)
> + Â Â Â Â Â Â Â if (n > 0) {
> Â Â Â Â Â Â Â Â Â Â Â Âbufsize = n;
> + Â Â Â Â Â Â Â Â Â Â Â sz = bufsize + 8;
> + Â Â Â Â Â Â Â Â Â Â Â buf = xmalloc(sz * sizeof(char));
> + Â Â Â Â Â Â Â }
> Â Â Â Â}
>
> - Â Â Â if (bufsize) {
> - Â Â Â Â Â Â Â sz = bufsize + 8;
> - Â Â Â Â Â Â Â buf = xmalloc(sz * sizeof(char));
> - Â Â Â Â Â Â Â n = klogctl(cmd, buf, sz);
> - Â Â Â } else {
> - Â Â Â Â Â Â Â sz = 16392;
> - Â Â Â Â Â Â Â while (1) {
> - Â Â Â Â Â Â Â Â Â Â Â buf = xmalloc(sz * sizeof(char));
> - Â Â Â Â Â Â Â Â Â Â Â n = klogctl(3, buf, sz); Â Â Â Â/* read only */
> - Â Â Â Â Â Â Â Â Â Â Â if (n != sz || sz > (1 << 28))
> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â break;
> + Â Â Â do {
> + Â Â Â Â Â Â Â if (bufsize && sz)
> + Â Â Â Â Â Â Â Â Â Â Â n = klogctl(cmd, buf, sz);
> + Â Â Â Â Â Â Â else {
> Â Â Â Â Â Â Â Â Â Â Â Âfree(buf);
> - Â Â Â Â Â Â Â Â Â Â Â sz *= 4;
> + Â Â Â Â Â Â Â Â Â Â Â sz = 16392;
> + Â Â Â Â Â Â Â Â Â Â Â while (1) {
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â buf = xmalloc(sz * sizeof(char));
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â n = klogctl(3, buf, sz); Â Â Â Â/* read only */
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â if (n != sz || sz > (1 << 28))
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â break;
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â free(buf);
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â sz *= 4;
> + Â Â Â Â Â Â Â Â Â Â Â }
> + Â Â Â Â Â Â Â Â Â Â Â if (n > 0 && cmd == 4)
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â n = klogctl(cmd, buf, sz); Â Â Â/* read and clear */
> Â Â Â Â Â Â Â Â}
>
> - Â Â Â Â Â Â Â if (n > 0 && cmd == 4)
> - Â Â Â Â Â Â Â Â Â Â Â n = klogctl(cmd, buf, sz); Â Â Â/* read and clear */
> - Â Â Â }
> -
> - Â Â Â if (n < 0)
> - Â Â Â Â Â Â Â err(EXIT_FAILURE, _("klogctl failed"));
> -
> - Â Â Â lastc = '\n';
> - Â Â Â for (i = 0; i < n; i++) {
> - Â Â Â Â Â Â Â if (!raw && (i == 0 || buf[i - 1] == '\n') && buf[i] == '<') {
> - Â Â Â Â Â Â Â Â Â Â Â i++;
> - Â Â Â Â Â Â Â Â Â Â Â while (isdigit(buf[i]))
> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â i++;
> - Â Â Â Â Â Â Â Â Â Â Â if (buf[i] == '>')
> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â i++;
> + Â Â Â Â Â Â Â if (n < 0)
> + Â Â Â Â Â Â Â Â Â Â Â err(EXIT_FAILURE, _("klogctl failed"));
> + Â Â Â Â Â Â Â if (raw)
> + Â Â Â Â Â Â Â Â Â Â Â write_all(STDIN_FILENO, buf, n);
> + Â Â Â Â Â Â Â else {
> + Â Â Â Â Â Â Â Â Â Â Â int i;
> +
> + Â Â Â Â Â Â Â Â Â Â Â for (i = 0; i < n; i++) {
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â if ((i == 0 || buf[i - 1] == '\n') &&
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â buf[i] == '<') {
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â i++;
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â while (isdigit(buf[i]))
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â i++;
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â if (buf[i] == '>')
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â i++;
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â }
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â putchar(buf[i]);
> + Â Â Â Â Â Â Â Â Â Â Â }
> Â Â Â Â Â Â Â Â}
> - Â Â Â Â Â Â Â lastc = buf[i];
> - Â Â Â Â Â Â Â putchar(lastc);
> - Â Â Â }
> - Â Â Â if (lastc != '\n')
> + Â Â Â } while (follow);
> +
> + Â Â Â if (sz && n > 0 && buf && buf[n - 1] != '\n')
> Â Â Â Â Â Â Â Âputchar('\n');
> +
> Â Â Â Âfree(buf);
>
> Â Â Â Âreturn EXIT_SUCCESS;
> --
> 1.7.3.4
>
>
ÿô.nlj·Ÿ®‰­†+%ŠË±é¥Šwÿº{.nlj·®¶)ÿ–)›¡Ü}©ž²ÆzÚj:+v‰¨þø®w¥þŠàÞ¨è&¢)ß«a¶Úÿûz¹ÞúŽŠÝjÿŠwèf



[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux