linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* kernel support for non-english user messages
@ 2003-04-09  5:02 Frank Davis
  2003-04-09  5:29 ` Oliver Neukum
                   ` (4 more replies)
  0 siblings, 5 replies; 137+ messages in thread
From: Frank Davis @ 2003-04-09  5:02 UTC (permalink / raw)
  To: linux-kernel

All,

I wish to suggest a possible 2.6 or 2.7 feature (too late for 2.4.x and 
2.5.x, I believe) that I believe would be helpful. Currently, printk 
messages are all in english, and I was wondering if printk could be 
modified to print out user messages that are in the default language of 
the machine. For example,

printk(KERN_WARN "This driver is messed up!\n", 'en'); //Prints the 
english text .

printk(KERN_WARN "This driver is messed up!\n", 'wel'); //Prints the 
welsh translation of the english text.

printk(KERN_WARN "This driver is messed up!\n", getdefaultlanguage());

I'm looking for a possible uniform design to make this happen, short of 
adding a complete machine translation module to the kernel. :) Userland 
internationalization support is already provided(I haven't personally 
used other languages besides English, but I've seen the options), but a 
kernel module or printk addition that handles localized kernel messages 
seems reasonable.

Thoughts, comments?

Regards,
Frank


^ permalink raw reply	[flat|nested] 137+ messages in thread
* RE: kernel support for non-english user messages
@ 2003-04-09 19:01 Perez-Gonzalez, Inaky
  0 siblings, 0 replies; 137+ messages in thread
From: Perez-Gonzalez, Inaky @ 2003-04-09 19:01 UTC (permalink / raw)
  To: 'fdavis@si.rr.com', 'linux-kernel@vger.kernel.org'


> I wish to suggest a possible 2.6 or 2.7 feature (too late for 2.4.x and
> 2.5.x, I believe) that I believe would be helpful. Currently, printk
> messages are all in english, and I was wondering if printk could be
> modified to print out user messages that are in the default language of
> the machine. For example,

A classic: http://www.tux.org/lkml/#s9-16

Iñaky Pérez-González -- Not speaking for Intel -- all opinions are my own
(and my fault)

^ permalink raw reply	[flat|nested] 137+ messages in thread
* RE: kernel support for non-english user messages
@ 2003-04-09 19:25 Perez-Gonzalez, Inaky
  0 siblings, 0 replies; 137+ messages in thread
From: Perez-Gonzalez, Inaky @ 2003-04-09 19:25 UTC (permalink / raw)
  To: 'oliver@neukum.name', 'Matti Aarnio',
	'Frank Davis'
  Cc: 'linux-kernel@vger.kernel.org'


> From: Oliver Neukum 

> If we do this, why not go the whole way?
> Could we compute a hash value for every message that's not KERN_CRIT,
> use it to create a table of messages and hashes and replace the messages
> in the kernel image with the hash values leaving expansion to klogd?

What about argument expansion? You are killing it

Iñaky Pérez-González -- Not speaking for Intel -- all opinions are my own
(and my fault)


^ permalink raw reply	[flat|nested] 137+ messages in thread
* Re: kernel support for non-english user messages
@ 2003-04-09 23:31 Jim Keniston[UNIX]
  2003-04-10 19:01 ` Alan Cox
  0 siblings, 1 reply; 137+ messages in thread
From: Jim Keniston[UNIX] @ 2003-04-09 23:31 UTC (permalink / raw)
  To: linux-kernel

I'm one of those IBM guys who has been working on ideas for enhanced
error/event logging in Linux.  As part of this work, we've developed
ideas for I18N of event-log messages.  Here are some observations:

Most developers are comfortable with printk.  Whatever approach you
take, the closer you stay to printk in the programmatic interface, the
more likely you are to gain acceptance.

Kernel messages need to be logged in English.  By application of message
catalogs or similar techniques, they can also be made available in other
languages.  Translation to other languages should be done when the log
is viewed.

If you're serious about I18N, you must keep a message's format string 
distinct from the arg list.  Your event-log viewer combines them all for
you, using the desired language.  For example, given the message
	printk(KERN_INFO "link up, %d Mbps, %s-duplex\n", speed, duplex);
you log the format string and the values of speed and duplex as separate
attributes in the event log.  If/when you compute a hash, it's on the
format string (and possibly on the function name and/or source-file
name, to provide more context).

Note that if you're particularly brave and/or stingy, you don't even
have
to log the format string, just the hash.  The event-log viewer can fetch
the format string given the hash.

As the above suggests, a structured event log (see, for example,
evlog.sourceforge.net) lends itself more readily to manipulation and
analysis than does a simple text file.

We've come up with a couple of ways of generating message catalogs
automatically.  The method we prefer captures information about each
printk* at compile time, and stores it in the .log section of the .o
file.  A post-processor then reads all the .o files and generates a sort
of catalog entry for each printk call.  The .log sections are stripped
out when the bzImage is created.  [*This technique requires some macro
fussing.  For reasons I won't go into, the macro is NOT called "printk",
so this feature doesn't come for free.]

There are tens of thousands of printk calls in Linux.  This has several
implications:

- Inertia is a major factor.

- If we use 32-bit hash codes, there's a real chance of different
messages
yielding the same hash code.  We take the approach that each subsystem
(e.g., each device driver) gets its own facility code (i.e., not KERN
for everybody).  If you key on hash code AND facility, the chance of
collisions is very small.

- Although I believe it's worthwhile to categorize messages and tag them
accordingly -- e.g., "hardware failure: <description of problem>" or
"configuration note: <whatever>" -- most of the existing printk messages
contain very context-specific info, and couldn't be entirely replaced
with standard messages without loss of useful info.

Jim Keniston
IBM Linux Technology Center

^ permalink raw reply	[flat|nested] 137+ messages in thread
* Re: kernel support for non-english user messages
@ 2003-04-10 10:47 Ruth Ivimey-Cook
  0 siblings, 0 replies; 137+ messages in thread
From: Ruth Ivimey-Cook @ 2003-04-10 10:47 UTC (permalink / raw)
  To: linux-kernel

At 23:55 09/04/2003, you wrote:
> > "My suggestion would be to add the required i18n support to klogd, so
> > that kernel messages are translated as they are removed from dmesg into
> > syslog. Then, like any i18n support,
>
>This is _not_ like any i18n support.  The problem is that normal

Agreed. How about changing the way printk works, so that instead of 
combining the format string, it just "prints" its args:

printk("%s: name %p is %d\n", name, ptr, val);

results in the following in the kernel buffer:

"%s: name %p is %d\n", "stringval", 0x4790243, 44


Then run a process to either push them together again (native mode) or do 
the getmsg() thing for i18n mode?

Only problem I can see is early-boot, where the normal demons can't be 
running. Could we have a  kernel-thread that can be run ASAP and does the 
native-mode thing, that can be killed if userspace runs an i18n demon?

HTH,

Ruth  


^ permalink raw reply	[flat|nested] 137+ messages in thread
* RE: kernel support for non-english user messages
@ 2003-04-10 19:21 Perez-Gonzalez, Inaky
  2003-04-10 20:41 ` Robert White
  0 siblings, 1 reply; 137+ messages in thread
From: Perez-Gonzalez, Inaky @ 2003-04-10 19:21 UTC (permalink / raw)
  To: 'Ruth Ivimey-Cook', 'linux-kernel@vger.kernel.org'



> From: Ruth Ivimey-Cook [mailto:Ruth.Ivimey-Cook@ivimey.org]
>
> >This is _not_ like any i18n support.  The problem is that normal
> 
> Agreed. How about changing the way printk works, so that instead of
> combining the format string, it just "prints" its args:
> 
> printk("%s: name %p is %d\n", name, ptr, val);
> 
> results in the following in the kernel buffer:
> 
> "%s: name %p is %d\n", "stringval", 0x4790243, 44

Debugging a non-klogd enabled kernel would be a pain - alas, having some
preprocessing tool, this can be done without that modification. If you 
know the format string (from the sources), given a printed message, a 
regexp could extract the parts that need translation.

Iñaky Pérez-González -- Not speaking for Intel -- all opinions are my own
(and my fault)

^ permalink raw reply	[flat|nested] 137+ messages in thread
* RE: kernel support for non-english user messages
@ 2003-04-10 20:54 Chuck Ebbert
  2003-04-10 21:08 ` Bernd Petrovitsch
  0 siblings, 1 reply; 137+ messages in thread
From: Chuck Ebbert @ 2003-04-10 20:54 UTC (permalink / raw)
  To: Perez-Gonzalez, Inaky, linux-kernel


>>      How about changing the way printk works, so that instead of
>> combining the format string, it just "prints" its args:
>> 
>> printk("%s: name %p is %d\n", name, ptr, val);
>> 
>> results in the following in the kernel buffer:
>> 
>> "%s: name %p is %d\n", "stringval", 0x4790243, 44
>
> Debugging a non-klogd enabled kernel would be a pain


 Why?  Shouldn't it be easy to fix dmesg so it unmangles the output?

 The real problem I see is that this approach doesn't make it any
easier to translate the messages.

  Maybe someone should just try to write a Babelfish-like thing that
takes English kernel-speak and translates it as best it can?  It would
at least be amusing to read the output. :)

--
 Chuck
 I am not a number!

^ permalink raw reply	[flat|nested] 137+ messages in thread
* RE: kernel support for non-english user messages
@ 2003-04-10 21:20 Perez-Gonzalez, Inaky
  2003-04-10 22:06 ` Andreas Dilger
  0 siblings, 1 reply; 137+ messages in thread
From: Perez-Gonzalez, Inaky @ 2003-04-10 21:20 UTC (permalink / raw)
  To: 'Chuck Ebbert', 'linux-kernel'


> From: Chuck Ebbert [mailto:76306.1226@compuserve.com]
>
> >>      How about changing the way printk works, so that instead of
> >> combining the format string, it just "prints" its args:
> >>
> >> printk("%s: name %p is %d\n", name, ptr, val);
> >>
> >> results in the following in the kernel buffer:
> >>
> >> "%s: name %p is %d\n", "stringval", 0x4790243, 44
> >
> > Debugging a non-klogd enabled kernel would be a pain
> 
> 
>  Why?  Shouldn't it be easy to fix dmesg so it unmangles the output?

s/non-klogd enabled/dmesg/

Same thing - what I mean is that if you don't have some automatic
means to recompose the messages, reading the direct output of 
the console (as sometimes you have to), becomes a mess.

Iñaky Pérez-González -- Not speaking for Intel -- all opinions are my own
(and my fault)

^ permalink raw reply	[flat|nested] 137+ messages in thread
* Re: kernel support for non-english user messages
@ 2003-04-10 22:13 Chuck Ebbert
  2003-04-10 22:33 ` Stephen Hemminger
  0 siblings, 1 reply; 137+ messages in thread
From: Chuck Ebbert @ 2003-04-10 22:13 UTC (permalink / raw)
  To: linux-kernel

John Bradford wrote:


> When are we going to see versioned filesystems in Linux?  That
> was a standard feature in VMS.


  Just a trivial change the the VFS, no doubt.


--
 Chuck
 I am not a number!

^ permalink raw reply	[flat|nested] 137+ messages in thread
* Re: kernel support for non-english user messages
@ 2003-04-10 23:23 Chuck Ebbert
  0 siblings, 0 replies; 137+ messages in thread
From: Chuck Ebbert @ 2003-04-10 23:23 UTC (permalink / raw)
  To: Bernd Petrovitsch, linux-kernel


>>>> "%s: name %p is %d\n", "stringval", 0x4790243, 44
>[...]
>> The real problem I see is that this approach doesn't make it any
>>easier to translate the messages.
>
>If you habe the above, you could use/copy/reuse gettext() since the 
>format string is used a key/hash/unique id for the translation.


 If all you need is the hash of the format string, why not put that
at the end of the log message, i.e.

  <severity>message<hash>

(Note this is the hash of the *format* string, not the message.)

This would be nearly-trivial to do.


--
 Chuck

^ permalink raw reply	[flat|nested] 137+ messages in thread
* Re: kernel support for non-english user messages
@ 2003-04-11 10:10 Chuck Ebbert
  0 siblings, 0 replies; 137+ messages in thread
From: Chuck Ebbert @ 2003-04-11 10:10 UTC (permalink / raw)
  To: DevilKin, linux-kernel


>linux dmesg=verbose
>
>and
>
>linux dmesg=quiet


 You really need "dmesg=normal" as well, unless you are calling the
current behavior verbose.  After seeing FreeBSD in bootverbose
mode, I wouldn't...

--
 Chuck
 I am not a number!

^ permalink raw reply	[flat|nested] 137+ messages in thread
[parent not found: <20030409051006$1ecf@gated-at.bofh.it>]
* Re: kernel support for non-English user messages
@ 2003-04-11 13:17 Chuck Ebbert
  2003-04-11 13:40 ` John Bradford
                   ` (3 more replies)
  0 siblings, 4 replies; 137+ messages in thread
From: Chuck Ebbert @ 2003-04-11 13:17 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel

Linux Torvalds wrote:


> I've used VMS, and error code number encoding is a total heap of crap.


 Maybe for developers, but users like it.  I can still remember back in
the Old Days, taking those error codes and looking them up in something
called a "manual" where there was a coherent explanation of
what had gone wrong and even suggestions on what to do about it.

 (Of course there were drawbacks, too... when the leather belt driving
the Difference Engine broke, for example, it was every man for himself!)

--
 Chuck

^ permalink raw reply	[flat|nested] 137+ messages in thread
* Re: kernel support for non-English user messages
@ 2003-04-11 14:52 Paolo Ciarrocchi
  0 siblings, 0 replies; 137+ messages in thread
From: Paolo Ciarrocchi @ 2003-04-11 14:52 UTC (permalink / raw)
  To: linux-kernel; +Cc: john

>On a related note, if we are going to make a dmesg interpreter and
>translator, could we include the ability to generate a kernel .config
>from the boot time output?  Note, I don't mean re-create the .config
>that the kernel was compiled with, but something like NetBSD, (at
>least), which lets you boot with a kernel that has drivers that you
>don't need, and generate a config file which will compile a kernel
>which contains only those that are actually needed.

Yes please, it is a 'nice to have stuff'.

Ciao,
       Paolo


-- 
______________________________________________
http://www.linuxmail.org/
Now with e-mail forwarding for only US$5.95/yr

Powered by Outblaze

^ permalink raw reply	[flat|nested] 137+ messages in thread
* RE: kernel support for non-English user messages
@ 2003-04-11 16:57 Chuck Ebbert
  2003-04-11 17:38 ` Richard B. Johnson
  2003-04-11 18:10 ` Matti Aarnio
  0 siblings, 2 replies; 137+ messages in thread
From: Chuck Ebbert @ 2003-04-11 16:57 UTC (permalink / raw)
  To: Alan Cox; +Cc: linux-kernel

Alan Cox wrote:


> You are right about needing to log parameters, but given a log line
> of the form
>
> %s: went up in flames\n\0eth0\0\0
>
> that can be handled by the log viewer


  I still see some problems...

  For one, there are 131 instances of:

      printk("%s\n", blurb);

in various forms in 2.5.66.  Besides possible ritual immolation of
those responsible for such things, something would have to be done
about them.

  Another problem is the one of getting that text onto the console
in readable form. The only thing I can think of is have a two-stage
process where printk puts the data into the log buffer as
zero-terminated strings and then the console write routines format
it for display.  They'd probably need their own buffers to do that.


> %s: went up in flames\n\0eth0\0\0


  Is that "\n" an actual ASCII newline or the printk escape sequence?



--
 "Let's fight until six, and then have dinner," said Tweedledum.
 --Lewis Carroll, _Through the Looking Glass_

^ permalink raw reply	[flat|nested] 137+ messages in thread
* RE: kernel support for non-english user messages
@ 2003-04-11 20:02 Perez-Gonzalez, Inaky
  0 siblings, 0 replies; 137+ messages in thread
From: Perez-Gonzalez, Inaky @ 2003-04-11 20:02 UTC (permalink / raw)
  To: 'Valdis.Kletnieks@vt.edu', 'Shaya Potter'
  Cc: 'John Bradford', 'Alan Cox',
	'root@chaos.analogic.com', 'Frank Davis',
	'Linux Kernel Mailing List'


> 3) Version a 500 megabyte file.  Change one block.  Do it a few more
times.
> Are you better off copying the whole file (which bloats your disk usage
and
> kills your I/O bandwidth), or keeping deltas (the list of allocated blocks
could be
> almost identical except for the replaced/rewritten blocks).  However, this
DOES
> make doing an fsck() a *lot* more interesting - is a block allocated to
multiple
> files in error or not?

For this I would yield to a mechanism similar to COW, block you modify,
block you copy ... it would impose some restrictions here and there, 
but it'd work, I'd say - still it is fun for fsck(), as you are changing
some semantics, but it'd be interesting.

Iñaky Pérez-González -- Not speaking for Intel -- all opinions are my own
(and my fault)

^ permalink raw reply	[flat|nested] 137+ messages in thread
[parent not found: <A46BBDB345A7D5118EC90002A5072C780BEBA7DD@orsmsx116.jf.inte l.com>]
* Re: kernel support for non-English user messages
@ 2003-04-11 22:21 Chuck Ebbert
  2003-04-11 22:53 ` Martin J. Bligh
                   ` (2 more replies)
  0 siblings, 3 replies; 137+ messages in thread
From: Chuck Ebbert @ 2003-04-11 22:21 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel


> I thought you might be seriously in need of some mental evaluation
> when you claimed that users "liked looking up error numbers in
> manuals".


 Not the looking up part, but that fact that the explanation
for every single message the software could emit was available.

 Today it's all HTML documents or PDFs or something, but it's still
a staggering amount of information.  I have ~300MB of Oracle
documentation on one desktop, 6 of it server error messages alone.
Every possible message is explained to some extent, except this one:


-----------------------------------------------------------------------
ORA-00600 internal error code, arguments: [string], [string], [string],
                   [string], [string], [string], [string], [string]

Cause: This is the generic internal error number for Oracle program
exceptions. It indicates that a process has encountered a low-level,
unexpected condition.
<SNIP>
The first argument is the internal message number. Other arguments
are various numbers, names, and character strings. The numbers may
change meanings between different versions of Oracle. 

Action: Report this error to Oracle Customer Support after gathering
the following information:
<SNIP>
Note: The cause of this message may manifest itself as different errors
at different times. Be aware of the history of errors that occurred
before this internal error. 
-----------------------------------------------------------------------


which is currently pretty much the only explanation available for
a whole lot of Linux error messages. I can go read the source when e.g.
the md driver splats its internal status dumps all over the console
during array rebuild, but that doesn't help much.


> Whee. April first is long gone, but the jokers stay around.


 Our kind knows no season.


--
 "Let's fight till six, and then have dinner," said Tweedledum.
  --Lewis Carroll, _Through the Looking Glass_

^ permalink raw reply	[flat|nested] 137+ messages in thread
* Re: kernel support for non-English user messages
@ 2003-04-11 23:36 Jim Keniston[UNIX]
  0 siblings, 0 replies; 137+ messages in thread
From: Jim Keniston[UNIX] @ 2003-04-11 23:36 UTC (permalink / raw)
  To: LKML

[-- Attachment #1: Type: text/plain, Size: 1810 bytes --]

On Fri, 2003-04-11 at 12:16, Alan Cox wrote:

> Providing the viewer is translating the originals always exist. Indeed
> you can do
> 
>         LANG=es view-logs
>         LANG=ru view-logs
>         ...
> 
> You can have sysadmins with no common language("not a recommended
> configuration" ;))
> 
> You are right about needing to log parameters, but given a log line
> of the form
> 
> %s: went up in flames\n\0eth0\0\0
> 
> that can be handled by the log viewer

Other contributors have also endorsed the idea of creating a message
log where the format and args are kept separate.  Here's code to do it.

Enclosed is a patch that adds support for logging kernel events to a
structured event log (see evlog.sourceforge.net).  When EVLOG_FWPRINTK
is enabled, printk messages are automatically forwarded to the event
log in this form.  (They are also logged to klogd/syslogd, as usual.)

The log viewer (evlview) can reconstruct the complete message from the
components.  If you provide translations (AKA formatting templates) for
particular messages, and set your LANG environment variable
appropriately,
evlview will display those messages in the selected language.  (Messages
without translations are displayed in English.)

A few more notes about this event-logging support:
- printk calls don't change; one line is added to printk(), about 20 to
printk.c.
- Like syslog, it also handles messages from user space.  There are also
a variety of other ways to use this support to log information from the
kernel.
- User-mode event logging requires no kernel support.
- There's a bunch of stuff that sysadmins and tech support people have
found useful, such as APIs for examining the log and receiving
notification
of events.

See evlog.sourceforge.net for more info.

Jim Keniston
IBM Linux Technology Center

[-- Attachment #2: evlog-1.5.2_kernel-2.5.67.patch --]
[-- Type: text/plain, Size: 35393 bytes --]

diff -Naur linux.org/include/linux/evl_log.h linux.kernel.patched/include/linux/evl_log.h
--- linux.org/include/linux/evl_log.h	Wed Dec 31 16:00:00 1969
+++ linux.kernel.patched/include/linux/evl_log.h	Fri Apr 11 15:27:45 2003
@@ -0,0 +1,142 @@
+/*
+ * Linux Event Logging for the Enterprise
+ * Copyright (c) International Business Machines Corp., 2003
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *  Please send e-mail to lkessler@users.sourceforge.net if you have
+ *  questions or comments.
+ *
+ *  Project Website:  http://evlog.sourceforge.net/
+ *
+ */
+
+#ifndef _LINUX_EVL_LOG_H
+#define _LINUX_EVL_LOG_H
+
+#ifndef __KERNEL__
+#ifdef _POSIX_THREADS
+#include <pthread.h>
+#endif
+#endif
+
+/* Values for log_flags member */
+#define POSIX_LOG_TRUNCATE  0x1
+#define EVL_KERNEL_EVENT	0x2
+#define EVL_INITIAL_BOOT_EVENT 	0x4
+#define EVL_KERNTIME_LOCAL	0x8
+#define EVL_INTERRUPT		0x10	/* Logged from interrupt context */
+#define EVL_PRINTK		0x20	/* Logged by printk() */
+
+/* Formats for optional portion of record. */
+#define POSIX_LOG_NODATA    0
+#define POSIX_LOG_BINARY    1
+#define POSIX_LOG_STRING    2
+#define POSIX_LOG_PRINTF    3
+
+/* Maximum length of variable portion of record */
+#define POSIX_LOG_ENTRY_MAXLEN      (8 * 1024)
+
+/* Maximum length for a string returned by posix_log_memtostr */
+/* Thus also the max length of a facility name */
+#define POSIX_LOG_MEMSTR_MAXLEN	128
+
+typedef unsigned int posix_log_facility_t;
+typedef int posix_log_severity_t;
+typedef int posix_log_recid_t;
+typedef int posix_log_procid_t;
+
+#define EVL_INVALID_FACILITY ((posix_log_facility_t)-1)
+
+struct posix_log_entry {
+	unsigned int            log_magic;
+        posix_log_recid_t   	log_recid;
+        size_t          	log_size;
+        int             	log_format;
+        int             	log_event_type;
+        posix_log_facility_t 	log_facility;
+        posix_log_severity_t    log_severity;
+        uid_t           	log_uid;
+        gid_t           	log_gid;
+        pid_t           	log_pid;
+        pid_t           	log_pgrp;
+        struct timespec 	log_time;
+        unsigned int    	log_flags;
+#ifdef __KERNEL__
+        unsigned long int	log_thread;
+#else
+#ifdef _POSIX_THREADS
+	pthread_t		log_thread;
+#else
+	unsigned long int	log_thread;
+#endif
+#endif
+        posix_log_procid_t	log_processor;
+}; 
+
+typedef struct posix_log_entry rec_hdr_t;
+typedef struct evl_buf_rec {
+        struct posix_log_entry  rechdr;
+        char                    varbuf[1];
+} evl_buf_rec_t;
+
+
+#define LOGFILE_MAGIC   0xbeefface
+#define LOGREC_MAGIC    0xfeefface
+#define REC_HDR_SIZE    sizeof(struct posix_log_entry)
+
+/*
+ * Reserved Event Types
+ */
+#define EVL_SYSLOG_MESSAGE      0x1
+#define EVL_PRINTK_MESSAGE      0x2
+#define EVL_BUFFER_OVERRUN      0x6
+#define EVL_DUPS_DISCARDED      0x7
+
+#define LOG_LOGMGMT              (12<<3)	/* EVL Facility */
+
+#ifdef __KERNEL__
+/*
+ * Reserved Facilities
+ */
+#define LOG_KERN        (0<<3)  /* Kernel Facility */
+#define LOG_AUTHPRIV    (10<<3) /* security/authorization messages (private) */
+/*
+ * priorities (these are ordered)
+ */
+#define LOG_EMERG   0   /* system is unusable */
+#define LOG_ALERT   1   /* action must be taken immediately */
+#define LOG_CRIT    2   /* critical conditions */
+#define LOG_ERR     3   /* error conditions */
+#define LOG_WARNING 4   /* warning conditions */
+#define LOG_NOTICE  5   /* normal but significant condition */
+#define LOG_INFO    6   /* informational */
+#define LOG_DEBUG   7   /* debug-level messages */
+
+#ifdef CONFIG_EVLOG
+extern int posix_log_write(posix_log_facility_t facility, int event_type,
+         	posix_log_severity_t severity, const void *buf,
+        	size_t len, int format, unsigned int flags);
+#else	/* ! CONFIG_EVLOG */
+inline int posix_log_write(posix_log_facility_t facility, int event_type,
+		posix_log_severity_t severity, const void *buf,
+		size_t len, int format, unsigned int flags)
+		{ return -ENOSYS; }
+#endif	/* CONFIG_EVLOG */
+
+#endif	/* __KERNEL__ */
+
+#endif	/* _LINUX_EVL_LOG_H */
diff -Naur linux.org/init/Kconfig linux.kernel.patched/init/Kconfig
--- linux.org/init/Kconfig	Fri Apr 11 15:27:45 2003
+++ linux.kernel.patched/init/Kconfig	Fri Apr 11 15:27:45 2003
@@ -92,6 +92,35 @@
 	  building a kernel for install/rescue disks or your system is very
 	  limited in memory.
 
+config EVLOG
+	bool "Enterprise event logging support"
+	help
+	  This enables support for enterprise-level event logging based
+	  upon the draft POSIX 1003.25 standard.  Enabling this feature
+	  does not affect the operation of the sysklogd package in any
+	  way.  In order to fully utilize this feature, user must also
+	  install the companion evlog package in user-space.
+
+	  For more information see http://evlog.sourceforge.net
+
+	  If you don't know what to do here, say N.
+
+config EVLOG_BUFSIZE
+	int "Event log buffer size (in Kbytes)"
+	depends on EVLOG
+	default "128"
+	help
+	  Event log buffer size in Kbytes. Default size is 128 Kbytes.
+
+config EVLOG_FWPRINTK
+	bool "Forward printk messages to enterprise event log"
+	depends on EVLOG
+	help
+	  This option forwards printk log messages to the enterprise event
+	  log.  Printk messages are still logged to /var/log/messages.
+
+	  If you don't know what to do here, say N.
+
 config LOG_BUF_SHIFT
 	int "Kernel log buffer size" if DEBUG_KERNEL
 	default 17 if ARCH_S390
diff -Naur linux.org/kernel/Makefile linux.kernel.patched/kernel/Makefile
--- linux.org/kernel/Makefile	Fri Apr 11 15:27:45 2003
+++ linux.kernel.patched/kernel/Makefile	Fri Apr 11 15:27:45 2003
@@ -18,6 +18,7 @@
 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
 obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o
 obj-$(CONFIG_COMPAT) += compat.o
+obj-$(CONFIG_EVLOG) += evlog.o
 
 ifneq ($(CONFIG_IA64),y)
 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff -Naur linux.org/kernel/evlog.c linux.kernel.patched/kernel/evlog.c
--- linux.org/kernel/evlog.c	Wed Dec 31 16:00:00 1969
+++ linux.kernel.patched/kernel/evlog.c	Fri Apr 11 15:27:45 2003
@@ -0,0 +1,933 @@
+/*
+ * Linux Event Logging for the Enterprise
+ * Copyright (c) International Business Machines Corp., 2003
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *  Please send e-mail to lkessler@users.sourceforge.net if you have
+ *  questions or comments.
+ *
+ *  Project Website:  http://evlog.sourceforge.net/
+ *
+ */
+
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/spinlock.h>
+#include <linux/time.h>
+#include <linux/smp.h>
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <asm/uaccess.h>
+#include <asm/semaphore.h>
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/nls.h>
+#include <linux/ctype.h>
+#include <linux/console.h>
+#include <linux/smp_lock.h>
+#include <linux/crc32.h>
+
+#ifdef __i386__
+#include <asm/fixmap.h>
+#include <asm/mpspec.h>
+#include <asm/io_apic.h>
+#include <asm/apic.h>
+#endif
+
+#include <asm/bitops.h>
+#include <asm/smp.h>
+
+#include <linux/evl_log.h>
+
+
+static void mk_rec_header(struct posix_log_entry *rechdr,
+	posix_log_facility_t facility, int event_type,
+	posix_log_severity_t severity, size_t recsize,
+	uint recflags, int format);
+
+extern struct timezone sys_tz;
+
+#define EVL_BUF_SIZE (CONFIG_EVLOG_BUFSIZE * 1024)   /* EVL buffer size */
+#define EVL_BUF_FREESPACE (64*1024U) /* max free space reqd after buff */
+				    /* overrun to start writing events again. */
+
+/*
+ * This data structure describes the circular buffer that is written into
+ * by evl_kwrite_buf() and drained by evl_kbufread().
+ *
+ * bf_buf, bf_len, and bf_end are the start, length, and end of the buffer,
+ * and in the current implementation these remain constant.
+ *
+ * bf_tail advances as event records are logged to the buffer, and bf_head
+ * advances as records are drained from the buffer.  bf_curr is used
+ * internally by certain functions.  bf_dropped maintains a count of
+ * records that have been dropped due to buffer overrun.
+ */
+struct cbuf {
+	unsigned char	*bf_buf;	/* base buffer address */
+	unsigned int	bf_len;		/* buffer length */
+	unsigned int	bf_dropped;	/* (internal) dropped count */
+	unsigned char	*bf_head;	/* head-pointer for circ. buf */
+	unsigned char	*bf_tail;	/* tail-pointer for circ. buf */
+	unsigned char	*bf_curr;	/* (internal) current write ptr */
+	unsigned char	*bf_end;	/* end buffer address */
+};
+ 
+static unsigned char evl_buffer[EVL_BUF_SIZE + sizeof(long)];
+
+static struct cbuf evl_ebuf = {
+	evl_buffer,
+	EVL_BUF_SIZE,
+	0,
+	evl_buffer,
+	evl_buffer, 
+	evl_buffer,
+	evl_buffer + EVL_BUF_SIZE
+};
+
+/*
+ * This is for the serialisation of reads from the kernel buffer.
+ */
+static DECLARE_MUTEX(evl_read_sem);
+DECLARE_WAIT_QUEUE_HEAD(readq);
+spinlock_t ebuf_lock = SPIN_LOCK_UNLOCKED;
+
+/*
+ * FUNCTION     : cbufwrap
+ * Caller wants to write a chunk of size len bytes into the buffer starting at
+ * bf_curr.  If bf_curr is near the end of the buffer, then we may have to
+ * split the chunk so that some of it appears at the end of the buffer and
+ * the rest appears at the beginning.  dont_split_hdr=1 means the chunk is
+ * an entire record, and we're not allowed to split the record's header --
+ * we may have to leave unused space at the end of the buffer and start the
+ * record at the beginning.
+ *
+ * Return the location where the chunk should start, or NULL if there's
+ * no room for it (i.e., it would overrun the buffer's head pointer).
+ *
+ * ARGUMENTS    : bf_curr - where caller wants to put record
+ *              : len - total record size
+ *              : dont_split_hdr - 0 if it's OK to split the header, else 1
+ *
+ * RETURN       : where the record should be put, or NULL if no room
+ */
+static unsigned char *
+cbufwrap(unsigned char *bf_curr, size_t len, int dont_split_hdr)
+{
+	unsigned char *head, *end;
+	unsigned char *wrapbuf = bf_curr;
+
+	end = bf_curr + len;
+	head = evl_ebuf.bf_head;
+
+	if (bf_curr < head && end >= head) {
+		/* Insufficient free space in buffer; drop record. */
+		return NULL;
+	}
+	if (end > evl_ebuf.bf_end) {
+		/* end would be of end of buffer */
+		if (dont_split_hdr
+		    && bf_curr + REC_HDR_SIZE > evl_ebuf.bf_end) {
+			/* Start record at start of buffer. */
+			wrapbuf = evl_ebuf.bf_buf;
+		} else {
+			/* Split record */
+			len -= evl_ebuf.bf_end - bf_curr;
+		}
+
+		end = evl_ebuf.bf_buf + len;
+		if (end >= head) {
+			/* Insufficient free space in buffer; drop record. */
+			return NULL;
+		}
+	}
+	return wrapbuf;
+}
+
+/*
+ * FUNCTION     : cbufwrite
+ * Copy the len bytes starting at s into the buffer starting at bufp,
+ * splitting the data if we run off the end of the buffer.
+ *
+ * ARGUMENTS    : The pointer in cbuf to write at,
+ *                the buffer to write,
+ *                the number of bytes to write
+ * RETURN       : The pointer in cbuf at the end of the copied data
+ * NOTE
+ *      bf_head is owned by the drainer. bf_curr is allowed to be equal to
+ *      bf_head only when buffer is empty indicated by drainer. It is never
+ *      set to be equal by writer.
+ */
+static unsigned char *
+cbufwrite(unsigned char *bufp, unsigned char *s, size_t len)
+{
+	unsigned char *e;
+	size_t n, lw;
+
+	e = bufp + len;
+	n = len;
+
+	if (e > evl_ebuf.bf_end) {
+		lw = evl_ebuf.bf_end - bufp;
+		n -= lw;
+		e = evl_ebuf.bf_buf + n;
+		memcpy(bufp, s, lw);
+		memcpy(evl_ebuf.bf_buf, s + lw, n);
+		return e;
+	} else {
+		memcpy(bufp, s, n);
+		return (e == evl_ebuf.bf_end) ? evl_ebuf.bf_buf : e;
+	}
+}
+
+/*
+ * FUNCTION     : cbufptr
+ * Return cbuf_ptr + offset, taking possible wraparound into account.
+ *
+ * ARGUMENTS    : starting pointer in cbuf,
+ *                offset in bytes from pointer
+ * RETURN       : The pointer in circular buf that is offset bytes from
+ *                starting pointer.
+ */
+static unsigned char *
+cbufptr(unsigned char *cbuf_ptr, size_t offset)
+{
+	unsigned char *e;
+	size_t lw;
+
+	e = cbuf_ptr + offset;
+	if (e >= evl_ebuf.bf_end) {
+		lw = evl_ebuf.bf_end - cbuf_ptr;
+		e = evl_ebuf.bf_buf + (offset - lw);
+	}
+	return e;
+}
+
+/*
+ * FUNCTION     : copy_data_to_cbuf
+ * Copies the indicated record into the buffer at evl_ebuf.bf_curr.
+ * Assumes we've previously verified that the header won't be split.
+ * Updates evl_ebuf.bf_curr to point past the record just copied in.
+ *
+ * ARGUMENTS    : Record header
+ *                pointer to variable data
+ */
+static int
+copy_data_to_cbuf(struct posix_log_entry *rhdr, unsigned char *vbuf)
+{
+	memcpy(evl_ebuf.bf_curr, rhdr, REC_HDR_SIZE);
+	evl_ebuf.bf_curr += REC_HDR_SIZE;
+
+	if (rhdr->log_size > 0) {
+		evl_ebuf.bf_curr = 
+			cbufwrite(evl_ebuf.bf_curr, vbuf, rhdr->log_size);
+	}
+	
+	return 0;
+}
+
+/*
+ * EVL circular buffer had been full and caused later messages to be
+ * dropped. Now the buffer has space.  (Still it is better to identify the
+ * cause so it doesn't repeat. The buffer gets full if the rate of incoming
+ * messages is much higher than can be drained. This could happen if messages
+ * are repeated at an excessively high rate or the daemon in user-space is
+ * not running.)
+ *
+ * Now that we can log events again, log one giving the number of events
+ * dropped.
+ */
+static int
+log_dropped_recs_event(void)
+{
+	unsigned char sbuf[255];
+	struct posix_log_entry drechdr;
+	size_t vbuflen;
+	unsigned char *oldcur = evl_ebuf.bf_curr;
+
+	snprintf(sbuf, sizeof(sbuf), "%d event records dropped due to EVL buffer overflow.", 
+		evl_ebuf.bf_dropped);
+	evl_ebuf.bf_dropped = 0;
+	vbuflen = strlen(sbuf) + 1;
+	mk_rec_header(&drechdr, LOG_KERN, EVL_BUFFER_OVERRUN, LOG_INFO,
+		vbuflen, 0, POSIX_LOG_STRING);
+	evl_ebuf.bf_curr = cbufwrap(evl_ebuf.bf_curr, REC_HDR_SIZE+vbuflen, 1);
+	if (evl_ebuf.bf_curr != (unsigned char *)NULL) {
+		copy_data_to_cbuf(&drechdr, sbuf);
+		return 0;
+	} else {
+		/*
+		 * This shouldn't happen, since EVL_BUF_FREESPACE is much
+		 * bigger than the event we're logging here.
+		 */
+		evl_ebuf.bf_curr = oldcur;
+		return -1;
+	}
+}
+
+/*
+ * FUNCTION     : evl_check_buf
+ * ARGUMENTS    : NONE
+ * RETURN       : -1 for failure, ie. insufficient buffer space
+ *                 0 for success
+ * If buffer free space is greater than the applicable water-mark,
+ * returns 0.  If not, return -1.  Sets evl_buf.bf_curr to the location
+ * where the next record should go.
+ *
+ * Once the high water mark is hit and failure is returned (discarded
+ * messages) it sets a substantial low water mark before permitting
+ * messages to be buffered again.  It counts the number of discards
+ * in the meantime and reports them when restarted.  If the water
+ * marks were equivalent, then there could be a thrashing of stops
+ * and starts, making the discarded message reporting annoying.
+ *
+ */
+static int
+evl_check_buf(void)
+{
+	unsigned char *head, *tail;
+	size_t water_mark, avail;
+
+	head    = evl_ebuf.bf_head;
+	tail	= evl_ebuf.bf_tail;
+	avail   = (head <= tail) ?
+	      (evl_ebuf.bf_len - (tail - head)) :
+	      (head - tail);
+
+	if (evl_ebuf.bf_dropped != 0) {
+		/*
+		 * Still recovering from buffer overflow.
+		 * Apply the low water mark.
+		 */
+		water_mark = min(EVL_BUF_FREESPACE, evl_ebuf.bf_len / 2);
+	} else {
+		water_mark = REC_HDR_SIZE;
+	}
+
+	if (avail < water_mark) {
+		return -1;
+	}
+
+	/* There's enough free buffer space.  Return success. */
+	evl_ebuf.bf_curr = tail;
+	if (evl_ebuf.bf_dropped != 0) {
+		return log_dropped_recs_event();
+	}
+	return 0;
+}
+
+/*
+ * FUNCTION     : evl_getnext_rec
+ * ARGUMENTS    : rec is a pointer to the log event record.
+ *                The next record pointer mustn't be beyond tail.
+ * RETURN       : This function returns a pointer to the place to start the
+ *                next record in the circular buffer.  As a special case,
+ *                if rec is NULL, then the location of the first record at
+ *                or after bf_head is returned; else the record following
+ *                rec is returned.
+ */
+static unsigned char *
+evl_getnext_rec(unsigned char *rec, size_t recsize, unsigned char *tail)
+{
+	if (rec == NULL) {
+		rec = evl_ebuf.bf_head;
+	} else {
+		rec = cbufptr(rec, recsize);
+	}
+
+	if (rec == tail) {
+		return rec;
+	}
+
+	/* Check for wrap. */
+	if ((rec + REC_HDR_SIZE) > evl_ebuf.bf_end) {
+		rec = evl_ebuf.bf_buf;
+	}
+	return rec;
+}
+
+/*
+ * FUNCTION     : evl_kbufread - Used to read event records from the EVL
+ *                circular buffer.
+ * ARGUMENTS    : retbuf is a pointer to the buffer to be filled with the
+ *                event records.
+ *              : bufsize is length of the buffer allocated by the user.
+ * RETURN       : Number of bytes copied if read is successful, else -ve value.
+ *                event record and data to buffer.
+ */
+
+int
+evl_kbufread(unsigned char *retbuf, size_t bufsize)
+{
+	unsigned char *rec;
+	size_t rec_size;
+	int error = 0;
+	int retbuflen = 0;
+	unsigned char *tail, *buf = retbuf;
+
+	/*
+	 * the read request size must be at least rec_hdr_t size
+	 */
+	if (bufsize < REC_HDR_SIZE) {
+		return -EINVAL;
+	}
+	/* 
+	 * Serialize all reads, just in case someone got sneaky 
+	 */
+	error = down_interruptible(&evl_read_sem);
+	if (error == -EINTR) {
+		return -EINTR;
+	}
+	/*
+	 * Go to sleep if the buffer is empty.
+	 */
+	error = wait_event_interruptible(readq, 
+		(evl_ebuf.bf_head != evl_ebuf.bf_tail));
+	if (error) {
+		up(&evl_read_sem);
+		return error;
+	}
+	/*
+	 * Assemble message(s) into the user buffer, as many as will
+	 * fit.  On running out of space in the buffer, try to copy
+	 * the header for the overflowing message.  This means that
+	 * there will always be at least a header returned.  The caller
+	 * must compare the numbers of bytes returned (remaining) with
+	 * the length of the message to see if the entire message is
+	 * present.  A subsequent read will get the entire message,
+	 * including the header (again).
+	 */
+	tail = evl_ebuf.bf_tail;
+	rec = evl_getnext_rec(NULL, 0, tail);	/* typically evl_ebuf.bf_head */
+	if (rec == NULL) { 
+		/* Should not happen. Buffer must have atleast one record. */
+		error = -EFAULT;
+		goto out;
+	}
+
+	do {
+#if defined(__ia64__)
+		evl_buf_rec_t record;
+		memcpy(&record, rec, sizeof(evl_buf_rec_t));
+		rec_size = REC_HDR_SIZE + record.rechdr.log_size;
+#else
+		evl_buf_rec_t *p_rec;
+		p_rec = (evl_buf_rec_t *) rec;
+		rec_size = REC_HDR_SIZE + p_rec->rechdr.log_size;
+#endif
+
+		if (bufsize < REC_HDR_SIZE) {
+			/* user buffer is smaller than header */
+			break;
+		}
+		if (bufsize < rec_size) {
+			/* 
+			 * Copyout only the header 'cause user buffer can't
+			 * hold full record.
+			 */
+			error = copy_to_user(buf, rec, REC_HDR_SIZE);
+			if (error) {
+				error = -EFAULT;
+				break;
+			}
+			bufsize -= REC_HDR_SIZE;
+			retbuflen += REC_HDR_SIZE;
+			break;
+		}
+		if ((rec + rec_size) > evl_ebuf.bf_end) {
+			size_t lw = evl_ebuf.bf_end - rec;
+			error = copy_to_user(buf, rec, lw);
+			if (!error) {
+				error = copy_to_user(buf + lw, evl_ebuf.bf_buf, 
+					rec_size - lw); 
+			}
+		} else {
+			error = copy_to_user(buf, rec, rec_size);
+		}
+		if (error) {
+			error = -EFAULT;
+			break;
+		}
+		rec = evl_getnext_rec(rec, rec_size, tail);
+		buf += rec_size;
+		bufsize -= rec_size;
+		retbuflen += rec_size;
+	} while (rec != tail);
+
+	if (error == 0) {
+		evl_ebuf.bf_head = rec;
+		error = retbuflen;
+	}
+
+out:
+	up(&evl_read_sem);
+	return(error);
+}
+
+/*
+ * FUNCTION	: kwrite_buf
+ * Called by evl_kwrite_buf() to write to the buffer the event record
+ * consisting of rec_hdr and vardata.
+ *
+ * RETURN	: 0 on success, -ENOSPC on failure
+ *		On success evl_ebuf.bf_curr is updated to point just past
+ *		the event we just wrote to the buffer.
+ */
+static int
+kwrite_buf(struct posix_log_entry *rec_hdr, unsigned char *vardata)
+{
+	size_t recsize;
+	unsigned char *rec;
+	if (rec_hdr->log_size > POSIX_LOG_ENTRY_MAXLEN) {
+		rec_hdr->log_size = POSIX_LOG_ENTRY_MAXLEN;
+		rec_hdr->log_flags |= POSIX_LOG_TRUNCATE;
+	}
+	recsize = REC_HDR_SIZE + rec_hdr->log_size;
+	rec = cbufwrap(evl_ebuf.bf_curr, recsize, 1);
+	if (rec == (unsigned char *)NULL) {
+		return -ENOSPC;
+	}
+
+	evl_ebuf.bf_curr = rec;
+	copy_data_to_cbuf(rec_hdr, vardata);
+
+	/*
+	 * If the variable data is a truncated string, make sure it
+	 * ends with a null character.
+	 */
+	if ((rec_hdr->log_flags & POSIX_LOG_TRUNCATE) &&
+	    rec_hdr->log_format == POSIX_LOG_STRING) {
+		if (evl_ebuf.bf_curr == evl_ebuf.bf_buf) {
+			*(evl_ebuf.bf_end - 1) = '\0';
+		} else {
+			*(evl_ebuf.bf_curr - 1) = '\0';
+		}
+	}
+	return 0;
+}
+
+/*
+ * FUNCTION     : evl_kwrite_buf - Used to write kernel level messages.
+ * RETURN       : 0 if writing to buffer is successful, else -errno.
+ */
+
+static int
+evl_kwrite_buf(posix_log_facility_t    fac,
+		int                    ev_type,
+		posix_log_severity_t   sev,
+		int                    format,
+		unsigned char          *recbuf,
+		uint                   var_rec_len,
+		uint                   flags) 
+{
+	uint recflags = flags;
+	struct posix_log_entry rec_hdr;
+	int error = 0;
+	unsigned char *oldtail = evl_ebuf.bf_tail;
+		/* Used to wake the read call if it sleeps */ 
+	long iflags;	/* for spin_lock_irqsave() */
+
+	if (sev > LOG_DEBUG) {
+		return -EINVAL;
+	}
+	
+	recflags |= EVL_KERNEL_EVENT;   /* kernel mesagge */    
+	if (in_interrupt()) {
+		recflags |= EVL_INTERRUPT;
+	}
+	mk_rec_header(&rec_hdr, fac, ev_type, sev, var_rec_len, recflags,
+		format);
+	
+	spin_lock_irqsave(&ebuf_lock, iflags);
+	if (evl_check_buf() < 0) {
+		evl_ebuf.bf_dropped++;
+		spin_unlock_irqrestore(&ebuf_lock, iflags);
+		return -ENOSPC;
+	}
+
+	error = kwrite_buf(&rec_hdr, recbuf);
+
+	if (error == 0) {
+		evl_ebuf.bf_tail = evl_ebuf.bf_curr;
+		if ((evl_ebuf.bf_head == oldtail) &&
+		    (evl_ebuf.bf_head != evl_ebuf.bf_tail)) {
+			wake_up_interruptible(&readq);
+		}
+	} else if (error == -ENOSPC) {        
+		evl_ebuf.bf_dropped++;
+	}
+	spin_unlock_irqrestore(&ebuf_lock, iflags);
+	return error;
+}
+
+/*
+ *      This is the standard POSIX function for writing events to the event log, *      See event logging specification at:
+ *      http://evlog.sourceforge.net/linuxEvlog.html
+ */
+int posix_log_write(posix_log_facility_t facility, int event_type,
+                posix_log_severity_t severity, const void *buf,
+                size_t recsize, int format, unsigned int flags)
+{
+        int ret = 0;
+
+        if ((buf == (void *)NULL) && (recsize > 0)) {
+                return -EINVAL;
+        }
+        if (recsize == 0 && format != POSIX_LOG_NODATA) {
+                return -EINVAL;
+        }
+        if (format == POSIX_LOG_STRING) {
+                if (strlen((const char*)buf) != recsize-1) {
+                        return -EBADMSG;
+                }
+        }
+
+        ret = evl_kwrite_buf(facility, event_type, severity, format,
+                                (char *)buf, recsize, flags);
+
+        return ret;
+}
+
+/*
+ * buf is a buffer of size POSIX_LOG_ENTRY_MAXLEN.  It currently contains
+ * *reclen bytes.  Append as much of data to buf as will fit.  Set *reclen
+ * to what the updated size would be if buf were big enough.
+ */
+void
+evl_append_to_buf(char *buf, size_t *reclen, const void *data, size_t datasz)
+{
+        int copysz = (int) datasz;
+        int room = (int) POSIX_LOG_ENTRY_MAXLEN - (int) *reclen;
+        if (room > 0) {
+                if (copysz > room) {
+                        copysz = room;
+                }
+                (void) memcpy(buf + *reclen, data, copysz);
+        }
+        *reclen += datasz;
+}
+
+/*
+ * Append a string to the buffer.  If null == 1, we include the terminating
+ * null.  If the string extends over the end of the buffer, terminate the
+ * buffer with a null.
+ */
+void
+evl_append_string_to_buf(char *buf, size_t *reclen, const char *s, int null)
+{
+        size_t old_reclen = *reclen;
+        evl_append_to_buf(buf, reclen, s, strlen(s) + null);
+        if (*reclen > POSIX_LOG_ENTRY_MAXLEN
+            && old_reclen < POSIX_LOG_ENTRY_MAXLEN) {
+                buf[POSIX_LOG_ENTRY_MAXLEN-1] = '\0';
+        }
+}
+
+/*
+ * Note: This function is derived from vsnprintf() (see * lib/vsprintf.c),
+ * and should be kept in sync with that function.
+ */
+
+static int skip_atoi(const char **s)
+{
+        int i=0;
+
+        while (isdigit(**s))
+                i = i*10 + *((*s)++) - '0';
+        return i;
+}
+
+/*
+ * fmt points to the '%' in a printk conversion specification.  Advance
+ * fmt past any flags, width and/or precision specifiers, and qualifiers
+ * such as 'l' and 'L'.  Return a pointer to the conversion character.
+ * Stores the qualifier character (or -1, if there is none) at *pqualifier.
+ * *wp is set to flags indicating whether the width and/or precision are '*'.
+ * For example, given
+ *      %*.2lx
+ * *pqualifier is set to 'l', *wp is set to 0x1, and a pointer to the 'x'
+ * is returned.
+ *
+ * Note: This function is derived from vsnprintf() (see * lib/vsprintf.c),
+ * and should be kept in sync with that function.
+ */
+const char *
+parse_printf_fmt(const char *fmt, int *pqualifier, int *wp)
+{
+        int qualifier = -1;
+        *wp = 0;
+
+        /* process flags */
+        repeat:
+                ++fmt;          /* this also skips first '%' */
+                switch (*fmt) {
+                        case '-':
+                        case '+':
+                        case ' ':
+                        case '#':
+                        case '0':
+                                goto repeat;
+                }
+
+        /* get field width */
+        if (isdigit(*fmt))
+                skip_atoi(&fmt);
+        else if (*fmt == '*') {
+                ++fmt;
+                /* it's the next argument */
+                *wp |= 0x1;
+        }
+
+        /* get the precision */
+        if (*fmt == '.') {
+                ++fmt;
+                if (isdigit(*fmt))
+                        skip_atoi(&fmt);
+                else if (*fmt == '*') {
+                        ++fmt;
+                        /* it's the next argument */
+                        *wp |= 0x2;
+                }
+        }
+
+        /* get the conversion qualifier */
+        if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
+                qualifier = *fmt;
+                ++fmt;
+                if (qualifier == 'l' && *fmt == 'l') {
+                        qualifier = 'L';
+                        ++fmt;
+                }
+        }
+
+        *pqualifier = qualifier;
+        return fmt;
+}
+
+static void
+pack_args(char *buf, size_t *reclen, const char *fmt, va_list args)
+{
+#define COPYARG(type) { type v=va_arg(args,type); evl_append_to_buf(buf,reclen,&v,sizeof(v)); }
+	const char *s;
+	int qualifier;		/* 'h', 'l', or 'L' for integer fields */
+	                    /* 'z' support added 23/7/1999 S.H.    */
+	                    /* 'z' changed to 'Z' --davidm 1/25/99 */
+
+	for (; *fmt ; ++fmt) {
+		int wp = 0x0;
+		if (*fmt != '%') {
+			continue;
+		}
+
+		fmt = parse_printf_fmt(fmt, &qualifier, &wp);
+		if (wp & 0x1) {
+			/* width is '*' (next arg) */
+			COPYARG(int)
+		}
+		if (wp & 0x2) {
+			/* ditto precision */
+			COPYARG(int)
+		}
+
+		switch (*fmt) {
+			case 'c':
+				COPYARG(int)
+				continue;
+
+			case 's':
+				s = va_arg(args, char *);
+				evl_append_string_to_buf(buf, reclen, s, 1);
+				continue;
+
+			case 'p':
+				COPYARG(void*)
+				continue;
+
+			case 'n':
+				/* Skip over the %n arg. */
+				if (qualifier == 'l') {
+					(void) va_arg(args, long *);
+				} else if (qualifier == 'Z') {
+					(void) va_arg(args, size_t *);
+				} else {
+					(void) va_arg(args, int *);
+				}
+				continue;
+
+			case '%':
+				continue;
+
+				/* integer number formats - handle outside switch */
+			case 'o':
+			case 'X':
+			case 'x':
+			case 'd':
+			case 'i':
+			case 'u':
+				break;
+
+			default:
+				/* Bogus conversion.  Pass thru unchanged. */
+				if (*fmt == '\0')
+					--fmt;
+				continue;
+		}
+		if (qualifier == 'L') {
+			COPYARG(long long)
+		} else if (qualifier == 'l') {
+			COPYARG(long)
+		} else if (qualifier == 'Z') {
+			COPYARG(size_t)
+		} else if (qualifier == 'h') {
+			COPYARG(int)
+		} else {
+			COPYARG(int)
+		}
+	}
+}
+
+/*
+ * These buffers are currently used only by evl_fwd_printk(), and hence
+ * are protected by printk's logbuf_lock.  They're too big to be auto
+ * variables in evl_fwd_printk().
+ */
+static char prtk_argbuf[POSIX_LOG_ENTRY_MAXLEN];
+static size_t argbuf_idx;
+static char prtk_msgbuf[POSIX_LOG_ENTRY_MAXLEN + 1];
+static int msgbuf_idx = 0;
+/*
+ * msg is the message obtained by applying vsnprintf() to
+ * fmt and args.  (Caller does this anyway, so we don't have to.)
+ * Create and log a PRINTF-format event record whose contents are:
+ *	format string (possibly concatenated from multiple segments)
+ *	int containing args size
+ *	args
+ *	return address
+ *
+ * We consult msg only to determine the severity (e.g., "<1>") and whether
+ * we have a terminating newline.  If this message segment doesn't end
+ * in a newline, we save the fmt and args for concatenation with the next
+ * printk.
+ *
+ */
+int
+evl_fwd_printk(const char *fmt, va_list args, const char *msg)
+{
+	static int sev = -1;
+	int event_type;
+	int ret = 0;
+	int argsz;
+	int msglen = strlen(msg);
+	int last_segment = (msglen > 0 && msg[msglen-1] == '\n');
+
+	if (sev == -1) {
+		/* Severity not yet defined.  Must be a new message. */
+		sev = LOG_NOTICE;
+		if (msg[0] == '<'
+		    && msg[1] >= '0' && msg[1] <= '7'
+		    && msg[2] == '>') {
+			sev = msg[1] - '0';
+		}
+		msgbuf_idx = 0;
+		argbuf_idx = 0;
+	}
+
+	evl_append_string_to_buf(prtk_msgbuf, &msgbuf_idx, fmt, 0);
+	pack_args(prtk_argbuf, &argbuf_idx, fmt, args);
+	if (!last_segment) {
+		return 0;
+	}
+
+	/*
+	 * Message completed.  Change the terminating newline to a null.
+	 * We remove the terminating newline to increase flexibility when
+	 * formatting the record for viewing.
+	 */
+	if (msgbuf_idx <= POSIX_LOG_ENTRY_MAXLEN) {
+		prtk_msgbuf[msgbuf_idx-1] = '\0';
+	}
+
+	argsz = (int) argbuf_idx;
+	evl_append_to_buf(prtk_msgbuf, &msgbuf_idx, &argsz, sizeof(argsz));
+	evl_append_to_buf(prtk_msgbuf, &msgbuf_idx, prtk_argbuf, argbuf_idx);
+
+	if (msgbuf_idx > POSIX_LOG_ENTRY_MAXLEN) {
+		msgbuf_idx = POSIX_LOG_ENTRY_MAXLEN;
+	}
+
+	/* event type = CRC of format string */
+	event_type = (int) crc32(0, prtk_msgbuf, strlen(prtk_msgbuf));
+	
+	ret = evl_kwrite_buf(LOG_KERN, event_type, sev, POSIX_LOG_PRINTF,
+		prtk_msgbuf, msgbuf_idx, EVL_PRINTK);
+	sev = -1;
+	return ret;
+}
+
+/*
+ * FUNCTION             : mk_rec_header
+ * ARGS                 : rec_hdr - the record header stucture
+ *                      : facility -
+ *                      : event_type -
+ *                      : severity -
+ *                      : recsize
+ *                      : flags -
+ *                      : format - indicates string or binary format or no data
+ * RETURN       : void
+ */
+static void mk_rec_header(struct posix_log_entry *rec_hdr,
+		   posix_log_facility_t   facility,
+		   int                    event_type,
+		   posix_log_severity_t   severity,
+		   size_t                 recsize,
+		   uint                   flags,
+		   int            	  format)
+{
+
+	rec_hdr->log_size               =  recsize;
+	rec_hdr->log_format             =  format;
+	rec_hdr->log_event_type         =  event_type;
+	rec_hdr->log_facility           =  facility;
+	rec_hdr->log_severity           =  severity;
+	rec_hdr->log_uid                =  current->uid;
+	rec_hdr->log_gid                =  current->gid;
+	rec_hdr->log_pid                =  current->pid;
+	rec_hdr->log_pgrp               =  current->pgrp;
+	rec_hdr->log_flags              =  flags;
+	rec_hdr->log_thread             =  0;
+	rec_hdr->log_processor          =  smp_processor_id();
+
+	if (get_seconds() == 0) {
+		rec_hdr->log_flags |= EVL_INITIAL_BOOT_EVENT;
+	} else {
+#if defined(__i386__)
+		if (sys_tz.tz_minuteswest == 0) {
+			/* localtime */
+                        rec_hdr->log_flags |= EVL_KERNTIME_LOCAL;
+		}
+#endif
+	}
+	rec_hdr->log_time = CURRENT_TIME;
+}
+
+EXPORT_SYMBOL(posix_log_write);
diff -Naur linux.org/kernel/printk.c linux.kernel.patched/kernel/printk.c
--- linux.org/kernel/printk.c	Fri Apr 11 15:27:45 2003
+++ linux.kernel.patched/kernel/printk.c	Fri Apr 11 15:27:45 2003
@@ -83,6 +83,13 @@
 struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
 static int preferred_console = -1;
 
+#ifdef CONFIG_EVLOG
+extern int evl_kbufread(char *, size_t);
+#endif
+#ifdef CONFIG_EVLOG_FWPRINTK
+extern int evl_fwd_printk(const char *fmt, va_list args, const char *msg);
+#endif
+
 /* Flag: console code may call schedule() */
 static int console_may_schedule;
 
@@ -154,6 +161,7 @@
  * 	7 -- Enable printk's to console
  *	8 -- Set level of messages printed to console
  *	9 -- Return number of unread characters in the log buffer
+ *     20 -- Read from event logging buffer 
  */
 int do_syslog(int type, char * buf, int len)
 {
@@ -268,6 +276,17 @@
 	case 9:		/* Number of chars in the log buffer */
 		error = log_end - log_start;
 		break;
+	case 20:
+#ifdef CONFIG_EVLOG
+		error = verify_area(VERIFY_WRITE, buf, len);
+		if (error) {
+			goto out;
+		}
+		error = evl_kbufread(buf, len);
+#else
+		error = -EIO;
+#endif
+		break;
 	default:
 		error = -EINVAL;
 		break;
@@ -408,6 +427,9 @@
 	/* Emit the output into the temporary buffer */
 	va_start(args, fmt);
 	printed_len = vsnprintf(printk_buf, sizeof(printk_buf), fmt, args);
+#ifdef CONFIG_EVLOG_FWPRINTK
+	(void) evl_fwd_printk(fmt, args, printk_buf);
+#endif
 	va_end(args);
 
 	/*

^ permalink raw reply	[flat|nested] 137+ messages in thread
* Re: kernel support for non-English user messages
@ 2003-04-11 23:38 Chuck Ebbert
  0 siblings, 0 replies; 137+ messages in thread
From: Chuck Ebbert @ 2003-04-11 23:38 UTC (permalink / raw)
  To: Matti Aarnio; +Cc: linux-kernel


>> > %s: went up in flames\n\0eth0\0\0
>> 
>>   Is that "\n" an actual ASCII newline or the printk escape sequence?
>
>The backslash is not "printk escape".  It is C-string compilation 
>notation.


  Oops, I guess I was mixing up which layer does what.


--
 "Let's fight till six, and then have dinner," said Tweedledum.
  --Lewis Carroll, _Through the Looking Glass_

^ permalink raw reply	[flat|nested] 137+ messages in thread
* RE: kernel support for non-English user messages
@ 2003-04-12  9:52 Chuck Ebbert
  0 siblings, 0 replies; 137+ messages in thread
From: Chuck Ebbert @ 2003-04-12  9:52 UTC (permalink / raw)
  To: Alan Cox; +Cc: linux-kernel

Alan Cox wrote:


> %s: went up in flames\n\0eth0\0\0


  You could make the placeholder just '%' instead of '%s' if you
were only writing zero-terminated strings.

  Every little bit helps.

--
 "Let's fight till six, and then have dinner," said Tweedledum.
  --Lewis Carroll, _Through the Looking Glass_

^ permalink raw reply	[flat|nested] 137+ messages in thread
* Re: kernel support for non-English user messages
@ 2003-04-12 15:20 Chuck Ebbert
  2003-04-12 15:34 ` Alan Cox
  0 siblings, 1 reply; 137+ messages in thread
From: Chuck Ebbert @ 2003-04-12 15:20 UTC (permalink / raw)
  To: John Bradford; +Cc: linux-kernel


> /Documentation could be a lot better than it is...  Some of it
> is very out of date.


  You are being way too kind.

  /Documentation is *awful*.

--
 "Let's fight till six, and then have dinner," said Tweedledum.
  --Lewis Carroll, _Through the Looking Glass_

^ permalink raw reply	[flat|nested] 137+ messages in thread
* RE: kernel support for non-English user messages
@ 2003-04-12 16:47 Chuck Ebbert
  0 siblings, 0 replies; 137+ messages in thread
From: Chuck Ebbert @ 2003-04-12 16:47 UTC (permalink / raw)
  To: Alan Cox; +Cc: linux-kernel


> You are right about needing to log parameters, but given a log line
> of the form
>
> %s: went up in flames\n\0eth0\0\0
>
> that can be handled by the log viewer


  How about this scheme instead?

    printk("%s: went up in flames\n", "eth0");

would become

    \0eth0\0: went up in flames\n\0\0

i.e. the zeros would mark a transition between text that came from
parameters and what was from the format string.  This would be a
lot easier to write to the console.


--
 "Let's fight till six, and then have dinner," said Tweedledum.
  --Lewis Carroll, _Through the Looking Glass_

^ permalink raw reply	[flat|nested] 137+ messages in thread
* Re: kernel support for non-English user messages
@ 2003-04-12 20:31 Chuck Ebbert
  2003-04-14  9:07 ` Denis Vlasenko
  0 siblings, 1 reply; 137+ messages in thread
From: Chuck Ebbert @ 2003-04-12 20:31 UTC (permalink / raw)
  To: Alan Cox; +Cc: linux-kernel


>>   /Documentation is *awful*.
>
> You know where to submit contributions


  If I could *write* the documentation, I wouldn't need it,
now would I?  Maybe that's the problem...


--
 Chuck
 Why is my email address an octal number?

^ permalink raw reply	[flat|nested] 137+ messages in thread
* Re: kernel support for non-English user messages
@ 2003-04-14 21:27 Chuck Ebbert
  0 siblings, 0 replies; 137+ messages in thread
From: Chuck Ebbert @ 2003-04-14 21:27 UTC (permalink / raw)
  To: vda; +Cc: linux-kernel

vda wrote:


> OTOH "I can go read the source" is the ultimate documentation
> which we have for zero extra effort.


  ...except for that required to actually understand it.

--
 CHuck

^ permalink raw reply	[flat|nested] 137+ messages in thread

end of thread, other threads:[~2003-04-26  6:41 UTC | newest]

Thread overview: 137+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-04-09  5:02 kernel support for non-english user messages Frank Davis
2003-04-09  5:29 ` Oliver Neukum
2003-04-09  5:50   ` Frank Davis
2003-04-09  9:37     ` Bernd Petrovitsch
2003-04-09 11:04   ` Alan Cox
2003-04-09  5:53 ` Andreas Dilger
2003-04-09  8:08 ` Matti Aarnio
2003-04-09  9:33   ` Oliver Neukum
2003-04-09 10:24     ` Matti Aarnio
2003-04-09 22:07   ` Werner Almesberger
2003-04-09 22:41     ` Frank Davis
2003-04-09 22:55       ` Ulrich Drepper
2003-04-09 23:53         ` Johannes Ruscheinski
2003-04-10  1:43       ` Richard B. Johnson
2003-04-10 18:57         ` Alan Cox
2003-04-10 20:13           ` Trond Myklebust
2003-04-10 19:42             ` Alan Cox
2003-04-11  0:48               ` Christer Weinigel
2003-04-11 15:56                 ` Daniel Stekloff
2003-04-10 20:53             ` Richard B. Johnson
2003-04-10 23:05               ` Jon Portnoy
2003-04-11  5:39                 ` DevilKin
2003-04-11  5:49                   ` Arnaldo Carvalho de Melo
2003-04-11  6:17                     ` DevilKin
2003-04-11 17:51                     ` Randy.Dunlap
2003-04-11 11:57               ` Helge Hafting
2003-04-11 17:55                 ` David Lang
2003-04-10 20:36           ` John Bradford
2003-04-10 22:20             ` Shaya Potter
2003-04-11  4:19               ` Valdis.Kletnieks
2003-04-11  4:23                 ` Shaya Potter
2003-04-11  8:40                   ` Henning P. Schmiedehausen
2003-04-11  9:09                 ` John Bradford
2003-04-11 10:59                   ` Valdis.Kletnieks
2003-04-11 11:11                     ` John Bradford
2003-04-11 11:40                 ` Helge Hafting
2003-04-24 23:25             ` versioned filesystems in linux (was Re: kernel support for non-english user messages) Stewart Smith
2003-04-25  7:14               ` John Bradford
2003-04-25 15:20               ` Matthew Sell
2003-04-25 15:45                 ` Richard B. Johnson
2003-04-25 16:18                   ` versioned filesystems in linux (was Re: kernel support for John Bradford
2003-04-25 17:06                     ` Richard B. Johnson
2003-04-25 17:48                       ` Valdis.Kletnieks
2003-04-25 19:38                         ` H. Peter Anvin
2003-04-25 21:21                           ` 9-track tape drive (Was: Re: versioned filesystems in linux) John Bradford
2003-04-25 21:22                             ` H. Peter Anvin
2003-04-25 21:31                               ` Mike Dresser
2003-04-26  6:32                                 ` H. Peter Anvin
2003-04-26  6:57                                   ` John Bradford
2003-04-25 18:13                       ` versioned filesystems in linux (was Re: kernel support for John Bradford
2003-04-25 18:34                         ` Richard B. Johnson
2003-04-10  8:19       ` kernel support for non-english user messages Oliver Neukum
2003-04-09 13:11 ` Giuliano Pochini
2003-04-10  3:08 ` Linus Torvalds
2003-04-10  9:05   ` kernel support for non-English " Riley Williams
2003-04-10 17:35     ` Linus Torvalds
2003-04-10 18:32       ` John Bradford
2003-04-12  2:55       ` Chris Wedgwood
2003-04-09 19:01 kernel support for non-english " Perez-Gonzalez, Inaky
2003-04-09 19:25 Perez-Gonzalez, Inaky
2003-04-09 23:31 Jim Keniston[UNIX]
2003-04-10 19:01 ` Alan Cox
2003-04-11  9:21   ` kernel support for non-English " Riley Williams
2003-04-11 12:16     ` Alan Cox
2003-04-11 13:39       ` John Bradford
2003-04-11 13:11         ` Alan Cox
2003-04-11 14:48           ` John Bradford
2003-04-10 10:47 kernel support for non-english " Ruth Ivimey-Cook
2003-04-10 19:21 Perez-Gonzalez, Inaky
2003-04-10 20:41 ` Robert White
2003-04-11  9:21   ` kernel support for non-English " Riley Williams
2003-04-11 20:49     ` Robert White
2003-04-11 22:53       ` Riley Williams
2003-04-15  3:44         ` Robert White
2003-04-15 11:08           ` Alan Cox
2003-04-15 11:08           ` Alan Cox
2003-04-15 14:07           ` Timothy Miller
2003-04-11 21:04     ` Ruth Ivimey-Cook
2003-04-11 21:31       ` Daniel Stekloff
2003-04-10 20:54 kernel support for non-english " Chuck Ebbert
2003-04-10 21:08 ` Bernd Petrovitsch
2003-04-10 21:20 Perez-Gonzalez, Inaky
2003-04-10 22:06 ` Andreas Dilger
2003-04-11  7:38   ` Ville Herva
2003-04-10 22:13 Chuck Ebbert
2003-04-10 22:33 ` Stephen Hemminger
2003-04-10 23:23 Chuck Ebbert
2003-04-11 10:10 Chuck Ebbert
     [not found] <20030409051006$1ecf@gated-at.bofh.it>
     [not found] ` <20030409081011$5257@gated-at.bofh.it>
     [not found]   ` <20030409221017$6c98@gated-at.bofh.it>
     [not found]     ` <20030409225009$2558@gated-at.bofh.it>
     [not found]       ` <20030410014009$78fb@gated-at.bofh.it>
     [not found]         ` <20030410200019$3e8f@gated-at.bofh.it>
     [not found]           ` <20030410202016$7d48@gated-at.bofh.it>
2003-04-11 11:29             ` Tim Connors
2003-04-11 13:17 kernel support for non-English " Chuck Ebbert
2003-04-11 13:40 ` John Bradford
2003-04-16  1:59   ` Gerrit Huizenga
2003-04-16 14:28     ` Timothy Miller
2003-04-16 14:37       ` Alan Cox
2003-04-16 16:20         ` Timothy Miller
2003-04-16 17:04       ` Bruce Harada
2003-04-16 18:34         ` Timothy Miller
2003-04-16 18:37           ` Bruce Harada
2003-04-11 14:37 ` Richard B. Johnson
2003-04-11 16:00 ` Linus Torvalds
2003-04-12  8:22 ` Kai Henningsen
2003-04-12 11:08   ` John Bradford
2003-04-11 14:52 Paolo Ciarrocchi
2003-04-11 16:57 Chuck Ebbert
2003-04-11 17:38 ` Richard B. Johnson
2003-04-11 18:10 ` Matti Aarnio
2003-04-11 20:02 kernel support for non-english " Perez-Gonzalez, Inaky
     [not found] <A46BBDB345A7D5118EC90002A5072C780BEBA7DD@orsmsx116.jf.inte l.com>
2003-04-11 20:55 ` Ruth Ivimey-Cook
2003-04-11 22:21 kernel support for non-English " Chuck Ebbert
2003-04-11 22:53 ` Martin J. Bligh
2003-04-12  7:55   ` John Bradford
2003-04-12  7:48 ` John Bradford
2003-04-14 11:40 ` Denis Vlasenko
2003-04-14 12:55   ` John Bradford
2003-04-14 17:29     ` Linus Torvalds
2003-04-14 18:15       ` John Bradford
2003-04-14 23:04       ` Felipe Alfaro Solana
2003-04-15 13:21       ` Alex Combas
2003-04-15 18:02       ` Eric Altendorf
2003-04-17 13:46         ` Alan Cox
2003-04-17 15:07         ` Randolph Bentson
2003-04-17 18:49           ` Eric Altendorf
2003-04-14 13:18   ` Sean Neakums
2003-04-14 14:23   ` Valdis.Kletnieks
2003-04-16  5:03     ` Denis Vlasenko
2003-04-11 23:36 Jim Keniston[UNIX]
2003-04-11 23:38 Chuck Ebbert
2003-04-12  9:52 Chuck Ebbert
2003-04-12 15:20 Chuck Ebbert
2003-04-12 15:34 ` Alan Cox
2003-04-12 17:22   ` Robert P. J. Day
2003-04-13  3:59     ` Martin J. Bligh
2003-04-13  6:21   ` John Bradford
2003-04-12 16:47 Chuck Ebbert
2003-04-12 20:31 Chuck Ebbert
2003-04-14  9:07 ` Denis Vlasenko
2003-04-14 21:27 Chuck Ebbert

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).