* [patch 0/4] [RFC] kmsg macros, take x+2.
@ 2008-09-11 13:35 Martin Schwidefsky
2008-09-11 13:35 ` [patch 1/4] kmsg: Kernel message catalog macros Martin Schwidefsky
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Martin Schwidefsky @ 2008-09-11 13:35 UTC (permalink / raw)
To: linux-kernel, linux-s390, lf_kernel_messages, Rusty Russell,
Greg KH, Kay Sievers, Joe Perches, Tim Hockin, Andrew Morton,
Michael Holzheu, Gerrit Huizenga, Randy Dunlap, Jan Kara,
Pavel Machek, Sam Ravnborg, Jochen Voß, Kunai Takashi,
Tim Bird, Jan Blunck, Rick Troth, Utz Bacher
Greetings,
as requested this version of the kmsg patches uses a hash over the
message text instead of a manually assigned message number. There is
a new kernel function kmsg_printk which calculates the hash, prints
the prefix together with the hash and then the message itself.
Since it is impossible to add a parameter to a va_list kmsg_printk
has to do two seperate printk calls.
The kmsg tag now consists of the kmsg component and a 6 digit
hexadecimal hash. The code uses the lower 24 bit of the Jenkins hash
of the message text (there is a convenient inline implementation in
include/linux/jhash.h). The likelyhood of a hash collision with 100
messages per component is ~0.03%, with 1000 messages ~3% and with
10000 messages ~95%. As an example the old xpam.3 message:
xpram.3: No expanded memory available
now prints as:
xpram.f6ae78: No expanded memory available
For translation purposes all messages need a unique id, that makes
the special id 0 from the older kmsg patches rather useless. The
replacement for id 0 are single line kmsg comments, e.g.
/*? Tag: xpram.9a3d44 Text: " size of partition %d: %u kB\n" */
This makes the script to ignore the message, the check run will print
no warning and no man pages will be generated.
That leaves the question of dev_printk and friends. The dev_xxx macros
prefix the message with the driver name and the device name. Both
strings are dynamic, the perl script therefore can not find them which
makes them unusable as part of the kmsg tag. Now there are some options
how to deal with it:
1) Keep the existing dev_xxx printks, do not include a kmsg component in
the printk prefix and print the hash seperately. With the hash at the
start of the string an example printk would look like this:
617579: qeth: 0.0.f5f0: unknown card type
The bad: the hash prefix is out of place. The large number of dev_xxx
printks makes a hash collision very likely. The only solution would be
to increase the number of hash digits. The message looks like crap.
The good: the message check/print script works and existing code needs
no change.
2) Keep the exiting dev_xxx printks, do not include a kmsg component and
sneek in the hash right after the driver name. This would look like
this:
qeth.617579: 0.0.f5f0: unknown card type
The bad: the script has no chance to find the corresponding kmsg
description because the driver name is not known. Automatic message
checking and man page creation would be impossible.
The good: the messages look fine.
3) Keep the existing dev_xxx printks, include a kmsg component and print
the hash with the component. The example from above would look like
this:
qeth.617579: qeth: 0.0.f5f0: unknown card type
The bad: the driver name gets repeated and that every file that uses
dev_xxx has to define a KMSG_COMPONENT. The message looks like crap.
The good: the script works.
4) Define new kmsg_dev_xxx macros that are similar to dev_xxx, include
a kmsg component. These new macros do not print the dynamic driver
name, only the kmsg component. This is what is currently implemented.
The example from above looks like this:
qeth.617579: 0.0.f5f0: unknown card type
The bad: each driver that wants to use the kmsg_dev_xxx needs to be
changed. kmsg_dev_xxx in subsystems will have to do the print of the
driver name in each printk as it is not included automatically.
The good: the script works and the messages look fine.
I still prefer option 4). Anyone with a clever idea ?
--
blue skies,
Martin.
"Reality continues to ruin my life." - Calvin.
^ permalink raw reply [flat|nested] 5+ messages in thread
* [patch 1/4] kmsg: Kernel message catalog macros.
2008-09-11 13:35 [patch 0/4] [RFC] kmsg macros, take x+2 Martin Schwidefsky
@ 2008-09-11 13:35 ` Martin Schwidefsky
2008-09-11 13:35 ` [patch 2/4] kmsg: Kernel message catalog script Martin Schwidefsky
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Martin Schwidefsky @ 2008-09-11 13:35 UTC (permalink / raw)
To: linux-kernel, linux-s390, lf_kernel_messages, Rusty Russell,
Greg KH, Kay Sievers, Joe Perches, Tim Hockin, Andrew Morton,
Michael Holzheu, Gerrit Huizenga, Randy Dunlap, Jan Kara,
Pavel Machek, Sam Ravnborg, Jochen Voß, Kunai Takashi,
Tim Bird, Jan Blunck, Rick Troth, Utz Bacher
Cc: Martin Schwidefsky
[-- Attachment #1: 800-kmsg-macros.diff --]
[-- Type: text/plain, Size: 4514 bytes --]
From: Martin Schwidefsky <schwidefsky@de.ibm.com>
From: Michael Holzheu <holzheu@de.ibm.com>
Introduce a new family of printk macros which prefixes each kmsg message
with a component name and allows to tag the message with a 24 bit hash of
the message text. The kmsg component name is defined per source file with
the KMSG_COMPONENT macro.
If the message hash will be printed to the console / syslog at all depends
on CONFIG_MSG_IDS. If it is "n" then a kmsg_xxx call is just another
printk wrapper. These macros are intended to be used uniformly in the
s390 architecture and the s390 device drivers.
Signed-off-by: Michael Holzheu <holzheu@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---
arch/s390/Kconfig | 9 ++++++++
include/linux/kmsg.h | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++
kernel/printk.c | 24 ++++++++++++++++++++++
3 files changed, 87 insertions(+)
Index: quilt-2.6/arch/s390/Kconfig
===================================================================
--- quilt-2.6.orig/arch/s390/Kconfig
+++ quilt-2.6/arch/s390/Kconfig
@@ -571,6 +571,15 @@ bool "s390 guest support (EXPERIMENTAL)"
select VIRTIO_CONSOLE
help
Select this option if you want to run the kernel under s390 linux
+
+config KMSG_IDS
+ bool "Kernel message numbers"
+ default y
+ help
+ Select this option if you want to include a message number to the
+ prefix for kernel messages issued by the s390 architecture and
+ driver code. See "Documentation/s390/kmsg.txt" for more details.
+
endmenu
source "net/Kconfig"
Index: quilt-2.6/include/linux/kmsg.h
===================================================================
--- /dev/null
+++ quilt-2.6/include/linux/kmsg.h
@@ -0,0 +1,54 @@
+#ifndef _LINUX_KMSG_H
+#define _LINUX_KMSG_H
+
+int kmsg_printk(char *prefix, char *fmt, ...);
+
+#if defined(__KMSG_CHECKER)
+#define KMSG_ID KMSG_COMPONENT ".%06x"
+#define KMSG_FMT(fmt) _$_(fmt)_$_
+#define kmsg_printk __KMSG_CHECK
+#elif defined(CONFIG_KMSG_IDS)
+#define KMSG_ID KMSG_COMPONENT ".%06x"
+#define KMSG_FMT(fmt) fmt
+#else /* !defined(CONFIG_KMSG_IDS) */
+#define KMSG_ID KMSG_COMPONENT
+#define KMSG_FMT(fmt) fmt
+#define kmsg_printk(prefix, fmt, ...) printk(prefix # fmt, ##__VA_ARGS__)
+#endif
+
+#define kmsg_alert(fmt, ...) \
+ kmsg_printk(KERN_ALERT KMSG_ID ": ", KMSG_FMT(fmt), ##__VA_ARGS__)
+
+#define kmsg_err(fmt, ...) \
+ kmsg_printk(KERN_ERR KMSG_ID ": ", KMSG_FMT(fmt), ##__VA_ARGS__)
+
+#define kmsg_warn(fmt, ...) \
+ kmsg_printk(KERN_WARNING KMSG_ID ": ", KMSG_FMT(fmt), ##__VA_ARGS__)
+
+#define kmsg_info(fmt, ...) \
+ kmsg_printk(KERN_INFO KMSG_ID ": ", KMSG_FMT(fmt), ##__VA_ARGS__)
+
+#define kmsg_notice(fmt, ...) \
+ kmsg_printk(KERN_NOTICE KMSG_ID ": ", KMSG_FMT(fmt), ##__VA_ARGS__)
+
+#define kmsg_dev_alert(dev, fmt, ...) \
+ kmsg_printk(KERN_ALERT KMSG_ID ":%s: ", KMSG_FMT(fmt), \
+ dev_name(dev), ##__VA_ARGS__)
+
+#define kmsg_dev_err(dev, fmt, ...) \
+ kmsg_printk(KERN_ERR KMSG_ID ":%s: ", KMSG_FMT(fmt), \
+ dev_name(dev), ##__VA_ARGS__)
+
+#define kmsg_dev_warn(dev, fmt, ...) \
+ kmsg_printk(KERN_WARNING KMSG_ID ":%s: ", KMSG_FMT(fmt), \
+ dev_name(dev), ##__VA_ARGS__)
+
+#define kmsg_dev_info(dev, fmt, ...) \
+ kmsg_printk(KERN_INFO KMSG_ID ":%s: ", KMSG_FMT(fmt), \
+ dev_name(dev), ##__VA_ARGS__)
+
+#define kmsg_dev_notice(dev, fmt, ...) \
+ kmsg_printk(KERN_NOTICE KMSG_ID ":%s: ", KMSG_FMT(fmt), \
+ dev_name(dev), ##__VA_ARGS__)
+
+#endif /* _LINUX_KMSG_H */
Index: quilt-2.6/kernel/printk.c
===================================================================
--- quilt-2.6.orig/kernel/printk.c
+++ quilt-2.6/kernel/printk.c
@@ -32,6 +32,7 @@
#include <linux/security.h>
#include <linux/bootmem.h>
#include <linux/syscalls.h>
+#include <linux/jhash.h>
#include <asm/uaccess.h>
@@ -1343,3 +1344,26 @@ bool printk_timed_ratelimit(unsigned lon
}
EXPORT_SYMBOL(printk_timed_ratelimit);
#endif
+
+#if defined CONFIG_PRINTK && defined CONFIG_KMSG_IDS
+
+/**
+ * kmsg_printk - print a kernel message with a message id
+ * @fmt: format string
+ * @hfmt: revelant part of the format string included in the hash
+ */
+asmlinkage int kmsg_printk(const char *prefix, const char *fmt, ...)
+{
+ va_list args;
+ int r;
+
+ r = printk(prefix, jhash(fmt, strlen(fmt), 0) & 0xffffff);
+ va_start(args, fmt);
+ r += vprintk(fmt, args);
+ va_end(args);
+
+ return r;
+}
+EXPORT_SYMBOL(kmsg_printk);
+
+#endif
--
blue skies,
Martin.
"Reality continues to ruin my life." - Calvin.
^ permalink raw reply [flat|nested] 5+ messages in thread
* [patch 2/4] kmsg: Kernel message catalog script.
2008-09-11 13:35 [patch 0/4] [RFC] kmsg macros, take x+2 Martin Schwidefsky
2008-09-11 13:35 ` [patch 1/4] kmsg: Kernel message catalog macros Martin Schwidefsky
@ 2008-09-11 13:35 ` Martin Schwidefsky
2008-09-11 13:35 ` [patch 3/4] kmsg: convert xpram messages to kmsg api Martin Schwidefsky
2008-09-11 13:35 ` [patch 4/4] kmsg: convert vmcp " Martin Schwidefsky
3 siblings, 0 replies; 5+ messages in thread
From: Martin Schwidefsky @ 2008-09-11 13:35 UTC (permalink / raw)
To: linux-kernel, linux-s390, lf_kernel_messages, Rusty Russell,
Greg KH, Kay Sievers, Joe Perches, Tim Hockin, Andrew Morton,
Michael Holzheu, Gerrit Huizenga, Randy Dunlap, Jan Kara,
Pavel Machek, Sam Ravnborg, Jochen Voß, Kunai Takashi,
Tim Bird, Jan Blunck, Rick Troth, Utz Bacher
Cc: Martin Schwidefsky
[-- Attachment #1: 801-kmsg-script.diff --]
[-- Type: text/plain, Size: 17235 bytes --]
From: Martin Schwidefsky <schwidefsky@de.ibm.com>
From: Michael Holzheu <holzheu@de.ibm.com>
Add a script and the calls to the make process that allows to check the
kmsg printk messages and to format man pages from the message descriptions.
The kmsg message description is a comment with the following format:
/*?
* Tag: <component>.<hash>
* Text: "<kmsg message text>"
* Severity: <severity>
* Parameter:
* @1: <description of the first message parameter>
* @2: <description of the second message parameter>
* ...
* Description:
* <What is the kmsg message all about>
* User action:
* <What can the user do to fix the problem>
*/
The following short form of a kmsg message can be used if the message does
not have a full documentation:
/*? Tag: <component>.<hash> Text: "<kmsg message text>" */
No man page will be printed for these messages.
The script looks for a kmsg comment for a kmsg printk at three places,
the source file where the kmsg call is located, and in the files with
the name <component> in the two directories Documentation/kmsg and
Documentation/$ARCH/kmsg.
The kmsg check is invoked with "make D=1". It will read the source files for
all objects that are built by the current configuration and searches for
matching kmsg descriptions for the kmsg messages in the source. If a message
description can not be found the script prints a blueprint and causes a make
error.
The kmsg man page creation is invoked with "make D=2" and reads the source
files for all built objects, looks up the message description and writes
a man page to $(objtree)/man.
Signed-off-by: Michael Holzheu <holzheu@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---
Makefile | 16 +
scripts/Makefile.build | 14 +
scripts/kmsg-doc | 466 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 496 insertions(+)
Index: quilt-2.6/Makefile
===================================================================
--- quilt-2.6.orig/Makefile
+++ quilt-2.6/Makefile
@@ -63,6 +63,20 @@ ifndef KBUILD_CHECKSRC
KBUILD_CHECKSRC = 0
endif
+# Call message checker as part of the C compilation
+#
+# Use 'make D=1' to enable checking
+# Use 'make D=2' to create the message catalog
+
+ifdef D
+ ifeq ("$(origin D)", "command line")
+ KBUILD_KMSG_CHECK = $(D)
+ endif
+endif
+ifndef KBUILD_KMSG_CHECK
+ KBUILD_KMSG_CHECK = 0
+endif
+
# Use make M=dir to specify directory of external module to build
# Old syntax make ... SUBDIRS=$PWD is still supported
# Setting the environment variable KBUILD_EXTMOD take precedence
@@ -321,6 +335,7 @@ PERL = perl
CHECK = sparse
CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ -Wbitwise $(CF)
+KMSG_CHECK = $(srctree)/scripts/kmsg-doc
MODFLAGS = -DMODULE
CFLAGS_MODULE = $(MODFLAGS)
AFLAGS_MODULE = $(MODFLAGS)
@@ -355,6 +370,7 @@ export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODU
export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
+export KBUILD_KMSG_CHECK KMSG_CHECK
# When compiling out-of-tree modules, put MODVERDIR in the module
# tree rather than in the kernel tree. The kernel tree might
Index: quilt-2.6/scripts/kmsg-doc
===================================================================
--- /dev/null
+++ quilt-2.6/scripts/kmsg-doc
@@ -0,0 +1,466 @@
+#!/usr/bin/perl -w
+#
+# kmsg kernel messages check and print tool.
+#
+# To check the source code for missing messages the script is called
+# with check, the name compiler and the compile parameters
+# kmsg-doc check $(CC) $(c_flags) $<
+# To create man pages for the messages the script is called with
+# kmsg-doc print $(CC) $(c_flags) $<
+#
+# Copyright IBM Corp. 2008
+# Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+# Michael Holzheu <holzheu@linux.vnet.ibm.com>
+#
+
+use Cwd;
+use Switch;
+
+my $errors = 0;
+my $warnings = 0;
+my $srctree = "";
+my $objtree = "";
+my $kmsg_count = 0;
+
+sub remove_quotes($)
+{
+ my ($string) = @_;
+ my $inside = 0;
+ my $slash = 0;
+ my $result = "";
+
+ foreach my $str (split(/([\\"])/, $string)) {
+ if ($inside && ($str ne "\"" || $slash)) {
+ $result .= $str;
+ }
+ # Check for backslash before quote
+ if ($str eq "\"") {
+ if (!$slash) {
+ $inside = !$inside;
+ }
+ } elsif ($str eq "\\") {
+ $slash = !$slash;
+ } elsif ($str ne "") {
+ $slash = 0;
+ }
+ }
+ return $result;
+}
+
+sub string_to_bytes($)
+{
+ my ($string) = @_;
+ my %is_escape = ('"', 0x22, '\'', 0x27, 'n', 0x0a, 'r', 0x0d, 'b', 0x08,
+ 't', 0x09, 'f', 0x0c, 'a', 0x07, 'v', 0x0b, '?', 0x3f);
+ my (@ar, $slash, $len);
+
+ # scan string, interpret backslash escapes and write bytes to @ar
+ $len = 0;
+ foreach my $ch (split(//, $string)) {
+ if ($ch eq '\\') {
+ $slash = !$slash;
+ if (!$slash) {
+ $ar[$len] = ord('\\');
+ $len++;
+ }
+ } elsif ($slash && defined $is_escape{$ch}) {
+ # C99 backslash escapes: \\ \" \' \n \r \b \t \f \a \v \?
+ $ar[$len] = $is_escape{$ch};
+ $len++;
+ $slash = 0;
+ } elsif ($slash) {
+ # FIXME: C99 backslash escapes \nnn \xhh
+ die("Unknown backslash escape in message $string.");
+ } else {
+ # normal character
+ $ar[$len] = ord($ch);
+ $len++;
+ }
+ }
+ return @ar;
+}
+
+sub calc_jhash($)
+{
+ my ($string) = @_;
+ my @ar;
+ my ($a, $b, $c, $i, $length, $len);
+
+ @ar = string_to_bytes($string);
+ $length = @ar;
+ # add dummy elements to @ar to avoid if then else hell
+ push @ar, (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ $a = 0x9e3779b9;
+ $b = 0x9e3779b9;
+ $c = 0;
+ $i = 0;
+ for ($len = $length + 12; $len >= 12; $len -= 12) {
+ if ($len < 23) {
+ # add length for last round
+ $c += $length;
+ }
+ $a += $ar[$i] + ($ar[$i+1]<<8) + ($ar[$i+2]<<16) + ($ar[$i+3]<<24);
+ $b += $ar[$i+4] + ($ar[$i+5]<<8) + ($ar[$i+6]<<16) + ($ar[$i+7]<<24);
+ $c += $ar[$i+8] + ($ar[$i+9]<<8) + ($ar[$i+10]<<16) + ($ar[$i+11]<<24);
+ $a &= 0xffffffff; $b &= 0xffffffff; $c &= 0xffffffff;
+ $a -= $b; $a -= $c; $a ^= ($c >> 13); $a &= 0xffffffff;
+ $b -= $c; $b -= $a; $b ^= ($a << 8); $b &= 0xffffffff;
+ $c -= $a; $c -= $b; $c ^= ($b >> 13); $c &= 0xffffffff;
+ $a -= $b; $a -= $c; $a ^= ($c >> 12); $a &= 0xffffffff;
+ $b -= $c; $b -= $a; $b ^= ($a << 16); $b &= 0xffffffff;
+ $c -= $a; $c -= $b; $c ^= ($b >> 5); $c &= 0xffffffff;
+ $a -= $b; $a -= $c; $a ^= ($c >> 3); $a &= 0xffffffff;
+ $b -= $c; $b -= $a; $b ^= ($a << 10); $b &= 0xffffffff;
+ $c -= $a; $c -= $b; $c ^= ($b >> 15); $c &= 0xffffffff;
+ $i += 12;
+ }
+ return $c;
+}
+
+sub add_kmsg_desc($$$$$$)
+{
+ my ($tag, $text, $sev, $argv, $desc, $user) = @_;
+
+ if ($kmsg_desc{$tag}) {
+ warn "Duplicate message with tag $tag\n";
+ $errors++;
+ return;
+ }
+ $text = remove_quotes($text);
+ $kmsg_desc{$tag}->{'TEXT'} = $text;
+ $kmsg_desc{$tag}->{'SEV'} = $sev;
+ $kmsg_desc{$tag}->{'ARGV'} = $argv;
+ $kmsg_desc{$tag}->{'DESC'} = $desc;
+ $kmsg_desc{$tag}->{'USER'} = $user;
+}
+
+sub add_kmsg_print($$$$$)
+{
+ my ($component, $sev, $prefix, $text, $argv) = @_;
+ my ($hash, $tag, $count, $parm);
+
+ $text = remove_quotes($text);
+ $hash = substr(sprintf("%08x", calc_jhash($text)), 2, 6);
+ $tag = $component . "." . $hash;
+ # Pretty print severity
+ $sev =~ s/"<0>"/Emerg/;
+ $sev =~ s/"<1>"/Alert/;
+ $sev =~ s/"<2>"/Critical/;
+ $sev =~ s/"<3>"/Error/;
+ $sev =~ s/"<4>"/Warning/;
+ $sev =~ s/"<5>"/Notice/;
+ $sev =~ s/"<6>"/Informational/;
+ $sev =~ s/"<7>"/Debug/;
+ $kmsg_print{$kmsg_count}->{'TAG'} = $tag;
+ $kmsg_print{$kmsg_count}->{'TEXT'} = $text;
+ $kmsg_print{$kmsg_count}->{'SEV'} = $sev;
+ $kmsg_print{$kmsg_count}->{'ARGV'} = $argv;
+ $kmsg_count += 1;
+}
+
+sub process_source_file($)
+{
+ my $file = "@_";
+ my $state;
+ my $component = "";
+ my ($tag, $text, $sev, $argv, $desc, $user);
+
+ if (!open(FD, "$file")) {
+ return "";
+ }
+
+ $state = 0;
+ while (<FD>) {
+ chomp;
+ # kmsg message component: #define KMSG_COMPONENT "<component>"
+ if (/^#define\s+KMSG_COMPONENT\s+\"(.*)\"[^\"]*$/o) {
+ $component = $1;
+ }
+ if ($state == 0) {
+ # single line kmsg for undocumented messages, format:
+ # /*? Tag: <component>.<hash> Text: "<message>" */
+ if (/^\s*\/\*\?\s*Tag:\s*(\S*)\s*Text:\s*(\".*\")\s*\*\/\s*$/o) {
+ add_kmsg_desc($1, $2, "", "", "", "");
+ }
+ # kmsg message start: '/*?'
+ if (/^\s*\/\*\?\s*$/o) {
+ $state = 1;
+ ($tag, $text, $sev, $argv, $desc, $user) = ( "", "", "", "", "", "" );
+ }
+ } elsif ($state == 1) {
+ # kmsg message end: ' */'
+ if (/^\s*\*\/\s*/o) {
+ add_kmsg_desc($tag, $text, $sev, $argv, $desc, $user);
+ $state = 0;
+ }
+ # kmsg message tag: ' * Tag: <tag>'
+ elsif (/^\s*\*\s*Tag:\s*(\S*)\s*$/o) {
+ $tag = $1;
+ }
+ # kmsg message text: ' * Text: "<message>"'
+ elsif (/^\s*\*\s*Text:\s*(\".*\")\s*$/o) {
+ $text = $1;
+ }
+ # kmsg message severity: ' * Severity: <sev>'
+ elsif (/^\s*\*\s*Severity:\s*(\S*)\s*$/o) {
+ $sev = $1;
+ }
+ # kmsg message parameter: ' * Parameter: <argv>'
+ elsif (/^\s*\*\s*Parameter:\s*(\S*)\s*$/o) {
+ if (!defined($1)) {
+ $argv = "";
+ } else {
+ $argv = $1;
+ }
+ $state = 2;
+ }
+ # kmsg message description start: ' * Description:'
+ elsif (/^\s*\*\s*Description:\s*(\S*)\s*$/o) {
+ if (!defined($1)) {
+ $desc = "";
+ } else {
+ $desc = $1;
+ }
+ $state = 3;
+ }
+ # kmsg has unrecognizable lines
+ else {
+ warn "Warning(${file}:$.): Cannot understand $_";
+ $warnings++;
+ $state = 0;
+ }
+ } elsif ($state == 2) {
+ # kmsg message end: ' */'
+ if (/^\s*\*\//o) {
+ warn "Warning(${file}:$.): Missing description, skipping message";
+ $warnings++;
+ $state = 0;
+ }
+ # kmsg message description start: ' * Description:'
+ elsif (/^\s*\*\s*Description:\s*$/o) {
+ $desc = $1;
+ $state = 3;
+ }
+ # kmsg message parameter line: ' * <argv>'
+ elsif (/^\s*\*(.*)$/o) {
+ $argv .= "\n" . $1;
+ } else {
+ warn "Warning(${file}:$.): Cannot understand $_";
+ $warnings++;
+ $state = 0;
+ }
+ } elsif ($state == 3) {
+ # kmsg message end: ' */'
+ if (/^\s*\*\/\s*/o) {
+ add_kmsg_desc($tag, $text, $sev, $argv, $desc, $user);
+ $state = 0;
+ }
+ # kmsg message description start: ' * User action:'
+ elsif (/^\s*\*\s*User action:\s*$/o) {
+ $user = $1;
+ $state = 4;
+ }
+ # kmsg message description line: ' * <text>'
+ elsif (/^\s*\*\s*(.*)$/o) {
+ $desc .= "\n" . $1;
+ } else {
+ warn "Warning(${file}:$.): Cannot understand $_";
+ $warnings++;
+ $state = 0;
+ }
+ } elsif ($state == 4) {
+ # kmsg message end: ' */'
+ if (/^\s*\*\/\s*/o) {
+ add_kmsg_desc($tag, $text, $sev, $argv, $desc, $user);
+ $state = 0;
+ }
+ # kmsg message user action line: ' * <text>'
+ elsif (/^\s*\*\s*(.*)$/o) {
+ $user .= "\n" . $1;
+ } else {
+ warn "Warning(${file}:$.): Cannot understand $_";
+ $warnings++;
+ $state = 0;
+ }
+ }
+ }
+ return $component;
+}
+
+sub process_cpp_file($$$$)
+{
+ my ($cc, $options, $file, $component) = @_;
+
+ open(FD, "$cc $gcc_options|") or die ("Preprocessing failed.");
+
+ while (<FD>) {
+ chomp;
+ if (/.*__KMSG_CHECK\(\s*(\S*)\s*(.*)\s*,\s*_\$_\((.*)\)_\$_\s*,\s*(.*)\s*\)/o) {
+ if ($component ne "") {
+ add_kmsg_print($component, $1, $1.$2, $3, $4);
+ } else {
+ warn "Error(${file}:$.): kmsg without component\n";
+ $errors++;
+ }
+ } elsif (/.*__KMSG_CHECK\(\s*(\S*)\s*(.*)\s*,\s*_\$_\((.*)\)_\$_\s*\)/o) {
+ if ($component ne "") {
+ add_kmsg_print($component, $1, $1.$2, $3, "");
+ } else {
+ warn "Error(${file}:$.): kmsg without component\n";
+ $errors++;
+ }
+ }
+ }
+}
+
+sub check_messages($)
+{
+ my $component = "@_";
+ my $failed = 0;
+
+ for ($i = 0; $i < $kmsg_count; $i++) {
+ $tag = $kmsg_print{$i}->{'TAG'};
+ if (!defined($kmsg_desc{$tag})) {
+ add_kmsg_desc($tag,
+ "\"" . $kmsg_print{$i}->{'TEXT'} . "\"",
+ $kmsg_print{$i}->{'SEV'},
+ $kmsg_print{$i}->{'ARGV'},
+ "Please insert description here",
+ "What is the user supposed to do");
+ $kmsg_desc{$tag}->{'CHECK'} = 1;
+ $failed = 1;
+ warn "$component: Missing description for: $tag\n";
+ $errors++;
+ next;
+ }
+ if ($kmsg_print{$i}->{'TEXT'} ne $kmsg_desc{$tag}->{'TEXT'}) {
+ warn "$component: format string mismatch for: $tag\n";
+ warn " --- $kmsg_print{$i}->{'TEXT'}\n";
+ warn " +++ $kmsg_desc{$tag}->{'TEXT'}\n";
+ $errors++;
+ }
+ }
+ return $failed;
+}
+
+sub print_templates()
+{
+ print "Templates for missing messages:\n";
+ foreach $tag ( sort { $kmsg_desc{$a} <=> $kmsg_desc{$b} } keys %kmsg_desc ) {
+ if (!defined($kmsg_desc{$tag}->{'CHECK'})) {
+ next;
+ }
+ print "/*?\n";
+ print " * Tag: $tag\n";
+ print " * Text: \"$kmsg_desc{$tag}->{'TEXT'}\"\n";
+ print " * Severity: $kmsg_desc{$tag}->{'SEV'}\n";
+ $argv = $kmsg_desc{$tag}->{'ARGV'};
+ if ($argv ne "") {
+ print " * Parameter:\n";
+ @parms = split(/\s*,\s*/,$kmsg_desc{$tag}->{'ARGV'});
+ $count = 0;
+ foreach $parm (@parms) {
+ $count += 1;
+ if (!($parm eq "")) {
+ print " * \@$count: $parm\n";
+ }
+ }
+ }
+ print " * Description:\n";
+ print " * $kmsg_desc{$tag}->{'DESC'}\n";
+ print " * User action:\n";
+ print " * $kmsg_desc{$tag}->{'USER'}\n";
+ print " */\n\n";
+ }
+}
+
+sub write_man_pages()
+{
+ my $file;
+
+ foreach $tag (keys(%kmsg_desc)) {
+ if (defined($kmsg_desc{$tag}->{'CHECK'})) {
+ next;
+ }
+ if ($kmsg_desc{$tag}->{'DESC'} eq "") {
+ next;
+ }
+ $file = $objtree . "man/" . $tag . ".9";
+ if (!open(WR, ">$file")) {
+ warn "Error: Cannot open file $file\n";
+ $errors++;
+ return;
+ }
+ print WR ".TH \"$tag\" 9 \"Linux Messages\" LINUX\n";
+ print WR ".SH Message\n";
+ print WR $tag . ": " . $kmsg_desc{$tag}->{'TEXT'} . "\n";
+ print WR ".SH Severity\n";
+ print WR "$kmsg_desc{$tag}->{'SEV'}\n";
+ $argv = $kmsg_desc{$tag}->{'ARGV'};
+ if ($argv ne "") {
+ print WR ".SH Parameters\n";
+ @parms = split(/,/,$kmsg_desc{$tag}->{'ARGV'});
+ map{s/\s*//} @parms;
+ foreach $parm (@parms) {
+ $parm =~ s/^\s+//;
+ if (!($parm eq "")) {
+ print WR "$parm\n";
+ }
+ }
+ }
+ print WR ".SH Description";
+ print WR "$kmsg_desc{$tag}->{'DESC'}\n";
+ $user = $kmsg_desc{$tag}->{'USER'};
+ if ($user ne "") {
+ print WR ".SH User action";
+ print WR "$user\n";
+ }
+ }
+}
+
+if (defined($ENV{'srctree'})) {
+ $srctree = "$ENV{'srctree'}" . "/";
+} else {
+ $srctree = getcwd;
+}
+
+if (defined($ENV{'objtree'})) {
+ $objtree = "$ENV{'objtree'}" . "/";
+} else {
+ $objtree = getcwd;
+}
+
+if (defined($ENV{'SRCARCH'})) {
+ $srcarch = "$ENV{'SRCARCH'}" . "/";
+} else {
+ print "kmsg-doc called without a valid \$SRCARCH\n";
+ exit 1;
+}
+
+$option = shift;
+
+$cc = shift;
+$gcc_options = "-E -D __KMSG_CHECKER ";
+foreach $tmp (@ARGV) {
+ $tmp =~ s/\(/\\\(/;
+ $tmp =~ s/\)/\\\)/;
+ $gcc_options .= " $tmp";
+ $filename = $tmp;
+}
+
+$component = process_source_file($filename);
+if ($component ne "") {
+ process_source_file($srctree . "Documentation/kmsg/" . $srcarch . $component);
+ process_source_file($srctree . "Documentation/kmsg/" . $component);
+}
+
+if ($option eq "check") {
+ process_cpp_file($cc, $gcc_options, $filename, $component);
+ if (check_messages($component)) {
+ print_templates();
+ }
+} elsif ($option eq "print") {
+ write_man_pages();
+}
+
+exit($errors);
Index: quilt-2.6/scripts/Makefile.build
===================================================================
--- quilt-2.6.orig/scripts/Makefile.build
+++ quilt-2.6/scripts/Makefile.build
@@ -211,12 +211,14 @@ endef
# Built-in and composite module parts
$(obj)/%.o: $(src)/%.c FORCE
$(call cmd,force_checksrc)
+ $(call cmd,force_check_kmsg)
$(call if_changed_rule,cc_o_c)
# Single-part modules are special since we need to mark them in $(MODVERDIR)
$(single-used-m): $(obj)/%.o: $(src)/%.c FORCE
$(call cmd,force_checksrc)
+ $(call cmd,force_check_kmsg)
$(call if_changed_rule,cc_o_c)
@{ echo $(@:.o=.ko); echo $@; } > $(MODVERDIR)/$(@F:.o=.mod)
@@ -339,6 +341,18 @@ $(multi-used-m) : %.o: $(multi-objs-m) F
targets += $(multi-used-y) $(multi-used-m)
+# kmsg check tool
+ifneq ($(KBUILD_KMSG_CHECK),0)
+ ifeq ($(KBUILD_KMSG_CHECK),2)
+ kmsg_cmd := print
+ quiet_cmd_force_check_kmsg = KMSG_PRINT $<
+ $(shell [ -d $(objtree)/man ] || mkdir -p $(objtree)/man)
+ else
+ kmsg_cmd := check
+ quiet_cmd_force_check_kmsg = KMSG_CHECK $<
+ endif
+ cmd_force_check_kmsg = $(KMSG_CHECK) $(kmsg_cmd) $(CC) $(c_flags) $< ;
+endif
# Descending
# ---------------------------------------------------------------------------
--
blue skies,
Martin.
"Reality continues to ruin my life." - Calvin.
^ permalink raw reply [flat|nested] 5+ messages in thread
* [patch 3/4] kmsg: convert xpram messages to kmsg api.
2008-09-11 13:35 [patch 0/4] [RFC] kmsg macros, take x+2 Martin Schwidefsky
2008-09-11 13:35 ` [patch 1/4] kmsg: Kernel message catalog macros Martin Schwidefsky
2008-09-11 13:35 ` [patch 2/4] kmsg: Kernel message catalog script Martin Schwidefsky
@ 2008-09-11 13:35 ` Martin Schwidefsky
2008-09-11 13:35 ` [patch 4/4] kmsg: convert vmcp " Martin Schwidefsky
3 siblings, 0 replies; 5+ messages in thread
From: Martin Schwidefsky @ 2008-09-11 13:35 UTC (permalink / raw)
To: linux-kernel, linux-s390, lf_kernel_messages, Rusty Russell,
Greg KH, Kay Sievers, Joe Perches, Tim Hockin, Andrew Morton,
Michael Holzheu, Gerrit Huizenga, Randy Dunlap, Jan Kara,
Pavel Machek, Sam Ravnborg, Jochen Voß, Kunai Takashi,
Tim Bird, Jan Blunck, Rick Troth, Utz Bacher
Cc: Martin Schwidefsky
[-- Attachment #1: 802-kmsg-xpram.diff --]
[-- Type: text/plain, Size: 6785 bytes --]
From: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---
Documentation/kmsg/s390/xpram | 61 ++++++++++++++++++++++++++++++++++++++++++
drivers/s390/block/xpram.c | 41 +++++++++++++---------------
2 files changed, 80 insertions(+), 22 deletions(-)
Index: quilt-2.6/Documentation/kmsg/s390/xpram
===================================================================
--- /dev/null
+++ quilt-2.6/Documentation/kmsg/s390/xpram
@@ -0,0 +1,61 @@
+/*?
+ * Tag: xpram.ab9aa4
+ * Text: "%d is not a valid number of XPRAM devices\n"
+ * Severity: Error
+ * Parameter:
+ * @1: number of partitions
+ * Description:
+ * The number of XPRAM partitions specified for the 'devs' module parameter
+ * or with the 'xpram.parts' kernel parameter must be an integer in the
+ * range 1 to 32. The XPRAM device driver created a maximum of 32 partitions
+ * that are probably not configured as intended.
+ * User action:
+ * If the XPRAM device driver has been compiled as a separate module,
+ * unload the module and load it again with a correct value for the
+ * 'devs' module parameter. If the XPRAM device driver has been compiled
+ * into the kernel, correct the 'xpram.parts' parameter in the kernel
+ * command line and restart Linux.
+ */
+
+/*?
+ * Tag: xpram.f004d1
+ * Text: "Not enough expanded memory available\n"
+ * Severity: Error
+ * Description:
+ * The amount of expanded memory required to set up your XPRAM partitions
+ * depends on the 'sizes' parameter specified for the xpram module or on
+ * the specifications for the 'xpram.parts' parameter if the XPRAM device
+ * driver has been compiled into the kernel. Your
+ * current specification exceed the amount of available expanded memory.
+ * Your XPRAM partitions are probably not configured as intended.
+ * User action:
+ * If the XPRAM device driver has been compiled as a separate module,
+ * unload the xpram module and load it again with an appropriate value
+ * for the 'sizes' module parameter. If the XPRAM device driver has been
+ * compiled into the kernel, adjust the 'xpram.parts' parameter in the
+ * kernel command line and restart Linux. If you need more than the
+ * available expanded memory, increase the expanded memory allocation for
+ * your virtual hardware or LPAR.
+ */
+
+/*?
+ * Tag: xpram.f6ae78
+ * Text: "No expanded memory available\n"
+ * Severity: Error
+ * Description:
+ * The XPRAM device driver has been loaded in a Linux instance that runs
+ * in an LPAR or virtual hardware without expanded memory.
+ * are created.
+ * User action:
+ * Allocate expanded memory for your LPAR or virtual hardware or do not
+ * load the xpram module. You can ignore this message, if you do not want
+ * to create XPRAM partitions.
+ */
+
+/*? Tag: xpram.fc5e30 Text: " number of devices (partitions): %d \n" */
+/*? Tag: xpram.9a3d44 Text: " size of partition %d: %u kB\n" */
+/*? Tag: xpram.d1b9da Text: " size of partition %d to be set automatically\n" */
+/*? Tag: xpram.758fd6 Text: " memory needed (for sized partitions): %lu kB\n" */
+/*? Tag: xpram.3fc92b Text: " partitions to be sized automatically: %d\n" */
+/*? Tag: xpram.6cdcc1 Text: " automatically determined partition size: %lu kB\n" */
+/*? Tag: xpram.546055 Text: " %u pages expanded memory found (%lu KB).\n" */
Index: quilt-2.6/drivers/s390/block/xpram.c
===================================================================
--- quilt-2.6.orig/drivers/s390/block/xpram.c
+++ quilt-2.6/drivers/s390/block/xpram.c
@@ -36,18 +36,15 @@
#include <linux/hdreg.h> /* HDIO_GETGEO */
#include <linux/sysdev.h>
#include <linux/bio.h>
+#include <linux/kmsg.h>
#include <asm/uaccess.h>
+#define KMSG_COMPONENT "xpram"
+
#define XPRAM_NAME "xpram"
#define XPRAM_DEVS 1 /* one partition */
#define XPRAM_MAX_DEVS 32 /* maximal number of devices (partitions) */
-#define PRINT_DEBUG(x...) printk(KERN_DEBUG XPRAM_NAME " debug:" x)
-#define PRINT_INFO(x...) printk(KERN_INFO XPRAM_NAME " info:" x)
-#define PRINT_WARN(x...) printk(KERN_WARNING XPRAM_NAME " warning:" x)
-#define PRINT_ERR(x...) printk(KERN_ERR XPRAM_NAME " error:" x)
-
-
typedef struct {
unsigned int size; /* size of xpram segment in pages */
unsigned int offset; /* start page of xpram segment */
@@ -263,7 +260,7 @@ static int __init xpram_setup_sizes(unsi
/* Check number of devices. */
if (devs <= 0 || devs > XPRAM_MAX_DEVS) {
- PRINT_ERR("invalid number %d of devices\n",devs);
+ kmsg_err("%d is not a valid number of XPRAM devices\n",devs);
return -EINVAL;
}
xpram_devs = devs;
@@ -294,22 +291,22 @@ static int __init xpram_setup_sizes(unsi
mem_auto_no++;
}
- PRINT_INFO(" number of devices (partitions): %d \n", xpram_devs);
+ kmsg_info(" number of devices (partitions): %d \n", xpram_devs);
for (i = 0; i < xpram_devs; i++) {
if (xpram_sizes[i])
- PRINT_INFO(" size of partition %d: %u kB\n",
- i, xpram_sizes[i]);
+ kmsg_info(" size of partition %d: %u kB\n",
+ i, xpram_sizes[i]);
else
- PRINT_INFO(" size of partition %d to be set "
- "automatically\n",i);
+ kmsg_info(" size of partition %d to be set "
+ "automatically\n",i);
}
- PRINT_DEBUG(" memory needed (for sized partitions): %lu kB\n",
- mem_needed);
- PRINT_DEBUG(" partitions to be sized automatically: %d\n",
- mem_auto_no);
+ kmsg_info(" memory needed (for sized partitions): %lu kB\n",
+ mem_needed);
+ kmsg_info(" partitions to be sized automatically: %d\n",
+ mem_auto_no);
if (mem_needed > pages * 4) {
- PRINT_ERR("Not enough expanded memory available\n");
+ kmsg_err("Not enough expanded memory available\n");
return -EINVAL;
}
@@ -321,8 +318,8 @@ static int __init xpram_setup_sizes(unsi
*/
if (mem_auto_no) {
mem_auto = ((pages - mem_needed / 4) / mem_auto_no) * 4;
- PRINT_INFO(" automatically determined "
- "partition size: %lu kB\n", mem_auto);
+ kmsg_info(" automatically determined "
+ "partition size: %lu kB\n", mem_auto);
for (i = 0; i < xpram_devs; i++)
if (xpram_sizes[i] == 0)
xpram_sizes[i] = mem_auto;
@@ -412,12 +409,12 @@ static int __init xpram_init(void)
/* Find out size of expanded memory. */
if (xpram_present() != 0) {
- PRINT_WARN("No expanded memory available\n");
+ kmsg_err("No expanded memory available\n");
return -ENODEV;
}
xpram_pages = xpram_highest_page_index() + 1;
- PRINT_INFO(" %u pages expanded memory found (%lu KB).\n",
- xpram_pages, (unsigned long) xpram_pages*4);
+ kmsg_info(" %u pages expanded memory found (%lu KB).\n",
+ xpram_pages, (unsigned long) xpram_pages*4);
rc = xpram_setup_sizes(xpram_pages);
if (rc)
return rc;
--
blue skies,
Martin.
"Reality continues to ruin my life." - Calvin.
^ permalink raw reply [flat|nested] 5+ messages in thread
* [patch 4/4] kmsg: convert vmcp to kmsg api.
2008-09-11 13:35 [patch 0/4] [RFC] kmsg macros, take x+2 Martin Schwidefsky
` (2 preceding siblings ...)
2008-09-11 13:35 ` [patch 3/4] kmsg: convert xpram messages to kmsg api Martin Schwidefsky
@ 2008-09-11 13:35 ` Martin Schwidefsky
3 siblings, 0 replies; 5+ messages in thread
From: Martin Schwidefsky @ 2008-09-11 13:35 UTC (permalink / raw)
To: linux-kernel, linux-s390, lf_kernel_messages, Rusty Russell,
Greg KH, Kay Sievers, Joe Perches, Tim Hockin, Andrew Morton,
Michael Holzheu, Gerrit Huizenga, Randy Dunlap, Jan Kara,
Pavel Machek, Sam Ravnborg, Jochen Voß, Kunai Takashi,
Tim Bird, Jan Blunck, Rick Troth, Utz Bacher
Cc: Christian Borntraeger, Martin Schwidefsky
[-- Attachment #1: 803-kmsg-vmcp.diff --]
[-- Type: text/plain, Size: 2102 bytes --]
From: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---
drivers/s390/char/vmcp.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
Index: quilt-2.6/drivers/s390/char/vmcp.c
===================================================================
--- quilt-2.6.orig/drivers/s390/char/vmcp.c
+++ quilt-2.6/drivers/s390/char/vmcp.c
@@ -17,6 +17,7 @@
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/smp_lock.h>
+#include <linux/kmsg.h>
#include <asm/cpcmd.h>
#include <asm/debug.h>
#include <asm/uaccess.h>
@@ -26,7 +27,7 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Christian Borntraeger <borntraeger@de.ibm.com>");
MODULE_DESCRIPTION("z/VM CP interface");
-#define PRINTK_HEADER "vmcp: "
+#define KMSG_COMPONENT "vmcp"
static debug_info_t *vmcp_debug;
@@ -193,7 +194,8 @@ static int __init vmcp_init(void)
int ret;
if (!MACHINE_IS_VM) {
- PRINT_WARN("z/VM CP interface is only available under z/VM\n");
+ kmsg_warn("The z/VM CP interface device driver cannot be "
+ "loaded without z/VM\n");
return -ENODEV;
}
@@ -216,6 +218,21 @@ static int __init vmcp_init(void)
return 0;
}
+/*?
+ * Tag: vmcp.42661a
+ * Text: "The z/VM CP interface device driver cannot be loaded without z/VM\n"
+ * Severity: Warning
+ * Description:
+ * With the z/VM CP interface you can issue z/VM CP commands from a Linux
+ * terminal session. On Linux instances that run in environments other than
+ * the z/VM hypervisor, the z/VM CP interface does not provide any useful
+ * function and the corresponding vmcp device driver cannot be loaded.
+ * User action:
+ * Load the vmcp device driver only on Linux instances that run as guest
+ * operating systems of the z/VM hypervisor. If the device driver has been
+ * compiled into the kernel, ignore this message.
+ */
+
static void __exit vmcp_exit(void)
{
misc_deregister(&vmcp_dev);
--
blue skies,
Martin.
"Reality continues to ruin my life." - Calvin.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2008-09-11 13:47 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-11 13:35 [patch 0/4] [RFC] kmsg macros, take x+2 Martin Schwidefsky
2008-09-11 13:35 ` [patch 1/4] kmsg: Kernel message catalog macros Martin Schwidefsky
2008-09-11 13:35 ` [patch 2/4] kmsg: Kernel message catalog script Martin Schwidefsky
2008-09-11 13:35 ` [patch 3/4] kmsg: convert xpram messages to kmsg api Martin Schwidefsky
2008-09-11 13:35 ` [patch 4/4] kmsg: convert vmcp " Martin Schwidefsky
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox