D&C Lug - Home Page
Devon & Cornwall Linux Users' Group

[ Date Index ][ Thread Index ]
[ <= Previous by date / thread ] [ Next by date / thread => ]

Re: [LUG] Kernel drivers - printk()



On Wednesday 11 August 2004 14:48, Andrew Rogers wrote:
I have a kernel module that must output a lot of info, a few megabytes.

As I can't write to a file from a kernel module I write the output to
/var/log/messages using printk(). The problem is that after I have
called printk() a few thousand times it stops printting to
/var/log/messages and restarts printting some time later. It is very
likely that I am calling printk too often in a short time interval.

How can I ensure that printk() has output to /var/log/messages before
calling printk() again?

I don't think you can.

I've just had a look at printk().  You'll be disappointed at the size of the 
log buffer(s) :

#if defined(CONFIG_MULTIQUAD) || defined(CONFIG_IA64)
#define LOG_BUF_LEN     (65536)
#elif defined(CONFIG_ARCH_S390)
#define LOG_BUF_LEN     (131072)
#elif defined(CONFIG_SMP)
#define LOG_BUF_LEN     (32768)
#else
#define LOG_BUF_LEN     (16384)              /* This must be a power of two */
#endif

Told you so.

You'll be doubly disappointed that the code that actually puts bytes into the 
log buffer looks like this :

static void emit_log_char(char c)
{
       LOG_BUF(log_end) = c;
       log_end++;
       if (log_end - log_start > LOG_BUF_LEN)
               log_start = log_end - LOG_BUF_LEN;
       if (log_end - con_start > LOG_BUF_LEN)
               con_start = log_end - LOG_BUF_LEN;
       if (logged_chars < LOG_BUF_LEN)
               logged_chars++;
}

i.e it's a circular buffer, and the ends are not protected.

So - you can either :

1) write a new version of printk with sensible buffer handling :-),
2) (if this is quick-and-dirty and internal to your organisation...) redefine 
LOG_BUF_LEN to something sufficiently big to make the problem go away and 
recompile the kernel,
3) (I don't know if this is a possible solution for you, 'cause I don't know 
what you're doing ...) implement a /proc filesystem interface and write some 
user code to query it.
4) enter a world of pain. :-(

(this is usually where someone comes along and offers a brilliantly simple 
solution that I haven't thought of ...)

jd


-- 
John Daragon           argv[0] limited               john@xxxxxxxxxx
Lambs Lawn Cottage, Staple Fitzpaine, Taunton TA3 5SL, UK
(house) 01460 234537                           (office) 01460 234068
(mobile) 07836 576127                          (fax)     01460 234069

--
The Mailing List for the Devon & Cornwall LUG
Mail majordomo@xxxxxxxxxxxx with "unsubscribe list" in the
message body to unsubscribe.



Lynx friendly