summaryrefslogtreecommitdiffstats
path: root/sys-utils/dmesg.c
diff options
context:
space:
mode:
authorBjørn Mork2012-10-02 01:54:49 +0200
committerKarel Zak2012-10-02 11:43:10 +0200
commit8c8fa302c10d646a49d1d7565cbb60c5356a60b3 (patch)
treea25cbbdfbb92a897fc9f5fab0093ebab2226a889 /sys-utils/dmesg.c
parentcolumn: describe change of separator behavior in man page bugs section (diff)
downloadkernel-qcow2-util-linux-8c8fa302c10d646a49d1d7565cbb60c5356a60b3.tar.gz
kernel-qcow2-util-linux-8c8fa302c10d646a49d1d7565cbb60c5356a60b3.tar.xz
kernel-qcow2-util-linux-8c8fa302c10d646a49d1d7565cbb60c5356a60b3.zip
dmesg: fix console-level off-by-one
commit f06ec64f dmesg; support level names (e.g. --console-level=alert) introduced an off-by-one error. The kernel will print messages with a *higher* level than the console-level. The bug made it impossible to set the level for debugging, like it is documented in e.g Documentation/networking/netconsole.txt : nemi:/tmp# dmesg -n 8 dmesg: unknown level '8' And attempting to set the "emerg" level would result in an invalid 0 value: nemi:/tmp# dmesg -n emerg dmesg: klogctl failed: Invalid argument Restoring the old behaviour for numeric levels, and mapping the level names so that "dmesg -n debug" behaves as expected: logging everything at level "debug" and higher. [kzak@redhat.com: - add comment to parse_level()] Signed-off-by: Bjørn Mork <bjorn@mork.no> Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'sys-utils/dmesg.c')
-rw-r--r--sys-utils/dmesg.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/sys-utils/dmesg.c b/sys-utils/dmesg.c
index 0ee03eeba..4c85f9fce 100644
--- a/sys-utils/dmesg.c
+++ b/sys-utils/dmesg.c
@@ -227,24 +227,36 @@ static void __attribute__((__noreturn__)) usage(FILE *out)
/*
* LEVEL ::= <number> | <name>
- * <number> ::= number in range <0..N>, where N < ARRAY_SIZE(level_names)
+ * <number> ::= @len is set: number in range <0..N>, where N < ARRAY_SIZE(level_names)
+ * ::= @len not set: number in range <1..N>, where N <= ARRAY_SIZE(level_names)
* <name> ::= case-insensitive text
+ *
+ * Note that @len argument is not set when parsing "-n <level>" command line
+ * option. The console_level is intepreted as "log level less than the value".
+ *
+ * For example "dmesg -n 8" or "dmesg -n debug" enables debug console log
+ * level by klogctl(SYSLOG_ACTION_CONSOLE_LEVEL, NULL, 8). The @str argument
+ * has to be parsed to number in range <1..8>.
*/
static int parse_level(const char *str, size_t len)
{
+ int offset = 0;
+
if (!str)
return -1;
- if (!len)
+ if (!len) {
len = strlen(str);
+ offset = 1;
+ }
errno = 0;
if (isdigit(*str)) {
char *end = NULL;
- long x = strtol(str, &end, 10);
+ long x = strtol(str, &end, 10) - offset;
if (!errno && end && end > str && (size_t) (end - str) == len &&
x >= 0 && (size_t) x < ARRAY_SIZE(level_names))
- return x;
+ return x + offset;
} else {
size_t i;
@@ -252,7 +264,7 @@ static int parse_level(const char *str, size_t len)
const char *n = level_names[i].name;
if (strncasecmp(str, n, len) == 0 && *(n + len) == '\0')
- return i;
+ return i + offset;
}
}