Good design to expose debug info from kernel module

Good design to expose debug info from kernel module

Gilboa Davara gilboad at gmail.com
Mon Mar 30 17:08:38 IDT 2015


On Mon, Mar 30, 2015 at 3:44 PM, Elazar Leibovich <elazarl at gmail.com> wrote:
> Sounds good, thanks (although it'll be harder to use from non-C programs).

I usually complement each kernel module with a user-mode C library
wrapped inside a nice / easy to use (...) C++ class that handles the
"difficult bits".
It far easier to make a C++ class that handles idiot-proof (E.g.
string commands) data than doing it inside the kernel.
(Plus, when a user mode library goes up the flame due to bad input,
you don't end up with a dead machine...)

> Do you have a good idea how to stream information as a response to ioctl?

Use TLV (type / length / value-array).

typedef union _answer_data_ {
       int __out error_code;
       int   __out next_answer_time;
       struct access_info {
              int __out access_count;
              int __out user_count;
       };
} answer_data_t;

typedef struct _debug_request_
{
     request_t request_type;
     void *request_pointer;
     answer_t answer_type;  <--------------- Answer type. ( Enum, define, etc ).
     int answer_buffer_size;  <--------------- User supplied answer
buffer size (in answer_data union units).
     int __out answer_buffer_used;  <-------- Answer buffer used size
(number of answers copied by the kernel).
     answer_data_t *answer_data_array; <-- Answer buffer array
(user-mode pointer).
} debug_request_t;

Now, in-case of multiple answers, you simply
copy_to_user((void *)&debug_request_copy->answer_data_array[count],
                    (void *)&kernel_answer,
                    sizeof(answer_data_t));
count ++;

.. To copy each answer to the user buffer.
Once the array is depleted, the kernel function returns with a valid
error code (E.g. -EEXIST) and tells to the user mode caller that
there's additional data to be read (E.g. until the kernel returns
-EWOULDBLOCK).

Alternatively (and somewhat more complex) you can setup mmap over file
handle, and simply map a static kernel buffer directly to the user
mode. Though, unless you need to stream huge amounts of data and/or
ioctl performance penalty [50-200ns] is too high, I wouldn't bother.

BTW, Most likely your are aware of this, but just in case, never
access the user mode buffer directly. When you first access the
request buffer you copy it (copy_from_user) to kernel debug_request
(no need to allocate it, considering its size, you shouldn't have any
issues using stack, even on i386).

- Gilboa



More information about the Linux-il mailing list